瀏覽代碼

detect hidden elements by injected CSS

Former-commit-id: 125e43b85d6179a22b32140dc42b30824ac12255
Gildas 6 年之前
父節點
當前提交
d80dae59f4
共有 3 個文件被更改,包括 17 次插入8 次删除
  1. 6 4
      lib/single-file/single-file-core.js
  2. 10 4
      lib/single-file/single-file-helper.js
  3. 1 0
      lib/single-file/single-file-util.js

+ 6 - 4
lib/single-file/single-file-core.js

@@ -785,10 +785,12 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 		}
 
 		removeHiddenElements() {
-			const hiddenElements = this.doc.querySelectorAll("[" + util.REMOVED_CONTENT_ATTRIBUTE_NAME + "]");
-			this.stats.set("discarded", "hidden elements", hiddenElements.length);
-			this.stats.set("processed", "hidden elements", hiddenElements.length);
-			hiddenElements.forEach(element => element.remove());
+			const hiddenElements = this.doc.querySelectorAll("[" + util.HIDDEN_CONTENT_ATTRIBUTE_NAME + "]");
+			const removedElements = this.doc.querySelectorAll("[" + util.REMOVED_CONTENT_ATTRIBUTE_NAME + "]");
+			this.stats.set("discarded", "hidden elements", removedElements.length);
+			this.stats.set("processed", "hidden elements", removedElements.length);
+			hiddenElements.forEach(element => element.style.display = "none");
+			removedElements.forEach(element => element.remove());
 		}
 
 		resolveHrefs() {

+ 10 - 4
lib/single-file/single-file-helper.js

@@ -26,6 +26,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 	const singlefile = this.singlefile;
 
 	const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-single-file-removed-content";
+	const HIDDEN_CONTENT_ATTRIBUTE_NAME = "data-single-file-hidden-content";
 	const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-single-file-preserved-space-element";
 	const SHADOW_ROOT_ATTRIBUTE_NAME = "data-single-file-shadow-root-element";
 	const WIN_ID_ATTRIBUTE_NAME = "data-single-file-win-id";
@@ -54,6 +55,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 		WIN_ID_ATTRIBUTE_NAME,
 		PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
 		REMOVED_CONTENT_ATTRIBUTE_NAME,
+		HIDDEN_CONTENT_ATTRIBUTE_NAME,
 		IMAGE_ATTRIBUTE_NAME,
 		POSTER_ATTRIBUTE_NAME,
 		CANVAS_ATTRIBUTE_NAME,
@@ -127,7 +129,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 							}
 						});
 					}
-					elementHidden = ascendantHidden || testHiddenElement(element, computedStyle);
+					elementHidden = ascendantHidden || testHiddenElement(element, computedStyle, data.markedElements);
 				}
 				if (!elementHidden) {
 					if (options.compressHTML && computedStyle) {
@@ -272,14 +274,17 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 		return removeQuotes(fontFamilyName.trim()).toLowerCase();
 	}
 
-	function testHiddenElement(element, computedStyle) {
+	function testHiddenElement(element, computedStyle, markedElements) {
 		let hidden = false;
 		if (computedStyle) {
 			const display = computedStyle.getPropertyValue("display");
 			const opacity = computedStyle.getPropertyValue("opacity");
 			const visibility = computedStyle.getPropertyValue("visibility");
 			hidden = display == "none";
-			if (!hidden && (opacity == "0" || visibility == "hidden") && element.getBoundingClientRect) {
+			if (hidden) {
+				element.setAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME, "");
+				markedElements.push(element);
+			} else if ((opacity == "0" || visibility == "hidden") && element.getBoundingClientRect) {
 				const boundingRect = element.getBoundingClientRect();
 				hidden = !boundingRect.width && !boundingRect.height;
 			}
@@ -301,11 +306,12 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 			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 (!markedElements) {
-			const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, HTML_IMPORT_ATTRIBUTE_NAME, STYLESHEET_ATTRIBUTE_NAME];
+			const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, HIDDEN_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, HTML_IMPORT_ATTRIBUTE_NAME, STYLESHEET_ATTRIBUTE_NAME];
 			markedElements = doc.querySelectorAll(singleFileAttributes.map(name => "[" + name + "]").join(","));
 		}
 		markedElements.forEach(element => {
 			element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME);
+			element.removeAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME);
 			element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME);
 			element.removeAttribute(IMAGE_ATTRIBUTE_NAME);
 			element.removeAttribute(POSTER_ATTRIBUTE_NAME);

+ 1 - 0
lib/single-file/single-file-util.js

@@ -183,6 +183,7 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
 				},
 				WIN_ID_ATTRIBUTE_NAME: helper.WIN_ID_ATTRIBUTE_NAME,
 				REMOVED_CONTENT_ATTRIBUTE_NAME: helper.REMOVED_CONTENT_ATTRIBUTE_NAME,
+				HIDDEN_CONTENT_ATTRIBUTE_NAME: helper.HIDDEN_CONTENT_ATTRIBUTE_NAME,
 				IMAGE_ATTRIBUTE_NAME: helper.IMAGE_ATTRIBUTE_NAME,
 				POSTER_ATTRIBUTE_NAME: helper.POSTER_ATTRIBUTE_NAME,
 				CANVAS_ATTRIBUTE_NAME: helper.CANVAS_ATTRIBUTE_NAME,