Răsfoiți Sursa

extracted code related to lazy loading into lazy-loader.js

Gildas 7 ani în urmă
părinte
comite
610651fb67

+ 1 - 0
extension/core/bg/bg.js

@@ -40,6 +40,7 @@ singlefile.core = (() => {
 		"/lib/single-file/rules-minifier.js",
 		"/lib/single-file/htmlnano.js",
 		"/lib/single-file/parse-srcset.js",
+		"/lib/single-file/lazy-loader.js",
 		"/lib/single-file/single-file-core.js",
 		"/lib/single-file/single-file-browser.js",
 		"/lib/fetch/content/fetch.js",

+ 79 - 0
lib/single-file/lazy-loader.js

@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   SingleFile is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SingleFile is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+this.lazyLoader = this.lazyLoader || (() => {
+
+	const DATA_URI_PREFIX = "data:";
+	const EMPTY_DATA_URI = "data:base64,";
+
+	return {
+		process(doc) {
+			replaceSrc(doc.querySelectorAll("img[data-src]"), "src");
+			replaceSrc(doc.querySelectorAll("img[data-original]"), "original");
+			doc.querySelectorAll("[data-bg]").forEach(element => {
+				const dataBg = element.dataset.bg;
+				if (dataBg && dataBg.startsWith(DATA_URI_PREFIX) && dataBg != EMPTY_DATA_URI && !element.style.backgroundImage.includes(dataBg)) {
+					element.style.backgroundImage = "url(" + element.dataset.bg + ")";
+					element.removeAttribute("data-bg");
+					processElement(element);
+				}
+			});
+			doc.querySelectorAll("[data-srcset]").forEach(imgElement => {
+				const srcset = imgElement.dataset.srcset;
+				if (srcset && imgElement.srcset != srcset) {
+					imgElement.srcset = srcset;
+					imgElement.removeAttribute("data-srcset");
+					processElement(imgElement);
+				}
+			});
+			doc.querySelectorAll(".lazyload").forEach(element => {
+				element.classList.add("lazypreload");
+				element.classList.remove("lazyload");
+			});
+		},
+		imageSelectors: {
+			src: {
+				"img[data-src]": "data-src",
+				"img[data-original]": "data-original",
+				"img[data-bg]": "data-bg"
+			},
+			srcset: {
+				"[data-srcset]": "data-srcset"
+			}
+		}
+	};
+
+	function replaceSrc(elements, attributeName) {
+		elements.forEach(element => {
+			const dataSrc = element.dataset[attributeName];
+			if (dataSrc && dataSrc.startsWith(DATA_URI_PREFIX) && dataSrc != EMPTY_DATA_URI && element.src != dataSrc) {
+				element.src = element.dataset[attributeName];
+				element.removeAttribute("data-" + attributeName);
+				processElement(element);
+			}
+		});
+	}
+
+	function processElement(element) {
+		element.removeAttribute("data-lazyload");
+		element.classList.remove("b-lazy");
+	}
+
+})();

+ 5 - 1
lib/single-file/single-file-browser.js

@@ -18,7 +18,7 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global SingleFileCore, base64, DOMParser, TextDecoder, fetch, superFetch, parseSrcset, uglifycss, htmlnano, rulesMinifier */
+/* global SingleFileCore, base64, DOMParser, TextDecoder, fetch, superFetch, parseSrcset, uglifycss, htmlnano, rulesMinifier, lazyLoader */
 
 this.SingleFile = this.SingleFile || (() => {
 
@@ -98,6 +98,10 @@ this.SingleFile = this.SingleFile || (() => {
 				serialize: () => getDoctype(doc) + doc.documentElement.outerHTML,
 				parseSrcset: srcset => parseSrcset.process(srcset),
 				uglifycss: (content, options) => uglifycss.processString(content, options),
+				lazyLoader: {
+					process: doc => lazyLoader.process(doc),
+					imageSelectors: lazyLoader.imageSelectors
+				},
 				htmlnano: {
 					process: doc => htmlnano.process(doc),
 					postProcess: doc => htmlnano.postProcess(doc),

+ 4 - 33
lib/single-file/single-file-core.js

@@ -282,24 +282,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		lazyLoadImages() {
-			DomProcessorHelper.replaceSrc(this.doc.querySelectorAll("img[data-src]"), "src");
-			DomProcessorHelper.replaceSrc(this.doc.querySelectorAll("img[data-original]"), "original");
-			this.doc.querySelectorAll("[data-bg]").forEach(element => {
-				const dataBg = element.dataset.bg;
-				if (dataBg && dataBg.startsWith(DATA_URI_PREFIX) && dataBg != EMPTY_DATA_URI && !element.style.backgroundImage.includes(dataBg)) {
-					element.style.backgroundImage = "url(" + element.dataset.bg + ")";
-					element.removeAttribute("data-bg");
-					element.removeAttribute("data-lazyload");
-				}
-			});
-			this.doc.querySelectorAll("[data-srcset]").forEach(imgElement => {
-				const srcset = imgElement.dataset.srcset;
-				if (srcset && imgElement.srcset != srcset) {
-					imgElement.srcset = srcset;
-					imgElement.removeAttribute("data-srcset");
-					imgElement.removeAttribute("data-lazyload");
-				}
-			});
+			this.dom.lazyLoader.process(this.doc);
 		}
 
 		removeDiscardedResources() {
@@ -418,10 +401,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", this.baseURI));
 			}
 			if (this.options.lazyLoadImages) {
-				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[data-src]"), "data-src", this.baseURI));
-				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[data-original]"), "data-original", this.baseURI));
-				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[data-bg]"), "data-bg", this.baseURI));
-				resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[data-srcset]"), "data-srcset", this.baseURI, this.dom.parseSrcset));
+				const imageSelectors = this.dom.lazyLoader.imageSelectors;
+				Object.keys(imageSelectors.src).forEach(selector => resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), imageSelectors.src[selector], this.baseURI)));
+				Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI, this.dom.parseSrcset)));
 			}
 			await resourcePromises;
 		}
@@ -641,17 +623,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}));
 		}
 
-		static replaceSrc(elements, attributeName) {
-			elements.forEach(element => {
-				const dataSrc = element.dataset[attributeName];
-				if (dataSrc && dataSrc.startsWith(DATA_URI_PREFIX) && dataSrc != EMPTY_DATA_URI && element.src != dataSrc) {
-					element.src = element.dataset[attributeName];
-					element.removeAttribute("data-" + attributeName);
-					element.removeAttribute("data-lazyload");
-				}
-			});
-		}
-
 		static async processSrcset(resourceElements, attributeName, baseURI, parseSrcset) {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
 				const srcset = parseSrcset(resourceElement.getAttribute(attributeName));