MediaWiki:Common.js: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 1,053: Line 1,053:
     $(document).off('click.print', '#print-button');
     $(document).off('click.print', '#print-button');


    // Warm the font cache in the PARENT document (no Date.now; you already version via ?v=)
     function preloadFontForPrint() {
     function preloadFontForPrint() {
         var link = document.createElement('link');
         var link = document.createElement('link');
Line 1,058: Line 1,059:
         link.as  = 'font';
         link.as  = 'font';
         link.type = 'font/woff2';
         link.type = 'font/woff2';
         link.href = '/fonts/HALColant-TextRegular.woff2?v=20250820&_=' + Date.now();
         link.href = '/fonts/HALColant-TextRegular.woff2?v=20250820';
         link.crossOrigin = 'anonymous';
         link.crossOrigin = 'anonymous';
         document.head.appendChild(link);
         document.head.appendChild(link);
         setTimeout(function(){ document.head.removeChild(link); }, 4000);
         // keep it; no need to remove immediately
     }
     }


     $(document).on('click.print', '#print-button', function () {
     $(document).on('click.print', '#print-button', function () {
        preloadFontForPrint();
    preloadFontForPrint();
        var title = window.currentEntryTitle; // e.g. "090"
        if (!title) { console.warn('[print] no currentEntryTitle'); window.print(); return; }


        var pageUrl = mw.util.getUrl(title);
    var title = window.currentEntryTitle; // e.g. "090"
        var pageUrlFresh = cacheBust(pageUrl);                          // ⬅ cache bust
    if (!title) { console.warn('[print] no currentEntryTitle'); window.print(); return; }
        console.log('[print] fetching page HTML:', pageUrlFresh);


        $.get(pageUrlFresh).done(function (html) {
    var pageUrl = mw.util.getUrl(title);
            var $tmp = $('<div>').html(html);
    var pageUrlFresh = pageUrl + (pageUrl.indexOf('?') > -1 ? '&' : '?') + '_=' + Date.now();
            var $print = $tmp.find('.print-only').first();
    console.log('[print] fetching page HTML:', pageUrlFresh);
            console.log('[print] .print-only found:', $print.length);
            if (!$print.length) { console.warn('[print] no .print-only found; fallback print'); window.print(); return; }


            var iframe = document.createElement('iframe');
    $.get(pageUrlFresh).done(function (html) {
            iframe.style.position = 'fixed';
        var $tmp = $('<div>').html(html);
            iframe.style.right = '0';
        var $print = $tmp.find('.print-only').first();
            iframe.style.bottom = '0';
        console.log('[print] .print-only found:', $print.length);
            iframe.style.width = '0';
        if (!$print.length) { console.warn('[print] no .print-only found; fallback print'); window.print(); return; }
            iframe.style.height = '0';
            iframe.style.border = '0';
            document.body.appendChild(iframe);


            var doc = iframe.contentDocument || iframe.contentWindow.document;
        var iframe = document.createElement('iframe');
        iframe.style.position = 'fixed';
        iframe.style.right = '0';
        iframe.style.bottom = '0';
        iframe.style.width = '0';
        iframe.style.height = '0';
        iframe.style.border = '0';
        document.body.appendChild(iframe);


            var printCssUrl = '/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css';
        var doc = iframe.contentDocument || iframe.contentWindow.document;
            var printCssFresh = cacheBust(printCssUrl);                   // ⬅ cache bust
        doc.open();
        doc.write('<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>');
        doc.close();


            doc.open();
        // 1) Inject PRINT CSS with onload so we can await it
            doc.write(
        var printCssUrl = '/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css';
            '<!doctype html><html><head><meta charset="utf-8">' +
        var printCssFresh = printCssUrl + (printCssUrl.indexOf('?') > -1 ? '&' : '?') + '_=' + Date.now();
            '<title>Print</title>' +
            '<link rel="stylesheet" href="' + printCssFresh + '">' +
            '</head><body>' + $print.prop('outerHTML') + '</body></html>'
            );
            doc.close();


            iframe.onload = function () {
        var linkCss = doc.createElement('link');
            try { iframe.contentWindow.focus(); iframe.contentWindow.print(); }
        linkCss.rel  = 'stylesheet';
             finally { setTimeout(function () { document.body.removeChild(iframe); }, 500); }
        linkCss.href = printCssFresh;
            };
 
         }).fail(function (xhr) {
        var cssLoaded = new Promise(function(resolve, reject){
            console.warn('[print] fetch failed:', xhr && xhr.status, xhr && xhr.statusText);
        linkCss.onload = function(){ resolve(); };
            window.print();
        linkCss.onerror = function(){ console.warn('[print] CSS failed to load'); resolve(); }; // don’t block print entirely
        });
 
        // 2) Preload the font INSIDE the iframe too (best chance Chrome has it in time)
        var linkFont = doc.createElement('link');
        linkFont.rel = 'preload';
        linkFont.as  = 'font';
        linkFont.type = 'font/woff2';
        linkFont.href = '/fonts/HALColant-TextRegular.woff2?v=20250820';
        linkFont.crossOrigin = 'anonymous';
 
        doc.head.appendChild(linkFont);
        doc.head.appendChild(linkCss);
 
        // 3) Inject the printable HTML
        doc.body.innerHTML = $print.prop('outerHTML');
 
        // 4) Wait for images (decode) + fonts + css
        function waitImages() {
        var imgs = Array.from(doc.images || []);
        if (!imgs.length) return Promise.resolve();
        return Promise.all(imgs.map(function(img){
            // decode() is best; fallback to load/error
            if (img.decode) {
            return img.decode().catch(function(){ /* ignore */ });
             }
            return new Promise(function(res){ if (img.complete) return res(); img.onload = img.onerror = function(){ res(); }; });
        }));
         }
 
        function waitFonts(timeoutMs) {
        // If fonts API missing (older engine), resolve immediately
        if (!doc.fonts || !doc.fonts.ready) return Promise.resolve();
        var ready = doc.fonts.ready;
        if (typeof Promise.race !== 'function') return ready;
        // timeout guard so we never hang
        var t = new Promise(function(res){ setTimeout(res, timeoutMs || 1200); });
        return Promise.race([ready, t]);
        }
 
        function nextFrame() {
        return new Promise(function(res){ (iframe.contentWindow.requestAnimationFrame || setTimeout)(res, 0); });
        }
 
        Promise.all([
        cssLoaded,
        waitImages(),
        waitFonts(1200),
        nextFrame(), // settle layout
        ]).then(function(){
        try { iframe.contentWindow.focus(); iframe.contentWindow.print(); }
        finally { setTimeout(function () { document.body.removeChild(iframe); }, 500); }
         });
         });
    }).fail(function (xhr) {
        console.warn('[print] fetch failed:', xhr && xhr.status, xhr && xhr.statusText);
        window.print();
     });
     });
    });




Navigation menu