Selaa lähdekoodia

fix handling of frames in lazy timeouts

Gildas 5 vuotta sitten
vanhempi
sitoutus
1160451813

+ 17 - 12
extension/lib/single-file/lazy/bg/lazy-timeout.js

@@ -30,8 +30,10 @@ const timeouts = new Map();
 browser.runtime.onMessage.addListener((message, sender) => {
 	if (message.method == "singlefile.lazyTimeout.setTimeout") {
 		let tabTimeouts = timeouts.get(sender.tab.id);
+		let frameTimeouts;
 		if (tabTimeouts) {
-			const previousTimeoutId = tabTimeouts.get(message.type);
+			frameTimeouts = tabTimeouts.get(sender.frameId);
+			const previousTimeoutId = frameTimeouts.get(message.type);
 			if (previousTimeoutId) {
 				clearTimeout(previousTimeoutId);
 			}
@@ -39,8 +41,9 @@ browser.runtime.onMessage.addListener((message, sender) => {
 		const timeoutId = setTimeout(async () => {
 			try {
 				const tabTimeouts = timeouts.get(sender.tab.id);
+				const frameTimeouts = tabTimeouts.get(sender.frameId);
 				if (tabTimeouts) {
-					deleteTimeout(tabTimeouts, sender.tab.id, message.type);
+					deleteTimeout(frameTimeouts, message.type);
 				}
 				await browser.tabs.sendMessage(sender.tab.id, { method: "singlefile.lazyTimeout.onTimeout", type: message.type });
 			} catch (error) {
@@ -49,19 +52,24 @@ browser.runtime.onMessage.addListener((message, sender) => {
 		}, message.delay);
 		if (!tabTimeouts) {
 			tabTimeouts = new Map();
+			frameTimeouts = new Map();
+			tabTimeouts.set(sender.frameId, frameTimeouts);
 			timeouts.set(sender.tab.id, tabTimeouts);
 		}
-		tabTimeouts.set(message.type, timeoutId);
+		frameTimeouts.set(message.type, timeoutId);
 		return Promise.resolve({});
 	}
 	if (message.method == "singlefile.lazyTimeout.clearTimeout") {
 		let tabTimeouts = timeouts.get(sender.tab.id);
 		if (tabTimeouts) {
-			const timeoutId = tabTimeouts.get(message.type);
-			if (timeoutId) {
-				clearTimeout(timeoutId);
+			const frameTimeouts = tabTimeouts.get(sender.frameId);
+			if (frameTimeouts) {
+				const timeoutId = frameTimeouts.get(message.type);
+				if (timeoutId) {
+					clearTimeout(timeoutId);
+				}
+				deleteTimeout(frameTimeouts, message.type);
 			}
-			deleteTimeout(tabTimeouts, sender.tab.id, message.type);
 		}
 		return Promise.resolve({});
 	}
@@ -69,9 +77,6 @@ browser.runtime.onMessage.addListener((message, sender) => {
 
 browser.tabs.onRemoved.addListener(tabId => timeouts.delete(tabId));
 
-function deleteTimeout(tabTimeouts, tabId, type) {
-	tabTimeouts.delete(type);
-	if (!tabTimeouts.size) {
-		timeouts.delete(tabId);
-	}
+function deleteTimeout(framesTimeouts, type) {
+	framesTimeouts.delete(type);
 }

+ 14 - 7
lib/single-file/processors/lazy/content/content-lazy-loader.js

@@ -99,19 +99,26 @@ function triggerLazyLoading(options) {
 				}
 			}
 		});
-		await setAsyncTimeout("idleTimeout", () => {
-			if (!loadingImages) {
-				clearAsyncTimeout("loadTimeout");
-				clearAsyncTimeout("maxTimeout");
-				lazyLoadEnd(observer, options, cleanupAndResolve);
-			}
-		}, options.loadDeferredImagesMaxIdleTime * 2);
+		await setIdleTimeout(options.loadDeferredImagesMaxIdleTime * 2);
 		await deferForceLazyLoadEnd(observer, options, cleanupAndResolve);
 		observer.observe(document, { subtree: true, childList: true, attributes: true });
 		addEventListener(hooksFrames.LOAD_IMAGE_EVENT, onImageLoadEvent);
 		addEventListener(hooksFrames.IMAGE_LOADED_EVENT, onImageLoadedEvent);
 		hooksFrames.loadDeferredImagesStart(options);
 
+		async function setIdleTimeout(delay) {
+			await setAsyncTimeout("idleTimeout", async () => {
+				if (!loadingImages) {
+					clearAsyncTimeout("loadTimeout");
+					clearAsyncTimeout("maxTimeout");
+					lazyLoadEnd(observer, options, cleanupAndResolve);
+				} else {
+					clearAsyncTimeout("idleTimeout");
+					await setIdleTimeout(Math.max(500, delay / 2));
+				}
+			}, delay);
+		}
+
 		function onResourceLoad(event) {
 			const element = event.target;
 			element.removeAttribute(helper.LAZY_SRC_ATTRIBUTE_NAME);