1(function () { 2 const enableLogging = false; // Enable debug logs 3 // Helper to check if the current page should be skipped for WebP transformation 4 function shouldSkipPage() { 5 const pathname = window.location.pathname.toLowerCase(); 6 if (enableLogging) { 7 console.log('WebP Debug: Current path:', pathname); 8 console.log('WebP Skip Paths:', window.drupalSettings.gevWebpSkipPaths); 9 } 10 if (window.drupalSettings && Array.isArray(window.drupalSettings.gevWebpSkipPaths)) { 11 return window.drupalSettings.gevWebpSkipPaths.some(function(pattern) { 12 pattern = pattern.trim().toLowerCase(); 13 if (!pattern) return false; 14 // Wildcard match: /admin* or /user/* 15 if (pattern.endsWith('*')) { 16 return pathname.startsWith(pattern.slice(0, -1)); 17 } 18 return pathname === pattern; 19 }); 20 } 21 return false; 22 } 23 24 function convertToWebpExt(imgURL) { 25 if (!imgURL) return null; 26 const ext = imgURL.split('.').pop().split('?')[0].toLowerCase(); 27 if (ext === 'svg' || ext === 'webp') return null; 28 return imgURL.replace(/\.(jpe?g|png|gif)(\?.*)?$/i, '.webp$2'); 29 } 30 31 function enhanceExistingPictures() { 32 const pictures = document.querySelectorAll('picture'); 33 34 pictures.forEach((picture, i) => { 35 const img = picture.querySelector('img'); 36 if (!img) return; 37 38 const originalSrc = img.getAttribute('data-src') || img.getAttribute('src'); 39 const webpSrc = convertToWebpExt(originalSrc); 40 if (!webpSrc) { 41 if (enableLogging) console.log(`[Picture ${i}] Skipped unsupported format: ${originalSrc}`); 42 return; 43 } 44 45 const hasWebpSource = [...picture.querySelectorAll('source')].some( 46 (source) => source.getAttribute('type') === 'image/webp' 47 ); 48 if (hasWebpSource) { 49 if (enableLogging) console.log(`[Picture ${i}] WebP source already present: ${originalSrc}`); 50 return; 51 } 52 53 const webpSource = document.createElement('source'); 54 webpSource.setAttribute('type', 'image/webp'); 55 webpSource.setAttribute('data-srcset', webpSrc); 56 57 // Only insert if img is still a child of picture 58 if (img.parentNode === picture) { 59 picture.insertBefore(webpSource, img); 60 } 61 62 if (enableLogging) console.log(`[Picture ${i}] Inserted WebP source: ${webpSrc}`); 63 }); 64 } 65 66 function wrapStandaloneImages() { 67 const images = document.querySelectorAll('img:not(picture img)'); 68 69 images.forEach((img, i) => { 70 if (img.closest('picture')) return; 71 72 const originalSrc = img.getAttribute('data-src') || img.getAttribute('src'); 73 const webpSrc = convertToWebpExt(originalSrc); 74 if (!webpSrc) { 75 if (enableLogging) console.log(`[Image ${i}] Skipped unsupported format: ${originalSrc}`); 76 return; 77 } 78 79 const picture = document.createElement('picture'); 80 81 const webpSource = document.createElement('source'); 82 webpSource.setAttribute('type', 'image/webp'); 83 webpSource.setAttribute('data-srcset', webpSrc); 84 85 const imgClone = img.cloneNode(false); 86 imgClone.removeAttribute('src'); 87 imgClone.removeAttribute('srcset'); 88 imgClone.removeAttribute('sizes'); 89 90 if (!imgClone.classList.contains('lazyload')) { 91 imgClone.classList.add('lazyload'); 92 } 93 94 if (!imgClone.hasAttribute('data-src') && originalSrc) { 95 imgClone.setAttribute('data-src', originalSrc); 96 } 97 98 picture.appendChild(webpSource); 99 picture.appendChild(imgClone); 100 img.replaceWith(picture); 101 102 if (enableLogging) console.log(`[Image ${i}] Wrapped in <picture>: ${originalSrc} â ${webpSrc}`); 103 }); 104 } 105 106 function start() { 107 if (shouldSkipPage()) { 108 if (enableLogging) console.log('Skipping WebP transformation for this page'); 109 return; // Skip the WebP transformations on configured pages 110 } 111 112 if ('requestIdleCallback' in window) { 113 requestIdleCallback(() => { 114 enhanceExistingPictures(); 115 wrapStandaloneImages(); 116 }); 117 } else { 118 setTimeout(() => { 119 enhanceExistingPictures(); 120 wrapStandaloneImages(); 121 }, 200); 122 } 123 } 124 125 if (document.readyState === 'loading') { 126 document.addEventListener('DOMContentLoaded', start); 127 } else { 128 start(); 129 } 130})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.