From 9a7419d2d16d94f9ec66d7d7e4026e8cc3d2430e Mon Sep 17 00:00:00 2001 From: Jaifroid <egk10@cam.ac.uk> Date: Mon, 13 Nov 2023 21:07:52 +0000 Subject: [PATCH] Fix some ESLint rules (indentation) (#1161) --- www/js/app.js | 138 ++++++++++++++++---------------- www/js/lib/arrayFromPolyfill.js | 53 ++++++------ www/js/lib/filecache.js | 2 +- www/js/lib/settingsStore.js | 2 +- www/js/lib/utf8.js | 2 +- www/js/lib/util.js | 37 +++++---- www/js/lib/xzdec_wrapper.js | 45 ++++++----- www/js/lib/zstddec_wrapper.js | 2 +- 8 files changed, 142 insertions(+), 139 deletions(-) diff --git a/www/js/app.js b/www/js/app.js index 46235040b..cde03edc8 100644 --- a/www/js/app.js +++ b/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 { diff --git a/www/js/lib/arrayFromPolyfill.js b/www/js/lib/arrayFromPolyfill.js index 6764c1527..f2507b4ba 100644 --- a/www/js/lib/arrayFromPolyfill.js +++ b/www/js/lib/arrayFromPolyfill.js @@ -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 -}()); \ No newline at end of file + 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 +}()); diff --git a/www/js/lib/filecache.js b/www/js/lib/filecache.js index ba7f7bc3e..5cbe81504 100644 --- a/www/js/lib/filecache.js +++ b/www/js/lib/filecache.js @@ -176,4 +176,4 @@ var read = function (file, begin, end) { export default { read: read -}; \ No newline at end of file +}; diff --git a/www/js/lib/settingsStore.js b/www/js/lib/settingsStore.js index 3aea303a3..23fd0b7de 100644 --- a/www/js/lib/settingsStore.js +++ b/www/js/lib/settingsStore.js @@ -1,6 +1,6 @@ 'use strict'; -/* global define, params */ +/* global params */ var regexpCookieKeysToMigrate = new RegExp([ 'hideActiveContentWarning', 'showUIAnimations', 'appTheme', 'useCache', diff --git a/www/js/lib/utf8.js b/www/js/lib/utf8.js index 6f9fd5e02..b439cb4bc 100644 --- a/www/js/lib/utf8.js +++ b/www/js/lib/utf8.js @@ -102,4 +102,4 @@ utf8.parse = function (data, zeroTerminated) { export default { toByteArray: utf8.toByteArray, parse: utf8.parse -}; \ No newline at end of file +}; diff --git a/www/js/lib/util.js b/www/js/lib/util.js index 3500527e9..87ec38a54 100644 --- a/www/js/lib/util.js +++ b/www/js/lib/util.js @@ -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(); }); }, diff --git a/www/js/lib/xzdec_wrapper.js b/www/js/lib/xzdec_wrapper.js index 533e78aa0..350d3db46 100644 --- a/www/js/lib/xzdec_wrapper.js +++ b/www/js/lib/xzdec_wrapper.js @@ -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; diff --git a/www/js/lib/zstddec_wrapper.js b/www/js/lib/zstddec_wrapper.js index 45a30cd9e..5343c626f 100644 --- a/www/js/lib/zstddec_wrapper.js +++ b/www/js/lib/zstddec_wrapper.js @@ -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