diff options
author | Ed Sanders <esanders@wikimedia.org> | 2024-11-21 17:09:04 +0000 |
---|---|---|
committer | Ed Sanders <esanders@wikimedia.org> | 2024-11-21 17:09:04 +0000 |
commit | db5b086b760d5ccaccb2917c572fa951ee48a4af (patch) | |
tree | 35bcf889bff2b6b7eae0255af5e2289bec573f06 /resources/src/mediawiki.deflate | |
parent | 47108cf44c0e2824977fb0bda7b358ee75b78080 (diff) | |
download | mediawikicore-db5b086b760d5ccaccb2917c572fa951ee48a4af.tar.gz mediawikicore-db5b086b760d5ccaccb2917c572fa951ee48a4af.zip |
mediawiki.deflate: Support 'deflate' as well as 'deflate-raw'
The latter was only added in Chrome 103, as opposed to Chrome 80.
'deflate-raw' just removes the header and checksum which we
can do manually.
Change-Id: Ia26768e080663be3615184e117bed20e978a91fa
Diffstat (limited to 'resources/src/mediawiki.deflate')
-rw-r--r-- | resources/src/mediawiki.deflate/mw.deflate.js | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/resources/src/mediawiki.deflate/mw.deflate.js b/resources/src/mediawiki.deflate/mw.deflate.js index a485f556eb87..c77868d8b134 100644 --- a/resources/src/mediawiki.deflate/mw.deflate.js +++ b/resources/src/mediawiki.deflate/mw.deflate.js @@ -12,21 +12,6 @@ mw.deflate = function ( data ) { return 'rawdeflate,' + bytesToBase64( pako.deflateRaw( data, { level: 5 } ) ); }; -let compressionStreamAvailable; -// Check if CompressionStream is available and deflate-raw is an option -function isCompressionStreamAvailable() { - if ( compressionStreamAvailable === undefined ) { - try { - // eslint-disable-next-line no-new - new CompressionStream( 'deflate-raw' ); - compressionStreamAvailable = true; - } catch ( e ) { - compressionStreamAvailable = false; - } - } - return compressionStreamAvailable; -} - /** * Convert a byte stream to base64 text. * @@ -38,22 +23,45 @@ function isCompressionStreamAvailable() { * @return {Promise<string>} Compressed data */ mw.deflateAsync = function ( data ) { - if ( isCompressionStreamAvailable() ) { + // Support: Chrome < 80, Firefox < 113, Safari < 16.4 + if ( window.CompressionStream ) { return compress( data ).then( ( buffer ) => 'rawdeflate,' + bytesToBase64( new Uint8Array( buffer ) ) ); } else { return Promise.resolve( mw.deflate( data ) ); } }; +function stripHeaderAndChecksum( buffer ) { + // Header is 2 bytes, checksum is the last 4 bytes + return buffer.slice( 2, buffer.byteLength - 4 ); +} + function compress( string ) { const byteArray = new TextEncoder().encode( string ); - // eslint-disable-next-line compat/compat - const cs = new CompressionStream( 'deflate-raw' ); + let cs, isRaw; + // Support: Chrome < 103 + // Not all browsers with CompressionStream support 'deflate-raw' + // so fall back to the universally-supported 'deflate' and + // remove the header/checksum manually + try { + // eslint-disable-next-line compat/compat + cs = new CompressionStream( 'deflate-raw' ); + isRaw = true; + } catch ( e ) { + // eslint-disable-next-line compat/compat + cs = new CompressionStream( 'deflate' ); + isRaw = false; + } const writer = cs.writable.getWriter(); writer.write( byteArray ); writer.close(); - return new Response( cs.readable ).arrayBuffer(); + const arrayBuffer = new Response( cs.readable ).arrayBuffer(); + if ( isRaw ) { + return arrayBuffer; + } else { + return arrayBuffer.then( ( buffer ) => stripHeaderAndChecksum( new Uint8Array( buffer ) ) ); + } } /* |