Skip to content

Commit

Permalink
Clean up after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaifroid committed Oct 12, 2023
1 parent cd9778d commit d59384f
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 106 deletions.
46 changes: 23 additions & 23 deletions service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
* service-worker.js : Service Worker implementation,
* in order to capture the HTTP requests made by an article, and respond with the
* corresponding content, coming from the archive
*
*
* Copyright 2022 Mossroy, Jaifroid and contributors
* Licence GPL v3:
*
*
* This file is part of Kiwix.
*
*
* Kiwix is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation, either version 3 of the Licence, or
* (at your option) any later version.
*
*
* Kiwix is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
*
* You should have received a copy of the GNU General Public Licence
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
*/
Expand Down Expand Up @@ -62,9 +62,9 @@ var useAssetsCache = true;
* This is an expert setting in Configuration
* @type {Boolean}
*/
var useAppCache = true;
var useAppCache = true;

/**
/**
* A regular expression that matches the Content-Types of assets that may be stored in ASSETS_CACHE
* Add any further Content-Types you wish to cache to the regexp, separated by '|'
* @type {RegExp}
Expand All @@ -79,7 +79,7 @@ var regexpCachedContentTypes = /text\/css|text\/javascript|application\/javascri
*/
var regexpExcludedURLSchema = /^(?:file|chrome-extension|example-extension):/i;

/**
/**
* Pattern for ZIM file namespace: see https://wiki.openzim.org/wiki/ZIM_file_format#Namespaces
* In our case, there is also the ZIM file name used as a prefix in the URL
* @type {RegExp}
Expand All @@ -92,7 +92,7 @@ const regexpZIMUrlWithNamespace = /(?:^|\/)([^/]+\/)([-ABCIJMUVWX])\/(.+)/;
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range
* But, in our case, we send a header to tell the browser we only accept the bytes unit.
* I did not see multiple ranges asked by a browser.
*
*
* @type {RegExp}
*/
const regexpByteRangeHeader = /^\s*bytes=(\d+)-/;
Expand Down Expand Up @@ -241,7 +241,7 @@ self.addEventListener('fetch', function (event) {
event.respondWith(
// First see if the content is in the cache
fromCache(cache, rqUrl).then(function (response) {
// The response was found in the cache so we respond with it
// The response was found in the cache so we respond with it
return response;
}, function () {
// The response was not found in the cache so we look for it in the ZIM
Expand Down Expand Up @@ -278,7 +278,7 @@ self.addEventListener('fetch', function (event) {
/**
* Handle custom commands sent from app.js
*/
self.addEventListener('message', function (event) {
self.addEventListener('message', function (event) {
if (event.data.action) {
if (event.data.action === 'init') {
// On 'init' message, we initialize the outgoingMessagePort and enable the fetchEventListener
Expand Down Expand Up @@ -316,12 +316,12 @@ self.addEventListener('fetch', function (event) {

/**
* Handles URLs that need to be extracted from the ZIM archive
*
*
* @param {URL} urlObject The URL object to be processed for extraction from the ZIM
* @param {String} range Optional byte range string
* @returns {Promise<Response>} A Promise for the Response, or rejects with the invalid message port data
*/
function fetchUrlFromZIM(urlObject, range) {
function fetchUrlFromZIM (urlObject, range) {
return new Promise(function (resolve, reject) {
// Note that titles may contain bare question marks or hashes, so we must use only the pathname without any URL parameters.
// Be sure that you haven't encoded any querystring along with the URL.
Expand All @@ -346,14 +346,14 @@ function fetchUrlFromZIM(urlObject, range) {
headers.set('Content-Security-Policy', "default-src 'self' data: blob: about: chrome-extension: moz-extension: https://browser-extension.kiwix.org https://kiwix.github.io 'unsafe-inline' 'unsafe-eval'; sandbox allow-scripts allow-same-origin allow-modals allow-popups allow-forms allow-downloads;");
headers.set('Referrer-Policy', 'no-referrer');
if (contentType) headers.set('Content-Type', contentType);

// Test if the content is a video or audio file. In this case, Chrome & Edge need us to support ranges.
// See kiwix-js #519 and openzim/zimwriterfs #113 for why we test for invalid types like "mp4" or "webm" (without "video/")
// The full list of types produced by zimwriterfs is in https://github.com/openzim/zimwriterfs/blob/master/src/tools.cpp
if (contentLength >= 1 && /^(video|audio)|(^|\/)(mp4|webm|og[gmv]|mpeg)$/i.test(contentType)) {
headers.set('Accept-Ranges', 'bytes');
}

var slicedData = msgPortEvent.data.content;
if (range) {
// The browser asks for a range of bytes (usually for a video or audio stream)
Expand All @@ -367,18 +367,18 @@ function fetchUrlFromZIM(urlObject, range) {
const begin = partsOfRangeHeader[1];
const end = contentLength - 1;
slicedData = slicedData.slice(begin);

headers.set('Content-Range', 'bytes ' + begin + '-' + end + '/' + contentLength);
headers.set('Content-Length', end - begin + 1);
}

var responseInit = {
// HTTP status is usually 200, but has to bee 206 when partial content (range) is sent
status: range ? 206 : 200,
statusText: 'OK',
headers
};

var httpResponse = new Response(slicedData, responseInit);

// Let's send the content back from the ServiceWorker
Expand All @@ -402,7 +402,7 @@ function fetchUrlFromZIM(urlObject, range) {
* @param {String} requestUrl The Request URL to fulfill from cache
* @returns {Promise<Response>} A Promise for the cached Response, or rejects with strings 'disabled' or 'no-match'
*/
function fromCache(cache, requestUrl) {
function fromCache (cache, requestUrl) {
// Prevents use of Cache API if user has disabled it
if (!(useAppCache && cache === APP_CACHE || useAssetsCache && cache === ASSETS_CACHE)) {
return Promise.reject(new Error('disabled'));
Expand All @@ -425,7 +425,7 @@ function fromCache(cache, requestUrl) {
* @param {Response} response The Response received from the server/ZIM
* @returns {Promise} A Promise for the update action
*/
function updateCache(cache, request, response) {
function updateCache (cache, request, response) {
// Prevents use of Cache API if user has disabled it
if (!response.ok || !(useAppCache && cache === APP_CACHE || useAssetsCache && cache === ASSETS_CACHE)) {
return Promise.resolve();
Expand All @@ -442,16 +442,16 @@ function updateCache(cache, request, response) {
* @param {String} url A URL to test against excludedURLSchema
* @returns {Promise<Array>} A Promise for an array of format [cacheType, cacheDescription, assetCount]
*/
function testCacheAndCountAssets(url) {
function testCacheAndCountAssets (url) {
if (regexpExcludedURLSchema.test(url)) return Promise.resolve(['custom', 'custom', 'Custom', '-']);
if (!useAssetsCache) return Promise.resolve(['none', 'none', 'None', 0]);
return caches.open(ASSETS_CACHE).then(function (cache) {
return cache.keys().then(function (keys) {
return ['cacheAPI', ASSETS_CACHE, 'Cache API', keys.length];
}).catch(function(err) {
}).catch(function (err) {
return err;
});
}).catch(function(err) {
}).catch(function (err) {
return err;
});
}
168 changes: 85 additions & 83 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,67 +41,67 @@ if (params.abort) {
throw new Error('Managed error: exiting local extension code.')
}

/**
* The delay (in milliseconds) between two "keepalive" messages sent to the ServiceWorker (so that it is not stopped
* by the browser, and keeps the MessageChannel to communicate with the application)
* @type Integer
*/
const DELAY_BETWEEN_KEEPALIVE_SERVICEWORKER = 30000;

/**
* The name of the Cache API cache to use for caching Service Worker requests and responses for certain asset types
* We need access to the cache name in app.js in order to complete utility actions when Service Worker is not initialized,
* so we have to duplicate it here
* @type {String}
*/
// DEV: Ensure this matches the name defined in service-worker.js (a check is provided in refreshCacheStatus() below)
const ASSETS_CACHE = 'kiwixjs-assetsCache';
/**
* The delay (in milliseconds) between two "keepalive" messages sent to the ServiceWorker (so that it is not stopped
* by the browser, and keeps the MessageChannel to communicate with the application)
* @type Integer
*/
const DELAY_BETWEEN_KEEPALIVE_SERVICEWORKER = 30000;

/**
* Memory cache for CSS styles contained in ZIM: it significantly speeds up subsequent page display
* This cache is used by default in jQuery mode, but can be turned off in Configuration for low-memory devices
* In Service Worker mode, the Cache API will be used instead
* @type {Map}
*/
var cssCache = new Map();
/**
* The name of the Cache API cache to use for caching Service Worker requests and responses for certain asset types
* We need access to the cache name in app.js in order to complete utility actions when Service Worker is not initialized,
* so we have to duplicate it here
* @type {String}
*/
// DEV: Ensure this matches the name defined in service-worker.js (a check is provided in refreshCacheStatus() below)
const ASSETS_CACHE = 'kiwixjs-assetsCache';

/**
* Memory cache for CSS styles contained in ZIM: it significantly speeds up subsequent page display
* This cache is used by default in jQuery mode, but can be turned off in Configuration for low-memory devices
* In Service Worker mode, the Cache API will be used instead
* @type {Map}
*/
var cssCache = new Map();

/**
* A global object for storing app state
*
* @type Object
*/
var appstate = {};
/**
* A global object for storing app state
*
* @type Object
*/
var appstate = {};

/**
* @type ZIMArchive
*/
var selectedArchive = null;
/**
* @type ZIMArchive
*/
var selectedArchive = null;

// An object to hold the current search and its state (allows cancellation of search across modules)
appstate['search'] = {
// An object to hold the current search and its state (allows cancellation of search across modules)
appstate['search'] = {
prefix: '', // A field to hold the original search string
status: '', // The status of the search: ''|'init'|'interim'|'cancelled'|'complete'
type: '' // The type of the search: 'basic'|'full' (set automatically in search algorithm)
};
};

// A Boolean to store the update status of the PWA version (currently only used with Firefox Extension)
appstate['pwaUpdateNeeded'] = false; // This will be set to true if the Service Worker has an update waiting
// A Boolean to store the update status of the PWA version (currently only used with Firefox Extension)
appstate['pwaUpdateNeeded'] = false; // This will be set to true if the Service Worker has an update waiting

switchHomeKeyToFocusSearchBar();

// We check here if we have to warn the user that we switched to ServiceWorkerMode
// We check here if we have to warn the user that we switched to ServiceWorkerMode
// This is only needed if the ServiceWorker mode is available, or we are in an Extension that supports Service Workers
// outside of the extension environment, AND the user's settings are stuck on jQuery mode, AND the user has not already been
// alerted about the switch to ServiceWorker mode by default
// outside of the extension environment, AND the user's settings are stuck on jQuery mode, AND the user has not already been
// alerted about the switch to ServiceWorker mode by default
if ((isServiceWorkerAvailable() || isMessageChannelAvailable() && /^(moz|chrome)-extension:/i.test(window.location.protocol)) &&
params.contentInjectionMode === 'jquery' && !params.defaultModeChangeAlertDisplayed) {
// Attempt to upgrade user to ServiceWorker mode
params.contentInjectionMode = 'serviceworker';
} else if (params.contentInjectionMode === 'serviceworker') {
// User is already in SW mode, so we will never need to display the upgrade alert
params.defaultModeChangeAlertDisplayed = true;
settingsStore.setItem('defaultModeChangeAlertDisplayed', true, Infinity);
}
// Attempt to upgrade user to ServiceWorker mode
params.contentInjectionMode = 'serviceworker';
} else if (params.contentInjectionMode === 'serviceworker') {
// User is already in SW mode, so we will never need to display the upgrade alert
params.defaultModeChangeAlertDisplayed = true;
settingsStore.setItem('defaultModeChangeAlertDisplayed', true, Infinity);
}
if (!/^chrome-extension:/i.test(window.location.protocol)) {
document.getElementById('serviceWorkerLocal').style.display = 'none';
document.getElementById('serviceWorkerLocalDescription').style.display = 'none';
Expand Down Expand Up @@ -151,7 +151,7 @@ var expectedArticleURLToBeDisplayed = '';
nestedFrame.style.height = window.innerHeight - 110 + 'px';
} else {
// IE cannot retrieve computed headerStyles till the next paint, so we wait a few ticks
setTimeout(function () {
setTimeout(function() {
// Get header height *including* its bottom margin
const headerHeight = parseFloat(headerStyles.height) + parseFloat(headerStyles.marginBottom);
iframe.style.height = window.innerHeight - headerHeight + 'px';
Expand Down Expand Up @@ -1342,12 +1342,14 @@ document.getElementById('libraryBtn').addEventListener('click', function (e) {
selectedArchive = null;
selectedArchive = zimArchiveLoader.loadArchiveFromFiles(files, function () {
document.getElementById('downloadInstruction').style.display = 'none';
var tmpMessageChannel = new MessageChannel();
tmpMessageChannel.port1.onmessage = function () {
// The archive is set : go back to home page to start searching
$("#btnHome").click();
}
libzimWebWorker.postMessage({action: "init", files: selectedArchive._file._files}, [tmpMessageChannel.port2]);
// var tmpMessageChannel = new MessageChannel();
// tmpMessageChannel.port1.onmessage = function () {
// // The archive is set : go back to home page to start searching
// $("#btnHome").click();
// }
// selectedArchive.callLibzimWorker({ action: "init", files: selectedArchive._file._files }).then(function (worker) {
// $("#btnHome").click();
// });
}, function (message, label) {
// callbackError which is called in case of an error
uiUtil.systemAlert(message, label);
Expand Down Expand Up @@ -1672,34 +1674,34 @@ document.getElementById('libraryBtn').addEventListener('click', function (e) {
}
}

var libzimWebWorker = new Worker("a.out.js");
// var libzimWebWorker = new Worker("a.out.js");

/**
* Calls the libzim WebWorker with the given parameters, and returns a Promise with its response
*
* @param {Object} parameters
* @returns {Promise}
*/
function callLibzimWebWorker(parameters) {
return new Promise(function (resolve, reject) {
console.debug("Calling libzim WebWorker with parameters", parameters);
var tmpMessageChannel = new MessageChannel();
var t0 = performance.now();
tmpMessageChannel.port1.onmessage = function (event) {
var t1 = performance.now();
var readTime = Math.round(t1 - t0);
console.debug("Response given by the WebWorker in " + readTime + " ms", event.data);
resolve(event.data);
};
tmpMessageChannel.port1.onerror = function (event) {
var t1 = performance.now();
var readTime = Math.round(t1 - t0);
console.error("Error sent by the WebWorker in " + readTime + " ms", event.data);
reject(event.data);
};
libzimWebWorker.postMessage(parameters, [tmpMessageChannel.port2]);
});
}
// /**
// * Calls the libzim WebWorker with the given parameters, and returns a Promise with its response
// *
// * @param {Object} parameters
// * @returns {Promise}
// */
// function callLibzimWebWorker(parameters) {
// return new Promise(function (resolve, reject) {
// console.debug("Calling libzim WebWorker with parameters", parameters);
// var tmpMessageChannel = new MessageChannel();
// var t0 = performance.now();
// tmpMessageChannel.port1.onmessage = function (event) {
// var t1 = performance.now();
// var readTime = Math.round(t1 - t0);
// console.debug("Response given by the WebWorker in " + readTime + " ms", event.data);
// resolve(event.data);
// };
// tmpMessageChannel.port1.onerror = function (event) {
// var t1 = performance.now();
// var readTime = Math.round(t1 - t0);
// console.error("Error sent by the WebWorker in " + readTime + " ms", event.data);
// reject(event.data);
// };
// libzimWebWorker.postMessage(parameters, [tmpMessageChannel.port2]);
// });
// }

/**
* Function that handles a message of the messageChannel.
Expand Down Expand Up @@ -1733,8 +1735,8 @@ document.getElementById('libraryBtn').addEventListener('click', function (e) {
messagePort.postMessage(message);
}
};
callLibzimWebWorker({action: "getEntryByPath", path: title, follow: false}).then(readFile).catch(function () {
messagePort.postMessage({ action: 'giveContent', title: title, content: new Uint8Array() });
selectedArchive.callLibzimWorker({action: "getEntryByPath", path: title, follow: false}).then(readFile).catch(function () {
messagePort.postMessage({ action: 'giveContent', title: title, content: new Uint8Array() });
});
} else {
console.error('Invalid message received', event.data);
Expand Down
2 changes: 2 additions & 0 deletions www/js/lib/zimArchive.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ function ZIMArchive (storage, path, callbackReady, callbackError) {
params.searchProvider = 'fulltext: ' + libzimReaderType;
// Update the API panel
uiUtil.reportSearchProviderToAPIStatusPanel(params.searchProvider);
// Archive is set, go home
document.getElementById('btnHome').click();
}).catch(function (err) {
uiUtil.reportSearchProviderToAPIStatusPanel(params.searchProvider + ': ERROR');
console.error('The libzim worker could not be instantiated!', err);
Expand Down

0 comments on commit d59384f

Please sign in to comment.