Răsfoiți Sursa

better fix of issue #318

Former-commit-id: 7469f1c48386b4fad0d35065bf70e44c5ea18b61
Gildas 6 ani în urmă
părinte
comite
1a5f76da89

+ 1 - 1
extension/lib/single-file/frame-tree/bg/frame-tree.js

@@ -28,7 +28,7 @@
 	"use strict";
 
 	browser.runtime.onMessage.addListener((message, sender) => {
-		if (message.method == "singlefile.frameTree.initResponse") {
+		if (message.method == "singlefile.frameTree.initResponse" || message.method == "singlefile.frameTree.ackInitRequest") {
 			browser.tabs.sendMessage(sender.tab.id, message, { frameId: 0 });
 			return Promise.resolve({});
 		}

+ 42 - 10
lib/single-file/processors/frame-tree/content/content-frame-tree.js

@@ -31,10 +31,11 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 	const FRAMES_CSS_SELECTOR = "iframe, frame, object[type=\"text/html\"][data]";
 	const ALL_ELEMENTS_CSS_SELECTOR = "*";
 	const INIT_REQUEST_MESSAGE = "singlefile.frameTree.initRequest";
+	const ACK_INIT_REQUEST_MESSAGE = "singlefile.frameTree.ackInitRequest";
 	const CLEANUP_REQUEST_MESSAGE = "singlefile.frameTree.cleanupRequest";
 	const INIT_RESPONSE_MESSAGE = "singlefile.frameTree.initResponse";
 	const TARGET_ORIGIN = "*";
-	const TIMEOUT_INIT_REQUEST_MESSAGE = 5000;
+	const TIMEOUT_INIT_REQUEST_MESSAGE = 750;
 	const TOP_WINDOW_ID = "0";
 	const WINDOW_ID_SEPARATOR = ".";
 	const TOP_WINDOW = window == window.top;
@@ -45,6 +46,7 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 	const MessageChannel = window.MessageChannel;
 	const document = window.document;
 	const setTimeout = window.setTimeout;
+	const clearTimeout = window.clearTimeout;
 
 	const sessions = new Map();
 	let windowId;
@@ -56,6 +58,9 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 				if (message.method == INIT_RESPONSE_MESSAGE) {
 					initResponse(message);
 					return Promise.resolve({});
+				} else if (message.method == ACK_INIT_REQUEST_MESSAGE) {
+					clearFrameTimeout(message.sessionId, message.windowId);
+					return Promise.resolve({});
 				}
 			});
 		}
@@ -65,12 +70,17 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 			event.preventDefault();
 			event.stopPropagation();
 			const message = JSON.parse(event.data.substring(MESSAGE_PREFIX.length));
-			if (!TOP_WINDOW && message.method == INIT_REQUEST_MESSAGE) {
-				window.stop();
-				if (message.options.loadDeferredImages && singlefile.lib.processors.lazy.content.loader) {
-					singlefile.lib.processors.lazy.content.loader.process(message.options);
+			if (message.method == INIT_REQUEST_MESSAGE) {
+				sendMessage(event.source, { method: ACK_INIT_REQUEST_MESSAGE, windowId: message.windowId, sessionId: message.sessionId });
+				if (!TOP_WINDOW) {
+					window.stop();
+					if (message.options.loadDeferredImages && singlefile.lib.processors.lazy.content.loader) {
+						singlefile.lib.processors.lazy.content.loader.process(message.options);
+					}
+					await initRequestAsync(message);
 				}
-				await initRequestAsync(message);
+			} else if (message.method == ACK_INIT_REQUEST_MESSAGE) {
+				clearFrameTimeout(message.sessionId, message.windowId);
 			} else if (message.method == CLEANUP_REQUEST_MESSAGE) {
 				cleanupRequest(message);
 			} else if ((!browser || !browser.runtime) && message.method == INIT_RESPONSE_MESSAGE) {
@@ -84,14 +94,14 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 			const sessionId = options.sessionId || 0;
 			options = JSON.parse(JSON.stringify(options));
 			return new Promise(async resolve => {
-				sessions.set(sessionId, { frames: [], resolve });
+				sessions.set(sessionId, { frames: [], timeouts: {}, resolve });
 				await initRequestAsync({ windowId, sessionId, options });
 			});
 		},
 		getSync: options => {
 			const sessionId = options.sessionId || 0;
 			options = JSON.parse(JSON.stringify(options));
-			sessions.set(sessionId, { frames: [] });
+			sessions.set(sessionId, { frames: [], timeouts: {} });
 			initRequestSync({ windowId, sessionId, options });
 			return sessions.get(sessionId).frames;
 		},
@@ -199,18 +209,28 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 
 	function processFramesAsync(doc, frameElements, options, parentWindowId, sessionId) {
 		const frames = [];
+		let timeouts;
+		if (sessions.get(sessionId)) {
+			timeouts = sessions.get(sessionId).timeouts;
+		} else {
+			timeouts = {};
+			sessions.set(sessionId, { timeouts });
+		}
 		frameElements.forEach((frameElement, frameIndex) => {
 			const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
 			frameElement.setAttribute(singlefile.lib.helper.WIN_ID_ATTRIBUTE_NAME, windowId);
 			frames.push({ windowId });
+		});
+		sendInitResponse({ frames, sessionId, requestedFrameId: doc.documentElement.dataset.requestedFrameId && parentWindowId });
+		frameElements.forEach((frameElement, frameIndex) => {
+			const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
 			try {
 				sendMessage(frameElement.contentWindow, { method: INIT_REQUEST_MESSAGE, windowId, sessionId, options });
 			} catch (error) {
 				// ignored
 			}
-			setTimeout.call(window, () => sendInitResponse({ frames: [{ windowId, processed: true }], sessionId }), TIMEOUT_INIT_REQUEST_MESSAGE);
+			timeouts[windowId] = setTimeout.call(window, () => sendInitResponse({ frames: [{ windowId, processed: true }], sessionId }), TIMEOUT_INIT_REQUEST_MESSAGE);
 		});
-		sendInitResponse({ frames, sessionId, requestedFrameId: doc.documentElement.dataset.requestedFrameId && parentWindowId });
 		delete doc.documentElement.dataset.requestedFrameId;
 	}
 
@@ -228,6 +248,7 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 				try {
 					const frameWindow = frameElement.contentWindow;
 					frameWindow.stop();
+					clearFrameTimeout(sessionId, windowId);
 					processFrames(frameDoc, options, windowId, sessionId);
 					frames.push(getFrameData(frameDoc, frameWindow, windowId, options));
 				} catch (error) {
@@ -239,6 +260,17 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 		delete doc.documentElement.dataset.requestedFrameId;
 	}
 
+	function clearFrameTimeout(sessionId, windowId) {
+		const session = sessions.get(sessionId);
+		if (session && session.timeouts) {
+			const timeout = session.timeouts[windowId];
+			if (timeout) {
+				clearTimeout.call(window, timeout);
+				delete session.timeouts[windowId];
+			}
+		}
+	}
+
 	function cleanupFrames(frameElements, parentWindowId, sessionId) {
 		frameElements.forEach((frameElement, frameIndex) => {
 			const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;