1
0
Эх сурвалжийг харах

made "remove hidden elements" more reliable

Gildas 7 жил өмнө
parent
commit
e5e4901fb9

+ 43 - 18
lib/single-file/doc-helper.js

@@ -30,7 +30,7 @@ this.docHelper = this.docHelper || (() => {
 	const IMAGE_ATTRIBUTE_NAME = "data-single-file-image";
 	const INPUT_VALUE_ATTRIBUTE_NAME = "data-single-file-value";
 	const SHEET_ATTRIBUTE_NAME = "data-single-file-sheet";
-	const IGNORED_TAG_NAMES = ["SCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "NOSCRIPT", "TEMPLATE", "IFRAME", "FRAME", "OBJECT", "SOURCE"];
+	const IGNORED_REMOVED_TAG_NAMES = ["NOSCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "TEMPLATE", "SOURCE", "OBJECT"];
 
 	return {
 		preProcessDoc,
@@ -57,7 +57,15 @@ this.docHelper = this.docHelper || (() => {
 		if (options.removeHiddenElements) {
 			const markerRemovedContent = removedContentAttributeName(options.sessionId);
 			const markerRemovedCandidate = removedCandidateAttributeName(options.sessionId);
-			markHiddenElements(win, doc.body, markerRemovedContent, markerRemovedCandidate);
+			let ignoredTags = JSON.parse(JSON.stringify(IGNORED_REMOVED_TAG_NAMES));
+			if (!options.removeFrame) {
+				ignoredTags = ignoredTags.concat(...["IFRAME", "FRAME"]);
+			}
+			if (!options.removeScripts) {
+				ignoredTags = ignoredTags.concat("SCRIPT");
+			}
+			markHiddenCandidates(win, doc.body, markerRemovedContent, markerRemovedCandidate, ignoredTags);
+			markHiddenElements(win, doc.body, markerRemovedContent);
 			doc.querySelectorAll(("[" + markerRemovedCandidate + "]")).forEach(element => element.removeAttribute(markerRemovedCandidate));
 		}
 		if (options.compressHTML) {
@@ -79,27 +87,44 @@ this.docHelper = this.docHelper || (() => {
 		};
 	}
 
-	function markHiddenElements(win, element, markerRemovedContent, markerRemovedCandidate) {
+	function markHiddenCandidates(win, element, markerRemovedContent, markerRemovedCandidateStage, ignoredTags) {
 		const elements = Array.from(element.childNodes).filter(node => node.nodeType == Node.ELEMENT_NODE);
-		elements.forEach(element => markHiddenElements(win, element, markerRemovedContent, markerRemovedCandidate));
+		elements.forEach(element => markHiddenCandidates(win, element, markerRemovedContent, markerRemovedCandidateStage, ignoredTags));
 		if (elements.length) {
-			if (element instanceof win.HTMLElement) {
-				let hiddenElement = !IGNORED_TAG_NAMES.includes(element.nodeName);
-				if (hiddenElement) {
-					hiddenElement = !elements.find(element => (!(element instanceof win.HTMLElement) || element.getAttribute(markerRemovedCandidate) !== ""));
-					hiddenElement = hiddenElement && element.hidden || (element.style && (element.style.display == "none" || element.style.opacity == "0" || element.style.visibility == "hidden"));
-				}
-				if (!hiddenElement) {
-					const boundingRect = element.getBoundingClientRect();
-					hiddenElement = !boundingRect.width && !boundingRect.height;
-				}
-				if (hiddenElement) {
-					element.setAttribute(markerRemovedCandidate, "");
-					elements.forEach(element => element.setAttribute(markerRemovedContent, ""));
+			const hiddenCandidate = !elements.find(element => element.getAttribute(markerRemovedCandidateStage) !== "");
+			if (hiddenCandidate) {
+				if (hiddenElement(element, ignoredTags) && element instanceof win.HTMLElement) {
+					element.setAttribute(markerRemovedCandidateStage, "");
+					elements.forEach(element => {
+						if (element instanceof win.HTMLElement) {
+							element.setAttribute(markerRemovedContent, "");
+						}
+					});
 				}
 			}
+		} else if (hiddenElement(element, ignoredTags)) {
+			element.setAttribute(markerRemovedCandidateStage, "");
+		}
+	}
+
+	function markHiddenElements(win, element, markerRemovedContent) {
+		const elements = Array.from(element.childNodes).filter(node => node.nodeType == Node.ELEMENT_NODE);
+		elements.forEach(element => markHiddenElements(win, element, markerRemovedContent));
+		if (element.parentElement.getAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME) != "") {
+			element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME);
+		}
+	}
+
+	function hiddenElement(element, ignoredTags) {
+		if (ignoredTags.includes(element.tagName)) {
+			return false;
 		} else {
-			element.setAttribute(markerRemovedCandidate, "");
+			let hidden = element.hidden || (element.style && (element.style.display == "none" || element.style.opacity == "0" || element.style.visibility == "hidden"));
+			if (!hidden) {
+				const boundingRect = element.getBoundingClientRect();
+				hidden = !boundingRect.width && !boundingRect.height;
+			}
+			return hidden;
 		}
 	}