From 0e0cb9710337bf61d71b34c7b33acf743060b5db Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Fri, 14 Jun 2019 22:10:13 +0100 Subject: [PATCH] Streamline image code (faster) Former-commit-id: 74b5755d7a5aeb9a5b48efe8323beebebd091377 [formerly 27aebef21f5692dad7419fd69c73299b15bd0539] Former-commit-id: 967048752f39160c840e7fadb367d31badf354b3 --- www/js/app.js | 37 +++------------------ www/js/lib/images.js | 76 ++++++++++++++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/www/js/app.js b/www/js/app.js index 6d8f5360..448462d5 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -330,7 +330,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans } //Pre-load all images in case user wants to print them if (params.imageDisplay) { - loadImagesJQuery(10000); + loadImagesJQuery(printIntercept); document.getElementById("printImageCheck").disabled = false; } else { document.getElementById("printImageCheck").checked = false; @@ -2122,12 +2122,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans docBody.addEventListener('dragover', handleIframeDragover); docBody.addEventListener('drop', handleIframeDrop); } - if (/manual|progressive/.test(params.imageDisplayMode)) { - var imageList = doc.querySelectorAll('img'); - if (imageList.length) { - images.prepareImagesServiceWorker(imageList, params.imageDisplayMode); - } - } + if (/manual|progressive/.test(params.imageDisplayMode)) images.prepareImagesServiceWorker(); iframeArticleContent.contentWindow.onunload = function () { $("#searchingArticles").show(); }; @@ -2824,7 +2819,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans } }); - loadImagesJQuery(); + images.prepareImagesJQuery(); //loadJavascript(); //Disabled for now, since it does nothing - also, would have to load before images, ideally through controlled css loads above insertMediaBlobsJQuery(); var determinedTheme = params.cssTheme == 'auto' ? cssUIThemeGetOrSet('auto') : params.cssTheme; @@ -2994,37 +2989,13 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'images', 'cookies', 'q', 'trans if (params.preloadingAllImages !== true) { $('#searchingArticles').show(); params.preloadingAllImages = true; - if (params.imageDisplay) loadImagesJQuery(10000); + if (params.imageDisplay) images.prepareImagesJQuery(printIntercept); return; } // All images should now be loaded, or else user did not request loading images uiUtil.extractHTML(); $('#searchingArticles').hide(); }; - - function loadImagesJQuery(forPrinting) { - var iframeArticleContent = document.getElementById('articleContent'); - var imageNodes = iframeArticleContent.contentDocument.querySelectorAll('img[data-kiwixurl]'); - if (!imageNodes.length) return; - if (forPrinting) { - images.extractImages(imageNodes, params.preloadingAllImages ? params.preloadAllImages : params.printIntercept ? printIntercept : null); - } else if (params.imageDisplayMode === 'progressive') { - // Firefox squashes empty images, but we don't want to alter the vertical heights constantly as we scroll - // so substitute empty images with a plain svg - for (var i = imageNodes.length; i--;) { - imageNodes[i].src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E"; - imageNodes[i].style.opacity = '0'; - imageNodes[i].style.transition = 'opacity 0.5s ease-in'; - } - images.lazyLoad(imageNodes); - } else { - // User wishes to extract images manually - images.setupManualImageExtraction(imageNodes); - } - setTimeout(images.loadMathJax, 3000); - } - - /** * This is the main image loading function. diff --git a/www/js/lib/images.js b/www/js/lib/images.js index 65e893c7..8819d052 100644 --- a/www/js/lib/images.js +++ b/www/js/lib/images.js @@ -23,6 +23,11 @@ define(['uiUtil'], function (uiUtil) { + /** + * An array to hold all the images in the current document + */ + var documentImages = []; + /** * A variable to keep track of how many images are being extracted by the extractor */ @@ -168,45 +173,67 @@ define(['uiUtil'], function (uiUtil) { /** * Prepares an array or collection of image nodes that have been disabled in Service Worker for manual extraction - * - * @param {Object} images An array or collection of DOM image nodes - * @param {String} displayType If 'progressive', lazyLoad will be used; if 'manual', setupManualImageExtraction will be used */ - function prepareImagesServiceWorker (images, displayType) { - var zimImages = []; - for (var i = 0, l = images.length; i < l; i++) { + function prepareImagesServiceWorker () { + var iframe = document.getElementById('articleContent'); + var doc = iframe.contentDocument.documentElement; + documentImages = doc.getElementsByTagName('img'); + if (!documentImages.length) return; + for (var i = 0, l = documentImages.length; i < l; i++) { // DEV: make sure list of file types here is the same as the list in Service Worker code if (/(^|\/)[IJ]\/.*\.(jpe?g|png|svg|gif)($|[?#])/i.test(images[i].src)) { - images[i].dataset.kiwixurl = images[i].getAttribute('src'); - images[i].style.transition = 'opacity 0.5s ease-in'; + documentImages[i].dataset.kiwixurl = documentImages[i].getAttribute('src'); + documentImages[i].style.transition = 'opacity 0.5s ease-in'; if (displayType === 'progressive') { - images[i].style.opacity = '0'; + documentImages[i].style.opacity = '0'; } - zimImages.push(images[i]); } } - if (displayType === 'manual') { - prepareManualExtraction(zimImages); + if (params.imageDisplayMode === 'manual') { + prepareManualExtraction(); } else { - lazyLoad(zimImages); + lazyLoad(); } } + function prepareImagesJQuery (forPrinting) { + var iframe = document.getElementById('articleContent'); + var doc = iframe.contentDocument.documentElement; + documentImages = doc.querySelectorAll('img[data-kiwixurl]'); + if (!documentImages.length) return; + if (forPrinting) { + extractImages(documentImages, params.preloadingAllImages ? params.preloadAllImages : params.printIntercept ? forPrinting : null); + } else if (params.imageDisplayMode === 'progressive') { + // Firefox squashes empty images, but we don't want to alter the vertical heights constantly as we scroll + // so substitute empty images with a plain svg + for (var i = documentImages.length; i--;) { + documentImages[i].src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E"; + documentImages[i].style.opacity = '0'; + documentImages[i].style.transition = 'opacity 0.5s ease-in'; + } + lazyLoad(); + } else { + // User wishes to extract images manually + setupManualImageExtraction(); + } + setTimeout(loadMathJax, 3000); + } + /** * Processes an array or collection of image nodes so that they will be lazy loaded (progressive extraction) * - * @param {Object} images And array or collection of DOM image nodes which will be processed for + * @param {Object} documentImages And array or collection of DOM image nodes which will be processed for * progressive image extraction */ - function lazyLoad(images) { + function lazyLoad() { // The amount by which to offset the second reading of the viewport var offset = window.innerHeight; // Perform an immediate extraction of visible images so as not to disconcert the user // We request images twice because frequently the position of all of them is not known at this stage in rendering - images = queueImages(images, true, 0, function () { - images = queueImages(images, true, window.innerHeight).remaining; - }).remaining; - if (!images.length) return; + queueImages(documentImages, true, 0, function () { + queueImages(documentImages, true, window.innerHeight); + }); + if (!documentImages.length) return; // There are images remaining, so set up an event listener to load more images once user has stopped scrolling the iframe var iframe = document.getElementById('articleContent'); var iframeWindow = iframe.contentWindow; @@ -214,18 +241,18 @@ define(['uiUtil'], function (uiUtil) { var rateLimiter = 0; // NB we add the event listener this way so we can access it in app.js iframeWindow.onscroll = function () { - if (!images.length) return; + if (!documentImages.length) return; var velo = iframeWindow.pageYOffset - scrollPos; if (velo < 15 && velo > -15) { // Scroll is now quite slow, so start getting images in viewport - images = queueImages(images, true, 0, function () { + queueImages(documentImages, true, 0, function () { if (!rateLimiter) { rateLimiter = 1; - images = queueImages(images, true, velo >= 0 ? offset : -offset, function () { + queueImages(documentImages, true, velo >= 0 ? offset : -offset, function () { rateLimiter = 0; - }).remaining; + }); } - }).remaining; + }); } scrollPos = iframeWindow.pageYOffset; }; @@ -259,6 +286,7 @@ define(['uiUtil'], function (uiUtil) { extractImages: extractImages, setupManualImageExtraction: prepareManualExtraction, prepareImagesServiceWorker: prepareImagesServiceWorker, + prepareImagesJQuery: prepareImagesJQuery, lazyLoad: lazyLoad, loadMathJax: loadMathJax };