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

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
Метка: отменено
Строка 1: Строка 1:
(function($, mw){
( function ( $, mw ) {
     function detectAndFreeze(img){
     function parseChunks( buf ) {
         var xhr = new XMLHttpRequest();
         const dv = new DataView( buf );
         xhr.open('GET', img.src, true);
         let pos = 8;
         xhr.responseType = 'arraybuffer';
         const chunks = [];
         xhr.onload = function(){
         while ( pos < buf.byteLength ) {
             if (xhr.status < 200 || xhr.status >= 300) return;
             const length = dv.getUint32( pos );
             var bytes = new Uint8Array(xhr.response);
             const typeBytes = new Uint8Array( buf, pos + 4, 4 );
             for (var i = 0; i < bytes.length - 4; i++){
             const type = String.fromCharCode.apply( null, typeBytes );
                if (
            const dataStart = pos + 8;
                    bytes[i]  === 0x61 &&
            const dataEnd = dataStart + length;
                    bytes[i+1] === 0x63 &&
            const crcEnd = dataEnd + 4;
                    bytes[i+2] === 0x54 &&
            chunks.push({
                    bytes[i+3] === 0x4C
                type,
                ){
                start: pos,
                    freeze(img);
                 end: crcEnd
                    break;
            });
                 }
             pos = crcEnd;
             }
         }
         };
         return chunks;
         xhr.send();
     }
     }


     function freeze(img){
     async function detectAndStrip( img ) {
        var origW = img.getAttribute('width'),
            origH = img.getAttribute('height'),
            ow    = img.naturalWidth,
            oh    = img.naturalHeight,
            canvas = document.createElement('canvas');
        canvas.width  = ow;
        canvas.height = oh;
        canvas.getContext('2d').drawImage(img, 0, 0, ow, oh);
         try {
         try {
             img.src = canvas.toDataURL('image/png');
             const resp = await fetch( img.src );
             if (origW) img.setAttribute('width', origW);
            if ( !resp.ok ) return;
             if (origH) img.setAttribute('height', origH);
            const buf = await resp.arrayBuffer();
         } catch(e){}
            const chunks = parseChunks( buf );
 
             if ( !chunks.some( c => c.type === 'acTL' ) ) return;
 
            const keep = [];
            keep.push( buf.slice( 0, 8 ) );
             for ( const c of chunks ) {
                if ( c.type === 'acTL' || c.type === 'fcTL' ) continue;
                keep.push( buf.slice( c.start, c.end ) );
            }
 
            const blob = new Blob( keep, { type: 'image/png' } );
            const url  = URL.createObjectURL( blob );
 
            img.src = url;
         } catch ( e ) {
            console.error( 'freezeAPNG error:', e );
        }
     }
     }


     $(function(){
     $( () => {
         $('.freezeAPNG img[src$=".png"]').each(function(){
         $( '.freezeAPNG img[src$=".png"]' ).each( ( _, img ) => {
             if (this.complete) {
             if ( img.complete ) {
                 detectAndFreeze(this);
                 detectAndStrip( img );
             } else {
             } else {
                 this.addEventListener('load', function(){
                 img.addEventListener( 'load', () => detectAndStrip( img ), { once: true } );
                    detectAndFreeze(this);
                });
             }
             }
         });
         } );
     });
     } );
})(jQuery, mediaWiki);
} )( jQuery, mediaWiki );

Версия от 20:15, 30 июня 2025

( function ( $, mw ) {
    function parseChunks( buf ) {
        const dv = new DataView( buf );
        let pos = 8;
        const chunks = [];
        while ( pos < buf.byteLength ) {
            const length = dv.getUint32( pos );
            const typeBytes = new Uint8Array( buf, pos + 4, 4 );
            const type = String.fromCharCode.apply( null, typeBytes );
            const dataStart = pos + 8;
            const dataEnd = dataStart + length;
            const crcEnd = dataEnd + 4;
            chunks.push({
                type,
                start: pos,
                end: crcEnd
            });
            pos = crcEnd;
        }
        return chunks;
    }

    async function detectAndStrip( img ) {
        try {
            const resp = await fetch( img.src );
            if ( !resp.ok ) return;
            const buf = await resp.arrayBuffer();
            const chunks = parseChunks( buf );

            if ( !chunks.some( c => c.type === 'acTL' ) ) return;

            const keep = [];
            keep.push( buf.slice( 0, 8 ) );
            for ( const c of chunks ) {
                if ( c.type === 'acTL' || c.type === 'fcTL' ) continue;
                keep.push( buf.slice( c.start, c.end ) );
            }

            const blob = new Blob( keep, { type: 'image/png' } );
            const url  = URL.createObjectURL( blob );

            img.src = url;
        } catch ( e ) {
            console.error( 'freezeAPNG error:', e );
        }
    }

    $( () => {
        $( '.freezeAPNG img[src$=".png"]' ).each( ( _, img ) => {
            if ( img.complete ) {
                detectAndStrip( img );
            } else {
                img.addEventListener( 'load', () => detectAndStrip( img ), { once: true } );
            }
        } );
    } );
} )( jQuery, mediaWiki );