|
@@ -26,9 +26,11 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
const TIMEOUT_INIT_REQUEST_MESSAGE = 500;
|
|
const TIMEOUT_INIT_REQUEST_MESSAGE = 500;
|
|
|
const TIMEOUT_DATA_RESPONSE_MESSAGE = 500;
|
|
const TIMEOUT_DATA_RESPONSE_MESSAGE = 500;
|
|
|
|
|
|
|
|
- const FrameTree = { getFramesData };
|
|
|
|
|
|
|
+ const FrameTree = {
|
|
|
|
|
+ getFramesData
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- let framesData, dataRequestCallbacks, initResponseSent;
|
|
|
|
|
|
|
+ let sessions = new Map();
|
|
|
if (window == top) {
|
|
if (window == top) {
|
|
|
browser.runtime.onMessage.addListener(onTopBackgroundMessage);
|
|
browser.runtime.onMessage.addListener(onTopBackgroundMessage);
|
|
|
}
|
|
}
|
|
@@ -37,29 +39,30 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
return FrameTree;
|
|
return FrameTree;
|
|
|
|
|
|
|
|
async function getFramesData(options) {
|
|
async function getFramesData(options) {
|
|
|
- await Promise.all(framesData.map(async frameData => {
|
|
|
|
|
|
|
+ const sessionId = options.sessionId;
|
|
|
|
|
+ const sessionFramesData = sessions.get(sessionId);
|
|
|
|
|
+ await Promise.all(sessionFramesData.frames.map(async frameData => {
|
|
|
return new Promise(resolve => {
|
|
return new Promise(resolve => {
|
|
|
- dataRequestCallbacks.set(frameData.windowId, resolve);
|
|
|
|
|
|
|
+ sessionFramesData.dataRequestCallbacks.set(frameData.windowId, resolve);
|
|
|
if (frameData.sameDomain) {
|
|
if (frameData.sameDomain) {
|
|
|
- top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataRequest", windowId: frameData.windowId, options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML } }), "*");
|
|
|
|
|
|
|
+ top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataRequest", windowId: frameData.windowId, sessionId, options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML } }), "*");
|
|
|
} else {
|
|
} else {
|
|
|
browser.runtime.sendMessage({
|
|
browser.runtime.sendMessage({
|
|
|
method: "FrameTree.getDataRequest",
|
|
method: "FrameTree.getDataRequest",
|
|
|
windowId: frameData.windowId,
|
|
windowId: frameData.windowId,
|
|
|
|
|
+ sessionId,
|
|
|
options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML }
|
|
options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML }
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
- frameData.getDataResponseTimeout = timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: frameData.windowId }), "*"), TIMEOUT_DATA_RESPONSE_MESSAGE);
|
|
|
|
|
|
|
+ frameData.getDataResponseTimeout = timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: frameData.windowId, sessionId }), "*"), TIMEOUT_DATA_RESPONSE_MESSAGE);
|
|
|
});
|
|
});
|
|
|
}));
|
|
}));
|
|
|
- return framesData.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length);
|
|
|
|
|
|
|
+ sessions.delete(sessionId);
|
|
|
|
|
+ return sessionFramesData.frames.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function onTopBackgroundMessage(message) {
|
|
function onTopBackgroundMessage(message) {
|
|
|
if (message.method == "FrameTree.initRequest" && document.documentElement instanceof HTMLHtmlElement) {
|
|
if (message.method == "FrameTree.initRequest" && document.documentElement instanceof HTMLHtmlElement) {
|
|
|
- dataRequestCallbacks = new Map();
|
|
|
|
|
- framesData = [];
|
|
|
|
|
- initResponseSent = false;
|
|
|
|
|
initRequest(message);
|
|
initRequest(message);
|
|
|
}
|
|
}
|
|
|
if (message.method == "FrameTree.getDataResponse") {
|
|
if (message.method == "FrameTree.getDataResponse") {
|
|
@@ -73,6 +76,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
browser.runtime.sendMessage({
|
|
browser.runtime.sendMessage({
|
|
|
method: "FrameTree.getDataResponse",
|
|
method: "FrameTree.getDataResponse",
|
|
|
windowId: message.windowId,
|
|
windowId: message.windowId,
|
|
|
|
|
+ sessionId: message.sessionId,
|
|
|
tabId: message.tabId,
|
|
tabId: message.tabId,
|
|
|
content: docHelper.serialize(document),
|
|
content: docHelper.serialize(document),
|
|
|
emptyStyleRulesText: docData.emptyStyleRulesText,
|
|
emptyStyleRulesText: docData.emptyStyleRulesText,
|
|
@@ -100,10 +104,14 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
function initRequest(message) {
|
|
function initRequest(message) {
|
|
|
FrameTree.windowId = message.windowId;
|
|
FrameTree.windowId = message.windowId;
|
|
|
const frameElements = document.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]");
|
|
const frameElements = document.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]");
|
|
|
|
|
+ sessions.set(message.sessionId, {
|
|
|
|
|
+ frames: [],
|
|
|
|
|
+ dataRequestCallbacks: new Map()
|
|
|
|
|
+ });
|
|
|
if (frameElements.length) {
|
|
if (frameElements.length) {
|
|
|
- setFramesWinId(MESSAGE_PREFIX, frameElements, message.options, FrameTree.windowId, window);
|
|
|
|
|
|
|
+ setFramesWinId(MESSAGE_PREFIX, frameElements, message.options, message.windowId, message.sessionId, window);
|
|
|
} else {
|
|
} else {
|
|
|
- top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [], windowId: FrameTree.windowId }), "*");
|
|
|
|
|
|
|
+ top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [], windowId: message.windowId, sessionId: message.sessionId }), "*");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -111,15 +119,18 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
if (window == top) {
|
|
if (window == top) {
|
|
|
if (message.framesData) {
|
|
if (message.framesData) {
|
|
|
message.framesData = message.framesData instanceof Array ? message.framesData : JSON.parse(message.framesData);
|
|
message.framesData = message.framesData instanceof Array ? message.framesData : JSON.parse(message.framesData);
|
|
|
- framesData = framesData.concat(message.framesData);
|
|
|
|
|
- const frameData = framesData.find(frameData => frameData.windowId == message.windowId);
|
|
|
|
|
- if (message.windowId != "0") {
|
|
|
|
|
- frameData.processed = true;
|
|
|
|
|
- }
|
|
|
|
|
- const pendingCount = framesData.filter(frameData => !frameData.processed).length;
|
|
|
|
|
- if (!pendingCount && !initResponseSent) {
|
|
|
|
|
- initResponseSent = true;
|
|
|
|
|
- browser.runtime.sendMessage({ method: "FrameTree.initResponse" });
|
|
|
|
|
|
|
+ const sessionFramesData = sessions.get(message.sessionId);
|
|
|
|
|
+ if (sessionFramesData) {
|
|
|
|
|
+ sessionFramesData.frames = sessionFramesData.frames.concat(...message.framesData);
|
|
|
|
|
+ const frameData = sessionFramesData.frames.find(frameData => frameData.windowId == message.windowId);
|
|
|
|
|
+ if (message.windowId != "0") {
|
|
|
|
|
+ frameData.processed = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ const pendingCount = sessionFramesData.frames.filter(frameData => !frameData.processed).length;
|
|
|
|
|
+ if (!pendingCount && !sessionFramesData.initResponseSent) {
|
|
|
|
|
+ sessionFramesData.initResponseSent = true;
|
|
|
|
|
+ browser.runtime.sendMessage({ method: "FrameTree.initResponse", sessionId: message.sessionId });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -127,10 +138,24 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function setFramesWinId(MESSAGE_PREFIX, frameElements, options, windowId, win) {
|
|
|
|
|
|
|
+ function getDataResponse(message) {
|
|
|
|
|
+ delete message.tabId;
|
|
|
|
|
+ delete message.method;
|
|
|
|
|
+ const sessionFramesData = sessions.get(message.sessionId);
|
|
|
|
|
+ const frameData = sessionFramesData.frames.find(frameData => frameData.windowId == message.windowId);
|
|
|
|
|
+ timeout.clear(frameData.getDataResponseTimeout);
|
|
|
|
|
+ frameData.content = message.content;
|
|
|
|
|
+ frameData.baseURI = message.baseURI;
|
|
|
|
|
+ frameData.title = message.title;
|
|
|
|
|
+ frameData.emptyStyleRulesText = message.emptyStyleRulesText;
|
|
|
|
|
+ frameData.canvasData = message.canvasData;
|
|
|
|
|
+ sessionFramesData.dataRequestCallbacks.get(message.windowId)(message);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function setFramesWinId(MESSAGE_PREFIX, frameElements, options, windowId, sessionId, win) {
|
|
|
const framesData = [];
|
|
const framesData = [];
|
|
|
if (win != top) {
|
|
if (win != top) {
|
|
|
- win.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", windowId }), "*");
|
|
|
|
|
|
|
+ win.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", windowId, sessionId }), "*");
|
|
|
}
|
|
}
|
|
|
frameElements.forEach((frameElement, frameIndex) => {
|
|
frameElements.forEach((frameElement, frameIndex) => {
|
|
|
let src, sameDomain;
|
|
let src, sameDomain;
|
|
@@ -142,7 +167,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
}
|
|
}
|
|
|
framesData.push({ sameDomain, src, windowId: windowId + "." + frameIndex });
|
|
framesData.push({ sameDomain, src, windowId: windowId + "." + frameIndex });
|
|
|
});
|
|
});
|
|
|
- top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData, windowId }), "*");
|
|
|
|
|
|
|
+ top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData, windowId, sessionId }), "*");
|
|
|
frameElements.forEach((frameElement, frameIndex) => {
|
|
frameElements.forEach((frameElement, frameIndex) => {
|
|
|
const frameWinId = windowId + "." + frameIndex;
|
|
const frameWinId = windowId + "." + frameIndex;
|
|
|
frameElement.setAttribute(docHelper.WIN_ID_ATTRIBUTE_NAME, frameWinId);
|
|
frameElement.setAttribute(docHelper.WIN_ID_ATTRIBUTE_NAME, frameWinId);
|
|
@@ -156,7 +181,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
/* ignored */
|
|
/* ignored */
|
|
|
}
|
|
}
|
|
|
if (frameWindow && frameDoc && topWindow) {
|
|
if (frameWindow && frameDoc && topWindow) {
|
|
|
- setFramesWinId(MESSAGE_PREFIX, frameDoc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"), options, frameWinId, frameWindow);
|
|
|
|
|
|
|
+ setFramesWinId(MESSAGE_PREFIX, frameDoc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"), options, frameWinId, sessionId, frameWindow);
|
|
|
topWindow.addEventListener("message", onMessage, false);
|
|
topWindow.addEventListener("message", onMessage, false);
|
|
|
const docData = docHelper.preProcessDoc(frameDoc, frameWindow, options);
|
|
const docData = docHelper.preProcessDoc(frameDoc, frameWindow, options);
|
|
|
content = docHelper.serialize(frameDoc);
|
|
content = docHelper.serialize(frameDoc);
|
|
@@ -164,8 +189,8 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
canvasData = docData.canvasData;
|
|
canvasData = docData.canvasData;
|
|
|
docHelper.postProcessDoc(frameDoc, options);
|
|
docHelper.postProcessDoc(frameDoc, options);
|
|
|
} else if (frameWindow) {
|
|
} else if (frameWindow) {
|
|
|
- frameWindow.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initRequest", windowId: frameWinId, frameIndex, options }), "*");
|
|
|
|
|
- timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [], windowId: frameWinId, frameIndex }), "*"), TIMEOUT_INIT_REQUEST_MESSAGE);
|
|
|
|
|
|
|
+ frameWindow.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initRequest", windowId: frameWinId, sessionId, frameIndex, options }), "*");
|
|
|
|
|
+ timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [], windowId: frameWinId, sessionId, frameIndex }), "*"), TIMEOUT_INIT_REQUEST_MESSAGE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function onMessage(event) {
|
|
function onMessage(event) {
|
|
@@ -173,24 +198,11 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
const message = JSON.parse(event.data.substring(MESSAGE_PREFIX.length + 2));
|
|
const message = JSON.parse(event.data.substring(MESSAGE_PREFIX.length + 2));
|
|
|
if (message.method == "getDataRequest" && message.windowId == frameWinId) {
|
|
if (message.method == "getDataRequest" && message.windowId == frameWinId) {
|
|
|
topWindow.removeEventListener("message", onMessage, false);
|
|
topWindow.removeEventListener("message", onMessage, false);
|
|
|
- top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: message.windowId, content, baseURI: frameDoc.baseURI, title: document.title, emptyStyleRulesText, canvasData }), "*");
|
|
|
|
|
|
|
+ top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: message.windowId, sessionId, content, baseURI: frameDoc.baseURI, title: document.title, emptyStyleRulesText, canvasData }), "*");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function getDataResponse(message) {
|
|
|
|
|
- delete message.tabId;
|
|
|
|
|
- delete message.method;
|
|
|
|
|
- const frameData = framesData.find(frameData => frameData.windowId == message.windowId);
|
|
|
|
|
- timeout.clear(frameData.getDataResponseTimeout);
|
|
|
|
|
- frameData.content = message.content;
|
|
|
|
|
- frameData.baseURI = message.baseURI;
|
|
|
|
|
- frameData.title = message.title;
|
|
|
|
|
- frameData.emptyStyleRulesText = message.emptyStyleRulesText;
|
|
|
|
|
- frameData.canvasData = message.canvasData;
|
|
|
|
|
- dataRequestCallbacks.get(message.windowId)(message);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
})();
|
|
})();
|