Prechádzať zdrojové kódy

improved generic lazy loader

Gildas 7 rokov pred
rodič
commit
75eb208d59
1 zmenil súbory, kde vykonal 25 pridanie a 11 odobranie
  1. 25 11
      extension/core/content/content.js

+ 25 - 11
extension/core/content/content.js

@@ -18,11 +18,12 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global browser, SingleFile, singlefile, frameTree, document, Blob, MouseEvent, getSelection, prompt, addEventListener, Node, window */
+/* global browser, SingleFile, singlefile, frameTree, document, Blob, MouseEvent, getSelection, prompt, addEventListener, Node, window, timeout, MutationObserver */
 
 this.singlefile.top = this.singlefile.top || (() => {
 
 	const MESSAGE_PREFIX = "__SingleFile__::";
+	const TIMEOUT_LAZY_LOADING = 500;
 	const SingleFileClass = SingleFile.getClass();
 
 	let processing = false;
@@ -132,21 +133,34 @@ this.singlefile.top = this.singlefile.top || (() => {
 		const scriptBeforeElement = document.createElement("script");
 		scriptBeforeElement.src = scriptURL;
 		document.body.appendChild(scriptBeforeElement);
+		let timeoutId;
 		const promise = new Promise(resolve => {
-			scriptBeforeElement.onerror = resolve;
-			scriptBeforeElement.onload = () => setTimeout(() => {
-				scriptBeforeElement.remove();
-				const scriptURL = browser.runtime.getURL("lib/single-file/lazy-loader-after.js");
-				const scriptAfterElement = document.createElement("script");
-				scriptAfterElement.src = scriptURL;
-				document.body.appendChild(scriptAfterElement);
-				scriptAfterElement.onload = () => scriptAfterElement.remove();
-				resolve();
-			}, 250);
+			scriptBeforeElement.onload = () => scriptBeforeElement.remove();
+			var observer = new MutationObserver(mutationsList => {
+				mutationsList.forEach(mutation => {
+					if (mutation.attributeName == "src" || mutation.attributeName == "srcset") {
+						timeoutId = deferLazyLoadEnd(timeoutId, resolve);
+					}
+				});
+			});
+			observer.observe(document, { attributes: true, childList: true, subtree: true });
+			timeoutId = deferLazyLoadEnd(resolve);
 		});
 		return promise;
 	}
 
+	function deferLazyLoadEnd(timeoutId, resolve) {
+		timeout.clear(timeoutId);
+		return timeout.set(() => {
+			resolve();
+			const scriptURL = browser.runtime.getURL("lib/single-file/lazy-loader-after.js");
+			const scriptAfterElement = document.createElement("script");
+			scriptAfterElement.src = scriptURL;
+			document.body.appendChild(scriptAfterElement);
+			scriptAfterElement.onload = () => scriptAfterElement.remove();
+		}, TIMEOUT_LAZY_LOADING);
+	}
+
 	function markSelectedContent() {
 		const selection = getSelection();
 		const range = selection.rangeCount ? selection.getRangeAt(0) : null;