MediaWiki:Gadget-freezeAPNG.js: различия между версиями

Материал из Space Station 14 Вики
мНет описания правки
Метка: ручная отмена
Нет описания правки
Строка 1: Строка 1:
(function($, mw){
(function($, mw){
     function detectAndFreeze(img){
     function detectAndFreeze(img){
        if (img.dataset.freezeProcessed) return;
         var xhr = new XMLHttpRequest();
         var xhr = new XMLHttpRequest();
         xhr.open('GET', img.src, true);
         xhr.open('GET', img.src, true);
Строка 14: Строка 15:
                     bytes[i+3] === 0x4C
                     bytes[i+3] === 0x4C
                 ){
                 ){
                     freeze(img);
                     freezeWithSwap(img);
                     break;
                     break;
                 }
                 }
             }
             }
         };
         };
        xhr.onerror = function(){ /* ignore */ };
         xhr.send();
         xhr.send();
     }
     }


     function freeze(img){
     function freezeWithSwap(img){
        if (img.dataset.freezeProcessed) return;
        img.dataset.freezeProcessed = '1';
 
         var origW = img.getAttribute('width'),
         var origW = img.getAttribute('width'),
             origH = img.getAttribute('height'),
             origH = img.getAttribute('height'),
             ow   = img.naturalWidth,
             originalDisplay = window.getComputedStyle(img).display || 'inline';
             oh   = img.naturalHeight,
 
             canvas = document.createElement('canvas');
        var animatedClone = img.cloneNode(true);
         canvas.width = ow;
        animatedClone.className = (animatedClone.className ? animatedClone.className + ' ' : '') + 'freezeAPNG-animated';
        animatedClone.style.display = 'none';
        animatedClone.style.visibility = 'visible';
        if (origW) animatedClone.setAttribute('width', origW);
        if (origH) animatedClone.setAttribute('height', origH);
 
        var ow = img.naturalWidth || img.width || 0,
             oh = img.naturalHeight || img.height || 0;
 
        if (!ow || !oh) {
             return;
        }
 
        var canvas = document.createElement('canvas');
         canvas.width = ow;
         canvas.height = oh;
         canvas.height = oh;
         canvas.getContext('2d').drawImage(img, 0, 0, ow, oh);
         var ctx = canvas.getContext('2d');
        try {
            ctx.drawImage(img, 0, 0, ow, oh);
        } catch (e) {
            return;
        }
 
        var frozenData;
        try {
            frozenData = canvas.toDataURL('image/png');
        } catch (e) {
            return;
        }
 
        var parent = img.parentNode;
        if (!parent) return;
 
        if (img.nextSibling) parent.insertBefore(animatedClone, img.nextSibling);
        else parent.appendChild(animatedClone);
 
         try {
         try {
             img.src = canvas.toDataURL('image/png');
             img.src = frozenData;
             if (origW) img.setAttribute('width', origW);
             if (origW) img.setAttribute('width', origW);
             if (origH) img.setAttribute('height', origH);
             if (origH) img.setAttribute('height', origH);
         } catch(e){}
         } catch (e){ /* ignore */ }
 
        img.style.display = originalDisplay;
        animatedClone.style.display = 'none';
 
        var container = img.closest && img.closest('.freezeAPNG') ? img.closest('.freezeAPNG') : parent;
        var showAnimated = function(){
            img.style.display = 'none';
            animatedClone.style.display = originalDisplay;
        };
        var showFrozen = function(){
            animatedClone.style.display = 'none';
            img.style.display = originalDisplay;
        };
 
        container.addEventListener('mouseenter', showAnimated);
        container.addEventListener('mouseleave', showFrozen);
 
        container.addEventListener('focusin', showAnimated);
        container.addEventListener('focusout', showFrozen);
 
        var touchTimeout = null;
        container.addEventListener('touchstart', function(e){
            showAnimated();
            if (touchTimeout) clearTimeout(touchTimeout);
            touchTimeout = setTimeout(function(){
                showFrozen();
            }, 1200);
        }, {passive: true});
        container.addEventListener('touchend', function(){ if (touchTimeout) { clearTimeout(touchTimeout); touchTimeout = null; showFrozen(); } }, {passive: true});
        container.addEventListener('touchcancel', function(){ if (touchTimeout) { clearTimeout(touchTimeout); touchTimeout = null; showFrozen(); } }, {passive: true});
     }
     }


     $(function(){
     $(function(){
         $('.freezeAPNG img[src$=".png"]').each(function(){
         $('.freezeAPNG img[src$=".png"]').each(function(){
             if (this.complete) {
            var img = this;
                 detectAndFreeze(this);
            if (img.dataset.freezeProcessed) return;
             if (img.complete) {
                 detectAndFreeze(img);
             } else {
             } else {
                 this.addEventListener('load', function(){
                 img.addEventListener('load', function(){
                     detectAndFreeze(this);
                     detectAndFreeze(img);
                 });
                 });
             }
             }

Версия от 20:32, 17 марта 2026

(function($, mw){
    function detectAndFreeze(img){
        if (img.dataset.freezeProcessed) return;
        var xhr = new XMLHttpRequest();
        xhr.open('GET', img.src, true);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function(){
            if (xhr.status < 200 || xhr.status >= 300) return;
            var bytes = new Uint8Array(xhr.response);
            for (var i = 0; i < bytes.length - 4; i++){
                if (
                    bytes[i]   === 0x61 &&
                    bytes[i+1] === 0x63 &&
                    bytes[i+2] === 0x54 &&
                    bytes[i+3] === 0x4C
                ){
                    freezeWithSwap(img);
                    break;
                }
            }
        };
        xhr.onerror = function(){ /* ignore */ };
        xhr.send();
    }

    function freezeWithSwap(img){
        if (img.dataset.freezeProcessed) return;
        img.dataset.freezeProcessed = '1';

        var origW = img.getAttribute('width'),
            origH = img.getAttribute('height'),
            originalDisplay = window.getComputedStyle(img).display || 'inline';

        var animatedClone = img.cloneNode(true);
        animatedClone.className = (animatedClone.className ? animatedClone.className + ' ' : '') + 'freezeAPNG-animated';
        animatedClone.style.display = 'none';
        animatedClone.style.visibility = 'visible';
        if (origW) animatedClone.setAttribute('width', origW);
        if (origH) animatedClone.setAttribute('height', origH);

        var ow = img.naturalWidth || img.width || 0,
            oh = img.naturalHeight || img.height || 0;

        if (!ow || !oh) {
            return;
        }

        var canvas = document.createElement('canvas');
        canvas.width = ow;
        canvas.height = oh;
        var ctx = canvas.getContext('2d');
        try {
            ctx.drawImage(img, 0, 0, ow, oh);
        } catch (e) {
            return;
        }

        var frozenData;
        try {
            frozenData = canvas.toDataURL('image/png');
        } catch (e) {
            return;
        }

        var parent = img.parentNode;
        if (!parent) return;

        if (img.nextSibling) parent.insertBefore(animatedClone, img.nextSibling);
        else parent.appendChild(animatedClone);

        try {
            img.src = frozenData;
            if (origW) img.setAttribute('width', origW);
            if (origH) img.setAttribute('height', origH);
        } catch (e){ /* ignore */ }

        img.style.display = originalDisplay;
        animatedClone.style.display = 'none';

        var container = img.closest && img.closest('.freezeAPNG') ? img.closest('.freezeAPNG') : parent;
        var showAnimated = function(){
            img.style.display = 'none';
            animatedClone.style.display = originalDisplay;
        };
        var showFrozen = function(){
            animatedClone.style.display = 'none';
            img.style.display = originalDisplay;
        };

        container.addEventListener('mouseenter', showAnimated);
        container.addEventListener('mouseleave', showFrozen);

        container.addEventListener('focusin', showAnimated);
        container.addEventListener('focusout', showFrozen);

        var touchTimeout = null;
        container.addEventListener('touchstart', function(e){
            showAnimated();
            if (touchTimeout) clearTimeout(touchTimeout);
            touchTimeout = setTimeout(function(){
                showFrozen();
            }, 1200);
        }, {passive: true});
        container.addEventListener('touchend', function(){ if (touchTimeout) { clearTimeout(touchTimeout); touchTimeout = null; showFrozen(); } }, {passive: true});
        container.addEventListener('touchcancel', function(){ if (touchTimeout) { clearTimeout(touchTimeout); touchTimeout = null; showFrozen(); } }, {passive: true});
    }

    $(function(){
        $('.freezeAPNG img[src$=".png"]').each(function(){
            var img = this;
            if (img.dataset.freezeProcessed) return;
            if (img.complete) {
                detectAndFreeze(img);
            } else {
                img.addEventListener('load', function(){
                    detectAndFreeze(img);
                });
            }
        });
    });
})(jQuery, mediaWiki);