Attempt to fix image detection in tabs

Former-commit-id: 4104601c68bcb9396343dd623f7ca66b2a627295 [formerly af824c50b10435116de8cacd01402f44001bf3a4 [formerly 6e737414a9ace179b16a4d20517ad008a3b1f716]]
Former-commit-id: 2ebbdedc733bb0e3d2dee3176920b449588adb29
Former-commit-id: 87353ab5f1f6e74229464a42e40c3491ec7cff27
This commit is contained in:
Jaifroid 2021-07-09 08:25:25 +01:00
parent 2ef13e7de7
commit c8d6af4cd9
3 changed files with 38 additions and 28 deletions

View File

@ -40,6 +40,11 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
// Define global state: // Define global state:
// Placeholders for the article container, the article window and the article DOM
var articleContainer = document.getElementById('articleContent');
var articleWindow = articleContainer.contentWindow;
var articleDocument;
/** /**
* @type ZIMArchive * @type ZIMArchive
*/ */
@ -217,7 +222,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
activeElement.classList.remove('hover'); activeElement.classList.remove('hover');
activeElement = activeElement.nextElementSibling || activeElement; activeElement = activeElement.nextElementSibling || activeElement;
var nextElement = activeElement.nextElementSibling || activeElement; var nextElement = activeElement.nextElementSibling || activeElement;
if (!uiUtil.isElementInView(nextElement, true)) nextElement.scrollIntoView(false); if (!uiUtil.isElementInView(window, nextElement, true)) nextElement.scrollIntoView(false);
} }
} }
// If user presses ArrowUp... // If user presses ArrowUp...
@ -225,7 +230,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
activeElement.classList.remove('hover'); activeElement.classList.remove('hover');
activeElement = activeElement.previousElementSibling || activeElement; activeElement = activeElement.previousElementSibling || activeElement;
var previousElement = activeElement.previousElementSibling || activeElement; var previousElement = activeElement.previousElementSibling || activeElement;
if (!uiUtil.isElementInView(previousElement, true)) previousElement.scrollIntoView(); if (!uiUtil.isElementInView(window, previousElement, true)) previousElement.scrollIntoView();
if (previousElement === activeElement) { if (previousElement === activeElement) {
document.getElementById('articleListWithHeader').scrollIntoView(); document.getElementById('articleListWithHeader').scrollIntoView();
document.getElementById('top').scrollIntoView(); document.getElementById('top').scrollIntoView();
@ -3367,10 +3372,6 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
//var cssDirEntryCache = new Map(); //This one is never hit! //var cssDirEntryCache = new Map(); //This one is never hit!
var cssBlobCache = new Map(); var cssBlobCache = new Map();
// Placeholders for the article container, the article window and the article DOM
var articleContainer = document.getElementById('articleContent');
var articleWindow, articleDocument;
/** /**
* Display the the given HTML article in the web page, * Display the the given HTML article in the web page,
* and convert links to javascript calls * and convert links to javascript calls

View File

@ -23,6 +23,11 @@
define(['uiUtil'], function (uiUtil) { define(['uiUtil'], function (uiUtil) {
/**
* The Window on which to operate
*/
var container;
/** /**
* A variable to keep track of how many images are being extracted by the extractor * A variable to keep track of how many images are being extracted by the extractor
*/ */
@ -96,7 +101,8 @@ define(['uiUtil'], function (uiUtil) {
* extraction when user taps the indicated area * extraction when user taps the indicated area
* *
*/ */
function prepareManualExtraction(container) { function prepareManualExtraction(win) {
container = win;
var doc = container.document; var doc = container.document;
var documentImages = doc.querySelectorAll('img'); var documentImages = doc.querySelectorAll('img');
for (var i = 0, l = documentImages.length; i < l; i++) { for (var i = 0, l = documentImages.length; i < l; i++) {
@ -140,8 +146,9 @@ define(['uiUtil'], function (uiUtil) {
/** /**
* Sorts an array or collection of image nodes, returning a list of those that are inside the visible viewport * Sorts an array or collection of image nodes, returning a list of those that are inside the visible viewport
* *
* @param {Array} docImgs The array of images to process
* @param {String} action If null, imageStore only will be processed; if 'extract', documentImages in viewport will be * @param {String} action If null, imageStore only will be processed; if 'extract', documentImages in viewport will be
* extracted; if 'poll', will just return the visible and remaining image arrays * extracted; if 'poll', will just return the visible and remaining image arrays
* @param {Number} margin An extra margin to add to the top (-) or bottom (+) of windows.innerHeight * @param {Number} margin An extra margin to add to the top (-) or bottom (+) of windows.innerHeight
* @param {Function} callback Function to call when last image has been extracted (only called if <extract> is true) * @param {Function} callback Function to call when last image has been extracted (only called if <extract> is true)
* @returns {Object} An object with two arrays of images, visible and remaining * @returns {Object} An object with two arrays of images, visible and remaining
@ -165,7 +172,7 @@ define(['uiUtil'], function (uiUtil) {
//console.log('Images requested...'); //console.log('Images requested...');
for (var i = 0, l = docImgs.length; i < l; i++) { for (var i = 0, l = docImgs.length; i < l; i++) {
if (docImgs[i].queued || !docImgs[i].dataset.kiwixurl) continue; if (docImgs[i].queued || !docImgs[i].dataset.kiwixurl) continue;
if (uiUtil.isElementInView(docImgs[i], null, margin)) { if (uiUtil.isElementInView(container, docImgs[i], null, margin)) {
visible.push(docImgs[i]); visible.push(docImgs[i]);
if (action !== 'extract') continue; if (action !== 'extract') continue;
docImgs[i].queued = true; docImgs[i].queued = true;
@ -194,15 +201,16 @@ define(['uiUtil'], function (uiUtil) {
/** /**
* Prepares the article container in order to process the image nodes that have been disabled in Service Worker * Prepares the article container in order to process the image nodes that have been disabled in Service Worker
* *
* @param {Window} container The iframe or the window that contains the document * @param {Window} win The Window of the iframe tab that contains the document
* @param {Boolean} forPrinting If true, extracts all images * @param {Boolean} forPrinting If true, extracts all images
*/ */
function prepareImagesServiceWorker (container, forPrinting) { function prepareImagesServiceWorker (win, forPrinting) {
container = win;
var doc = container.document; var doc = container.document;
var documentImages = doc.querySelectorAll('img'); var documentImages = doc.querySelectorAll('img');
// Schedule loadMathJax here in case next line aborts this function // Schedule loadMathJax here in case next line aborts this function
setTimeout(function() { setTimeout(function() {
loadMathJax(container); loadMathJax();
}, 1000); }, 1000);
if (!forPrinting && !documentImages.length) return; if (!forPrinting && !documentImages.length) return;
var imageHtml; var imageHtml;
@ -233,7 +241,7 @@ define(['uiUtil'], function (uiUtil) {
} else { } else {
// We need to start detecting images after the hidden articleContent has been displayed (otherwise they are not detected) // We need to start detecting images after the hidden articleContent has been displayed (otherwise they are not detected)
setTimeout(function() { setTimeout(function() {
lazyLoad(container, documentImages); lazyLoad(documentImages);
}, 300); }, 300);
} }
} }
@ -242,15 +250,16 @@ define(['uiUtil'], function (uiUtil) {
/** /**
* Prepares the article container in order to process the image nodes that have been disabled in the DOM * Prepares the article container in order to process the image nodes that have been disabled in the DOM
* *
* @param {Window} container The iframe or the window that contains the document * @param {Window} win The Window of the iframe or tab that contains the document
* @param {Boolean} forPrinting If true, extracts all images * @param {Boolean} forPrinting If true, extracts all images
*/ */
function prepareImagesJQuery (container, forPrinting) { function prepareImagesJQuery (win, forPrinting) {
container = win;
var doc = container.document; var doc = container.document;
var documentImages = doc.querySelectorAll('img[data-kiwixurl]'); var documentImages = doc.querySelectorAll('img[data-kiwixurl]');
// In case there are no images in the doc, we need to schedule the loadMathJax function here // In case there are no images in the doc, we need to schedule the loadMathJax function here
setTimeout(function() { setTimeout(function() {
loadMathJax(container); loadMathJax();
}, 1000); }, 1000);
if (!forPrinting && !documentImages.length) return; if (!forPrinting && !documentImages.length) return;
if (forPrinting) { if (forPrinting) {
@ -264,7 +273,7 @@ define(['uiUtil'], function (uiUtil) {
} }
// We need to start detecting images after the hidden articleContent has been displayed (otherwise they are not detected) // We need to start detecting images after the hidden articleContent has been displayed (otherwise they are not detected)
setTimeout(function() { setTimeout(function() {
lazyLoad(container, documentImages); lazyLoad(documentImages);
}, 500); }, 500);
} else { } else {
// User wishes to extract images manually // User wishes to extract images manually
@ -275,11 +284,10 @@ define(['uiUtil'], function (uiUtil) {
/** /**
* Processes an array or collection of image nodes so that they will be lazy loaded (progressive extraction) * Processes an array or collection of image nodes so that they will be lazy loaded (progressive extraction)
* *
* @param {Window} cont The iframe or window that contains the images
* @param {Object} documentImages An array or collection of DOM image nodes which will be processed for * @param {Object} documentImages An array or collection of DOM image nodes which will be processed for
* progressive image extraction * progressive image extraction
*/ */
function lazyLoad(cont, documentImages) { function lazyLoad(documentImages) {
// The amount by which to offset the second reading of the viewport // The amount by which to offset the second reading of the viewport
var offset = window.innerHeight * 2; var offset = window.innerHeight * 2;
// Perform an immediate extraction of visible images so as not to disconcert the user // Perform an immediate extraction of visible images so as not to disconcert the user
@ -294,10 +302,10 @@ define(['uiUtil'], function (uiUtil) {
var rate = 80; // DEV: Set the milliseconds to wait before allowing another iteration of the image stack var rate = 80; // DEV: Set the milliseconds to wait before allowing another iteration of the image stack
var timeout; var timeout;
// NB we add the event listener this way so we can access it in app.js // NB we add the event listener this way so we can access it in app.js
cont.onscroll = function () { container.onscroll = function () {
abandon = true; abandon = true;
clearTimeout(timeout); clearTimeout(timeout);
var velo = cont.pageYOffset - scrollPos; var velo = container.pageYOffset - scrollPos;
timeout = setTimeout(function() { timeout = setTimeout(function() {
// We have stopped scrolling // We have stopped scrolling
//console.log("Stopped scrolling; velo=" + velo); //console.log("Stopped scrolling; velo=" + velo);
@ -307,13 +315,13 @@ define(['uiUtil'], function (uiUtil) {
queueImages(documentImages, 'extract', velo >= 0 ? offset : -offset); queueImages(documentImages, 'extract', velo >= 0 ? offset : -offset);
}); });
}, rate); }, rate);
scrollPos = cont.pageYOffset; scrollPos = container.pageYOffset;
}; };
} }
function loadMathJax(cont) { function loadMathJax() {
if (!params.useMathJax) return; if (!params.useMathJax) return;
var doc = cont.document; var doc = container.document;
var prefix = ''; var prefix = '';
if (params.contentInjectionMode === 'serviceworker') { if (params.contentInjectionMode === 'serviceworker') {
params.containsMathSVG = /<img\s+(?=[^>]+?math-fallback-image)[^>]*?alt\s*=\s*['"][^'"]+[^>]+>/i.test(doc.body.innerHTML); params.containsMathSVG = /<img\s+(?=[^>]+?math-fallback-image)[^>]*?alt\s*=\s*['"][^'"]+[^>]+>/i.test(doc.body.innerHTML);
@ -339,7 +347,7 @@ define(['uiUtil'], function (uiUtil) {
script3.type = "text/javascript"; script3.type = "text/javascript";
script3.src = prefix + "js/katex/contrib/auto-render.min.js"; script3.src = prefix + "js/katex/contrib/auto-render.min.js";
script3.onload = function() { script3.onload = function() {
cont.renderMathInElement(doc.body, { container.renderMathInElement(doc.body, {
delimiters: [{ delimiters: [{
left: "$$", left: "$$",
right: "$$", right: "$$",

View File

@ -586,20 +586,21 @@ define(rqDef, function() {
/** /**
* Checks whether an element is partially or fully inside the current viewport, and adds the rect.top value to element.top * Checks whether an element is partially or fully inside the current viewport, and adds the rect.top value to element.top
* *
* @param {Window} area The Window to check
* @param {Element} el The DOM element for which to check visibility * @param {Element} el The DOM element for which to check visibility
* @param {Boolean} fully If true, checks that the entire element is inside the viewport * @param {Boolean} fully If true, checks that the entire element is inside the viewport
* @param {Integer} offset An additional bottom (+) or top (-) margin to include in the search window * @param {Integer} offset An additional bottom (+) or top (-) margin to include in the search window
* @returns {Boolean} True if the element is fully or partially inside the current viewport * @returns {Boolean} True if the element is fully or partially inside the current viewport
*/ */
function isElementInView(el, fully, offset) { function isElementInView(area, el, fully, offset) {
offset = offset || 0; offset = offset || 0;
var rect = el.getBoundingClientRect(); var rect = el.getBoundingClientRect();
el.top = rect.top; el.top = rect.top;
//console.log(el.dataset.kiwixurl + ': ' + rect.top); //console.log(el.dataset.kiwixurl + ': ' + rect.top);
if (fully) if (fully)
return rect.top > 0 + (offset < 0 ? offset : 0) && rect.bottom < window.innerHeight + (offset > 0 ? offset : 0) && rect.left > 0 && rect.right < window.innerWidth; return rect.top > 0 + (offset < 0 ? offset : 0) && rect.bottom < area.innerHeight + (offset > 0 ? offset : 0) && rect.left > 0 && rect.right < area.innerWidth;
else else
return rect.top < window.innerHeight + (offset > 0 ? offset : 0) && rect.bottom > 0 + (offset < 0 ? offset : 0) && rect.left < window.innerWidth && rect.right > 0; return rect.top < area.innerHeight + (offset > 0 ? offset : 0) && rect.bottom > 0 + (offset < 0 ? offset : 0) && rect.left < area.innerWidth && rect.right > 0;
} }
/** /**