MediaWiki:Gadget-freezeAPNG.js: различия между версиями
Материал из Space Station 14 Вики
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) мНет описания правки Метка: отменено |
||
| Строка 1: | Строка 1: | ||
(function($, mw){ | ( function ( $, mw ) { | ||
function | 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; | ||
} | } | ||
function | async function detectAndStrip( img ) { | ||
try { | try { | ||
img.src = | const resp = await fetch( img.src ); | ||
if ( | if ( !resp.ok ) return; | ||
if ( | 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 ); | |||
} | |||
} | } | ||
$( | $( () => { | ||
$('.freezeAPNG img[src$=".png"]').each( | $( '.freezeAPNG img[src$=".png"]' ).each( ( _, img ) => { | ||
if ( | if ( img.complete ) { | ||
detectAndStrip( img ); | |||
} else { | } else { | ||
img.addEventListener( 'load', () => detectAndStrip( img ), { once: true } ); | |||
} | } | ||
}); | } ); | ||
}); | } ); | ||
})(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 );