|
@@ -18,62 +18,56 @@
|
|
|
* along with SingleFile. If not, see <http://www.gnu.org/licenses/>.
|
|
* along with SingleFile. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-/* global browser, window, top, document, HTMLHtmlElement, addEventListener, docHelper */
|
|
|
|
|
|
|
+/* global browser, window, top, document, HTMLHtmlElement, 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;
|
|
const TIMEOUT_INIT_REQUEST_MESSAGE = 500;
|
|
|
const TIMEOUT_DATA_RESPONSE_MESSAGE = 500;
|
|
const TIMEOUT_DATA_RESPONSE_MESSAGE = 500;
|
|
|
- const TIMEOUT_STEP = 100;
|
|
|
|
|
|
|
|
|
|
const FrameTree = { getFramesData };
|
|
const FrameTree = { getFramesData };
|
|
|
|
|
|
|
|
- const timeoutIds = [];
|
|
|
|
|
- const timeout = {
|
|
|
|
|
- set(fn, delay) {
|
|
|
|
|
- const id = timeoutIds.length;
|
|
|
|
|
- let elapsedTime = 0;
|
|
|
|
|
- timeoutIds[id] = setTimeout(step, 0);
|
|
|
|
|
- return id;
|
|
|
|
|
|
|
+ let framesData, dataRequestCallbacks, initResponseSent;
|
|
|
|
|
+ if (window == top) {
|
|
|
|
|
+ browser.runtime.onMessage.addListener(onTopBackgroundMessage);
|
|
|
|
|
+ }
|
|
|
|
|
+ browser.runtime.onMessage.addListener(onBackgroundMessage);
|
|
|
|
|
+ addEventListener("message", onFrameWindowMessage, false);
|
|
|
|
|
+ return FrameTree;
|
|
|
|
|
|
|
|
- function step() {
|
|
|
|
|
- if (elapsedTime < delay) {
|
|
|
|
|
- timeoutIds[id] = setTimeout(() => {
|
|
|
|
|
- elapsedTime += TIMEOUT_STEP;
|
|
|
|
|
- step();
|
|
|
|
|
- }, TIMEOUT_STEP);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- fn();
|
|
|
|
|
|
|
+ async function getFramesData(options) {
|
|
|
|
|
+ await Promise.all(framesData.map(async frameData => {
|
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
|
+ dataRequestCallbacks.set(frameData.windowId, resolve);
|
|
|
|
|
+ if (frameData.sameDomain) {
|
|
|
|
|
+ top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataRequest", windowId: frameData.windowId, options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML } }), "*");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ browser.runtime.sendMessage({
|
|
|
|
|
+ method: "FrameTree.getDataRequest",
|
|
|
|
|
+ windowId: frameData.windowId,
|
|
|
|
|
+ options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- clear(id) {
|
|
|
|
|
- if (timeoutIds[id]) {
|
|
|
|
|
- clearTimeout(timeoutIds[id]);
|
|
|
|
|
- timeoutIds[id] = null;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- let framesData, dataRequestCallbacks, initResponseSent;
|
|
|
|
|
|
|
+ frameData.getDataResponseTimeout = timeout.set(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: frameData.windowId }), "*"), TIMEOUT_DATA_RESPONSE_MESSAGE);
|
|
|
|
|
+ });
|
|
|
|
|
+ }));
|
|
|
|
|
+ return framesData.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (window == top) {
|
|
|
|
|
- browser.runtime.onMessage.addListener(message => {
|
|
|
|
|
- if (message.method == "FrameTree.initRequest" && document.documentElement instanceof HTMLHtmlElement) {
|
|
|
|
|
- dataRequestCallbacks = new Map();
|
|
|
|
|
- framesData = [];
|
|
|
|
|
- initResponseSent = false;
|
|
|
|
|
- initRequest(message);
|
|
|
|
|
- }
|
|
|
|
|
- if (message.method == "FrameTree.getDataResponse") {
|
|
|
|
|
- getDataResponse(message);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ function onTopBackgroundMessage(message) {
|
|
|
|
|
+ if (message.method == "FrameTree.initRequest" && document.documentElement instanceof HTMLHtmlElement) {
|
|
|
|
|
+ dataRequestCallbacks = new Map();
|
|
|
|
|
+ framesData = [];
|
|
|
|
|
+ initResponseSent = false;
|
|
|
|
|
+ initRequest(message);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (message.method == "FrameTree.getDataResponse") {
|
|
|
|
|
+ getDataResponse(message);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- browser.runtime.onMessage.addListener(message => {
|
|
|
|
|
|
|
+ function onBackgroundMessage(message) {
|
|
|
if (message.method == "FrameTree.getDataRequest" && FrameTree.windowId == message.windowId) {
|
|
if (message.method == "FrameTree.getDataRequest" && FrameTree.windowId == message.windowId) {
|
|
|
const docData = docHelper.preProcessDoc(document, window, message.options);
|
|
const docData = docHelper.preProcessDoc(document, window, message.options);
|
|
|
browser.runtime.sendMessage({
|
|
browser.runtime.sendMessage({
|
|
@@ -88,9 +82,9 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
});
|
|
});
|
|
|
docHelper.postProcessDoc(document, message.options);
|
|
docHelper.postProcessDoc(document, message.options);
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- addEventListener("message", event => {
|
|
|
|
|
|
|
+ function onFrameWindowMessage(event) {
|
|
|
if (typeof event.data == "string" && event.data.startsWith(MESSAGE_PREFIX + "::")) {
|
|
if (typeof event.data == "string" && event.data.startsWith(MESSAGE_PREFIX + "::")) {
|
|
|
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 == "initRequest") {
|
|
if (message.method == "initRequest") {
|
|
@@ -101,26 +95,6 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
getDataResponse(message);
|
|
getDataResponse(message);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }, false);
|
|
|
|
|
- return FrameTree;
|
|
|
|
|
-
|
|
|
|
|
- async function getFramesData(options) {
|
|
|
|
|
- await Promise.all(framesData.map(async frameData => {
|
|
|
|
|
- return new Promise(resolve => {
|
|
|
|
|
- dataRequestCallbacks.set(frameData.windowId, resolve);
|
|
|
|
|
- if (frameData.sameDomain) {
|
|
|
|
|
- top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataRequest", windowId: frameData.windowId, options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML } }), "*");
|
|
|
|
|
- } else {
|
|
|
|
|
- browser.runtime.sendMessage({
|
|
|
|
|
- method: "FrameTree.getDataRequest",
|
|
|
|
|
- windowId: frameData.windowId,
|
|
|
|
|
- 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);
|
|
|
|
|
- });
|
|
|
|
|
- }));
|
|
|
|
|
- return framesData.sort((frame1, frame2) => frame2.windowId.split(".").length - frame1.windowId.split(".").length);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function initRequest(message) {
|
|
function initRequest(message) {
|