|
|
@@ -46,7 +46,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
}
|
|
|
browser.runtime.onMessage.addListener(message => {
|
|
|
if (message.method == "FrameTree.getDataRequest" && FrameTree.windowId == message.windowId) {
|
|
|
- preProcessDoc(document, window);
|
|
|
+ preProcessDoc(document, window, message.options);
|
|
|
browser.runtime.sendMessage({
|
|
|
method: "FrameTree.getDataResponse",
|
|
|
windowId: message.windowId,
|
|
|
@@ -57,7 +57,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
baseURI: document.baseURI,
|
|
|
title: document.title
|
|
|
}).catch(() => {/* ignored */ });
|
|
|
- postProcessDoc(document);
|
|
|
+ postProcessDoc(document, message.options);
|
|
|
}
|
|
|
});
|
|
|
addEventListener("message", event => {
|
|
|
@@ -74,16 +74,17 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
}, false);
|
|
|
return FrameTree;
|
|
|
|
|
|
- async function getFramesData() {
|
|
|
+ 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 }), "*");
|
|
|
+ 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
|
|
|
+ windowId: frameData.windowId,
|
|
|
+ options: { removeHiddenElements: options.removeHiddenElements, compressHTML: options.compressHTML }
|
|
|
}).catch(() => { /* ignored */ });
|
|
|
}
|
|
|
frameData.getDataResponseTimeout = setTimeout(() => top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: frameData.windowId }), "*"), TIMEOUT_DATA_RESPONSE_MESSAGE);
|
|
|
@@ -164,10 +165,12 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
const message = JSON.parse(event.data.substring(MESSAGE_PREFIX.length + 2));
|
|
|
if (message.method == "getDataRequest" && message.windowId == frameWinId) {
|
|
|
topWindow.removeEventListener("message", onMessage, false);
|
|
|
+ preProcessDoc(frameDoc, frameWindow, message.options);
|
|
|
const content = getDoctype(frameDoc) + frameDoc.documentElement.outerHTML;
|
|
|
const emptyStyleRulesText = getEmptyStyleRulesText(frameDoc);
|
|
|
const canvasData = getCanvasData(frameDoc);
|
|
|
top.postMessage(MESSAGE_PREFIX + "::" + JSON.stringify({ method: "getDataResponse", windowId: message.windowId, content, baseURI: frameDoc.baseURI, title: document.title, emptyStyleRulesText, canvasData }), "*");
|
|
|
+ postProcessDoc(frameDoc, frameWindow, message.options);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -233,7 +236,7 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function preProcessDoc(doc, win) {
|
|
|
+ function preProcessDoc(doc, win, options) {
|
|
|
doc.querySelectorAll("script").forEach(element => element.textContent = element.textContent.replace(/<\/script>/gi, "<\\/script>"));
|
|
|
doc.head.querySelectorAll("noscript").forEach(element => {
|
|
|
const disabledNoscriptElement = doc.createElement("disabled-noscript");
|
|
|
@@ -242,29 +245,37 @@ this.FrameTree = this.FrameTree || (() => {
|
|
|
element.parentElement.replaceChild(disabledNoscriptElement, element);
|
|
|
});
|
|
|
doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.hidden = true);
|
|
|
- doc.querySelectorAll("html > body *:not(style):not(script):not(link):not(frame):not(iframe):not(object)").forEach(element => {
|
|
|
- const style = win.getComputedStyle(element);
|
|
|
- if (element instanceof win.HTMLElement && (element.hidden || style.display == "none" || ((style.opacity === 0 || style.visibility == "hidden") && !element.clientWidth && !element.clientHeight)) && !element.querySelector("iframe, frame, object[type=\"text/html\"][data]")) {
|
|
|
- element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
|
|
|
- }
|
|
|
- });
|
|
|
- doc.querySelectorAll("*").forEach(element => {
|
|
|
- const style = win.getComputedStyle(element);
|
|
|
- if (style.whiteSpace.startsWith("pre")) {
|
|
|
- element.setAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, "");
|
|
|
- }
|
|
|
- });
|
|
|
+ if (options.removeHiddenElements) {
|
|
|
+ doc.querySelectorAll("html > body *:not(style):not(script):not(link):not(frame):not(iframe):not(object)").forEach(element => {
|
|
|
+ const style = win.getComputedStyle(element);
|
|
|
+ if (element instanceof win.HTMLElement && (element.hidden || style.display == "none" || ((style.opacity === 0 || style.visibility == "hidden") && !element.clientWidth && !element.clientHeight)) && !element.querySelector("iframe, frame, object[type=\"text/html\"][data]")) {
|
|
|
+ element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (options.compressHTML) {
|
|
|
+ doc.querySelectorAll("*").forEach(element => {
|
|
|
+ const style = win.getComputedStyle(element);
|
|
|
+ if (style.whiteSpace.startsWith("pre")) {
|
|
|
+ element.setAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, "");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- function postProcessDoc(doc) {
|
|
|
+ function postProcessDoc(doc, options) {
|
|
|
doc.head.querySelectorAll("disabled-noscript").forEach(element => {
|
|
|
const noscriptElement = doc.createElement("noscript");
|
|
|
Array.from(element.childNodes).forEach(node => noscriptElement.appendChild(node));
|
|
|
element.parentElement.replaceChild(noscriptElement, element);
|
|
|
});
|
|
|
doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.removeAttribute("hidden"));
|
|
|
- doc.querySelectorAll("[" + REMOVED_CONTENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME));
|
|
|
- doc.querySelectorAll("[" + PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME));
|
|
|
+ if (options.removeHiddenElements) {
|
|
|
+ doc.querySelectorAll("[" + REMOVED_CONTENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME));
|
|
|
+ }
|
|
|
+ if (options.compressHTML) {
|
|
|
+ doc.querySelectorAll("[" + PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
})();
|