Cache the CSS content in jQuery mode #355 (#336)

This commit is contained in:
Jaifroid 2018-01-23 21:51:29 +00:00 committed by GitHub
parent 9f60c6bfcd
commit 84452384f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 27 deletions

View File

@ -529,6 +529,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
+ " storages found with getDeviceStorages instead of 1");
}
}
resetCssCache();
selectedArchive = zimArchiveLoader.loadArchiveFromDeviceStorage(selectedStorage, archiveDirectory, function (archive) {
cookies.setItem("lastSelectedArchive", archiveDirectory, Infinity);
// The archive is set : go back to home page to start searching
@ -538,6 +539,16 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
}
}
/**
* Resets the CSS Cache (used only in jQuery mode)
*/
function resetCssCache() {
// Reset the cssCache. Must be done when archive changes.
if (cssCache) {
cssCache = new Map();
}
}
/**
* Displays the zone to select files from the archive
*/
@ -547,6 +558,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
}
function setLocalArchiveFromFileList(files) {
resetCssCache();
selectedArchive = zimArchiveLoader.loadArchiveFromFiles(files, function (archive) {
// The archive is set : go back to home page to start searching
$("#btnHome").click();
@ -793,6 +805,10 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
var regexpImageUrl = /^(?:\.\.\/|\/)+(I\/.*)$/;
var regexpMetadataUrl = /^(?:\.\.\/|\/)+(-\/.*)$/;
// Cache for CSS styles contained in ZIM.
// It significantly speeds up subsequent page display. See kiwix-js issue #335
var cssCache = new Map();
/**
* Display the the given HTML article in the web page,
* and convert links to javascript calls
@ -895,35 +911,24 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
if (hrefMatch) {
// It's a CSS file contained in the ZIM file
var title = uiUtil.removeUrlParameters(decodeURIComponent(hrefMatch[1]));
selectedArchive.getDirEntryByTitle(title).then(function(dirEntry) {
selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, content) {
var cssContent = util.uintToString(content);
// For some reason, Firefox OS does not accept the syntax <link rel="stylesheet" href="data:text/css,...">
// So we replace the tag with a <style type="text/css">...</style>
// while copying some attributes of the original tag
// Cf http://jonraasch.com/blog/javascript-style-node
var cssElement = document.createElement('style');
cssElement.type = 'text/css';
if (cssElement.styleSheet) {
cssElement.styleSheet.cssText = cssContent;
if (cssCache && cssCache.has(title)) {
var cssContent = cssCache.get(title);
uiUtil.replaceCSSLinkWithInlineCSS(link, cssContent);
} else {
cssElement.appendChild(document.createTextNode(cssContent));
}
var mediaAttributeValue = link.attr('media');
if (mediaAttributeValue) {
cssElement.media = mediaAttributeValue;
}
var disabledAttributeValue = link.attr('media');
if (disabledAttributeValue) {
cssElement.disabled = disabledAttributeValue;
}
link.replaceWith(cssElement);
selectedArchive.getDirEntryByTitle(title)
.then(function (dirEntry) {
return selectedArchive.readBinaryFile(dirEntry,
function (fileDirEntry, content) {
var fullUrl = fileDirEntry.namespace + "/" + fileDirEntry.url;
var contentString = util.uintToString(content);
if (cssCache) cssCache.set(fullUrl, contentString);
uiUtil.replaceCSSLinkWithInlineCSS(link, contentString);
});
}).fail(function (e) {
console.error("could not find DirEntry for CSS : " + title, e);
});
}
}
});
// Load Javascript content

View File

@ -43,6 +43,36 @@ define([], function() {
jQueryNode.attr(nodeAttribute, url);
}
/**
* Replace the given CSS link (from the DOM) with an inline CSS of the given content
*
* Due to CSP, Firefox OS does not accept <link> syntax with href="data:text/css..." or href="blob:..."
* So we replace the tag with a <style type="text/css">...</style>
* while copying some attributes of the original tag
* Cf http://jonraasch.com/blog/javascript-style-node
*
* @param {Element} link from the DOM
* @param {String} cssContent
*/
function replaceCSSLinkWithInlineCSS (link, cssContent) {
var cssElement = document.createElement('style');
cssElement.type = 'text/css';
if (cssElement.styleSheet) {
cssElement.styleSheet.cssText = cssContent;
} else {
cssElement.appendChild(document.createTextNode(cssContent));
}
var mediaAttributeValue = link.attr('media');
if (mediaAttributeValue) {
cssElement.media = mediaAttributeValue;
}
var disabledAttributeValue = link.attr('disabled');
if (disabledAttributeValue) {
cssElement.disabled = disabledAttributeValue;
}
link.replaceWith(cssElement);
}
var regexpRemoveUrlParameters = new RegExp(/([^\?]+)\?.*$/);
function removeUrlParameters(url) {
@ -58,6 +88,7 @@ define([], function() {
*/
return {
feedNodeWithBlob: feedNodeWithBlob,
replaceCSSLinkWithInlineCSS: replaceCSSLinkWithInlineCSS,
removeUrlParameters: removeUrlParameters
};
});