mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-09 04:06:27 -04:00
Fix printing in SW mode
Former-commit-id: 9f0251eb239a343a8d1113453aed70462f16ed77 [formerly 5e466bbe464ddbbdc854424faae985a325a6a0f5] [formerly f7d5a1886dd7df812004bec3b986793f86d98f07] [formerly f08123233223cc3e5d4ff6f256ddbd763067d8ab [formerly f35330b746698ebaccaef786a48de0ec6ac9991b [formerly d2c76fb3bd117cf99407c50a7b96f581db8aeded]]] Former-commit-id: 3cd803a85a73df8a1f64d0851c1c1ab2a20bb19b [formerly d5ea8ad70283b083d8836304315b6cdbde7833a0 [formerly 3816993c578a8e4be96c63886d5d910895718abb]] Former-commit-id: 85025162f3ba3c50e5f185d648bb41ee2f81f168 [formerly 7b2ba394ab51d2507d7da32be534605656d37205] Former-commit-id: da6f88f5566fc8210e41bdd4e52c967e924f0f73
This commit is contained in:
parent
5cc3101578
commit
1540a2934d
@ -455,7 +455,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
if (params.contentInjectionMode == 'jquery') {
|
||||
images.prepareImagesJQuery(articleWindow, true);
|
||||
} else {
|
||||
images.prepareImagesServiceWorker(true);
|
||||
images.prepareImagesServiceWorker(articleWindow, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1152,8 +1152,14 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
document.getElementById('manipulateImagesCheck').addEventListener('click', function () {
|
||||
params.manipulateImages = this.checked;
|
||||
settingsStore.setItem('manipulateImages', params.manipulateImages, Infinity);
|
||||
if (this.checked && params.contentInjectionMode === 'serviceworker') {
|
||||
uiUtil.systemAlert('Please be aware that image manipulation can interfere badly with non-Wikimedia ZIMs (particularly ZIMs that have active content). If you cannot access the articles in such a ZIM, please turn this setting off.');
|
||||
if (this.checked) {
|
||||
if (/UWP/.test(params.appType)) {
|
||||
uiUtil.systemAlert('This option does not work in UWP apps. WORKAROUND: To save an image to disk, please select the "Add breakout link ..." option below, load the article you require, and export it to a browser window by clicking the breakout link. You will then be able to right-click or long-press images in the exported page and save them.');
|
||||
} else if (params.contentInjectionMode === 'serviceworker') {
|
||||
uiUtil.systemAlert('Please be aware that Image manipulation can interfere badly with non-Wikimedia ZIMs (particularly ZIMs that have active content). If you cannot access the articles in such a ZIM, please turn this setting off.');
|
||||
} else if (/PWA/.test(params.appType)) {
|
||||
uiUtil.systemAlert('Be aware that this option may interfere with active content if you switch to Service Worker mode.');
|
||||
}
|
||||
}
|
||||
params.themeChanged = true;
|
||||
});
|
||||
@ -1231,12 +1237,13 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
document.getElementById('allowHTMLExtractionCheck').addEventListener('change', function (e) {
|
||||
params.allowHTMLExtraction = e.target.checked;
|
||||
var alertMessage = '';
|
||||
if (params.windowOpener && params.allowHTMLExtraction) alertMessage = 'Enabling this option disables the more advanced tab/window opening option above.';
|
||||
if (params.windowOpener && params.allowHTMLExtraction) alertMessage = 'Enabling this option disables the more advanced tab/window opening option above. ';
|
||||
if (params.allowHTMLExtraction) {
|
||||
if (params.contentInjectionMode === 'serviceworker') {
|
||||
alertMessage = 'WARNING: This option can interfere badly with non-Wikimedia ZIMs that have active content: turn it off if affected. ' + alertMessage;
|
||||
alertMessage = 'Please be aware that Image manipulation can interfere badly with non-Wikimedia ZIMs (particularly ZIMs that have active content). ' +
|
||||
'If you cannot access the articles in such a ZIM, please turn this setting off. ' + alertMessage;
|
||||
} else if (/PWA/.test(params.appType)) {
|
||||
alertMessage += ' Be aware that this option may interfere with active content if you switch to Service Worker mode.';
|
||||
alertMessage += 'Be aware that this option may interfere with active content if you switch to Service Worker mode.';
|
||||
}
|
||||
uiUtil.systemAlert(alertMessage);
|
||||
params.windowOpener = false;
|
||||
@ -3455,7 +3462,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
// URLs that begin 'http' (i.e. non-relative URLs). It then captures the whole of the URL up until either the opening delimiter
|
||||
// (" or ', which is capture group \3) or a querystring or hash character (? or #). When the regex is used below, it will be further
|
||||
// processed to calculate the ZIM URL from the relative path. This regex can cope with legitimate single quote marks (') in the URL.
|
||||
var regexpTagsWithZimUrl = /(<(?:img|script|link)\b[^>]*?\s)(?:src|href)(\s*=\s*(["']))(?!http|app:)(.+?)(?=\3|\?|#)/ig;
|
||||
params.regexpTagsWithZimUrl = /(<(?:img|script|link)\b[^>]*?\s)(?:src|href)(\s*=\s*(["']))(?!http|app:)(.+?)(?=\3|\?|#)/ig;
|
||||
// Regex below tests the html of an article for active content [kiwix-js #466]
|
||||
// It inspects every <script> block in the html and matches in the following cases: 1) the script loads a UI application called app.js;
|
||||
// 2) the script block has inline content that does not contain "importScript()", "toggleOpenSection" or an "articleId" assignment
|
||||
@ -3500,7 +3507,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
console.log("Loading stylesheets...");
|
||||
|
||||
// Display Bootstrap warning alert if the landing page contains active content
|
||||
if (!params.hideActiveContentWarning && params.isLandingPage && (params.contentInjectionMode === 'jquery' || params.manipulateImages)) {
|
||||
if (!params.hideActiveContentWarning && params.isLandingPage && (params.contentInjectionMode === 'jquery' || params.manipulateImages || params.allowHTMLExtraction)) {
|
||||
if (regexpActiveContent.test(htmlArticle)) uiUtil.displayActiveContentWarning();
|
||||
}
|
||||
|
||||
@ -3510,7 +3517,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
params.isLandingPage = false;
|
||||
|
||||
// Calculate the current article's ZIM baseUrl to use when processing relative links
|
||||
var baseUrl = dirEntry.namespace + '/' + dirEntry.url.replace(/[^/]+$/, '');
|
||||
params.baseUrl = dirEntry.namespace + '/' + dirEntry.url.replace(/[^/]+$/, '');
|
||||
|
||||
//Since page has been successfully loaded, store it in the browser history
|
||||
if (params.contentInjectionMode === 'jquery') pushBrowserHistoryState(dirEntry.namespace + '/' + dirEntry.url);
|
||||
@ -3522,9 +3529,9 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
// Replaces ZIM-style URLs of img, script, link and media tags with a data-kiwixurl to prevent 404 errors [kiwix-js #272 #376]
|
||||
// This replacement also processes the URL relative to the page's ZIM URL so that we can find the ZIM URL of the asset
|
||||
// with the correct namespace (this works for old-style -,I,J namespaces and for new-style C namespace)
|
||||
if (params.contentInjectionMode == 'jquery' || params.manipulateImages) {
|
||||
htmlArticle = htmlArticle.replace(regexpTagsWithZimUrl, function(match, blockStart, equals, quote, relAssetUrl) {
|
||||
var assetZIMUrl = uiUtil.deriveZimUrlFromRelativeUrl(relAssetUrl, baseUrl);
|
||||
if (params.contentInjectionMode == 'jquery') {
|
||||
htmlArticle = htmlArticle.replace(params.regexpTagsWithZimUrl, function(match, blockStart, equals, quote, relAssetUrl) {
|
||||
var assetZIMUrl = uiUtil.deriveZimUrlFromRelativeUrl(relAssetUrl, params.baseURL);
|
||||
// DEV: Note that deriveZimUrlFromRelativeUrl produces a *decoded* URL (and incidentally would remove any URI component
|
||||
// if we had captured it). We therefore re-encode the URI with encodeURI (which does not encode forward slashes) instead
|
||||
// of encodeURIComponent.
|
||||
@ -4045,7 +4052,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
}
|
||||
|
||||
// Calculate the current article's encoded ZIM baseUrl to use when processing relative links
|
||||
baseUrl = (dirEntry.namespace + '/' + dirEntry.url.replace(/[^/]+$/, ''))
|
||||
params.baseURL = (dirEntry.namespace + '/' + dirEntry.url.replace(/[^/]+$/, ''))
|
||||
// URI-encode anything that is not a '/'
|
||||
.replace(/[^/]+/g, function(m) {
|
||||
return encodeURIComponent(m);
|
||||
@ -4076,7 +4083,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
var media = articleDocument.querySelectorAll('video, audio, source');
|
||||
Array.prototype.slice.call(media).forEach(function (mediaSource) {
|
||||
var source = mediaSource.getAttribute('src');
|
||||
source = source ? uiUtil.deriveZimUrlFromRelativeUrl(source, baseUrl) : null;
|
||||
source = source ? uiUtil.deriveZimUrlFromRelativeUrl(source, params.baseURL) : null;
|
||||
if (!source || !regexpZIMUrlWithNamespace.test(source)) {
|
||||
if (source) console.error('No usable media source was found for: ' + source);
|
||||
return;
|
||||
@ -4182,7 +4189,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
for (var i = currentTracks.length; i--;) {
|
||||
langs = currentTracks[i].label + ' [' + currentTracks[i].srclang + ']';
|
||||
src = currentTracks[i].getAttribute('src');
|
||||
src = src ? uiUtil.deriveZimUrlFromRelativeUrl(src, baseUrl) : null;
|
||||
src = src ? uiUtil.deriveZimUrlFromRelativeUrl(src, params.baseURL) : null;
|
||||
if (src && regexpZIMUrlWithNamespace.test(src)) {
|
||||
optionList.unshift('<option value="' + currentTracks[i].srclang + '" data-kiwixsrc="' +
|
||||
src + '" data-kiwixkind="' + currentTracks[i].kind + '">' + langs + '</option>');
|
||||
@ -4229,12 +4236,6 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
var currentProtocol = articleWindow.location.protocol;
|
||||
currentProtocol === 'about:' ? currentProtocol = ':' : currentProtocol;
|
||||
var currentHost = articleWindow.location.host;
|
||||
// Calculate the current article's encoded ZIM baseUrl to use when processing relative links
|
||||
var baseUrl = (dirEntry.namespace + '/' + dirEntry.url.replace(/[^/]+$/, ''))
|
||||
// URI-encode anything that is not a '/'
|
||||
.replace(/[^/]+/g, function(m) {
|
||||
return encodeURIComponent(m);
|
||||
});
|
||||
// Percent-encode dirEntry.url and add regex escape character \ to the RegExp special characters - see https://www.regular-expressions.info/characters.html;
|
||||
// NB dirEntry.url can also contain path separator / in some ZIMs (Stackexchange). } and ] do not need to be escaped as they have no meaning on their own.
|
||||
var escapedUrl = encodeURIComponent(dirEntry.url).replace(/([\\$^.|?*+/()[{])/g, '\\$1');
|
||||
@ -4261,13 +4262,13 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
anchor.target = '_blank';
|
||||
} else {
|
||||
// It's a link to an article or file in the ZIM
|
||||
addListenersToLink(anchor, href, baseUrl);
|
||||
addListenersToLink(anchor, href, params.baseURL);
|
||||
}
|
||||
});
|
||||
// Add event listeners to the main heading so user can open current document in new tab or window by clicking on it
|
||||
if (articleWindow.document.body) {
|
||||
var h1 = articleWindow.document.body.querySelector('h1');
|
||||
if (h1) addListenersToLink(h1, encodeURIComponent(dirEntry.url.replace(/[^/]+\//g, '')), baseUrl);
|
||||
if (h1) addListenersToLink(h1, encodeURIComponent(dirEntry.url.replace(/[^/]+\//g, '')), params.baseURL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4536,13 +4537,21 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
|
||||
params.preloadAllImages = function () {
|
||||
if (params.preloadingAllImages !== true) {
|
||||
$('#searchingArticles').show();
|
||||
setTimeout(function () {
|
||||
if (params.preloadingAllImages) {
|
||||
var assetsMsg = document.getElementById('cachingAssets');
|
||||
document.getElementById('searchingArticles').style.display = 'block';
|
||||
assetsMsg.style.display = 'block';
|
||||
assetsMsg.innerHTML = 'Extracting images...';
|
||||
}
|
||||
}, 1000);
|
||||
params.preloadingAllImages = true;
|
||||
if (params.imageDisplay) params.contentInjectionMode === 'jquery' ?
|
||||
images.prepareImagesJQuery(articleWindow, true) : images.prepareImagesServiceWorker(articleWindow, true);
|
||||
return;
|
||||
}
|
||||
// All images should now be loaded, or else user did not request loading images
|
||||
document.getElementById('searchingArticles').style.display = 'none';
|
||||
uiUtil.extractHTML();
|
||||
$('#searchingArticles').hide();
|
||||
};
|
||||
@ -4560,7 +4569,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
||||
} else {
|
||||
appstate.selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, content) {
|
||||
// TODO : JavaScript support not yet functional [kiwix-js #152]
|
||||
uiUtil.feedNodeWithBlob(script, 'src', content, 'text/javascript', params.manipulateImages);
|
||||
uiUtil.feedNodeWithBlob(script, 'src', content, 'text/javascript', params.manipulateImages || params.allowHTMLExtraction);
|
||||
});
|
||||
}
|
||||
}).catch(function (e) {
|
||||
|
@ -38,6 +38,12 @@ define(['uiUtil'], function (uiUtil) {
|
||||
*/
|
||||
var abandon = false;
|
||||
|
||||
/**
|
||||
* A regular expression to find or transform image URLs in an article
|
||||
* DEV: make sure list of file types here is the same as the list in Service Worker code
|
||||
*/
|
||||
var imageURLRegexp = /(^|\/).+\.(jpe?g|png|svg|gif|webp)($|[?#])/i;
|
||||
|
||||
/**
|
||||
* A regular expression to find MathTex in an image
|
||||
*/
|
||||
@ -67,7 +73,7 @@ define(['uiUtil'], function (uiUtil) {
|
||||
else { image.setAttribute('data-kiwixsrc', imageUrl); }
|
||||
image.removeAttribute('data-kiwixurl');
|
||||
var title = decodeURIComponent(imageUrl);
|
||||
if (params.contentInjectionMode === 'serviceworker' && !params.manipulateImages) {
|
||||
if (params.contentInjectionMode === 'serviceworker' && !(params.manipulateImages || params.allowHTMLExtraction)) {
|
||||
image.addEventListener('load', function () {
|
||||
image.style.transition = 'opacity 0.5s ease-in';
|
||||
image.style.opacity = '1';
|
||||
@ -83,7 +89,7 @@ define(['uiUtil'], function (uiUtil) {
|
||||
return appstate.selectedArchive.readBinaryFile(dirEntry, function (fileDirEntry, content) {
|
||||
image.style.background = '';
|
||||
var mimetype = dirEntry.getMimetype();
|
||||
uiUtil.feedNodeWithBlob(image, 'src', content, mimetype, params.manipulateImages, function () {
|
||||
uiUtil.feedNodeWithBlob(image, 'src', content, mimetype, params.manipulateImages || params.allowHTMLExtraction, function () {
|
||||
checkBatch();
|
||||
});
|
||||
image.style.transition = 'opacity 0.5s ease-in';
|
||||
@ -205,10 +211,6 @@ define(['uiUtil'], function (uiUtil) {
|
||||
* @param {Boolean} forPrinting If true, extracts all images
|
||||
*/
|
||||
function prepareImagesServiceWorker (win, forPrinting) {
|
||||
if (params.manipulateImages) {
|
||||
prepareImagesJQuery(win, forPrinting);
|
||||
return;
|
||||
}
|
||||
container = win;
|
||||
var doc = container.document;
|
||||
var documentImages = doc.querySelectorAll('img');
|
||||
@ -219,25 +221,41 @@ define(['uiUtil'], function (uiUtil) {
|
||||
if (!forPrinting && !documentImages.length) return;
|
||||
var imageHtml;
|
||||
for (var i = 0, l = documentImages.length; i < l; i++) {
|
||||
// Process Wikimedia MathML
|
||||
imageHtml = documentImages[i].outerHTML;
|
||||
if (params.useMathJax && /\bmath\/tex\b/i.test(imageHtml)) {
|
||||
params.containsMathTex = true;
|
||||
documentImages[i].outerHTML = imageHtml.replace(transformMathTextRegexp, function (p0, p1, math) {
|
||||
// Remove any rogue ampersands in MathJax due to double escaping (by Wikipedia)
|
||||
math = math.replace(/&/g, '&');
|
||||
return '<script type="math/tex">' + math + '</script>';
|
||||
});
|
||||
// Process Wikimedia MathML, but not if we'll be using the jQuery routine later
|
||||
if (!(params.manipulateImages || params.allowHTMLExtraction)) {
|
||||
imageHtml = documentImages[i].outerHTML;
|
||||
if (params.useMathJax && /\bmath\/tex\b/i.test(imageHtml)) {
|
||||
params.containsMathTex = true;
|
||||
documentImages[i].outerHTML = imageHtml.replace(transformMathTextRegexp, function (p0, p1, math) {
|
||||
// Remove any rogue ampersands in MathJax due to double escaping (by Wikipedia)
|
||||
math = math.replace(/&/g, '&');
|
||||
return '<script type="math/tex">' + math + '</script>';
|
||||
});
|
||||
}
|
||||
}
|
||||
// DEV: make sure list of file types here is the same as the list in Service Worker code
|
||||
if (/(^|\/).+\.(jpe?g|png|svg|gif|webp)($|[?#])/i.test(documentImages[i].src)) {
|
||||
if (imageURLRegexp.test(documentImages[i].src)) {
|
||||
documentImages[i].dataset.kiwixurl = documentImages[i].getAttribute('src');
|
||||
if (params.imageDisplayMode === 'progressive') {
|
||||
documentImages[i].style.opacity = '0';
|
||||
}
|
||||
if (params.manipulateImages || params.allowHTMLExtraction) {
|
||||
documentImages[i].outerHTML = documentImages[i].outerHTML.replace(params.regexpTagsWithZimUrl, function(match, blockStart, equals, quote, relAssetUrl) {
|
||||
var assetZIMUrl = uiUtil.deriveZimUrlFromRelativeUrl(relAssetUrl, params.baseUrl);
|
||||
// DEV: Note that deriveZimUrlFromRelativeUrl produces a *decoded* URL (and incidentally would remove any URI component
|
||||
// if we had captured it). We therefore re-encode the URI with encodeURI (which does not encode forward slashes) instead
|
||||
// of encodeURIComponent.
|
||||
return blockStart + 'data-kiwixurl' + equals + encodeURI(assetZIMUrl);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (params.manipulateImages || params.allowHTMLExtraction) {
|
||||
prepareImagesJQuery(win, forPrinting);
|
||||
return;
|
||||
}
|
||||
|
||||
if (forPrinting) {
|
||||
if (params.preloadAllImages) document.getElementById('searchingArticles').style.display = 'block';
|
||||
extractImages(documentImages, params.preloadingAllImages ? params.preloadAllImages : params.printImagesLoaded);
|
||||
} else {
|
||||
if (params.imageDisplayMode === 'manual') {
|
||||
|
@ -321,11 +321,11 @@ define(rqDef, function() {
|
||||
'<a id="swModeLink" href="#contentInjectionModeDiv" class="alert-link">switch to Service Worker mode</a> ' +
|
||||
'if your platform supports it. [<a id="stop" href="#otherSettingsDiv" class="alert-link">Permanently hide</a>]' +
|
||||
'</div>';
|
||||
if (params.contentInjectionMode === 'serviceworker' && params.manipulateImages) {
|
||||
if (params.contentInjectionMode === 'serviceworker' && (params.manipulateImages || params.allowHTMLExtraction)) {
|
||||
alertHTML =
|
||||
'<div id="activeContent" class="alert alert-warning alert-dismissible fade in" style="margin-bottom: 0;">' +
|
||||
'<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>' +
|
||||
'<strong>Active content may be disrupted:</strong> Please <a id="imModeLink" href="#imageManipulationDiv" class="alert-link">disable Image manipulation</a> ' +
|
||||
'<strong>Active content may be disrupted:</strong> Please <a id="imModeLink" href="#imageManipulationDiv" class="alert-link">disable Image manipulation</a> and/or disable Breakout link ' +
|
||||
'for this content to work properly. To use Archive Index <b><i>type a space</i></b> in the box above. [<a id="stop" href="#otherSettingsDiv" class="alert-link">Permanently hide</a>]' +
|
||||
'</div>';
|
||||
}
|
||||
@ -554,6 +554,10 @@ define(rqDef, function() {
|
||||
iframe.head.innerHTML = headHtml;
|
||||
itemsCount = false;
|
||||
params.preloadingAllImages = false;
|
||||
var assetsMsg = document.getElementById('cachingAssets');
|
||||
assetsMsg.innerHTML = '';
|
||||
assetsMsg.style.display = 'none';
|
||||
document.getElementById('searchingArticles').style.display = 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user