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 } 29 else { 30 img.style.width = 'auto'; 31 } 32 33 if (h) { 34 img.style.height = h + 'px'; 35 } 36 else { 37 img.style.height = 'auto'; 38 } 39 40 // Optimization for High-DPI (Retina) displays 41 img.style.imageRendering = '-webkit-optimize-contrast'; 42 img.dataset.hiResProcessed = "true"; 43 } 44 } catch (e) { 45 // Ignore parsing errors for non-standard URLs 46 } 47 }; 48 49 const scan = function() { 50 const sel = 'img.media, img.medialeft, img.mediaright, img.mediacenter'; 51 document.querySelectorAll(sel).forEach(sharpen); 52 }; 53 54 // Run on initial page load 55 if (document.readyState === 'loading') { 56 document.addEventListener('DOMContentLoaded', scan); 57 } else { 58 scan(); // Run immediately 59 } 60 61 // Dynamic observer for editors (like Prosemirror) or async content 62 const observer = new MutationObserver(function(mutations) { 63 mutations.forEach(function(mutation) { 64 if (mutation.addedNodes) { 65 mutation.addedNodes.forEach(function(node) { 66 if (node.nodeType === 1) { 67 if (node.tagName === 'IMG') { 68 sharpen(node); 69 } else { 70 node.querySelectorAll('img').forEach(sharpen); 71 } 72 } 73 }); 74 } 75 }); 76 }); 77 78 observer.observe(document.body, { childList: true, subtree: true }); 79})();