|
|
@@ -20,36 +20,14 @@
|
|
|
|
|
|
/* global window, top, document, addEventListener, docHelper, timeout */
|
|
|
|
|
|
-this.FrameTree = this.FrameTree || (() => {
|
|
|
+this.frameTree = this.frameTree || (() => {
|
|
|
|
|
|
- const MESSAGE_PREFIX = "__FrameTree__";
|
|
|
+ const MESSAGE_PREFIX = "__frameTree__";
|
|
|
const TIMEOUT_INIT_REQUEST_MESSAGE = 500;
|
|
|
|
|
|
- let sessionId = 0;
|
|
|
+ let sessionId = 0, sessions = new Map(), windowId;
|
|
|
|
|
|
- const FrameTree = {
|
|
|
- getFramesData
|
|
|
- };
|
|
|
-
|
|
|
- let sessions = new Map();
|
|
|
- addEventListener("message", onFrameWindowMessage, false);
|
|
|
- return FrameTree;
|
|
|
-
|
|
|
- async function getFramesData(options) {
|
|
|
- options = JSON.parse(JSON.stringify(options));
|
|
|
- options.sessionId = sessionId;
|
|
|
- sessionId++;
|
|
|
- return new Promise(resolve => {
|
|
|
- sessions.set(options.sessionId, {
|
|
|
- frames: [],
|
|
|
- dataRequestCallbacks: new Map(),
|
|
|
- resolve
|
|
|
- });
|
|
|
- initRequest({ windowId: "0", sessionId: options.sessionId, options });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- function onFrameWindowMessage(event) {
|
|
|
+ addEventListener("message", event => {
|
|
|
if (typeof event.data == "string" && event.data.startsWith(MESSAGE_PREFIX + "::")) {
|
|
|
const message = JSON.parse(event.data.substring(MESSAGE_PREFIX.length + 2));
|
|
|
if (message.method == "initRequest") {
|
|
|
@@ -58,18 +36,26 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
initResponse(message);
|
|
|
}
|
|
|
}
|
|
|
+ }, false);
|
|
|
+ return { get: getFramesData };
|
|
|
+
|
|
|
+ async function getFramesData(options) {
|
|
|
+ options = JSON.parse(JSON.stringify(options));
|
|
|
+ options.sessionId = sessionId;
|
|
|
+ options.win = null;
|
|
|
+ sessionId++;
|
|
|
+ return new Promise(resolve => {
|
|
|
+ sessions.set(options.sessionId, { frames: [], resolve });
|
|
|
+ initRequest({ windowId: "0", sessionId: options.sessionId, options });
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function initRequest(message) {
|
|
|
- const windowId = message.windowId;
|
|
|
const sessionId = message.sessionId;
|
|
|
- FrameTree.windowId = windowId;
|
|
|
+ windowId = message.windowId;
|
|
|
const frameElements = document.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]");
|
|
|
if (window != top) {
|
|
|
- sessions.set(message.sessionId, {
|
|
|
- frames: [],
|
|
|
- dataRequestCallbacks: new Map()
|
|
|
- });
|
|
|
+ sessions.set(message.sessionId, { frames: [] });
|
|
|
const docData = docHelper.preProcessDoc(document, window, message.options);
|
|
|
const content = docHelper.serialize(document);
|
|
|
docHelper.postProcessDoc(document, window, message.options);
|
|
|
@@ -80,13 +66,13 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
|
|
|
function initResponse(message) {
|
|
|
if (window == top) {
|
|
|
- const sessionFramesData = sessions.get(message.sessionId);
|
|
|
- if (sessionFramesData) {
|
|
|
+ const windowData = sessions.get(message.sessionId);
|
|
|
+ if (windowData) {
|
|
|
message.framesData.forEach(messageFrameData => {
|
|
|
- let frameData = sessionFramesData.frames.find(frameData => messageFrameData.windowId == frameData.windowId);
|
|
|
+ let frameData = windowData.frames.find(frameData => messageFrameData.windowId == frameData.windowId);
|
|
|
if (!frameData) {
|
|
|
frameData = { windowId: messageFrameData.windowId };
|
|
|
- sessionFramesData.frames.push(frameData);
|
|
|
+ windowData.frames.push(frameData);
|
|
|
}
|
|
|
frameData.content = messageFrameData.content;
|
|
|
frameData.baseURI = messageFrameData.baseURI;
|
|
|
@@ -95,14 +81,14 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
frameData.canvasData = messageFrameData.canvasData;
|
|
|
frameData.processed = messageFrameData.processed;
|
|
|
});
|
|
|
- const pendingCount = sessionFramesData.frames.filter(frameData => !frameData.processed).length;
|
|
|
+ const pendingCount = windowData.frames.filter(frameData => !frameData.processed).length;
|
|
|
if (!pendingCount) {
|
|
|
sessions.delete(message.sessionId);
|
|
|
- sessionFramesData.resolve(sessionFramesData.frames.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length));
|
|
|
+ windowData.resolve(windowData.frames.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length));
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- FrameTree.windowId = message.windowId;
|
|
|
+ windowId = message.windowId;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -115,32 +101,32 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
const frameWinId = windowId + "." + frameIndex;
|
|
|
frameElement.setAttribute(docHelper.WIN_ID_ATTRIBUTE_NAME, frameWinId);
|
|
|
framesData.push({ windowId: frameWinId });
|
|
|
- try {
|
|
|
- if (!frameElement.contentDocument) {
|
|
|
- options.win = null;
|
|
|
+ if (!frameElement.contentDocument) {
|
|
|
+ try {
|
|
|
frameElement.contentWindow.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initRequest", windowId: frameWinId, sessionId, options }), "*");
|
|
|
- timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [{ windowId: frameWinId, processed: true }], windowId: frameWinId, sessionId }), "*"), TIMEOUT_INIT_REQUEST_MESSAGE);
|
|
|
+ } catch (error) {
|
|
|
+ /* ignored */
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- /* ignored */
|
|
|
}
|
|
|
+ timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData: [{ windowId: frameWinId, processed: true }], windowId: frameWinId, sessionId }), "*"), TIMEOUT_INIT_REQUEST_MESSAGE);
|
|
|
});
|
|
|
top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData, windowId, sessionId }), "*");
|
|
|
framesData = [];
|
|
|
frameElements.forEach((frameElement, frameIndex) => {
|
|
|
const frameWinId = windowId + "." + frameIndex;
|
|
|
const frameWindow = frameElement.contentWindow;
|
|
|
- try {
|
|
|
- const frameDoc = frameElement.contentDocument;
|
|
|
- if (frameDoc) {
|
|
|
+ const frameDoc = frameElement.contentDocument;
|
|
|
+ if (frameDoc) {
|
|
|
+ try {
|
|
|
processFrames(frameDoc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"), options, frameWinId, sessionId, frameWindow);
|
|
|
const docData = docHelper.preProcessDoc(frameDoc, frameWindow, options);
|
|
|
framesData.push({ windowId: frameWinId, content: docHelper.serialize(frameDoc), baseURI: frameDoc.baseURI, title: frameDoc.title, emptyStyleRulesText: docData.emptyStyleRulesText, canvasData: docData.canvasData, processed: true });
|
|
|
docHelper.postProcessDoc(frameDoc, frameWindow, options);
|
|
|
+ } catch (error) {
|
|
|
+ /* ignored */
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- /* ignored */
|
|
|
}
|
|
|
+
|
|
|
});
|
|
|
top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "initResponse", framesData, windowId, sessionId }), "*");
|
|
|
}
|