mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-18 08:47:35 -04:00
Fix memory issues
Former-commit-id: 3523937e13175610cd516968174f1403675500b5 [formerly eb79c290efd7ff9d0710d0f8ac8d72e7fcb5a30b] [formerly cd8660f1cdfd2c69728aa8a3bf93b50255902b82] [formerly 513913cb38d94c86b0e1b62657d9682420360120 [formerly 17d84e571a88071850bdd462395ad3dd540006b8 [formerly 6ea3f6a62e410dd6c9f8313fb1498d8a8a3f6388]]] Former-commit-id: 68398e55efae1db32da3142118acaada5f821b32 [formerly 78891836e99634606af52ba4beddb36aab969071 [formerly 96eeafc04911f4a36a86e96e69870c2708fc0290]] Former-commit-id: f57e0da2589c945c52ee8b58f92e6b47c00ab584 [formerly c71c78a09ecbc86cbface5bb1510f4cf327106af] Former-commit-id: bcb00d466675411c7533f1d45f223c92eb8f7534
This commit is contained in:
parent
5c27860a3a
commit
40ef8ede77
@ -248,7 +248,7 @@
|
|||||||
<a class="btn btn-primary" style="display:none;" title="Back" id="btnBackAlt"><span class="glyphicon glyphicon-circle-arrow-left"></span></a>
|
<a class="btn btn-primary" style="display:none;" title="Back" id="btnBackAlt"><span class="glyphicon glyphicon-circle-arrow-left"></span></a>
|
||||||
<a class="btn btn-primary" style="display:none;" title="Forward" id="btnForwardAlt"><span class="glyphicon glyphicon-circle-arrow-right"></span></a>
|
<a class="btn btn-primary" style="display:none;" title="Forward" id="btnForwardAlt"><span class="glyphicon glyphicon-circle-arrow-right"></span></a>
|
||||||
</span>
|
</span>
|
||||||
<input type="search" id="prefix" placeholder="Search [with .*] or type a space..."
|
<input type="search" id="prefix" placeholder="Search [.*] or type a space..."
|
||||||
class="form-control" style="z-index: 0; width: 99.5%" />
|
class="form-control" style="z-index: 0; width: 99.5%" />
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<a class="btn btn-primary" title="Article Search" id="searchArticles" style="display:none;"><span class="glyphicon glyphicon-book"></span></a>
|
<a class="btn btn-primary" title="Article Search" id="searchArticles" style="display:none;"><span class="glyphicon glyphicon-book"></span></a>
|
||||||
|
@ -429,8 +429,7 @@ require.config({
|
|||||||
},
|
},
|
||||||
'bootstrap': {
|
'bootstrap': {
|
||||||
deps: ['jquery']
|
deps: ['jquery']
|
||||||
},
|
}
|
||||||
'webpHeroBundle': ''
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,170 +1,170 @@
|
|||||||
/**
|
/**
|
||||||
* xzdec_wrapper.js: Javascript wrapper around compiled xz decompressor.
|
* xzdec_wrapper.js: Javascript wrapper around compiled xz decompressor.
|
||||||
*
|
*
|
||||||
* Copyright 2015 Mossroy and contributors
|
* Copyright 2015 Mossroy and contributors
|
||||||
* License GPL v3:
|
* License GPL v3:
|
||||||
*
|
*
|
||||||
* This file is part of Kiwix.
|
* This file is part of Kiwix.
|
||||||
*
|
*
|
||||||
* Kiwix is free software: you can redistribute it and/or modify
|
* Kiwix is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Kiwix is distributed in the hope that it will be useful,
|
* Kiwix is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
define(['xzdec'], function() {
|
define(['xzdec'], function() {
|
||||||
// DEV: xzdec.js emits a global Module variable, which cannot be set in requireJS function line above, though it can be loaded in definition
|
// DEV: xzdec.js emits a global Module variable, which cannot be set in requireJS function line above, though it can be loaded in definition
|
||||||
var xzdec = Module;
|
var xzdec = Module;
|
||||||
xzdec._init();
|
xzdec._init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of milliseconds to wait for the decompressor to be available for another chunk
|
* Number of milliseconds to wait for the decompressor to be available for another chunk
|
||||||
* @type Integer
|
* @type Integer
|
||||||
*/
|
*/
|
||||||
var DELAY_WAITING_IDLE_DECOMPRESSOR = 50;
|
var DELAY_WAITING_IDLE_DECOMPRESSOR = 50;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the decompressor already working?
|
* Is the decompressor already working?
|
||||||
* @type Boolean
|
* @type Boolean
|
||||||
*/
|
*/
|
||||||
var busy = false;
|
var busy = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef Decompressor
|
* @typedef Decompressor
|
||||||
* @property {Integer} _chunkSize
|
* @property {Integer} _chunkSize
|
||||||
* @property {FileReader} _reader
|
* @property {FileReader} _reader
|
||||||
* @property {unresolved} _decHandle
|
* @property {unresolved} _decHandle
|
||||||
* @property {Integer} _inStreamPos
|
* @property {Integer} _inStreamPos
|
||||||
* @property {Integer} _outStreamPos
|
* @property {Integer} _outStreamPos
|
||||||
* @property {Array} _outBuffer
|
* @property {Array} _outBuffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {FileReader} reader
|
* @param {FileReader} reader
|
||||||
* @param {Integer} chunkSize
|
* @param {Integer} chunkSize
|
||||||
* @returns {Decompressor}
|
* @returns {Decompressor}
|
||||||
*/
|
*/
|
||||||
function Decompressor(reader, chunkSize) {
|
function Decompressor(reader, chunkSize) {
|
||||||
this._chunkSize = chunkSize || 1024 * 5;
|
this._chunkSize = chunkSize || 1024 * 5;
|
||||||
this._reader = reader;
|
this._reader = reader;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Read length bytes, offset into the decompressed stream. Consecutive calls may only
|
* Read length bytes, offset into the decompressed stream. Consecutive calls may only
|
||||||
* advance in the stream and may not overlap.
|
* advance in the stream and may not overlap.
|
||||||
* @param {Integer} offset
|
* @param {Integer} offset
|
||||||
* @param {Integer} length
|
* @param {Integer} length
|
||||||
*/
|
*/
|
||||||
Decompressor.prototype.readSlice = function(offset, length) {
|
Decompressor.prototype.readSlice = function(offset, length) {
|
||||||
busy = true;
|
busy = true;
|
||||||
var that = this;
|
var that = this;
|
||||||
this._inStreamPos = 0;
|
this._inStreamPos = 0;
|
||||||
this._outStreamPos = 0;
|
this._outStreamPos = 0;
|
||||||
this._decHandle = xzdec._init_decompression(this._chunkSize);
|
this._decHandle = xzdec._init_decompression(this._chunkSize);
|
||||||
this._outBuffer = new Int8Array(new ArrayBuffer(length));
|
this._outBuffer = new Int8Array(new ArrayBuffer(length));
|
||||||
this._outBufferPos = 0;
|
this._outBufferPos = 0;
|
||||||
return this._readLoop(offset, length).then(function(data) {
|
return this._readLoop(offset, length).then(function(data) {
|
||||||
xzdec._release(that._decHandle);
|
xzdec._release(that._decHandle);
|
||||||
busy = false;
|
busy = false;
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads stream of data from file offset for length of bytes to send to the decompresor
|
* Reads stream of data from file offset for length of bytes to send to the decompresor
|
||||||
* This function ensures that only one decompression runs at a time
|
* This function ensures that only one decompression runs at a time
|
||||||
* @param {Integer} offset The file offset at which to begin reading compressed data
|
* @param {Integer} offset The file offset at which to begin reading compressed data
|
||||||
* @param {Integer} length The amount of data to read
|
* @param {Integer} length The amount of data to read
|
||||||
* @returns {Promise} A Promise for the read data
|
* @returns {Promise} A Promise for the read data
|
||||||
*/
|
*/
|
||||||
Decompressor.prototype.readSliceSingleThread = function(offset, length) {
|
Decompressor.prototype.readSliceSingleThread = function(offset, length) {
|
||||||
if (!busy) {
|
if (xzdec && !busy) {
|
||||||
return this.readSlice(offset, length);
|
return this.readSlice(offset, length);
|
||||||
} else {
|
} else {
|
||||||
// The decompressor is already in progress.
|
// The decompressor is already in progress.
|
||||||
// To avoid using too much memory, we wait until it has finished
|
// To avoid using too much memory, we wait until it has finished
|
||||||
// before using it for another decompression
|
// before using it for another decompression
|
||||||
var that = this;
|
var that = this;
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
that.readSliceSingleThread(offset, length).then(resolve, reject);
|
that.readSliceSingleThread(offset, length).then(resolve, reject);
|
||||||
}, DELAY_WAITING_IDLE_DECOMPRESSOR);
|
}, DELAY_WAITING_IDLE_DECOMPRESSOR);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Integer} offset
|
* @param {Integer} offset
|
||||||
* @param {Integer} length
|
* @param {Integer} length
|
||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
Decompressor.prototype._readLoop = function(offset, length) {
|
Decompressor.prototype._readLoop = function(offset, length) {
|
||||||
var that = this;
|
var that = this;
|
||||||
return this._fillInBufferIfNeeded().then(function() {
|
return this._fillInBufferIfNeeded().then(function() {
|
||||||
var ret = xzdec._decompress(that._decHandle);
|
var ret = xzdec._decompress(that._decHandle);
|
||||||
var finished = false;
|
var finished = false;
|
||||||
if (ret === 0) {
|
if (ret === 0) {
|
||||||
// supply more data or free output buffer
|
// supply more data or free output buffer
|
||||||
} else if (ret === 1) {
|
} else if (ret === 1) {
|
||||||
// stream ended
|
// stream ended
|
||||||
finished = true;
|
finished = true;
|
||||||
} else {
|
} else {
|
||||||
// error @todo handle
|
// error @todo handle
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var outPos = xzdec._get_out_pos(that._decHandle);
|
var outPos = xzdec._get_out_pos(that._decHandle);
|
||||||
if (outPos > 0 && that._outStreamPos + outPos >= offset)
|
if (outPos > 0 && that._outStreamPos + outPos >= offset)
|
||||||
{
|
{
|
||||||
var outBuffer = xzdec._get_out_buffer(that._decHandle);
|
var outBuffer = xzdec._get_out_buffer(that._decHandle);
|
||||||
var copyStart = offset - that._outStreamPos;
|
var copyStart = offset - that._outStreamPos;
|
||||||
if (copyStart < 0)
|
if (copyStart < 0)
|
||||||
copyStart = 0;
|
copyStart = 0;
|
||||||
for (var i = copyStart; i < outPos && that._outBufferPos < that._outBuffer.length; i++)
|
for (var i = copyStart; i < outPos && that._outBufferPos < that._outBuffer.length; i++)
|
||||||
that._outBuffer[that._outBufferPos++] = xzdec.HEAP8[outBuffer + i];
|
that._outBuffer[that._outBufferPos++] = xzdec.HEAP8[outBuffer + i];
|
||||||
}
|
}
|
||||||
that._outStreamPos += outPos;
|
that._outStreamPos += outPos;
|
||||||
if (outPos > 0)
|
if (outPos > 0)
|
||||||
xzdec._out_buffer_cleared(that._decHandle);
|
xzdec._out_buffer_cleared(that._decHandle);
|
||||||
if (finished || that._outStreamPos >= offset + length)
|
if (finished || that._outStreamPos >= offset + length)
|
||||||
return that._outBuffer;
|
return that._outBuffer;
|
||||||
else
|
else
|
||||||
return that._readLoop(offset, length);
|
return that._readLoop(offset, length);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
Decompressor.prototype._fillInBufferIfNeeded = function() {
|
Decompressor.prototype._fillInBufferIfNeeded = function() {
|
||||||
if (!xzdec._input_empty(this._decHandle)) {
|
if (!xzdec._input_empty(this._decHandle)) {
|
||||||
// DEV: When converting to Promise/A+, use Promise.resolve(0) here
|
// DEV: When converting to Promise/A+, use Promise.resolve(0) here
|
||||||
return Promise.resolve(0);
|
return Promise.resolve(0);
|
||||||
}
|
}
|
||||||
var that = this;
|
var that = this;
|
||||||
return this._reader(this._inStreamPos, this._chunkSize).then(function(data) {
|
return this._reader(this._inStreamPos, this._chunkSize).then(function(data) {
|
||||||
if (data.length > that._chunkSize)
|
if (data.length > that._chunkSize)
|
||||||
data = data.slice(0, that._chunkSize);
|
data = data.slice(0, that._chunkSize);
|
||||||
// For some reason, xzdec.writeArrayToMemory does not seem to be available, and is equivalent to xzdec.HEAP8.set
|
// For some reason, xzdec.writeArrayToMemory does not seem to be available, and is equivalent to xzdec.HEAP8.set
|
||||||
xzdec.HEAP8.set(data, xzdec._get_in_buffer(that._decHandle));
|
xzdec.HEAP8.set(data, xzdec._get_in_buffer(that._decHandle));
|
||||||
that._inStreamPos += data.length;
|
that._inStreamPos += data.length;
|
||||||
xzdec._set_new_input(that._decHandle, data.length);
|
xzdec._set_new_input(that._decHandle, data.length);
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Decompressor: Decompressor
|
Decompressor: Decompressor
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,11 @@ function(ZD) {
|
|||||||
|
|
||||||
|
|
||||||
var a;a||(a=typeof ZD !== 'undefined' ? ZD : {});
|
var a;a||(a=typeof ZD !== 'undefined' ? ZD : {});
|
||||||
var u,v;a.ready=new Promise(function(c,e){u=c;v=e});var w={},x;for(x in a)a.hasOwnProperty(x)&&(w[x]=a[x]);var y="";document.currentScript&&(y=document.currentScript.src);_scriptDir&&(y=_scriptDir);
|
var Promise=function(){function c(){}function e(b,f){return function(){b.apply(f,arguments)}}function d(b){if(!(this instanceof d))throw new TypeError("Promises must be constructed via new");if("function"!==typeof b)throw new TypeError("not a function");this.u=0;this.C=!1;this.v=void 0;this.w=[];D(b,this)}function m(b,f){for(;3===b.u;)b=b.v;0===b.u?b.w.push(f):(b.C=!0,d.D(function(){var g=1===b.u?f.G:f.H;if(null===g)(1===b.u?l:p)(f.B,b.v);else{try{var h=g(b.v)}catch(k){p(f.B,k);return}l(f.B,h)}}))}
|
||||||
|
function l(b,f){try{if(f===b)throw new TypeError("A promise cannot be resolved with itself.");if(f&&("object"===typeof f||"function"===typeof f)){var g=f.then;if(f instanceof d){b.u=3;b.v=f;r(b);return}if("function"===typeof g){D(e(g,f),b);return}}b.u=1;b.v=f;r(b)}catch(h){p(b,h)}}function p(b,f){b.u=2;b.v=f;r(b)}function r(b){2===b.u&&0===b.w.length&&d.D(function(){b.C||d.I(b.v)});for(var f=0,g=b.w.length;f<g;f++)m(b,b.w[f]);b.w=null}function q(b,f,g){this.G="function"===typeof b?b:null;this.H="function"===
|
||||||
|
typeof f?f:null;this.B=g}function D(b,f){var g=!1;try{b(function(h){g||(g=!0,l(f,h))},function(h){g||(g=!0,p(f,h))})}catch(h){g||(g=!0,p(f,h))}}d.prototype["catch"]=function(b){return this.then(null,b)};d.prototype.then=function(b,f){var g=new this.constructor(c);m(this,new q(b,f,g));return g};d.all=function(b){return new d(function(f,g){function h(I,z){try{if(z&&("object"===typeof z||"function"===typeof z)){var S=z.then;if("function"===typeof S){S.call(z,function(N){h(I,N)},g);return}}k[I]=z;0===
|
||||||
|
--t&&f(k)}catch(N){g(N)}}if(!Array.isArray(b))return g(new TypeError("Promise.all accepts an array"));var k=Array.prototype.slice.call(b);if(0===k.length)return f([]);for(var t=k.length,n=0;n<k.length;n++)h(n,k[n])})};d.resolve=function(b){return b&&"object"===typeof b&&b.constructor===d?b:new d(function(f){f(b)})};d.reject=function(b){return new d(function(f,g){g(b)})};d.race=function(b){return new d(function(f,g){if(!Array.isArray(b))return g(new TypeError("Promise.race accepts an array"));for(var h=
|
||||||
|
0,k=b.length;h<k;h++)d.resolve(b[h]).then(f,g)})};d.D="function"===typeof setImmediate&&function(b){setImmediate(b)}||function(b){setTimeout(b,0)};d.I=function(b){"undefined"!==typeof console&&console&&console.warn("Possible Unhandled Promise Rejection:",b)};return d}(),u,v;a.ready=new Promise(function(c,e){u=c;v=e});var w={},x;for(x in a)a.hasOwnProperty(x)&&(w[x]=a[x]);var y="";document.currentScript&&(y=document.currentScript.src);_scriptDir&&(y=_scriptDir);
|
||||||
0!==y.indexOf("blob:")?y=y.substr(0,y.lastIndexOf("/")+1):y="";var A=a.printErr||console.warn.bind(console);for(x in w)w.hasOwnProperty(x)&&(a[x]=w[x]);w=null;var B;a.wasmBinary&&(B=a.wasmBinary);var noExitRuntime;a.noExitRuntime&&(noExitRuntime=a.noExitRuntime);function aa(){this.buffer=new ArrayBuffer(C/65536*65536);this.grow=function(c){return E(c)}}function ba(){this.exports=(
|
0!==y.indexOf("blob:")?y=y.substr(0,y.lastIndexOf("/")+1):y="";var A=a.printErr||console.warn.bind(console);for(x in w)w.hasOwnProperty(x)&&(a[x]=w[x]);w=null;var B;a.wasmBinary&&(B=a.wasmBinary);var noExitRuntime;a.noExitRuntime&&(noExitRuntime=a.noExitRuntime);function aa(){this.buffer=new ArrayBuffer(C/65536*65536);this.grow=function(c){return E(c)}}function ba(){this.exports=(
|
||||||
// EMSCRIPTEN_START_ASM
|
// EMSCRIPTEN_START_ASM
|
||||||
function a(asmLibraryArg,wasmMemory,wasmTable){function b(global,env,buffer){var memory=env.a;var c=wasmTable;var d=new global.Int8Array(buffer);var e=new global.Int16Array(buffer);var f=new global.Int32Array(buffer);var g=new global.Uint8Array(buffer);var h=new global.Uint16Array(buffer);var i=new global.Uint32Array(buffer);var j=new global.Float32Array(buffer);var k=new global.Float64Array(buffer);var l=global.Math.imul;var m=global.Math.fround;var n=global.Math.abs;var o=global.Math.clz32;var p=global.Math.min;var q=global.Math.max;var r=global.Math.floor;var s=global.Math.ceil;var t=global.Math.sqrt;var u=env.abort;var v=global.NaN;var w=global.Infinity;var x=env.c;var y=env.d;var z=5248768;var A=0;
|
function a(asmLibraryArg,wasmMemory,wasmTable){function b(global,env,buffer){var memory=env.a;var c=wasmTable;var d=new global.Int8Array(buffer);var e=new global.Int16Array(buffer);var f=new global.Int32Array(buffer);var g=new global.Uint8Array(buffer);var h=new global.Uint16Array(buffer);var i=new global.Uint32Array(buffer);var j=new global.Float32Array(buffer);var k=new global.Float64Array(buffer);var l=global.Math.imul;var m=global.Math.fround;var n=global.Math.abs;var o=global.Math.clz32;var p=global.Math.min;var q=global.Math.max;var r=global.Math.floor;var s=global.Math.ceil;var t=global.Math.sqrt;var u=env.abort;var v=global.NaN;var w=global.Infinity;var x=env.c;var y=env.d;var z=5248768;var A=0;
|
||||||
|
@ -152,7 +152,7 @@ define(['zstddec'], function() {
|
|||||||
* @returns {Promise} A Promise for the readSlice() function
|
* @returns {Promise} A Promise for the readSlice() function
|
||||||
*/
|
*/
|
||||||
Decompressor.prototype.readSliceSingleThread = function (offset, length) {
|
Decompressor.prototype.readSliceSingleThread = function (offset, length) {
|
||||||
if (!appstate.zdBusy) {
|
if (zd && !appstate.zdBusy) {
|
||||||
return this.readSlice(offset, length);
|
return this.readSlice(offset, length);
|
||||||
} else {
|
} else {
|
||||||
// The decompressor is already in progress.
|
// The decompressor is already in progress.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user