Explorar o código

moved common code into common.js

Gildas %!s(int64=7) %!d(string=hai) anos
pai
achega
cf9fb8bf46

+ 73 - 0
lib/single-file/common.js

@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   SingleFile is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SingleFile is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+this.common = this.common || (() => {
+
+	const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-single-file-removed-content";
+	const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-single-file-preserved-space-element";
+
+	return {
+		preProcessDoc,
+		postProcessDoc
+	};
+
+	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");
+			Array.from(element.childNodes).forEach(node => disabledNoscriptElement.appendChild(node));
+			disabledNoscriptElement.hidden = true;
+			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);
+		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, 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"));
+		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));
+		}
+	}
+
+})();

+ 0 - 0
lib/frame-tree/bg/frame-tree.js → lib/single-file/frame-tree/bg/frame-tree.js


+ 5 - 49
lib/frame-tree/content/frame-tree.js → lib/single-file/frame-tree/content/frame-tree.js

@@ -18,15 +18,13 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global browser, window, top, document, HTMLHtmlElement, addEventListener */
+/* global browser, window, top, document, HTMLHtmlElement, addEventListener, common */
 
 this.FrameTree = this.FrameTree || (() => {
 
 	const MESSAGE_PREFIX = "__FrameTree__";
 	const TIMEOUT_INIT_REQUEST_MESSAGE = 1000;
 	const TIMEOUT_DATA_RESPONSE_MESSAGE = 1000;
-	const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-single-file-removed-content";
-	const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-single-file-preserved-space-element";
 
 	const FrameTree = { getFramesData };
 
@@ -46,7 +44,7 @@ this.FrameTree = this.FrameTree || (() => {
 	}
 	browser.runtime.onMessage.addListener(message => {
 		if (message.method == "FrameTree.getDataRequest" && FrameTree.windowId == message.windowId) {
-			preProcessDoc(document, window, message.options);
+			common.preProcessDoc(document, window, message.options);
 			browser.runtime.sendMessage({
 				method: "FrameTree.getDataResponse",
 				windowId: message.windowId,
@@ -57,7 +55,7 @@ this.FrameTree = this.FrameTree || (() => {
 				baseURI: document.baseURI,
 				title: document.title
 			}).catch(() => {/* ignored */ });
-			postProcessDoc(document, message.options);
+			common.postProcessDoc(document, message.options);
 		}
 	});
 	addEventListener("message", event => {
@@ -165,12 +163,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);
+						common.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);
+						common.postProcessDoc(frameDoc, frameWindow, message.options);
 					}
 				}
 			}
@@ -236,46 +234,4 @@ this.FrameTree = this.FrameTree || (() => {
 		}
 	}
 
-	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");
-			Array.from(element.childNodes).forEach(node => disabledNoscriptElement.appendChild(node));
-			disabledNoscriptElement.hidden = true;
-			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);
-		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, 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"));
-		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));
-		}
-	}
-
 })();

+ 9 - 1
lib/single-file/single-file-browser.js

@@ -18,7 +18,7 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global SingleFileCore, base64, DOMParser, TextDecoder, fetch, superFetch, parseSrcset, uglifycss, htmlmini, rulesMinifier, lazyLoader, serializer */
+/* global SingleFileCore, base64, DOMParser, TextDecoder, fetch, superFetch, parseSrcset, uglifycss, htmlmini, rulesMinifier, lazyLoader, serializer, common */
 
 this.SingleFile = this.SingleFile || (() => {
 
@@ -133,6 +133,14 @@ this.SingleFile = this.SingleFile || (() => {
 		static serialize(doc, compressHTML) {
 			return serializer.process(doc, compressHTML);
 		}
+
+		static preProcessDoc(doc, win, options) {
+			common.preProcessDoc(doc, win, options);
+		}
+
+		static postProcessDoc(doc, options) {
+			common.postProcessDoc(doc, options);
+		}
 	}
 
 	return { getClass: () => SingleFileCore.getClass(Download, DOM, URL) };

+ 2 - 64
lib/single-file/single-file-core.js

@@ -79,15 +79,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			if (this.options.doc) {
 				this.options.canvasData = this.processor.getCanvasData();
 				this.options.emptyStyleRulesText = this.processor.getEmptyStyleRulesText();
-				this.processor.fixInlineScripts();
-				this.processor.disableNoscriptElements();
-				this.processor.hideNonMetadataContents();
-				if (this.options.removeHiddenElements) {
-					this.processor.markRemovedElements();
-				}
-				if (this.options.compressHTML) {
-					this.processor.markPreservedElements();
-				}
+				DOM.preProcessDoc(this.options.doc, this.options.win, this.options);
 			}
 			this.options.content = this.options.content || (this.options.doc ? DOM.serialize(this.options.doc, false) : null);
 			this.onprogress = options.onprogress || (() => { });
@@ -148,14 +140,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				this.pendingPromises.push(this.processor.scripts());
 			}
 			if (this.options.doc) {
-				this.processor.enableDisabledNoscriptTags(this.options.doc.querySelectorAll("disabled-noscript"));
-				this.processor.displayHiddenNonMetadataContents();
-				if (this.options.removeHiddenElements) {
-					this.processor.unmarkRemovedElements();
-				}
-				if (this.options.compressHTML) {
-					this.processor.unmarkPreservedElements();
-				}
+				DOM.postProcessDoc(this.options.doc, this.options);
 				if (!this.options.removeFrames) {
 					this.processor.removeWindowIdFrames();
 				}
@@ -335,53 +320,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			};
 		}
 
-		fixInlineScripts() {
-			this.options.doc.querySelectorAll("script").forEach(element => element.textContent = element.textContent.replace(/<\/script>/gi, "<\\/script>"));
-		}
-
-		disableNoscriptElements() {
-			this.options.doc.head.querySelectorAll("noscript").forEach(element => {
-				const disabledNoscriptElement = this.options.doc.createElement("disabled-noscript");
-				Array.from(element.childNodes).forEach(node => disabledNoscriptElement.appendChild(node));
-				disabledNoscriptElement.hidden = true;
-				element.parentElement.replaceChild(disabledNoscriptElement, element);
-			});
-		}
-
-		hideNonMetadataContents() {
-			this.options.doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.hidden = true);
-		}
-
-		markRemovedElements() {
-			this.options.doc.querySelectorAll("html > body *:not(style):not(script):not(link):not(frame):not(iframe):not(object)").forEach(element => {
-				const style = this.options.win.getComputedStyle(element);
-				if (element instanceof this.options.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, "");
-				}
-			});
-		}
-
-		markPreservedElements() {
-			this.options.doc.querySelectorAll("*").forEach(element => {
-				const style = this.options.win.getComputedStyle(element);
-				if (style.whiteSpace.startsWith("pre")) {
-					element.setAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, "");
-				}
-			});
-		}
-
-		displayHiddenNonMetadataContents() {
-			this.options.doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.removeAttribute("hidden"));
-		}
-
-		unmarkPreservedElements() {
-			this.options.doc.querySelectorAll("[" + PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME));
-		}
-
-		unmarkRemovedElements() {
-			this.options.doc.querySelectorAll("[" + REMOVED_CONTENT_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME));
-		}
-
 		removeWindowIdFrames() {
 			this.options.doc.querySelectorAll("[" + WIN_ID_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(WIN_ID_ATTRIBUTE_NAME));
 		}

+ 3 - 2
manifest.json

@@ -18,7 +18,8 @@
                 "lib/browser-polyfill/custom-browser-polyfill.js",
                 "extension/index.js",
                 "extension/ui/content/infobar.js",
-                "lib/frame-tree/content/frame-tree.js",
+                "lib/single-file/common.js",
+                "lib/single-file/frame-tree/content/frame-tree.js",
                 "extension/core/content/content-frame.js"
             ],
             "all_frames": true,
@@ -28,7 +29,7 @@
     "background": {
         "scripts": [
             "lib/browser-polyfill/custom-browser-polyfill.js",
-            "lib/frame-tree/bg/frame-tree.js",
+            "lib/single-file/frame-tree/bg/frame-tree.js",
             "lib/fetch/bg/fetch.js",
             "extension/index.js",
             "extension/core/bg/config.js",