mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-09-22 12:01:15 -04:00
Fix some ESLint rules (indentation) (#1161)
This commit is contained in:
parent
e772cffd13
commit
9a7419d2d1
138
www/js/app.js
138
www/js/app.js
@ -25,7 +25,6 @@
|
||||
|
||||
// The global parameters object is defined in init.js
|
||||
/* global params, webpMachine, $ */
|
||||
/* eslint-disable indent */
|
||||
|
||||
// import styles from '../css/app.css' assert { type: "css" };
|
||||
// import bootstrap from '../css/bootstrap.min.css' assert { type: "css" };
|
||||
@ -240,19 +239,19 @@ function getDefaultLanguageAndTranslateApp () {
|
||||
// Use the override language if set, or else use the browser default
|
||||
var languageCode = params.overrideBrowserLanguage || defaultBrowserLanguage.base;
|
||||
translateUI.translateApp(languageCode)
|
||||
.catch(function (err) {
|
||||
if (languageCode !== 'en') {
|
||||
var message = '<p>We cannot load the translation strings for language code <code>' + languageCode + '</code>';
|
||||
// if (/^file:\/\//.test(window.location.href)) {
|
||||
// message += ' because you are accessing Kiwix from the file system. Try using a web server instead';
|
||||
// }
|
||||
message += '.</p><p>Falling back to English...</p>';
|
||||
if (err) message += '<p>The error message was:</p><code>' + err + '</code>';
|
||||
uiUtil.systemAlert(message);
|
||||
document.getElementById('languageSelector').value = 'en';
|
||||
return translateUI.translateApp('en');
|
||||
}
|
||||
});
|
||||
.catch(function (err) {
|
||||
if (languageCode !== 'en') {
|
||||
var message = '<p>We cannot load the translation strings for language code <code>' + languageCode + '</code>';
|
||||
// if (/^file:\/\//.test(window.location.href)) {
|
||||
// message += ' because you are accessing Kiwix from the file system. Try using a web server instead';
|
||||
// }
|
||||
message += '.</p><p>Falling back to English...</p>';
|
||||
if (err) message += '<p>The error message was:</p><code>' + err + '</code>';
|
||||
uiUtil.systemAlert(message);
|
||||
document.getElementById('languageSelector').value = 'en';
|
||||
return translateUI.translateApp('en');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add a listener for the language selection dropdown which will change the language of the app
|
||||
@ -261,8 +260,8 @@ document.getElementById('languageSelector').addEventListener('change', function
|
||||
if (language === 'other') {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-other-language-message') ||
|
||||
'We are working hard to bring you more languages! If you are interested in helping to translate the interface to your language, please create an issue on our GitHub. Thank you!'),
|
||||
(translateUI.t('configure-language-selector-other') || 'More soon...')).then(function () {
|
||||
document.getElementById('languageSelector').value = params.overrideBrowserLanguage || 'default';
|
||||
(translateUI.t('configure-language-selector-other') || 'More soon...')).then(function () {
|
||||
document.getElementById('languageSelector').value = params.overrideBrowserLanguage || 'default';
|
||||
});
|
||||
} else if (language === 'default') {
|
||||
params.overrideBrowserLanguage = null;
|
||||
@ -454,7 +453,7 @@ document.getElementById('useCanvasElementsCheck').addEventListener('change', fun
|
||||
});
|
||||
document.getElementById('btnReset').addEventListener('click', function () {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-reset-warning-message') || 'This will reset the app to a freshly installed state, deleting all app caches and settings!'),
|
||||
(translateUI.t('dialog-reset-warning-title') || 'WARNING!'), true).then(function (response) {
|
||||
(translateUI.t('dialog-reset-warning-title') || 'WARNING!'), true).then(function (response) {
|
||||
if (response) {
|
||||
settingsStore.reset();
|
||||
}
|
||||
@ -489,15 +488,15 @@ document.querySelectorAll('input[type="checkbox"][name=hideActiveContentWarning]
|
||||
})
|
||||
});
|
||||
document.getElementById('slideAwayCheck').addEventListener('change', function (e) {
|
||||
params.slideAway = e.target.checked;
|
||||
if (typeof navigator.getDeviceStorages === 'function') {
|
||||
// We are in Firefox OS, which may have a bug with this setting turned on - see [kiwix-js #1140]
|
||||
uiUtil.systemAlert(translateUI.t('dialog-slideawaycheck-message') || ('This setting may not work correctly on Firefox OS. ' +
|
||||
params.slideAway = e.target.checked;
|
||||
if (typeof navigator.getDeviceStorages === 'function') {
|
||||
// We are in Firefox OS, which may have a bug with this setting turned on - see [kiwix-js #1140]
|
||||
uiUtil.systemAlert(translateUI.t('dialog-slideawaycheck-message') || ('This setting may not work correctly on Firefox OS. ' +
|
||||
'If you find that some ZIM links become unresponsive, try turning this setting off.'), translateUI.t('dialog-warning') || 'Warning');
|
||||
}
|
||||
settingsStore.setItem('slideAway', params.slideAway, Infinity);
|
||||
// This has methods to add or remove the event listeners needed
|
||||
resizeIFrame();
|
||||
}
|
||||
settingsStore.setItem('slideAway', params.slideAway, Infinity);
|
||||
// This has methods to add or remove the event listeners needed
|
||||
resizeIFrame();
|
||||
});
|
||||
document.querySelectorAll('input[type="checkbox"][name=showUIAnimations]').forEach(function (element) {
|
||||
element.addEventListener('change', function () {
|
||||
@ -625,7 +624,7 @@ function checkAndDisplayInjectionModeChangeAlert () {
|
||||
'It supports more types of ZIM archives and is much more robust.</p>' +
|
||||
'<p>If you experience problems with this mode, you can switch back to the (now deprecated) JQuery mode. ' +
|
||||
'In that case, please report the problems you experienced to us (see About section).</p>'),
|
||||
(translateUI.t('dialog-serviceworker-defaultmodechange-title') || 'Change of default content injection mode')];
|
||||
(translateUI.t('dialog-serviceworker-defaultmodechange-title') || 'Change of default content injection mode')];
|
||||
uiUtil.systemAlert(message[0], message[1]).then(function () {
|
||||
settingsStore.setItem('defaultModeChangeAlertDisplayed', true, Infinity);
|
||||
});
|
||||
@ -635,7 +634,7 @@ function checkAndDisplayInjectionModeChangeAlert () {
|
||||
'<p>You can continue to use the app in the (now deprecated) JQuery mode, but note that this mode only works well with ' +
|
||||
'ZIM archives that have static content, such as Wikipedia / Wikimedia ZIMs or Stackexchange.</p>' +
|
||||
'<p>If you can, we recommend that you update your browser to a version that supports ServiceWorker mode.</p>'),
|
||||
(translateUI.t('dialog-serviceworker-unsupported-title') || 'ServiceWorker mode unsupported')];
|
||||
(translateUI.t('dialog-serviceworker-unsupported-title') || 'ServiceWorker mode unsupported')];
|
||||
uiUtil.systemAlert(message[0], message[1], true, null, (translateUI.t('dialog-ok') || 'Okay')).then(function (result) {
|
||||
if (result) {
|
||||
// If user selected OK, then do not display again ever
|
||||
@ -841,7 +840,7 @@ function setContentInjectionMode (value) {
|
||||
if (value === 'jquery') {
|
||||
if (!params.appCache) {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-bypassappcache-conflict-message') || 'You must deselect the "Bypass AppCache" option before switching to JQuery mode!'),
|
||||
(translateUI.t('dialog-bypassappcache-conflict-title') || 'Deselect "Bypass AppCache"')).then(function () {
|
||||
(translateUI.t('dialog-bypassappcache-conflict-title') || 'Deselect "Bypass AppCache"')).then(function () {
|
||||
setContentInjectionMode('serviceworker');
|
||||
})
|
||||
return;
|
||||
@ -1074,9 +1073,9 @@ function launchBrowserExtensionServiceWorker () {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-serveraccess-check-failed') || 'The server is not currently accessible! ' +
|
||||
'<br/><br/>(Kiwix needs one-time access to the server to cache the PWA).' +
|
||||
'<br/>Please try again when you have a stable Internet connection.'), (translateUI.t('dialog-error-title') || 'Error!')).then(function () {
|
||||
settingsStore.setItem('allowInternetAccess', false, Infinity);
|
||||
setContentInjectionMode(params.oldInjectionMode || 'jquery');
|
||||
});
|
||||
settingsStore.setItem('allowInternetAccess', false, Infinity);
|
||||
setContentInjectionMode(params.oldInjectionMode || 'jquery');
|
||||
});
|
||||
});
|
||||
};
|
||||
if (settingsStore.getItem('allowInternetAccess') === 'true') {
|
||||
@ -1147,7 +1146,7 @@ if (storages !== null && storages.length > 0) {
|
||||
// This way, it is only done once at this moment, instead of being done several times in callbacks
|
||||
// After that, we can start looking for archives
|
||||
storages[0].get('fake-file-to-read').then(searchForArchivesInPreferencesOrStorage,
|
||||
searchForArchivesInPreferencesOrStorage);
|
||||
searchForArchivesInPreferencesOrStorage);
|
||||
} else {
|
||||
// If DeviceStorage is not available, we display the file select components
|
||||
displayFileSelect();
|
||||
@ -1200,7 +1199,7 @@ function populateDropDownListOfArchives (archiveDirectories) {
|
||||
if (archiveDirectory === '/') {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-invalid-archivelocation-message') ||
|
||||
'It looks like you have put some archive files at the root of your sdcard (or internal storage). Please move them to a subdirectory'),
|
||||
(translateUI.t('dialog-invalid-archivelocation-title') || 'Error: invalid archive files location'));
|
||||
(translateUI.t('dialog-invalid-archivelocation-title') || 'Error: invalid archive files location'));
|
||||
} else {
|
||||
comboArchiveList.options[i] = new Option(archiveDirectory, archiveDirectory);
|
||||
}
|
||||
@ -1220,7 +1219,7 @@ function populateDropDownListOfArchives (archiveDirectories) {
|
||||
setLocalArchiveFromArchiveList();
|
||||
} else {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-welcome-message') || 'Welcome to Kiwix! This application needs at least a ZIM file in your SD-card (or internal storage). Please download one and put it on the device (see About section). Also check that your device is not connected to a computer through USB device storage (which often locks the SD-card content)'),
|
||||
(translateUI.t('dialog-welcome-title') || 'Welcome')).then(function () {
|
||||
(translateUI.t('dialog-welcome-title') || 'Welcome')).then(function () {
|
||||
document.getElementById('btnAbout').click();
|
||||
var isAndroid = (navigator.userAgent.indexOf('Android') !== -1);
|
||||
if (isAndroid) {
|
||||
@ -1504,7 +1503,7 @@ function setLocalArchiveFromFileList (files) {
|
||||
// DEV: you can support other file types by adding (e.g.) '|dat|idx' after 'zim\w{0,2}'
|
||||
if (!/\.(?:zim\w{0,2})$/i.test(files[i].name)) {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-invalid-zim-message') || 'One or more files does not appear to be a ZIM file!'),
|
||||
(translateUI.t('dialog-invalid-zim-title') || 'Invalid file format'));
|
||||
(translateUI.t('dialog-invalid-zim-title') || 'Invalid file format'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1671,12 +1670,12 @@ function populateListOfArticles (dirEntryArray, reportingSearch) {
|
||||
// and prevents this event from firing; note that touch also triggers mousedown
|
||||
document.querySelectorAll('#articleList a').forEach(function (link) {
|
||||
link.addEventListener('mousedown', function (e) {
|
||||
// Cancel search immediately
|
||||
appstate.search.status = 'cancelled';
|
||||
handleTitleClick(e);
|
||||
return false;
|
||||
// Cancel search immediately
|
||||
appstate.search.status = 'cancelled';
|
||||
handleTitleClick(e);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
});
|
||||
if (!stillSearching) document.getElementById('searchingArticles').style.display = 'none';
|
||||
document.getElementById('articleListWithHeader').style.display = '';
|
||||
}
|
||||
@ -2004,9 +2003,9 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
|
||||
// Add any missing classes stripped from the <html> tag
|
||||
if (htmlCSS) {
|
||||
htmlCSS.forEach(function (cl) {
|
||||
docBody.classList.add(cl);
|
||||
});
|
||||
}
|
||||
docBody.classList.add(cl);
|
||||
});
|
||||
}
|
||||
// Deflect drag-and-drop of ZIM file on the iframe to Config
|
||||
docBody.addEventListener('dragover', handleIframeDragover);
|
||||
docBody.addEventListener('drop', handleIframeDrop);
|
||||
@ -2222,7 +2221,7 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Code below is currently non-functional in jQuery mode, but provides an outline of how JS scripts could
|
||||
* be attached to the DOM. Users who want JS support should switch to ServiceWorker mode if avaialable on
|
||||
* their browser/OS. There is an experimental implementation of JS support in jQuery mode in the branch
|
||||
@ -2252,30 +2251,30 @@ function displayArticleContentInIframe (dirEntry, htmlArticle) {
|
||||
function insertMediaBlobsJQuery () {
|
||||
var iframe = iframeArticleContent.contentDocument;
|
||||
Array.prototype.slice.call(iframe.querySelectorAll('video, audio, source, track'))
|
||||
.forEach(function (mediaSource) {
|
||||
var source = mediaSource.getAttribute('src');
|
||||
source = source ? uiUtil.deriveZimUrlFromRelativeUrl(source, baseUrl) : null;
|
||||
// We have to exempt text tracks from using deriveZimUrlFromRelativeurl due to a bug in Firefox [kiwix-js #496]
|
||||
source = source || decodeURIComponent(mediaSource.dataset.kiwixurl);
|
||||
if (!source || !regexpZIMUrlWithNamespace.test(source)) {
|
||||
if (source) console.error('No usable media source was found for: ' + source);
|
||||
return;
|
||||
}
|
||||
var mediaElement = /audio|video/i.test(mediaSource.tagName) ? mediaSource : mediaSource.parentElement;
|
||||
// If the "controls" property is missing, we need to add it to ensure jQuery-only users can operate the video. See kiwix-js #760.
|
||||
if (/audio|video/i.test(mediaElement.tagName) && !mediaElement.hasAttribute('controls')) mediaElement.setAttribute('controls', '');
|
||||
selectedArchive.getDirEntryByPath(source).then(function (dirEntry) {
|
||||
return selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, mediaArray) {
|
||||
var mimeType = mediaSource.type ? mediaSource.type : dirEntry.getMimetype();
|
||||
var blob = new Blob([mediaArray], { type: mimeType });
|
||||
mediaSource.src = URL.createObjectURL(blob);
|
||||
// In Firefox and Chromium it is necessary to re-register the inserted media source
|
||||
// but do not reload for text tracks (closed captions / subtitles)
|
||||
if (/track/i.test(mediaSource.tagName)) return;
|
||||
mediaElement.load();
|
||||
.forEach(function (mediaSource) {
|
||||
var source = mediaSource.getAttribute('src');
|
||||
source = source ? uiUtil.deriveZimUrlFromRelativeUrl(source, baseUrl) : null;
|
||||
// We have to exempt text tracks from using deriveZimUrlFromRelativeurl due to a bug in Firefox [kiwix-js #496]
|
||||
source = source || decodeURIComponent(mediaSource.dataset.kiwixurl);
|
||||
if (!source || !regexpZIMUrlWithNamespace.test(source)) {
|
||||
if (source) console.error('No usable media source was found for: ' + source);
|
||||
return;
|
||||
}
|
||||
var mediaElement = /audio|video/i.test(mediaSource.tagName) ? mediaSource : mediaSource.parentElement;
|
||||
// If the "controls" property is missing, we need to add it to ensure jQuery-only users can operate the video. See kiwix-js #760.
|
||||
if (/audio|video/i.test(mediaElement.tagName) && !mediaElement.hasAttribute('controls')) mediaElement.setAttribute('controls', '');
|
||||
selectedArchive.getDirEntryByPath(source).then(function (dirEntry) {
|
||||
return selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, mediaArray) {
|
||||
var mimeType = mediaSource.type ? mediaSource.type : dirEntry.getMimetype();
|
||||
var blob = new Blob([mediaArray], { type: mimeType });
|
||||
mediaSource.src = URL.createObjectURL(blob);
|
||||
// In Firefox and Chromium it is necessary to re-register the inserted media source
|
||||
// but do not reload for text tracks (closed captions / subtitles)
|
||||
if (/track/i.test(mediaSource.tagName)) return;
|
||||
mediaElement.load();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2347,7 +2346,7 @@ function goToArticle (path, download, contentType) {
|
||||
}
|
||||
}).catch(function (e) {
|
||||
uiUtil.systemAlert((translateUI.t('dialog-article-readerror-message') || 'Error reading article with url:' + ' ' + path + ' : ' + e),
|
||||
translateUI.t('dialog-article-readerror-title') || 'Error reading article');
|
||||
translateUI.t('dialog-article-readerror-title') || 'Error reading article');
|
||||
});
|
||||
}
|
||||
|
||||
@ -2358,7 +2357,7 @@ function goToRandomArticle () {
|
||||
if (dirEntry === null || dirEntry === undefined) {
|
||||
document.getElementById('searchingArticles').style.display = 'none';
|
||||
uiUtil.systemAlert(translateUI.t('dialog-randomarticle-error-message') || 'Error finding random article',
|
||||
translateUI.t('dialog-article-notfound-title') || 'Error: article not found');
|
||||
translateUI.t('dialog-article-notfound-title') || 'Error: article not found');
|
||||
} else {
|
||||
// We fall back to the old A namespace to support old ZIM files without a text/html MIME type for articles
|
||||
// DEV: If articlePtrPos is defined in zimFile, then we are using a v1 article-only title listing. By definition,
|
||||
@ -2400,8 +2399,7 @@ function goToMainArticle () {
|
||||
'<a href="https://pwa.kiwix.org" target="_blank">https://pwa.kiwix.org</a>.</p>' +
|
||||
'<p>Alternatively, you can use Kiwix Serve to serve this archive to your browser from localhost. ' +
|
||||
'Kiwix Serve is included with <a href="https://www.kiwix.org/applications/" target="_blank">Kiwix Desktop</a>.</p>',
|
||||
translateUI.t('dialog-unsupported-archivetype-title') || 'Unsupported archive type!'
|
||||
);
|
||||
translateUI.t('dialog-unsupported-archivetype-title') || 'Unsupported archive type!');
|
||||
document.getElementById('searchingArticles').style.display = 'none';
|
||||
document.getElementById('welcomeText').style.display = '';
|
||||
} else {
|
||||
|
@ -2,34 +2,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');
|
||||
|
||||
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 = [];
|
||||
var k = []; // used for convert Set to an Array
|
||||
var i = 0;
|
||||
var v;
|
||||
|
||||
var arNew = [],
|
||||
k = [], // used for convert Set to an Array
|
||||
i = 0,
|
||||
v;
|
||||
// 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;
|
||||
}
|
||||
|
||||
//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 || arr.size); i++) {
|
||||
v = typeof arr[i] !== 'undefined' ? arr[i] : arr.get ? arr.get(i) : null;
|
||||
arNew[i] = callbackFn
|
||||
? callbackFn.call(thisArg, v, i, arr) : v;
|
||||
}
|
||||
|
||||
for (; i < (arr.length || arr.size); i++) {
|
||||
v = typeof arr[i] !== 'undefined' ? arr[i] : arr.get ? arr.get(i) : null;
|
||||
arNew[i] = callbackFn ?
|
||||
callbackFn.call(thisArg, v, i, arr) : v;
|
||||
}
|
||||
|
||||
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
|
||||
}());
|
||||
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
|
||||
}());
|
||||
|
@ -176,4 +176,4 @@ var read = function (file, begin, end) {
|
||||
|
||||
export default {
|
||||
read: read
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
/* global define, params */
|
||||
/* global params */
|
||||
|
||||
var regexpCookieKeysToMigrate = new RegExp([
|
||||
'hideActiveContentWarning', 'showUIAnimations', 'appTheme', 'useCache',
|
||||
|
@ -102,4 +102,4 @@ utf8.parse = function (data, zeroTerminated) {
|
||||
export default {
|
||||
toByteArray: utf8.toByteArray,
|
||||
parse: utf8.parse
|
||||
};
|
||||
};
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable indent */
|
||||
/* eslint-disable one-var */
|
||||
|
||||
var regExpFindStringParts = /(?:^|.+?)(?:[\s$£€\uFFE5^+=`~<>{}[\]|\u3000-\u303F!-#%-\x2A,-/:;\x3F@\x5B-\x5D_\x7B}\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]+|$)/g;
|
||||
|
||||
/**
|
||||
@ -198,29 +201,29 @@ function leftShift (int, bits) {
|
||||
* @param {Integer} nChr Numerical character code
|
||||
* @returns {Integer} Converted character code
|
||||
*/
|
||||
function b64ToUint6(nChr) {
|
||||
return nChr > 64 && nChr < 91 ?
|
||||
nChr - 65 :
|
||||
nChr > 96 && nChr < 123 ?
|
||||
nChr - 71 :
|
||||
nChr > 47 && nChr < 58 ?
|
||||
nChr + 4 :
|
||||
nChr === 43 ?
|
||||
62 :
|
||||
nChr === 47 ?
|
||||
63 :
|
||||
0;
|
||||
function b64ToUint6 (nChr) {
|
||||
return nChr > 64 && nChr < 91
|
||||
? nChr - 65
|
||||
: nChr > 96 && nChr < 123
|
||||
? nChr - 71
|
||||
: nChr > 47 && nChr < 58
|
||||
? nChr + 4
|
||||
: nChr === 43
|
||||
? 62
|
||||
: nChr === 47
|
||||
? 63
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recommended rewrite of the faulty .btoa() function in JavaScript because of the problem with UTF-8-encoded data
|
||||
* From https://developer.mozilla.org/en-US/docs/Glossary/Base64
|
||||
* @param {String} sBase64 Base 64 encoded string
|
||||
* @param {String} sBase64 Base 64 encoded string
|
||||
* @param {Integer} nBlocksSize Optional block size
|
||||
* @returns {Uint8Array} A Uint8Array containing the converted data
|
||||
*/
|
||||
function base64DecToArr(sBase64, nBlocksSize) {
|
||||
var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""),
|
||||
function base64DecToArr (sBase64, nBlocksSize) {
|
||||
var sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, ''),
|
||||
nInLen = sB64Enc.length,
|
||||
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2,
|
||||
taBytes = new Uint8Array(nOutLen);
|
||||
@ -242,7 +245,7 @@ function base64DecToArr(sBase64, nBlocksSize) {
|
||||
* @param {String} dataURI The data URI to convert
|
||||
* @returns {Uint8Array} A Uint8Array with the converted buffer
|
||||
*/
|
||||
function dataURItoUint8Array(dataURI) {
|
||||
function dataURItoUint8Array (dataURI) {
|
||||
var parsedString = dataURI.match(/^data:([^,]*),(.*)/i);
|
||||
if (parsedString && /base64/i.test(parsedString[1])) {
|
||||
return base64DecToArr(parsedString[2]);
|
||||
@ -282,7 +285,7 @@ var PromiseQueue = {
|
||||
return new Promise(function (resolve, reject) {
|
||||
// Don't allow more than four dialogues to queue up
|
||||
if (that._queue.length >= 4) reject(new Error('PromiseQueue: queue length exceeded'));
|
||||
else that._queue.push({promise: promiseFactory, resolve: resolve, reject: reject});
|
||||
else that._queue.push({ promise: promiseFactory, resolve: resolve, reject: reject });
|
||||
if (!that._working) that._dequeue();
|
||||
});
|
||||
},
|
||||
|
@ -21,6 +21,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/* global self, params */
|
||||
|
||||
import uiUtil from './uiUtil.js';
|
||||
import XZASM from './xzdec-asm.js';
|
||||
import XZWASM from './xzdec-wasm.js';
|
||||
@ -64,13 +66,14 @@ if (XZMachineType === 'WASM') {
|
||||
params.decompressorAPI.assemblerMachineType = XZMachineType;
|
||||
xzdec = instance;
|
||||
}).catch(function (err) {
|
||||
console.warn('WASM xz decoder failed to load, falling back to ASM', err);
|
||||
XZMachineType = 'ASM';
|
||||
loadASM();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
loadASM();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Number of milliseconds to wait for the decompressor to be available for another chunk
|
||||
* @type Integer
|
||||
@ -99,7 +102,7 @@ var busy = false;
|
||||
* @param {Integer} chunkSize
|
||||
* @returns {Decompressor}
|
||||
*/
|
||||
function Decompressor(reader, chunkSize) {
|
||||
function Decompressor (reader, chunkSize) {
|
||||
params.decompressorAPI.decompressorLastUsed = 'XZ';
|
||||
this._chunkSize = chunkSize || 1024 * 5;
|
||||
this._reader = reader;
|
||||
@ -111,7 +114,7 @@ function Decompressor(reader, chunkSize) {
|
||||
* @param {Integer} offset
|
||||
* @param {Integer} length
|
||||
*/
|
||||
Decompressor.prototype.readSlice = function(offset, length) {
|
||||
Decompressor.prototype.readSlice = function (offset, length) {
|
||||
busy = true;
|
||||
var that = this;
|
||||
this._inStreamPos = 0;
|
||||
@ -119,7 +122,7 @@ Decompressor.prototype.readSlice = function(offset, length) {
|
||||
this._decHandle = xzdec._init_decompression(this._chunkSize);
|
||||
this._outBuffer = new Int8Array(new ArrayBuffer(length));
|
||||
this._outBufferPos = 0;
|
||||
return this._readLoop(offset, length).then(function(data) {
|
||||
return this._readLoop(offset, length).then(function (data) {
|
||||
xzdec._release(that._decHandle);
|
||||
busy = false;
|
||||
return data;
|
||||
@ -151,14 +154,14 @@ Decompressor.prototype.readSliceSingleThread = function (offset, length) {
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {Integer} offset
|
||||
* @param {Integer} length
|
||||
* @returns {Array}
|
||||
*/
|
||||
Decompressor.prototype._readLoop = function(offset, length) {
|
||||
Decompressor.prototype._readLoop = function (offset, length) {
|
||||
var that = this;
|
||||
return this._fillInBufferIfNeeded().then(function() {
|
||||
return this._fillInBufferIfNeeded().then(function () {
|
||||
var ret = xzdec._decompress(that._decHandle);
|
||||
var finished = false;
|
||||
if (ret === 0) {
|
||||
@ -172,37 +175,37 @@ Decompressor.prototype._readLoop = function(offset, length) {
|
||||
}
|
||||
|
||||
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 copyStart = offset - that._outStreamPos;
|
||||
if (copyStart < 0)
|
||||
if (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._outStreamPos += outPos;
|
||||
if (outPos > 0)
|
||||
xzdec._out_buffer_cleared(that._decHandle);
|
||||
if (finished || that._outStreamPos >= offset + length)
|
||||
if (outPos > 0) { xzdec._out_buffer_cleared(that._decHandle); }
|
||||
if (finished || that._outStreamPos >= offset + length) {
|
||||
return that._outBuffer;
|
||||
else
|
||||
} else {
|
||||
return that._readLoop(offset, length);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
Decompressor.prototype._fillInBufferIfNeeded = function() {
|
||||
Decompressor.prototype._fillInBufferIfNeeded = function () {
|
||||
if (!xzdec._input_empty(this._decHandle)) {
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
var that = this;
|
||||
return this._reader(this._inStreamPos, this._chunkSize).then(function(data) {
|
||||
if (data.length > that._chunkSize)
|
||||
data = data.slice(0, that._chunkSize);
|
||||
return this._reader(this._inStreamPos, this._chunkSize).then(function (data) {
|
||||
if (data.length > 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
|
||||
xzdec.HEAP8.set(data, xzdec._get_in_buffer(that._decHandle));
|
||||
that._inStreamPos += data.length;
|
||||
|
@ -176,7 +176,7 @@ Decompressor.prototype.readSlice = function (offset, length) {
|
||||
}
|
||||
|
||||
return this._readLoop(offset, length).then(function (data) {
|
||||
// DEV: We are re-using all the allocated w/asm memory, so we do not need to free any of structures assigned wiht _malloc
|
||||
// DEV: We are re-using all the allocated w/asm memory, so we do not need to free any of structures assigned with _malloc
|
||||
// However, should you need to free assigned structures use, e.g., zd._free(zd._inBuffer.src);
|
||||
// Additionally, freeing zd._decHandle is not needed, and actually increases memory consumption (crashing zstddeclib)
|
||||
// Should you need to free the decoder stream handle, use command below, but be sure to create a new stream control object
|
||||
|
Loading…
x
Reference in New Issue
Block a user