Преглед изворни кода

improved removal of hidden elements

Gildas пре 5 година
родитељ
комит
ab5a301646
1 измењених фајлова са 22 додато и 17 уклоњено
  1. 22 17
      lib/single-file/single-file-helper.js

+ 22 - 17
lib/single-file/single-file-helper.js

@@ -31,6 +31,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 	const ON_AFTER_CAPTURE_EVENT_NAME = "single-file-on-after-capture";
 	const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-single-file-removed-content";
 	const HIDDEN_CONTENT_ATTRIBUTE_NAME = "data-single-file-hidden-content";
+	const KEPT_CONTENT_ATTRIBUTE_NAME = "data-single-file-kept-content";
 	const HIDDEN_FRAME_ATTRIBUTE_NAME = "data-single-file-hidden-frame";
 	const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-single-file-preserved-space-element";
 	const SHADOW_ROOT_ATTRIBUTE_NAME = "data-single-file-shadow-root-element";
@@ -46,7 +47,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 	const SELECTED_CONTENT_ATTRIBUTE_NAME = "data-single-file-selected-content";
 	const ASYNC_SCRIPT_ATTRIBUTE_NAME = "data-single-file-async-script";
 	const FLOW_ELEMENTS_SELECTOR = "*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)";
-	const IGNORED_REMOVED_TAG_NAMES = ["NOSCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "TEMPLATE", "SOURCE", "OBJECT", "SCRIPT", "HEAD"];
+	const KEPT_TAG_NAMES = ["NOSCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "TEMPLATE", "SOURCE", "OBJECT", "SCRIPT", "HEAD"];
 	const REGEXP_SIMPLE_QUOTES_STRING = /^'(.*?)'$/;
 	const REGEXP_DOUBLE_QUOTES_STRING = /^"(.*?)"$/;
 	const FONT_WEIGHTS = {
@@ -151,19 +152,18 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 	function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map(), canvases: [], images: [], posters: [], shadowRoots: [], imports: [], markedElements: [] }, ascendantHidden) {
 		const elements = Array.from(element.childNodes).filter(node => node instanceof win.HTMLElement);
 		elements.forEach(element => {
-			let elementHidden, computedStyle;
+			let elementHidden, elementKept, computedStyle;
 			if (!options.autoSaveExternalSave && (options.removeHiddenElements || options.removeUnusedFonts || options.compressHTML)) {
 				computedStyle = win.getComputedStyle(element);
 				if (options.removeHiddenElements) {
-					if (ascendantHidden) {
-						Array.from(element.childNodes).filter(node => node instanceof win.HTMLElement).forEach(element => {
-							if (!IGNORED_REMOVED_TAG_NAMES.includes(element.tagName)) {
-								element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
-								data.markedElements.push(element);
-							}
-						});
+					elementKept = ascendantHidden && KEPT_TAG_NAMES.includes(element.tagName);
+					if (!elementKept) {
+						elementHidden = ascendantHidden || testHiddenElement(element, computedStyle);
+						if (elementHidden) {
+							element.setAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME, "");
+							data.markedElements.push(element);
+						}
 					}
-					elementHidden = ascendantHidden || testHiddenElement(element, computedStyle, data.markedElements);
 				}
 				if (!elementHidden) {
 					if (options.compressHTML && computedStyle) {
@@ -196,6 +196,15 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 				}
 			}
 			getElementsInfo(win, doc, element, options, data, elementHidden);
+			if (!options.autoSaveExternalSave && options.removeHiddenElements && ascendantHidden) {
+				if (elementKept || element.getAttribute(KEPT_CONTENT_ATTRIBUTE_NAME) == "") {
+					element.parentElement.setAttribute(KEPT_CONTENT_ATTRIBUTE_NAME, "");
+					data.markedElements.push(element);
+				} else if (elementHidden) {
+					element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
+					data.markedElements.push(element);
+				}
+			}
 		});
 		return data;
 	}
@@ -316,19 +325,14 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 		return removeQuotes(singlefile.lib.vendor.cssUnescape.process(fontFamilyName.trim())).toLowerCase();
 	}
 
-	function testHiddenElement(element, computedStyle, markedElements) {
+	function testHiddenElement(element, computedStyle) {
 		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) {
-				if (element.style.getPropertyValue("display") != "none" && !IGNORED_REMOVED_TAG_NAMES.includes(element.tagName)) {
-					element.setAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME, "");
-					markedElements.push(element);
-				}
-			} else if ((opacity == "0" || visibility == "hidden") && element.getBoundingClientRect) {
+			if (!hidden && (opacity == "0" || visibility == "hidden") && element.getBoundingClientRect) {
 				const boundingRect = element.getBoundingClientRect();
 				hidden = !boundingRect.width && !boundingRect.height;
 			}
@@ -355,6 +359,7 @@ this.singlefile.lib.helper = this.singlefile.lib.helper || (() => {
 		markedElements.forEach(element => {
 			element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME);
 			element.removeAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME);
+			element.removeAttribute(KEPT_CONTENT_ATTRIBUTE_NAME);
 			element.removeAttribute(HIDDEN_FRAME_ATTRIBUTE_NAME);
 			element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME);
 			element.removeAttribute(IMAGE_ATTRIBUTE_NAME);