mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-08 11:48:26 -04:00
Upgrade cookie support (partial)
Former-commit-id: 6a37fc8fd0ec37913ef7b4bf87f3087643a611bf [formerly d72eb8c6399b6f641a04070323044ea0b9ddf68a [formerly ff4f67d0b82442769141628dfb63c3c7d7b8436f]] Former-commit-id: 099b7da1c94f4e3b9d385fd3c85990f5cf1d91c9 Former-commit-id: a20ad2588fe6f55dbb261f9985a86a20f447406a
This commit is contained in:
parent
1dd1569b10
commit
f4e0b9f53b
@ -299,7 +299,7 @@
|
||||
<Content Include="www\js\katex\README.md" />
|
||||
<Content Include="www\js\lib\bootstrap.min.js" />
|
||||
<Content Include="www\js\lib\cache.js" />
|
||||
<Content Include="www\js\lib\cookies.js" />
|
||||
<Content Include="www\js\lib\settingsStore.js" />
|
||||
<Content Include="www\js\lib\filecache.js" />
|
||||
<Content Include="www\js\lib\images.js" />
|
||||
<Content Include="www\js\lib\jquery-3.2.1.slim.js" />
|
||||
|
@ -51,7 +51,7 @@ const precacheFiles = [
|
||||
"www/js/init.js",
|
||||
"www/js/lib/bootstrap.js",
|
||||
"www/js/lib/bootstrap.min.js",
|
||||
"www/js/lib/cookies.js",
|
||||
"www/js/lib/settingsStore.js",
|
||||
"www/js/lib/filecache.js",
|
||||
"www/js/lib/images.js",
|
||||
"www/js/lib/jquery-3.2.1.slim.js",
|
||||
|
@ -56,7 +56,7 @@ params['fileVersion'] = "wikipedia_en_100_maxi_2020-12.zim (23-Dec-2020)"; //Use
|
||||
params['cachedStartPage'] = false; //If you have cached the start page for quick start, give its URI here
|
||||
params['kiwixDownloadLink'] = "https://download.kiwix.org/zim/"; //Include final slash
|
||||
|
||||
params['cookieSupport'] = checkCookies();
|
||||
params['storeType'] = checkCookies();
|
||||
params['maxResults'] = ~~(getCookie('maxResults') || 25); //Number of search results to display
|
||||
params['relativeFontSize'] = ~~(getCookie('relativeFontSize') || 100); //Sets the initial font size for articles (as a percentage) - user can adjust using zoom buttons
|
||||
params['relativeUIFontSize'] = ~~(getCookie('relativeUIFontSize') || 100); //Sets the initial font size for UI (as a percentage) - user can adjust using slider in Config
|
||||
@ -92,7 +92,7 @@ params['localStorage'] = params['localStorage'] || "";
|
||||
params['pickedFile'] = launchArguments ? launchArguments.files[0] : "";
|
||||
params['pickedFolder'] = params['pickedFolder'] || "";
|
||||
params['lastPageVisit'] = getCookie('lastPageVisit') || "";
|
||||
params['lastPageVisit'] = params['lastPageVisit'] ? decodeURIComponent(params['lastPageVisit']) : "";
|
||||
params.lastPageVisit = params.lastPageVisit ? decodeURIComponent(params.lastPageVisit): "";
|
||||
params['themeChanged'] = params['themeChanged'] || false;
|
||||
params['allowInternetAccess'] = params['allowInternetAccess'] || false; //Do not get value from cookie, should be explicitly set by user on a per-session basis
|
||||
params['printIntercept'] = false;
|
||||
@ -146,10 +146,6 @@ document.getElementById('hideToolbarsCheck').indeterminate = params.hideToolbars
|
||||
document.getElementById('hideToolbarsCheck').readOnly = params.hideToolbars === "top";
|
||||
document.getElementById('hideToolbarsState').innerHTML = (params.hideToolbars === "top" ? "top" : params.hideToolbars ? "both" : "never");
|
||||
|
||||
//Set up packaged Electron app
|
||||
if (!params.pickedFile && params.storedFile && typeof window.fs !== 'undefined') {
|
||||
params.pickedFile = params.storedFile;
|
||||
}
|
||||
//Set up storage types
|
||||
if (params.storedFile && typeof Windows !== 'undefined' && typeof Windows.Storage !== 'undefined') { //UWP
|
||||
Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync(params.archivePath).done(function (folder) {
|
||||
@ -245,7 +241,7 @@ window.addEventListener('appinstalled', function(e) {
|
||||
|
||||
function getCookie(name) {
|
||||
var result;
|
||||
if (params.cookieSupport == 'cookie') {
|
||||
if (params.storeType == 'cookie') {
|
||||
var regexp = new RegExp('(?:^|;)\\s*' + name + '=([^;]+)(?:;|$)');
|
||||
result = document.cookie.match(regexp);
|
||||
result = result && result.length > 1 ? result[1] : null;
|
||||
|
@ -1,117 +0,0 @@
|
||||
'use strict';
|
||||
define([], function() {
|
||||
/*\
|
||||
|*|
|
||||
|*| :: cookies.js ::
|
||||
|*|
|
||||
|*| A complete cookies reader/writer framework with full unicode support.
|
||||
|*|
|
||||
|*| https://developer.mozilla.org/en-US/docs/DOM/document.cookie
|
||||
|*|
|
||||
|*| This framework is released under the GNU Public License, version 3 or later.
|
||||
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|
||||
|*|
|
||||
|*| Syntaxes:
|
||||
|*|
|
||||
|*| * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|
||||
|*| * docCookies.getItem(name)
|
||||
|*| * docCookies.removeItem(name[, path])
|
||||
|*| * docCookies.hasItem(name)
|
||||
|*| * docCookies.keys()
|
||||
|*|
|
||||
\*/
|
||||
|
||||
// Test for cookie support
|
||||
var storeType = 'cookie';
|
||||
document.cookie = 'kiwixCookie=working;expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
||||
var kiwixCookie = /kiwixCookie=working/i.test(document.cookie);
|
||||
if (kiwixCookie) {
|
||||
document.cookie = 'kiwixCookie=broken;expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
||||
kiwixCookie = !/kiwixCookie=working/i.test(document.cookie);
|
||||
}
|
||||
document.cookie = 'kiwixCookie=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
if (!kiwixCookie) {
|
||||
// Cookies appear to be blocked, so test for localStorage support
|
||||
var result = false;
|
||||
try {
|
||||
result = 'localStorage' in window && window['localStorage'] !== null;
|
||||
} catch (e) {
|
||||
console.log('LocalStorage is not supported!');
|
||||
}
|
||||
if (result) storeType = 'local_storage';
|
||||
}
|
||||
console.log('Test2: storeType: ' + storeType);
|
||||
|
||||
var docCookies = {
|
||||
getItem: function (sKey) {
|
||||
if (!sKey) {
|
||||
return null;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
|
||||
} else {
|
||||
return localStorage.getItem(keyPrefix + sKey);
|
||||
}
|
||||
},
|
||||
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
|
||||
if (params.storeType !== 'local_storage') {
|
||||
if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
|
||||
return false;
|
||||
}
|
||||
var sExpires = "";
|
||||
if (vEnd) {
|
||||
switch (vEnd.constructor) {
|
||||
case Number:
|
||||
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
|
||||
break;
|
||||
case String:
|
||||
sExpires = "; expires=" + vEnd;
|
||||
break;
|
||||
case Date:
|
||||
sExpires = "; expires=" + vEnd.toUTCString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
|
||||
} else {
|
||||
localStorage.setItem(keyPrefix + sKey, sValue);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
removeItem: function (sKey, sPath, sDomain) {
|
||||
if (!this.hasItem(sKey)) {
|
||||
return false;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
|
||||
} else {
|
||||
localStorage.removeItem(keyPrefix + sKey);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
hasItem: function (sKey) {
|
||||
if (!sKey) {
|
||||
return false;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
|
||||
} else {
|
||||
return localStorage.getItem(keyPrefix + sKey) === null ? false : true;
|
||||
}
|
||||
},
|
||||
_cookieKeys: function () {
|
||||
var aKeys = document.cookie.replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:=[^;]*)?;\s*/);
|
||||
for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) {
|
||||
aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]);
|
||||
}
|
||||
return aKeys;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
getItem: docCookies.getItem,
|
||||
setItem: docCookies.setItem,
|
||||
removeItem: docCookies.removeItem,
|
||||
hasItem: docCookies.hasItem
|
||||
};
|
||||
});
|
171
www/js/lib/settingsStore.js
Normal file
171
www/js/lib/settingsStore.js
Normal file
@ -0,0 +1,171 @@
|
||||
'use strict';
|
||||
define([], function () {
|
||||
/**
|
||||
* settingsStore.js
|
||||
*
|
||||
* A reader/writer framework for cookies or localStorage with full unicode support based on the Mozilla cookies framework.
|
||||
* The Mozilla code has been adapted to test for the availability of the localStorage API, and to use it in preference to settingsStore.
|
||||
*
|
||||
* Mozilla version information:
|
||||
*
|
||||
* Revision #1 - September 4, 2014
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|
||||
* https://developer.mozilla.org/User:fusionchess
|
||||
*
|
||||
* This framework is released under the GNU Public License, version 3 or later.
|
||||
* http://www.gnu.org/licenses/gpl-3.0-standalone.html
|
||||
*
|
||||
* Syntaxes:
|
||||
*
|
||||
* * settingsStore.setItem(name, value[, end[, path[, domain[, secure]]]])
|
||||
* * settingsStore.getItem(name)
|
||||
* * settingsStore.removeItem(name[, path[, domain]])
|
||||
* * settingsStore.hasItem(name)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A RegExp of the settings keys used in the cookie that should be migrated to localStorage if the API is available
|
||||
* DEV: It should not be necessary to keep this list up-to-date because any keys added after this list was created
|
||||
* (April 2020) will already be stored in localStorage if it is available to the client's browser or platform and
|
||||
* will not need to be migrated
|
||||
* @type {RegExp}
|
||||
*/
|
||||
var regexpCookieKeysToMigrate = new RegExp([
|
||||
'lastContentInjectionMode', 'lastSelectedArchivePath', 'imageDisplay', 'useMathJax', 'version', 'lastSelectedArchive',
|
||||
'listOfArchives', 'lastPageVisit', 'cssUITheme', 'cssTheme', 'cssSource', 'removePageMaxWidth', 'hideActiveContentWarning',
|
||||
'allowHTMLExtraction'
|
||||
].join('|'));
|
||||
|
||||
/**
|
||||
* A constant to set the prefix that will be added to keys when stored in localStorage: this is used to prevent
|
||||
* potential collision of key names with localStorage keys used by code inside ZIM archives
|
||||
* @type {String}
|
||||
*/
|
||||
const keyPrefix = 'kiwixjs-';
|
||||
|
||||
// Tests for available Storage APIs (document.cookie or localStorage) and returns the best available of these
|
||||
function getBestAvailableStorageAPI() {
|
||||
// DEV: In FF extensions, cookies are blocked since at least FF 68.6 but possibly since FF 55 [kiwix-js #612]
|
||||
var type = 'none';
|
||||
// First test for localStorage API support
|
||||
var localStorageTest;
|
||||
try {
|
||||
localStorageTest = 'localStorage' in window && window['localStorage'] !== null;
|
||||
// DEV: Above test returns true in IE11 running from file:// protocol, but attempting to write a key to
|
||||
// localStorage causes an exception; so to test fully, we must now attempt to write and remove a test key
|
||||
if (localStorageTest) {
|
||||
localStorage.setItem('tempKiwixStorageTest', '');
|
||||
localStorage.removeItem('tempKiwixStorageTest');
|
||||
}
|
||||
} catch (e) {
|
||||
localStorageTest = false;
|
||||
}
|
||||
// Now test for document.cookie API support
|
||||
document.cookie = 'tempKiwixCookieTest=working; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=Strict';
|
||||
var kiwixCookieTest = /tempKiwixCookieTest=working/.test(document.cookie);
|
||||
// Remove test value by expiring the key
|
||||
document.cookie = 'tempKiwixCookieTest=; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict';
|
||||
if (kiwixCookieTest) type = 'cookie';
|
||||
// Prefer localStorage if supported due to some platforms removing cookies once the session ends in some contexts
|
||||
if (localStorageTest) type = 'local_storage';
|
||||
// If both cookies and localStorage are supported, and document.cookie contains keys to migrate,
|
||||
// migrate settings to use localStorage
|
||||
if (kiwixCookieTest && localStorageTest && regexpCookieKeysToMigrate.test(document.cookie)) _migrateStorageSettings();
|
||||
// Note that if this function returns 'none', the cookie implementations below will run anyway. This is because storing a cookie
|
||||
// does not cause an exception even if cookies are blocked in some contexts, whereas accessing localStorage may cause an exception
|
||||
return type;
|
||||
}
|
||||
|
||||
var settingsStore = {
|
||||
getItem: function (sKey) {
|
||||
if (!sKey) {
|
||||
return null;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
|
||||
} else {
|
||||
return localStorage.getItem(keyPrefix + sKey);
|
||||
}
|
||||
},
|
||||
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
|
||||
if (params.storeType !== 'local_storage') {
|
||||
if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
|
||||
return false;
|
||||
}
|
||||
var sExpires = "";
|
||||
if (vEnd) {
|
||||
switch (vEnd.constructor) {
|
||||
case Number:
|
||||
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
|
||||
break;
|
||||
case String:
|
||||
sExpires = "; expires=" + vEnd;
|
||||
break;
|
||||
case Date:
|
||||
sExpires = "; expires=" + vEnd.toUTCString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
|
||||
} else {
|
||||
localStorage.setItem(keyPrefix + sKey, sValue);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
removeItem: function (sKey, sPath, sDomain) {
|
||||
if (!this.hasItem(sKey)) {
|
||||
return false;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
|
||||
} else {
|
||||
localStorage.removeItem(keyPrefix + sKey);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
hasItem: function (sKey) {
|
||||
if (!sKey) {
|
||||
return false;
|
||||
}
|
||||
if (params.storeType !== 'local_storage') {
|
||||
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
|
||||
} else {
|
||||
return localStorage.getItem(keyPrefix + sKey) === null ? false : true;
|
||||
}
|
||||
},
|
||||
_cookieKeys: function () {
|
||||
var aKeys = document.cookie.replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:=[^;]*)?;\s*/);
|
||||
for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) {
|
||||
aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]);
|
||||
}
|
||||
return aKeys;
|
||||
}
|
||||
};
|
||||
|
||||
// One-off migration of storage settings from cookies to localStorage
|
||||
function _migrateStorageSettings() {
|
||||
console.log('Migrating Settings Store from cookies to localStorage...');
|
||||
var cookieKeys = settingsStore._cookieKeys();
|
||||
// Note that because migration occurs before setting params.storeType, settingsStore.getItem() will get the item from
|
||||
// document.cookie instead of localStorage, which is the intended behaviour
|
||||
for (var i = 0; i < cookieKeys.length; i++) {
|
||||
if (regexpCookieKeysToMigrate.test(cookieKeys[i])) {
|
||||
var migratedKey = keyPrefix + cookieKeys[i];
|
||||
localStorage.setItem(migratedKey, settingsStore.getItem(cookieKeys[i]));
|
||||
settingsStore.removeItem(cookieKeys[i]);
|
||||
console.log('- ' + migratedKey);
|
||||
}
|
||||
}
|
||||
console.log('Migration done.');
|
||||
}
|
||||
|
||||
return {
|
||||
getItem: settingsStore.getItem,
|
||||
setItem: settingsStore.setItem,
|
||||
removeItem: settingsStore.removeItem,
|
||||
hasItem: settingsStore.hasItem,
|
||||
getBestAvailableStorageAPI: getBestAvailableStorageAPI
|
||||
};
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user