1/** 2 * HiRes Image: Enhances image sharpness by loading original files. 3 */ 4(function() { 5 "use strict"; 6 7 const sharpen = function(img) { 8 if (!img || img.dataset.hiResProcessed) return; 9 10 try { 11 const url = new URL(img.src); 12 13 // Match images scaled by DokuWiki (containing w= or h=) 14 if (url.searchParams.has('w') || url.searchParams.has('h')) { 15 const w = url.searchParams.get('w'); 16 const h = url.searchParams.get('h'); 17 18 // Remove scaling parameters and security tokens to fetch original 19 url.searchParams.delete('w'); 20 url.searchParams.delete('h'); 21 url.searchParams.delete('tok'); 22 23 img.src = url.toString(); 24 25 // Apply CSS constraints to maintain intended layout size 26 if (w) { 27 img.style.width = w + 'px'; 28 img.style.height = 'auto'; 29 } else if (h) { 30 img.style.height = h + 'px'; 31 img.style.width = 'auto'; 32 } 33 34 // Optimization for High-DPI (Retina) displays 35 img.style.imageRendering = '-webkit-optimize-contrast'; 36 img.dataset.hiResProcessed = "true"; 37 } 38 } catch (e) { 39 // Ignore parsing errors for non-standard URLs 40 } 41 }; 42 43 const scan = function() { 44 const sel = 'img.media, img.medialeft, img.mediaright, img.mediacenter'; 45 document.querySelectorAll(sel).forEach(sharpen); 46 }; 47 48 // Run on initial page load 49 if (document.readyState === 'loading') { 50 document.addEventListener('DOMContentLoaded', scan); 51 } else { 52 scan(); // Run immediately 53 } 54 55 // Dynamic observer for editors (like Prosemirror) or async content 56 const observer = new MutationObserver(function(mutations) { 57 mutations.forEach(function(mutation) { 58 if (mutation.addedNodes) { 59 mutation.addedNodes.forEach(function(node) { 60 if (node.nodeType === 1) { 61 if (node.tagName === 'IMG') { 62 sharpen(node); 63 } else { 64 node.querySelectorAll('img').forEach(sharpen); 65 } 66 } 67 }); 68 } 69 }); 70 }); 71 72 observer.observe(document.body, { childList: true, subtree: true }); 73})();