mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-09-22 03:52:21 -04:00
parent
5a2ea27df1
commit
8fb07bb5a4
@ -30,14 +30,19 @@ require.config({
|
||||
baseUrl: (window.__karma__ ? 'base/' : '') + 'www/js/lib/',
|
||||
paths: {
|
||||
'jquery': 'jquery-3.2.1.slim',
|
||||
'webpHeroBundle': 'webpHeroBundle_0.0.0-dev.27',
|
||||
'webpHeroPolyfills': 'webpHeroPolyfills_0.0.0-dev.27'
|
||||
'webpHeroBundle': 'webpHeroBundle_0.0.0-dev.27'
|
||||
},
|
||||
shim: {
|
||||
'webpHeroBundle': {
|
||||
deps: ['webpHeroPolyfills']
|
||||
}
|
||||
'webpHeroBundle': ''
|
||||
}
|
||||
});
|
||||
|
||||
requirejs(['../../../tests/tests']);
|
||||
var req = []; // Baseline Require array
|
||||
|
||||
// Add polyfills to the Require array only if needed
|
||||
if (!('Promise' in self)) req.push('promisePolyfill');
|
||||
if (!('from' in Array)) req.push('arrayFromPolyfill');
|
||||
|
||||
requirejs(req, function () {
|
||||
requirejs(['../../../tests/tests']);
|
||||
});
|
||||
|
@ -109,13 +109,13 @@ define(['jquery', 'zimArchive', 'zimDirEntry', 'util', 'uiUtil', 'utf8'],
|
||||
var testString3 = "le Couvre-chef Est sur le porte-manteaux";
|
||||
var testString4 = "épée";
|
||||
var testString5 = '$¥€“«xριστός» †¡Ἀνέστη!”';
|
||||
var testString6 = "Καλά Νερά Μαγνησίας žižek";
|
||||
var testString6 = "Καλά Νερά Μαγνησία žižek";
|
||||
assert.equal(util.allCaseFirstLetters(testString1).indexOf("Téléphone") >= 0, true, "The first letter should be uppercase");
|
||||
assert.equal(util.allCaseFirstLetters(testString2).indexOf("paris") >= 0, true, "The first letter should be lowercase");
|
||||
assert.equal(util.allCaseFirstLetters(testString3).indexOf("Le Couvre-Chef Est Sur Le Porte-Manteaux") >= 0, true, "The first letter of every word should be uppercase");
|
||||
assert.equal(util.allCaseFirstLetters(testString4).indexOf("Épée") >= 0, true, "The first letter should be uppercase (with accent)");
|
||||
assert.equal(util.allCaseFirstLetters(testString5).indexOf('$¥€“«Xριστός» †¡ἀνέστη!”') >= 0, true, "First non-punctuation/non-currency Unicode letter should be uppercase, second (with breath mark) lowercase");
|
||||
assert.equal(util.allCaseFirstLetters(testString6, "full").indexOf("ΚΑΛΆ ΝΕΡΆ ΜΑΓΝΗΣΊΑΣ ŽIŽEK") >= 0, true, "All Unicode letters should be uppercase");
|
||||
assert.equal(util.allCaseFirstLetters(testString6, "full").indexOf("ΚΑΛΆ ΝΕΡΆ ΜΑΓΝΗΣΊΑ ŽIŽEK") >= 0, true, "All Unicode letters should be uppercase");
|
||||
});
|
||||
QUnit.test("check removal of parameters in URL", function(assert) {
|
||||
var testUrl1 = "A/question.html";
|
||||
|
@ -26,8 +26,8 @@
|
||||
// This uses require.js to structure javascript:
|
||||
// http://requirejs.org/docs/api.html#define
|
||||
|
||||
define(['jquery', 'zimArchiveLoader', 'uiUtil', 'settingsStore','abstractFilesystemAccess','q'],
|
||||
function($, zimArchiveLoader, uiUtil, settingsStore, abstractFilesystemAccess, Q) {
|
||||
define(['jquery', 'zimArchiveLoader', 'uiUtil', 'settingsStore','abstractFilesystemAccess'],
|
||||
function($, zimArchiveLoader, uiUtil, settingsStore, abstractFilesystemAccess) {
|
||||
|
||||
/**
|
||||
* The delay (in milliseconds) between two "keepalive" messages sent to the ServiceWorker (so that it is not stopped
|
||||
@ -475,7 +475,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'settingsStore','abstractFilesys
|
||||
* @returns {Promise<Object>} A Promise for an object with cache attributes 'type', 'description', and 'count'
|
||||
*/
|
||||
function getCacheAttributes() {
|
||||
return Q.Promise(function (resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (contentInjectionMode === 'serviceworker') {
|
||||
// Create a Message Channel
|
||||
var channel = new MessageChannel();
|
||||
@ -963,26 +963,24 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'settingsStore','abstractFilesys
|
||||
* @returns {Promise<Blob>} A promise for the requested file (blob)
|
||||
*/
|
||||
function readRemoteArchive(url) {
|
||||
// DEV: This deferred can't be standardized to a Promise/A+ pattern (using Q) because
|
||||
// IE11 is unable to scope the callbacks inside the Promise correctly. See [kiwix.js #589]
|
||||
var deferred = Q.defer();
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", url);
|
||||
request.responseType = "blob";
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === XMLHttpRequest.DONE) {
|
||||
if (request.status >= 200 && request.status < 300 || request.status === 0) {
|
||||
// Hack to make this look similar to a file
|
||||
request.response.name = url;
|
||||
deferred.resolve(request.response);
|
||||
} else {
|
||||
deferred.reject("HTTP status " + request.status + " when reading " + url);
|
||||
return new Promise(function (resolve, reject) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", url);
|
||||
request.responseType = "blob";
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === XMLHttpRequest.DONE) {
|
||||
if (request.status >= 200 && request.status < 300 || request.status === 0) {
|
||||
// Hack to make this look similar to a file
|
||||
request.response.name = url;
|
||||
resolve(request.response);
|
||||
} else {
|
||||
reject("HTTP status " + request.status + " when reading " + url);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
request.onabort = request.onerror = deferred.reject;
|
||||
request.send();
|
||||
return deferred.promise;
|
||||
};
|
||||
request.onabort = request.onerror = reject;
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -994,7 +992,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'settingsStore','abstractFilesys
|
||||
Array.prototype.slice.call(arguments).forEach(function (arg) {
|
||||
readRequests.push(readRemoteArchive(arg));
|
||||
});
|
||||
return Q.all(readRequests).then(function (arrayOfArchives) {
|
||||
return Promise.all(readRequests).then(function (arrayOfArchives) {
|
||||
setLocalArchiveFromFileList(arrayOfArchives);
|
||||
}).catch(function (e) {
|
||||
console.error('Unable to load remote archive(s)', e);
|
||||
|
@ -36,7 +36,6 @@ require.config({
|
||||
'jquery': 'jquery-3.2.1.slim',
|
||||
'bootstrap': 'bootstrap.bundle',
|
||||
'webpHeroBundle': 'webpHeroBundle_0.0.0-dev.27',
|
||||
'webpHeroPolyfills': 'webpHeroPolyfills_0.0.0-dev.27',
|
||||
'fontawesome': 'fontawesome/fontawesome',
|
||||
'fontawesome-solid': 'fontawesome/solid'
|
||||
},
|
||||
@ -47,13 +46,17 @@ require.config({
|
||||
'bootstrap': {
|
||||
deps: ['jquery', 'fontawesome', 'fontawesome-solid']
|
||||
},
|
||||
'webpHeroBundle': {
|
||||
deps: ['webpHeroPolyfills']
|
||||
}
|
||||
'webpHeroBundle': ''
|
||||
}
|
||||
});
|
||||
|
||||
requirejs(['bootstrap'], function (bootstrap) {
|
||||
var req = ['bootstrap']; // Baseline Require array
|
||||
|
||||
// Add polyfills to the Require array only if needed
|
||||
if (!('Promise' in self)) req.push('promisePolyfill');
|
||||
if (!('from' in Array)) req.push('arrayFromPolyfill');
|
||||
|
||||
requirejs(req, function () {
|
||||
requirejs(['../app']);
|
||||
});
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
'use strict';
|
||||
define(['q', 'jquery'], function(q, jQuery) {
|
||||
define([], function() {
|
||||
|
||||
/**
|
||||
* Storage implemented by Firefox OS
|
||||
@ -50,11 +50,12 @@ define(['q', 'jquery'], function(q, jQuery) {
|
||||
* rejected with an error message.
|
||||
*/
|
||||
StorageFirefoxOS.prototype.get = function(path) {
|
||||
var deferred = q.defer();
|
||||
var request = this._storage.get(path);
|
||||
request.onsuccess = function() { deferred.resolve(this.result); };
|
||||
request.onerror = function() { deferred.reject(this.error.name); };
|
||||
return deferred.promise;
|
||||
var that = this;
|
||||
return new Promise(function (resolve, reject){
|
||||
var request = that._storage.get(path);
|
||||
request.onsuccess = function() { resolve(this.result); };
|
||||
request.onerror = function() { reject(this.error.name); };
|
||||
});
|
||||
};
|
||||
|
||||
// We try to match both a standalone ZIM file (.zim) or
|
||||
@ -67,26 +68,27 @@ define(['q', 'jquery'], function(q, jQuery) {
|
||||
* paths and rejected with an error message.
|
||||
*/
|
||||
StorageFirefoxOS.prototype.scanForArchives = function() {
|
||||
var deferred = jQuery.Deferred();
|
||||
var directories = [];
|
||||
var cursor = this._storage.enumerate();
|
||||
cursor.onerror = function() {
|
||||
deferred.reject(cursor.error);
|
||||
};
|
||||
cursor.onsuccess = function() {
|
||||
if (!cursor.result) {
|
||||
deferred.resolve(directories);
|
||||
return;
|
||||
}
|
||||
var file = cursor.result;
|
||||
var that = this;
|
||||
return new Promise(function (resolve, reject){
|
||||
var directories = [];
|
||||
var cursor = that._storage.enumerate();
|
||||
cursor.onerror = function () {
|
||||
reject(cursor.error);
|
||||
};
|
||||
cursor.onsuccess = function () {
|
||||
if (!cursor.result) {
|
||||
resolve(directories);
|
||||
return;
|
||||
}
|
||||
var file = cursor.result;
|
||||
|
||||
if (regexpZIMFileName.test(file.name)) {
|
||||
directories.push(file.name);
|
||||
}
|
||||
if (regexpZIMFileName.test(file.name)) {
|
||||
directories.push(file.name);
|
||||
}
|
||||
|
||||
cursor.continue();
|
||||
};
|
||||
return deferred.promise();
|
||||
cursor.continue();
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
33
www/js/lib/arrayFromPolyfill.js
Normal file
33
www/js/lib/arrayFromPolyfill.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Simple Array.from polyfill (with Set support) from https://stackoverflow.com/a/62682524/9727685
|
||||
*/
|
||||
(function () {
|
||||
|
||||
function arrayFrom(arr, callbackFn, thisArg) {
|
||||
//if you need you can uncomment the following line
|
||||
//if(!arr || typeof arr == 'function')throw new Error('This function requires an array-like object - not null, undefined or a function');
|
||||
|
||||
var arNew = [],
|
||||
k = [], // used for convert Set to an Array
|
||||
i = 0;
|
||||
|
||||
//if you do not need a Set object support then
|
||||
//you can comment or delete the following if statement
|
||||
if (window.Set && arr instanceof Set) {
|
||||
//we use forEach from Set object
|
||||
arr.forEach(function (v) {
|
||||
k.push(v)
|
||||
});
|
||||
arr = k;
|
||||
}
|
||||
|
||||
for (; i < arr.length; i++)
|
||||
arNew[i] = callbackFn ?
|
||||
callbackFn.call(thisArg, arr[i], i, arr) :
|
||||
arr[i];
|
||||
|
||||
return arNew;
|
||||
}
|
||||
//You could also use it without the following line, but it is not recommended because native function is faster.
|
||||
Array.from = Array.from || arrayFrom; //We set it as polyfill
|
||||
}());
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
define(['q'], function (Q) {
|
||||
define([], function () {
|
||||
/**
|
||||
* Set maximum number of cache blocks of BLOCK_SIZE bytes each
|
||||
* Maximum size of cache in bytes = MAX_CACHE_SIZE * BLOCK_SIZE
|
||||
@ -166,7 +166,7 @@ define(['q'], function (Q) {
|
||||
// misses = 0;
|
||||
// }
|
||||
// Wait for all the blocks to be read either from the cache or from the archive
|
||||
return Q.all(readRequests).then(function () {
|
||||
return Promise.all(readRequests).then(function () {
|
||||
var result = new Uint8Array(end - begin);
|
||||
var pos = 0;
|
||||
// Stitch together the data parts in the right order
|
||||
|
878
www/js/lib/promisePolyfill.js
Normal file
878
www/js/lib/promisePolyfill.js
Normal file
@ -0,0 +1,878 @@
|
||||
/*
|
||||
Yaku v0.19.3
|
||||
(c) 2015 Yad Smood. http://ysmood.org
|
||||
License MIT
|
||||
*/
|
||||
/*
|
||||
Yaku v0.17.9
|
||||
(c) 2015 Yad Smood. http://ysmood.org
|
||||
License MIT
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var $undefined
|
||||
, $null = null
|
||||
, isBrowser = typeof self === 'object'
|
||||
, root = self
|
||||
, nativePromise = root.Promise
|
||||
, process = root.process
|
||||
, console = root.console
|
||||
, isLongStackTrace = true
|
||||
, Arr = Array
|
||||
, Err = Error
|
||||
|
||||
, $rejected = 1
|
||||
, $resolved = 2
|
||||
, $pending = 3
|
||||
|
||||
, $Symbol = 'Symbol'
|
||||
, $iterator = 'iterator'
|
||||
, $species = 'species'
|
||||
, $speciesKey = $Symbol + '(' + $species + ')'
|
||||
, $return = 'return'
|
||||
|
||||
, $unhandled = '_uh'
|
||||
, $promiseTrace = '_pt'
|
||||
, $settlerTrace = '_st'
|
||||
|
||||
, $invalidThis = 'Invalid this'
|
||||
, $invalidArgument = 'Invalid argument'
|
||||
, $fromPrevious = '\nFrom previous '
|
||||
, $promiseCircularChain = 'Chaining cycle detected for promise'
|
||||
, $unhandledRejectionMsg = 'Uncaught (in promise)'
|
||||
, $rejectionHandled = 'rejectionHandled'
|
||||
, $unhandledRejection = 'unhandledRejection'
|
||||
|
||||
, $tryCatchFn
|
||||
, $tryCatchThis
|
||||
, $tryErr = { e: $null }
|
||||
, $noop = function () {}
|
||||
, $cleanStackReg = /^.+\/node_modules\/yaku\/.+\n?/mg
|
||||
;
|
||||
|
||||
/**
|
||||
* This class follows the [Promises/A+](https://promisesaplus.com) and
|
||||
* [ES6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) spec
|
||||
* with some extra helpers.
|
||||
* @param {Function} executor Function object with two arguments resolve, reject.
|
||||
* The first argument fulfills the promise, the second argument rejects it.
|
||||
* We can call these functions, once our operation is completed.
|
||||
*/
|
||||
var Yaku = function (executor) {
|
||||
var self = this,
|
||||
err;
|
||||
|
||||
// "this._s" is the internao state of: pending, resolved or rejected
|
||||
// "this._v" is the internal value
|
||||
|
||||
if (!isObject(self) || self._s !== $undefined)
|
||||
throw genTypeError($invalidThis);
|
||||
|
||||
self._s = $pending;
|
||||
|
||||
if (isLongStackTrace) self[$promiseTrace] = genTraceInfo();
|
||||
|
||||
if (executor !== $noop) {
|
||||
if (!isFunction(executor))
|
||||
throw genTypeError($invalidArgument);
|
||||
|
||||
err = genTryCatcher(executor)(
|
||||
genSettler(self, $resolved),
|
||||
genSettler(self, $rejected)
|
||||
);
|
||||
|
||||
if (err === $tryErr)
|
||||
settlePromise(self, $rejected, err.e);
|
||||
}
|
||||
};
|
||||
|
||||
Yaku['default'] = Yaku;
|
||||
|
||||
extend(Yaku.prototype, {
|
||||
/**
|
||||
* Appends fulfillment and rejection handlers to the promise,
|
||||
* and returns a new promise resolving to the return value of the called handler.
|
||||
* @param {Function} onFulfilled Optional. Called when the Promise is resolved.
|
||||
* @param {Function} onRejected Optional. Called when the Promise is rejected.
|
||||
* @return {Yaku} It will return a new Yaku which will resolve or reject after
|
||||
* @example
|
||||
* the current Promise.
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* var p = Promise.resolve(10);
|
||||
*
|
||||
* p.then((v) => {
|
||||
* console.log(v);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
then: function (onFulfilled, onRejected) {
|
||||
if (this._s === undefined) throw genTypeError();
|
||||
|
||||
return addHandler(
|
||||
this,
|
||||
newCapablePromise(Yaku.speciesConstructor(this, Yaku)),
|
||||
onFulfilled,
|
||||
onRejected
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* The `catch()` method returns a Promise and deals with rejected cases only.
|
||||
* It behaves the same as calling `Promise.prototype.then(undefined, onRejected)`.
|
||||
* @param {Function} onRejected A Function called when the Promise is rejected.
|
||||
* This function has one argument, the rejection reason.
|
||||
* @return {Yaku} A Promise that deals with rejected cases only.
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* var p = Promise.reject(new Error("ERR"));
|
||||
*
|
||||
* p['catch']((v) => {
|
||||
* console.log(v);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
'catch': function (onRejected) {
|
||||
return this.then($undefined, onRejected);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when a promise is settled (either fulfilled or rejected).
|
||||
* Similar with the try-catch-finally, it's often used for cleanup.
|
||||
* @param {Function} onFinally A Function called when the Promise is settled.
|
||||
* It will not receive any argument.
|
||||
* @return {Yaku} A Promise that will reject if onFinally throws an error or returns a rejected promise.
|
||||
* Else it will resolve previous promise's final state (either fulfilled or rejected).
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* var p = Math.random() > 0.5 ? Promise.resolve() : Promise.reject();
|
||||
* p.finally(() => {
|
||||
* console.log('finally');
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
'finally': function (onFinally) {
|
||||
return this.then(function (val) {
|
||||
return Yaku.resolve(onFinally()).then(function () {
|
||||
return val;
|
||||
});
|
||||
}, function (err) {
|
||||
return Yaku.resolve(onFinally()).then(function () {
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// The number of current promises that attach to this Yaku instance.
|
||||
_c: 0,
|
||||
|
||||
// The parent Yaku.
|
||||
_p: $null
|
||||
});
|
||||
|
||||
/**
|
||||
* The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value.
|
||||
* If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable,
|
||||
* adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
|
||||
* @param {Any} value Argument to be resolved by this Promise.
|
||||
* Can also be a Promise or a thenable to resolve.
|
||||
* @return {Yaku}
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* var p = Promise.resolve(10);
|
||||
* ```
|
||||
*/
|
||||
Yaku.resolve = function (val) {
|
||||
return isYaku(val) ? val : settleWithX(newCapablePromise(this), val);
|
||||
};
|
||||
|
||||
/**
|
||||
* The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason.
|
||||
* @param {Any} reason Reason why this Promise rejected.
|
||||
* @return {Yaku}
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* var p = Promise.reject(new Error("ERR"));
|
||||
* ```
|
||||
*/
|
||||
Yaku.reject = function (reason) {
|
||||
return settlePromise(newCapablePromise(this), $rejected, reason);
|
||||
};
|
||||
|
||||
/**
|
||||
* The `Promise.race(iterable)` method returns a promise that resolves or rejects
|
||||
* as soon as one of the promises in the iterable resolves or rejects,
|
||||
* with the value or reason from that promise.
|
||||
* @param {iterable} iterable An iterable object, such as an Array.
|
||||
* @return {Yaku} The race function returns a Promise that is settled
|
||||
* the same way as the first passed promise to settle.
|
||||
* It resolves or rejects, whichever happens first.
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.race([
|
||||
* 123,
|
||||
* Promise.resolve(0)
|
||||
* ])
|
||||
* .then((value) => {
|
||||
* console.log(value); // => 123
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
Yaku.race = function (iterable) {
|
||||
var self = this
|
||||
, p = newCapablePromise(self)
|
||||
|
||||
, resolve = function (val) {
|
||||
settlePromise(p, $resolved, val);
|
||||
}
|
||||
|
||||
, reject = function (val) {
|
||||
settlePromise(p, $rejected, val);
|
||||
}
|
||||
|
||||
, ret = genTryCatcher(each)(iterable, function (v) {
|
||||
self.resolve(v).then(resolve, reject);
|
||||
});
|
||||
|
||||
if (ret === $tryErr) return self.reject(ret.e);
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
/**
|
||||
* The `Promise.all(iterable)` method returns a promise that resolves when
|
||||
* all of the promises in the iterable argument have resolved.
|
||||
*
|
||||
* The result is passed as an array of values from all the promises.
|
||||
* If something passed in the iterable array is not a promise,
|
||||
* it's converted to one by Promise.resolve. If any of the passed in promises rejects,
|
||||
* the all Promise immediately rejects with the value of the promise that rejected,
|
||||
* discarding all the other promises whether or not they have resolved.
|
||||
* @param {iterable} iterable An iterable object, such as an Array.
|
||||
* @return {Yaku}
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.all([
|
||||
* 123,
|
||||
* Promise.resolve(0)
|
||||
* ])
|
||||
* .then((values) => {
|
||||
* console.log(values); // => [123, 0]
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Use with iterable.
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.all((function * () {
|
||||
* yield 10;
|
||||
* yield new Promise(function (r) { setTimeout(r, 1000, "OK") });
|
||||
* })())
|
||||
* .then((values) => {
|
||||
* console.log(values); // => [123, 0]
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
Yaku.all = function (iterable) {
|
||||
var self = this
|
||||
, p1 = newCapablePromise(self)
|
||||
, res = []
|
||||
, ret
|
||||
;
|
||||
|
||||
function reject (reason) {
|
||||
settlePromise(p1, $rejected, reason);
|
||||
}
|
||||
|
||||
ret = genTryCatcher(each)(iterable, function (item, i) {
|
||||
self.resolve(item).then(function (value) {
|
||||
res[i] = value;
|
||||
if (!--ret) settlePromise(p1, $resolved, res);
|
||||
}, reject);
|
||||
});
|
||||
|
||||
if (ret === $tryErr) return self.reject(ret.e);
|
||||
|
||||
if (!ret) settlePromise(p1, $resolved, []);
|
||||
|
||||
return p1;
|
||||
};
|
||||
|
||||
/**
|
||||
* The ES6 Symbol object that Yaku should use, by default it will use the
|
||||
* global one.
|
||||
* @type {Object}
|
||||
* @example
|
||||
* ```js
|
||||
* var core = require("core-js/library");
|
||||
* var Promise = require("yaku");
|
||||
* Promise.Symbol = core.Symbol;
|
||||
* ```
|
||||
*/
|
||||
Yaku.Symbol = root[$Symbol] || {};
|
||||
|
||||
// To support browsers that don't support `Object.defineProperty`.
|
||||
genTryCatcher(function () {
|
||||
Object.defineProperty(Yaku, getSpecies(), {
|
||||
get: function () { return this; }
|
||||
});
|
||||
})();
|
||||
|
||||
/**
|
||||
* Use this api to custom the species behavior.
|
||||
* https://tc39.github.io/ecma262/#sec-speciesconstructor
|
||||
* @param {Any} O The current this object.
|
||||
* @param {Function} defaultConstructor
|
||||
*/
|
||||
Yaku.speciesConstructor = function (O, D) {
|
||||
var C = O.constructor;
|
||||
|
||||
return C ? (C[getSpecies()] || D) : D;
|
||||
};
|
||||
|
||||
/**
|
||||
* Catch all possibly unhandled rejections. If you want to use specific
|
||||
* format to display the error stack, overwrite it.
|
||||
* If it is set, auto `console.error` unhandled rejection will be disabled.
|
||||
* @param {Any} reason The rejection reason.
|
||||
* @param {Yaku} p The promise that was rejected.
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.unhandledRejection = (reason) => {
|
||||
* console.error(reason);
|
||||
* };
|
||||
*
|
||||
* // The console will log an unhandled rejection error message.
|
||||
* Promise.reject('my reason');
|
||||
*
|
||||
* // The below won't log the unhandled rejection error message.
|
||||
* Promise.reject('v')["catch"](() => {});
|
||||
* ```
|
||||
*/
|
||||
Yaku.unhandledRejection = function (reason, p) {
|
||||
console && console.error(
|
||||
$unhandledRejectionMsg,
|
||||
isLongStackTrace ? p.longStack : genStackInfo(reason, p)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Emitted whenever a Promise was rejected and an error handler was
|
||||
* attached to it (for example with `["catch"]()`) later than after an event loop turn.
|
||||
* @param {Any} reason The rejection reason.
|
||||
* @param {Yaku} p The promise that was rejected.
|
||||
*/
|
||||
Yaku.rejectionHandled = $noop;
|
||||
|
||||
/**
|
||||
* It is used to enable the long stack trace.
|
||||
* Once it is enabled, it can't be reverted.
|
||||
* While it is very helpful in development and testing environments,
|
||||
* it is not recommended to use it in production. It will slow down
|
||||
* application and eat up memory.
|
||||
* It will add an extra property `longStack` to the Error object.
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.enableLongStackTrace();
|
||||
* Promise.reject(new Error("err"))["catch"]((err) => {
|
||||
* console.log(err.longStack);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
Yaku.enableLongStackTrace = function () {
|
||||
isLongStackTrace = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Only Node has `process.nextTick` function. For browser there are
|
||||
* so many ways to polyfill it. Yaku won't do it for you, instead you
|
||||
* can choose what you prefer. For example, this project
|
||||
* [next-tick](https://github.com/medikoo/next-tick).
|
||||
* By default, Yaku will use `process.nextTick` on Node, `setTimeout` on browser.
|
||||
* @type {Function}
|
||||
* @example
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.nextTick = require('next-tick');
|
||||
* ```
|
||||
* @example
|
||||
* You can even use sync resolution if you really know what you are doing.
|
||||
* ```js
|
||||
* var Promise = require('yaku');
|
||||
* Promise.nextTick = fn => fn();
|
||||
* ```
|
||||
*/
|
||||
Yaku.nextTick = isBrowser ?
|
||||
function (fn) {
|
||||
nativePromise ?
|
||||
new nativePromise(function (resolve) { resolve(); }).then(fn) :
|
||||
setTimeout(fn);
|
||||
} :
|
||||
process.nextTick;
|
||||
|
||||
// ********************** Private **********************
|
||||
|
||||
Yaku._s = 1;
|
||||
|
||||
/**
|
||||
* All static variable name will begin with `$`. Such as `$rejected`.
|
||||
* @private
|
||||
*/
|
||||
|
||||
// ******************************* Utils ********************************
|
||||
|
||||
function getSpecies () {
|
||||
return Yaku[$Symbol][$species] || $speciesKey;
|
||||
}
|
||||
|
||||
function extend (src, target) {
|
||||
for (var k in target) {
|
||||
src[k] = target[k];
|
||||
}
|
||||
}
|
||||
|
||||
function isObject (obj) {
|
||||
return obj && typeof obj === 'object';
|
||||
}
|
||||
|
||||
function isFunction (obj) {
|
||||
return typeof obj === 'function';
|
||||
}
|
||||
|
||||
function isInstanceOf (a, b) {
|
||||
return a instanceof b;
|
||||
}
|
||||
|
||||
function isError (obj) {
|
||||
return isInstanceOf(obj, Err);
|
||||
}
|
||||
|
||||
function ensureType (obj, fn, msg) {
|
||||
if (!fn(obj)) throw genTypeError(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a function into a try-catch.
|
||||
* @private
|
||||
* @return {Any | $tryErr}
|
||||
*/
|
||||
function tryCatcher () {
|
||||
try {
|
||||
return $tryCatchFn.apply($tryCatchThis, arguments);
|
||||
} catch (e) {
|
||||
$tryErr.e = e;
|
||||
return $tryErr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a try-catch wrapped function.
|
||||
* @private
|
||||
* @param {Function} fn
|
||||
* @return {Function}
|
||||
*/
|
||||
function genTryCatcher (fn, self) {
|
||||
$tryCatchFn = fn;
|
||||
$tryCatchThis = self;
|
||||
return tryCatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a scheduler.
|
||||
* @private
|
||||
* @param {Integer} initQueueSize
|
||||
* @param {Function} fn `(Yaku, Value) ->` The schedule handler.
|
||||
* @return {Function} `(Yaku, Value) ->` The scheduler.
|
||||
*/
|
||||
function genScheduler (initQueueSize, fn) {
|
||||
/**
|
||||
* All async promise will be scheduled in
|
||||
* here, so that they can be execute on the next tick.
|
||||
* @private
|
||||
*/
|
||||
var fnQueue = Arr(initQueueSize)
|
||||
, fnQueueLen = 0;
|
||||
|
||||
/**
|
||||
* Run all queued functions.
|
||||
* @private
|
||||
*/
|
||||
function flush () {
|
||||
var i = 0;
|
||||
while (i < fnQueueLen) {
|
||||
fn(fnQueue[i], fnQueue[i + 1]);
|
||||
fnQueue[i++] = $undefined;
|
||||
fnQueue[i++] = $undefined;
|
||||
}
|
||||
|
||||
fnQueueLen = 0;
|
||||
if (fnQueue.length > initQueueSize) fnQueue.length = initQueueSize;
|
||||
}
|
||||
|
||||
return function (v, arg) {
|
||||
fnQueue[fnQueueLen++] = v;
|
||||
fnQueue[fnQueueLen++] = arg;
|
||||
|
||||
if (fnQueueLen === 2) Yaku.nextTick(flush);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a iterator
|
||||
* @param {Any} obj
|
||||
* @private
|
||||
* @return {Object || TypeError}
|
||||
*/
|
||||
function each (iterable, fn) {
|
||||
var len
|
||||
, i = 0
|
||||
, iter
|
||||
, item
|
||||
, ret
|
||||
;
|
||||
|
||||
if (!iterable) throw genTypeError($invalidArgument);
|
||||
|
||||
var gen = iterable[Yaku[$Symbol][$iterator]];
|
||||
if (isFunction(gen))
|
||||
iter = gen.call(iterable);
|
||||
else if (isFunction(iterable.next)) {
|
||||
iter = iterable;
|
||||
}
|
||||
else if (isInstanceOf(iterable, Arr)) {
|
||||
len = iterable.length;
|
||||
while (i < len) {
|
||||
fn(iterable[i], i++);
|
||||
}
|
||||
return i;
|
||||
} else
|
||||
throw genTypeError($invalidArgument);
|
||||
|
||||
while (!(item = iter.next()).done) {
|
||||
ret = genTryCatcher(fn)(item.value, i++);
|
||||
if (ret === $tryErr) {
|
||||
isFunction(iter[$return]) && iter[$return]();
|
||||
throw ret.e;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate type error object.
|
||||
* @private
|
||||
* @param {String} msg
|
||||
* @return {TypeError}
|
||||
*/
|
||||
function genTypeError (msg) {
|
||||
return new TypeError(msg);
|
||||
}
|
||||
|
||||
function genTraceInfo (noTitle) {
|
||||
return (noTitle ? '' : $fromPrevious) + new Err().stack;
|
||||
}
|
||||
|
||||
|
||||
// *************************** Promise Helpers ****************************
|
||||
|
||||
/**
|
||||
* Resolve the value returned by onFulfilled or onRejected.
|
||||
* @private
|
||||
* @param {Yaku} p1
|
||||
* @param {Yaku} p2
|
||||
*/
|
||||
var scheduleHandler = genScheduler(999, function (p1, p2) {
|
||||
var x, handler;
|
||||
|
||||
// 2.2.2
|
||||
// 2.2.3
|
||||
handler = p1._s !== $rejected ? p2._onFulfilled : p2._onRejected;
|
||||
|
||||
// 2.2.7.3
|
||||
// 2.2.7.4
|
||||
if (handler === $undefined) {
|
||||
settlePromise(p2, p1._s, p1._v);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2.2.7.1
|
||||
x = genTryCatcher(callHanler)(handler, p1._v);
|
||||
if (x === $tryErr) {
|
||||
// 2.2.7.2
|
||||
settlePromise(p2, $rejected, x.e);
|
||||
return;
|
||||
}
|
||||
|
||||
settleWithX(p2, x);
|
||||
});
|
||||
|
||||
var scheduleUnhandledRejection = genScheduler(9, function (p) {
|
||||
if (!hashOnRejected(p)) {
|
||||
p[$unhandled] = 1;
|
||||
emitEvent($unhandledRejection, p);
|
||||
}
|
||||
});
|
||||
|
||||
function emitEvent (name, p) {
|
||||
var browserEventName = 'on' + name.toLowerCase()
|
||||
, browserHandler = root[browserEventName];
|
||||
|
||||
if (process && process.listeners(name).length)
|
||||
name === $unhandledRejection ?
|
||||
process.emit(name, p._v, p) : process.emit(name, p);
|
||||
else if (browserHandler)
|
||||
browserHandler({ reason: p._v, promise: p });
|
||||
else
|
||||
Yaku[name](p._v, p);
|
||||
}
|
||||
|
||||
function isYaku (val) { return val && val._s; }
|
||||
|
||||
function newCapablePromise (Constructor) {
|
||||
if (isYaku(Constructor)) return new Constructor($noop);
|
||||
|
||||
var p, r, j;
|
||||
p = new Constructor(function (resolve, reject) {
|
||||
if (p) throw genTypeError();
|
||||
|
||||
r = resolve;
|
||||
j = reject;
|
||||
});
|
||||
|
||||
ensureType(r, isFunction);
|
||||
ensureType(j, isFunction);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* It will produce a settlePromise function to user.
|
||||
* Such as the resolve and reject in this `new Yaku (resolve, reject) ->`.
|
||||
* @private
|
||||
* @param {Yaku} self
|
||||
* @param {Integer} state The value is one of `$pending`, `$resolved` or `$rejected`.
|
||||
* @return {Function} `(value) -> undefined` A resolve or reject function.
|
||||
*/
|
||||
function genSettler (self, state) {
|
||||
var isCalled = false;
|
||||
return function (value) {
|
||||
if (isCalled) return;
|
||||
isCalled = true;
|
||||
|
||||
if (isLongStackTrace)
|
||||
self[$settlerTrace] = genTraceInfo(true);
|
||||
|
||||
if (state === $resolved)
|
||||
settleWithX(self, value);
|
||||
else
|
||||
settlePromise(self, state, value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Link the promise1 to the promise2.
|
||||
* @private
|
||||
* @param {Yaku} p1
|
||||
* @param {Yaku} p2
|
||||
* @param {Function} onFulfilled
|
||||
* @param {Function} onRejected
|
||||
*/
|
||||
function addHandler (p1, p2, onFulfilled, onRejected) {
|
||||
// 2.2.1
|
||||
if (isFunction(onFulfilled))
|
||||
p2._onFulfilled = onFulfilled;
|
||||
if (isFunction(onRejected)) {
|
||||
if (p1[$unhandled]) emitEvent($rejectionHandled, p1);
|
||||
|
||||
p2._onRejected = onRejected;
|
||||
}
|
||||
|
||||
if (isLongStackTrace) p2._p = p1;
|
||||
p1[p1._c++] = p2;
|
||||
|
||||
// 2.2.6
|
||||
if (p1._s !== $pending)
|
||||
scheduleHandler(p1, p2);
|
||||
|
||||
// 2.2.7
|
||||
return p2;
|
||||
}
|
||||
|
||||
// iterate tree
|
||||
function hashOnRejected (node) {
|
||||
// A node shouldn't be checked twice.
|
||||
if (node._umark)
|
||||
return true;
|
||||
else
|
||||
node._umark = true;
|
||||
|
||||
var i = 0
|
||||
, len = node._c
|
||||
, child;
|
||||
|
||||
while (i < len) {
|
||||
child = node[i++];
|
||||
if (child._onRejected || hashOnRejected(child)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
function genStackInfo (reason, p) {
|
||||
var stackInfo = [];
|
||||
|
||||
function push (trace) {
|
||||
return stackInfo.push(trace.replace(/^\s+|\s+$/g, ''));
|
||||
}
|
||||
|
||||
if (isLongStackTrace) {
|
||||
if (p[$settlerTrace])
|
||||
push(p[$settlerTrace]);
|
||||
|
||||
// Hope you guys could understand how the back trace works.
|
||||
// We only have to iterate through the tree from the bottom to root.
|
||||
(function iter (node) {
|
||||
if (node && $promiseTrace in node) {
|
||||
iter(node._next);
|
||||
push(node[$promiseTrace] + '');
|
||||
iter(node._p);
|
||||
}
|
||||
})(p);
|
||||
}
|
||||
|
||||
return (reason && reason.stack ? reason.stack : reason) +
|
||||
('\n' + stackInfo.join('\n')).replace($cleanStackReg, '');
|
||||
}
|
||||
|
||||
function callHanler (handler, value) {
|
||||
// 2.2.5
|
||||
return handler(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve or reject a promise.
|
||||
* @private
|
||||
* @param {Yaku} p
|
||||
* @param {Integer} state
|
||||
* @param {Any} value
|
||||
*/
|
||||
function settlePromise (p, state, value) {
|
||||
var i = 0
|
||||
, len = p._c;
|
||||
|
||||
// 2.1.2
|
||||
// 2.1.3
|
||||
if (p._s === $pending) {
|
||||
// 2.1.1.1
|
||||
p._s = state;
|
||||
p._v = value;
|
||||
|
||||
if (state === $rejected) {
|
||||
if (isLongStackTrace && isError(value)) {
|
||||
value.longStack = genStackInfo(value, p);
|
||||
}
|
||||
|
||||
scheduleUnhandledRejection(p);
|
||||
}
|
||||
|
||||
// 2.2.4
|
||||
while (i < len) {
|
||||
scheduleHandler(p, p[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve or reject promise with value x. The x can also be a thenable.
|
||||
* @private
|
||||
* @param {Yaku} p
|
||||
* @param {Any | Thenable} x A normal value or a thenable.
|
||||
*/
|
||||
function settleWithX (p, x) {
|
||||
// 2.3.1
|
||||
if (x === p && x) {
|
||||
settlePromise(p, $rejected, genTypeError($promiseCircularChain));
|
||||
return p;
|
||||
}
|
||||
|
||||
// 2.3.2
|
||||
// 2.3.3
|
||||
if (x !== $null && (isFunction(x) || isObject(x))) {
|
||||
// 2.3.2.1
|
||||
var xthen = genTryCatcher(getThen)(x);
|
||||
|
||||
if (xthen === $tryErr) {
|
||||
// 2.3.3.2
|
||||
settlePromise(p, $rejected, xthen.e);
|
||||
return p;
|
||||
}
|
||||
|
||||
if (isFunction(xthen)) {
|
||||
if (isLongStackTrace && isYaku(x))
|
||||
p._next = x;
|
||||
|
||||
// Fix https://bugs.chromium.org/p/v8/issues/detail?id=4162
|
||||
if (isYaku(x))
|
||||
settleXthen(p, x, xthen);
|
||||
else
|
||||
Yaku.nextTick(function () {
|
||||
settleXthen(p, x, xthen);
|
||||
});
|
||||
} else
|
||||
// 2.3.3.4
|
||||
settlePromise(p, $resolved, x);
|
||||
} else
|
||||
// 2.3.4
|
||||
settlePromise(p, $resolved, x);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get a promise's then method.
|
||||
* @private
|
||||
* @param {Thenable} x
|
||||
* @return {Function}
|
||||
*/
|
||||
function getThen (x) { return x.then; }
|
||||
|
||||
/**
|
||||
* Resolve then with its promise.
|
||||
* @private
|
||||
* @param {Yaku} p
|
||||
* @param {Thenable} x
|
||||
* @param {Function} xthen
|
||||
*/
|
||||
function settleXthen (p, x, xthen) {
|
||||
// 2.3.3.3
|
||||
var err = genTryCatcher(xthen, x)(function (y) {
|
||||
// 2.3.3.3.3
|
||||
// 2.3.3.3.1
|
||||
x && (x = $null, settleWithX(p, y));
|
||||
}, function (r) {
|
||||
// 2.3.3.3.3
|
||||
// 2.3.3.3.2
|
||||
x && (x = $null, settlePromise(p, $rejected, r));
|
||||
});
|
||||
|
||||
// 2.3.3.3.4.1
|
||||
if (err === $tryErr && x) {
|
||||
// 2.3.3.3.4.2
|
||||
settlePromise(p, $rejected, err.e);
|
||||
x = $null;
|
||||
}
|
||||
}
|
||||
|
||||
root.Promise = Yaku;
|
||||
})();
|
2076
www/js/lib/q.js
2076
www/js/lib/q.js
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@
|
||||
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
'use strict';
|
||||
define(['q'], function(Q) {
|
||||
define([], function() {
|
||||
|
||||
/**
|
||||
* A Regular Expression to match the first letter of a word even if preceded by Unicode punctuation
|
||||
@ -211,7 +211,7 @@ define(['q'], function(Q) {
|
||||
return new Uint8Array(buffer);
|
||||
});
|
||||
} else {
|
||||
return Q.Promise(function (resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var reader = new FileReader();
|
||||
reader.readAsArrayBuffer(file.slice(begin, end));
|
||||
reader.addEventListener('load', function (e) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -20,7 +20,7 @@
|
||||
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
'use strict';
|
||||
define(['q', 'xzdec'], function(Q) {
|
||||
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
|
||||
var xzdec = Module;
|
||||
xzdec._init();
|
||||
@ -86,14 +86,15 @@ define(['q', 'xzdec'], function(Q) {
|
||||
* @returns {Promise} A Promise for the read data
|
||||
*/
|
||||
Decompressor.prototype.readSliceSingleThread = function (offset, length) {
|
||||
if (!busy) {
|
||||
// Tests whether the decompressor is ready (initiated) and not busy
|
||||
if (xzdec && !busy) {
|
||||
return this.readSlice(offset, length);
|
||||
} else {
|
||||
// The decompressor is already in progress.
|
||||
// To avoid using too much memory, we wait until it has finished
|
||||
// before using it for another decompression
|
||||
var that = this;
|
||||
return Q.Promise(function (resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(function () {
|
||||
that.readSliceSingleThread(offset, length).then(resolve, reject);
|
||||
}, DELAY_WAITING_IDLE_DECOMPRESSOR);
|
||||
@ -148,8 +149,7 @@ define(['q', 'xzdec'], function(Q) {
|
||||
*/
|
||||
Decompressor.prototype._fillInBufferIfNeeded = function() {
|
||||
if (!xzdec._input_empty(this._decHandle)) {
|
||||
// DEV: When converting to Promise/A+, use Promise.resolve(0) here
|
||||
return Q.when(0);
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
var that = this;
|
||||
return this._reader(this._inStreamPos, this._chunkSize).then(function(data) {
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
define(['xzdec_wrapper', 'zstddec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry', 'filecache'], function(xz, zstd, util, utf8, Q, zimDirEntry, FileCache) {
|
||||
define(['xzdec_wrapper', 'zstddec_wrapper', 'util', 'utf8', 'zimDirEntry', 'filecache'], function(xz, zstd, util, utf8, zimDirEntry, FileCache) {
|
||||
|
||||
/**
|
||||
* A variable to keep track of the currently loaded ZIM archive, e.g., for labelling cache entries
|
||||
@ -118,12 +118,12 @@ define(['xzdec_wrapper', 'zstddec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry',
|
||||
}
|
||||
}
|
||||
if (readRequests.length === 0) {
|
||||
return Q(new Uint8Array(0).buffer);
|
||||
return Promise.resolve(new Uint8Array(0).buffer);
|
||||
} else if (readRequests.length === 1) {
|
||||
return readRequests[0];
|
||||
} else {
|
||||
// Wait until all are resolved and concatenate.
|
||||
return Q.all(readRequests).then(function (arrays) {
|
||||
return Promise.all(readRequests).then(function (arrays) {
|
||||
var concatenated = new Uint8Array(end - begin);
|
||||
var offset = 0;
|
||||
arrays.forEach(function (item) {
|
||||
@ -227,7 +227,7 @@ define(['xzdec_wrapper', 'zstddec_wrapper', 'util', 'utf8', 'q', 'zimDirEntry',
|
||||
return that._readSlice(offsetStart, size);
|
||||
}
|
||||
} else {
|
||||
return Q(new Uint8Array(0).buffer);
|
||||
return Promise.resolve(new Uint8Array(0).buffer);
|
||||
}
|
||||
};
|
||||
// If only metadata were requested and the cluster is compressed, return null (this is probably a ZIM format error)
|
||||
|
@ -35,7 +35,7 @@ function B(){return buffer.byteLength/65536|0}return{"e":Ha,"f":oa,"g":na,"h":ga
|
||||
B=[];"object"!==typeof WebAssembly&&J("no native wasm support detected");var G,H=new function(c){var e=Array(c.initial);e.set=function(d,m){e[d]=m};e.get=function(d){return e[d]};return e}({initial:1,maximum:1,element:"anyfunc"}),K=!1;function L(c){var e=a["_"+c];e||J("Assertion failed: Cannot call unknown function "+(c+", make sure it is exported"));return e}
|
||||
function ea(c,e,d,m){var l={string:function(b){var f=0;if(null!==b&&void 0!==b&&0!==b){var g=(b.length<<2)+1;f=M(g);var h=f,k=O;if(0<g){g=h+g-1;for(var t=0;t<b.length;++t){var n=b.charCodeAt(t);if(55296<=n&&57343>=n){var I=b.charCodeAt(++t);n=65536+((n&1023)<<10)|I&1023}if(127>=n){if(h>=g)break;k[h++]=n}else{if(2047>=n){if(h+1>=g)break;k[h++]=192|n>>6}else{if(65535>=n){if(h+2>=g)break;k[h++]=224|n>>12}else{if(h+3>=g)break;k[h++]=240|n>>18;k[h++]=128|n>>12&63}k[h++]=128|n>>6&63}k[h++]=128|n&63}}k[h]=
|
||||
0}}return f},array:function(b){var f=M(b.length);fa.set(b,f);return f}},p=L(c),r=[];c=0;if(m)for(var q=0;q<m.length;q++){var D=l[d[q]];D?(0===c&&(c=ha()),r[q]=D(m[q])):r[q]=m[q]}d=p.apply(null,r);d=function(b){if("string"===e)if(b){for(var f=O,g=b+NaN,h=b;f[h]&&!(h>=g);)++h;if(16<h-b&&f.subarray&&ia)b=ia.decode(f.subarray(b,h));else{for(g="";b<h;){var k=f[b++];if(k&128){var t=f[b++]&63;if(192==(k&224))g+=String.fromCharCode((k&31)<<6|t);else{var n=f[b++]&63;k=224==(k&240)?(k&15)<<12|t<<6|n:(k&7)<<
|
||||
18|t<<12|n<<6|f[b++]&63;65536>k?g+=String.fromCharCode(k):(k-=65536,g+=String.fromCharCode(55296|k>>10,56320|k&1023))}}else g+=String.fromCharCode(k)}b=g}}else b="";else b="boolean"===e?!!b:b;return b}(d);0!==c&&ja(c);return d}var ia="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0,P,fa,O,C=a.INITIAL_MEMORY||140247040;a.wasmMemory?G=a.wasmMemory:G=new aa;G&&(P=G.buffer);C=P.byteLength;var Q=P;P=Q;a.HEAP8=fa=new Int8Array(Q);a.HEAP16=new Int16Array(Q);a.HEAP32=new Int32Array(Q);
|
||||
18|t<<12|n<<6|f[b++]&63;65536>k?g+=String.fromCharCode(k):(k-=65536,g+=String.fromCharCode(55296|k>>10,56320|k&1023))}}else g+=String.fromCharCode(k)}b=g}}else b="";else b="boolean"===e?!!b:b;return b}(d);0!==c&&ja(c);return d}var ia="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0,P,fa,O,C=a.INITIAL_MEMORY||150994944;a.wasmMemory?G=a.wasmMemory:G=new aa;G&&(P=G.buffer);C=P.byteLength;var Q=P;P=Q;a.HEAP8=fa=new Int8Array(Q);a.HEAP16=new Int16Array(Q);a.HEAP32=new Int32Array(Q);
|
||||
a.HEAPU8=O=new Uint8Array(Q);a.HEAPU16=new Uint16Array(Q);a.HEAPU32=new Uint32Array(Q);a.HEAPF32=new Float32Array(Q);a.HEAPF64=new Float64Array(Q);var ka=[],la=[],ma=[],na=[];function oa(){var c=a.preRun.shift();ka.unshift(c)}Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(c,e){var d=c&65535,m=e&65535;return d*m+((c>>>16)*m+d*(e>>>16)<<16)|0});if(!Math.fround){var pa=new Float32Array(1);Math.fround=function(c){pa[0]=c;return pa[0]}}
|
||||
Math.clz32||(Math.clz32=function(c){var e=32,d=c>>16;d&&(e-=16,c=d);if(d=c>>8)e-=8,c=d;if(d=c>>4)e-=4,c=d;if(d=c>>2)e-=2,c=d;return c>>1?e-2:e-c});Math.trunc||(Math.trunc=function(c){return 0>c?Math.ceil(c):Math.floor(c)});var R=0,T=null,U=null;a.preloadedImages={};a.preloadedAudios={};function J(c){if(a.onAbort)a.onAbort(c);A(c);K=!0;c=new da("abort("+c+"). Build with -s ASSERTIONS=1 for more info.");v(c);throw c;}
|
||||
function V(c){return String.prototype.startsWith?c.startsWith("data:application/octet-stream;base64,"):0===c.indexOf("data:application/octet-stream;base64,")}var W="zstddec.wasm";if(!V(W)){var qa=W;W=a.locateFile?a.locateFile(qa,y):y+qa}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
'use strict';
|
||||
define(['q', 'zstddec'], function (Q) {
|
||||
define(['zstddec'], function () {
|
||||
// DEV: zstddec.js has been compiled with `-s EXPORT_NAME="ZD" -s MODULARIZE=1` to avoid a clash with xzdec which uses "Module" as its exported object
|
||||
// Note that we include zstddec above in requireJS definition, but we cannot change the name in the function list
|
||||
// There is no longer any need to load it in index.html
|
||||
@ -130,7 +130,7 @@ define(['q', 'zstddec'], function (Q) {
|
||||
this._outDataBufPos = 0;
|
||||
var ret = zd._ZSTD_initDStream(zd._decHandle);
|
||||
if (zd._ZSTD_isError(ret)) {
|
||||
return Q.reject('Failed to initialize ZSTD decompression');
|
||||
return Promise.reject('Failed to initialize ZSTD decompression');
|
||||
}
|
||||
|
||||
return this._readLoop(offset, length).then(function (data) {
|
||||
@ -153,14 +153,15 @@ define(['q', 'zstddec'], function (Q) {
|
||||
* @returns {Promise} A Promise for the readSlice() function
|
||||
*/
|
||||
Decompressor.prototype.readSliceSingleThread = function (offset, length) {
|
||||
if (!busy) {
|
||||
// Tests whether the decompressor is ready (initiated) and not busy
|
||||
if (zd && !busy) {
|
||||
return this.readSlice(offset, length);
|
||||
} else {
|
||||
// The decompressor is already in progress.
|
||||
// To avoid using too much memory, we wait until it has finished
|
||||
// before using it for another decompression
|
||||
var that = this;
|
||||
return Q.Promise(function (resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(function () {
|
||||
that.readSliceSingleThread(offset, length).then(resolve, reject);
|
||||
}, DELAY_WAITING_IDLE_DECOMPRESSOR);
|
||||
@ -181,7 +182,7 @@ define(['q', 'zstddec'], function (Q) {
|
||||
var ret = zd._ZSTD_decompressStream(zd._decHandle, zd._outBuffer.ptr, zd._inBuffer.ptr);
|
||||
if (zd._ZSTD_isError(ret)) {
|
||||
var errorMessage = "Failed to decompress data stream!\n" + zd.getErrorString(ret);
|
||||
return Q.reject(errorMessage);
|
||||
return Promise.reject(errorMessage);
|
||||
}
|
||||
// Get updated outbuffer values
|
||||
var obxPtr32Bit = zd._outBuffer.ptr >> 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user