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

Материал из Space Station 14 Вики
Нет описания правки
Нет описания правки
 
(не показана 1 промежуточная версия этого же участника)
Строка 1: Строка 1:
(function($, mw){
(function($, mw){
    function detectAndFreeze(img){
  function detectAndPrepare(img){
        if (img.dataset.freezeProcessed) return;
    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);
        xhr.responseType = 'arraybuffer';
    xhr.responseType = 'arraybuffer';
        xhr.onload = function(){
    xhr.onload = function(){
            if (xhr.status < 200 || xhr.status >= 300) return;
      if (xhr.status < 200 || xhr.status >= 300) return;
            var bytes = new Uint8Array(xhr.response);
      var bytes = new Uint8Array(xhr.response);
            for (var i = 0; i < bytes.length - 4; i++){
      for (var i = 0; i < bytes.length - 4; i++){
                if (
        if (
                    bytes[i]  === 0x61 &&
          bytes[i]  === 0x61 &&
                    bytes[i+1] === 0x63 &&
          bytes[i+1] === 0x63 &&
                    bytes[i+2] === 0x54 &&
          bytes[i+2] === 0x54 &&
                    bytes[i+3] === 0x4C
          bytes[i+3] === 0x4C
                ){
        ){
                    freezeWithSwap(img);
          prepareSwap(img);
                    break;
          break;
                }
        }
            }
      }
        };
    };
        xhr.onerror = function(){ /* ignore */ };
    xhr.onerror = function(){ /* ignore */ };
        xhr.send();
    xhr.send();
    }
  }


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


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


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


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


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


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


        var frozenData;
    var frozenData;
        try {
    try {
            frozenData = canvas.toDataURL('image/png');
      frozenData = canvas.toDataURL('image/png');
        } catch (e) {
    } catch (e) {
            return;
      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;
    var container = img.closest('.freezeAPNG') || img.parentNode;
        animatedClone.style.display = 'none';
    if (!container) return;
    container.classList.add('freezeAPNG');


        var container = img.closest && img.closest('.freezeAPNG') ? img.closest('.freezeAPNG') : parent;
    img.classList.add('freezeAPNG__freeze');
        var showAnimated = function(){
    try {
            img.style.display = 'none';
      img.src = frozenData;
            animatedClone.style.display = originalDisplay;
    } catch (e){ /* ignore */ }
        };
    if (origW) img.setAttribute('width', origW);
        var showFrozen = function(){
    if (origH) img.setAttribute('height', origH);
            animatedClone.style.display = 'none';
            img.style.display = originalDisplay;
        };


        container.addEventListener('mouseenter', showAnimated);
    container.appendChild(animated);
        container.addEventListener('mouseleave', showFrozen);
    container.addEventListener('focusin', function(){ container.classList.add('freezeAPNG--active'); });
    container.addEventListener('focusout', function(){ container.classList.remove('freezeAPNG--active'); });


        container.addEventListener('focusin', showAnimated);
    var touchTimer = null;
        container.addEventListener('focusout', showFrozen);
    container.addEventListener('touchstart', function(e){
 
      container.classList.add('freezeAPNG--active');
        var touchTimeout = null;
      if (touchTimer) clearTimeout(touchTimer);
        container.addEventListener('touchstart', function(e){
      touchTimer = setTimeout(function(){
            showAnimated();
        container.classList.remove('freezeAPNG--active');
            if (touchTimeout) clearTimeout(touchTimeout);
        touchTimer = null;
            touchTimeout = setTimeout(function(){
      }, 1400);
                showFrozen();
    }, {passive: true});
            }, 1200);
    container.addEventListener('touchend', function(){ if (touchTimer) { clearTimeout(touchTimer); touchTimer = null; container.classList.remove('freezeAPNG--active'); } }, {passive: true});
        }, {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(){
            var img = this;
      var img = this;
            if (img.dataset.freezeProcessed) return;
      if (img.dataset.freezeProcessed) return;
            if (img.complete) {
      if (img.complete) {
                detectAndFreeze(img);
        detectAndPrepare(img);
            } else {
      } else {
                img.addEventListener('load', function(){
        img.addEventListener('load', function(){ detectAndPrepare(this); });
                    detectAndFreeze(img);
      }
                });
            }
        });
     });
     });
  });
})(jQuery, mediaWiki);
})(jQuery, mediaWiki);

Текущая версия от 20:46, 17 марта 2026

(function($, mw){
  function detectAndPrepare(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
        ){
          prepareSwap(img);
          break;
        }
      }
    };
    xhr.onerror = function(){ /* ignore */ };
    xhr.send();
  }

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

    var origW = img.getAttribute('width'),
        origH = img.getAttribute('height');

    var animated = img.cloneNode(true);
    animated.classList.add('freezeAPNG__animation');
    if (origW) animated.setAttribute('width', origW);
    if (origH) animated.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 container = img.closest('.freezeAPNG') || img.parentNode;
    if (!container) return;
    container.classList.add('freezeAPNG');

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

    container.appendChild(animated);
    container.addEventListener('focusin', function(){ container.classList.add('freezeAPNG--active'); });
    container.addEventListener('focusout', function(){ container.classList.remove('freezeAPNG--active'); });

    var touchTimer = null;
    container.addEventListener('touchstart', function(e){
      container.classList.add('freezeAPNG--active');
      if (touchTimer) clearTimeout(touchTimer);
      touchTimer = setTimeout(function(){
        container.classList.remove('freezeAPNG--active');
        touchTimer = null;
      }, 1400);
    }, {passive: true});
    container.addEventListener('touchend', function(){ if (touchTimer) { clearTimeout(touchTimer); touchTimer = null; container.classList.remove('freezeAPNG--active'); } }, {passive: true});
  }

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