Ver Fonte

added an option to compress HTML

Gildas há 7 anos atrás
pai
commit
2bcd14d713

+ 6 - 1
extension/core/scripts/bg/config.js

@@ -28,6 +28,10 @@ singlefile.config = (() => {
 			config.removeScripts = true;
 			localStorage.config = JSON.stringify(config);
 		}
+		if (config.compressHTML === undefined) {
+			config.compressHTML = true;
+			localStorage.config = JSON.stringify(config);
+		}
 	}
 
 	return {
@@ -40,7 +44,8 @@ singlefile.config = (() => {
 				removeUnusedCSSRules: false,
 				removeFrames: true,
 				removeScripts: true,
-				rawDocument: false
+				rawDocument: false,
+				compressHTML: true
 			};
 		},
 		reset() {

+ 8 - 0
extension/ui/pages/help.html

@@ -41,6 +41,14 @@
 					<img src="../resources/icon_19.png" class="icon"> in the browser toolbar and select "Options" in the context menu to open the options page.</p>
 				<p>Details :</p>
 				<ul>
+					<li>
+						<span class="option">compress HTML</span>
+						<p>Check this option to remove all HTML comments, and unneeded spaces or returns. This helps to reduce the size of the
+							file without altering the document.</p>
+						<p class="notice">It is recommended to
+							<u>check</u> this option</p>
+					</li>
+
 					<li>
 						<span class="option">remove frame elements</span>
 						<p>Check this option to remove all frames and iframes. This can considerably reduce the size of the file without altering

+ 5 - 1
extension/ui/pages/options.html

@@ -10,7 +10,11 @@
 <body>
 	<div>
 		<div id="popupContent">
-			<h4>Options</h4>
+			<h4>Options</h4>			
+			<div class="option">
+				<label for="compressHTMLInput">compress HTML</label>
+				<input type="checkbox" id="compressHTMLInput">
+			</div>
 			<div class="option">
 				<label for="removeFramesInput">remove frames</label>
 				<input type="checkbox" id="removeFramesInput">

+ 4 - 1
extension/ui/scripts/bg/options.js

@@ -30,6 +30,7 @@
 		const removeFramesInput = document.getElementById("removeFramesInput");
 		const removeScriptsInput = document.getElementById("removeScriptsInput");
 		const saveRawPageInput = document.getElementById("saveRawPageInput");
+		const compressHTMLInput = document.getElementById("compressHTMLInput");
 		document.getElementById("resetButton").addEventListener("click", () => {
 			bgPage.singlefile.config.reset();
 			refresh();
@@ -52,6 +53,7 @@
 			removeFramesInput.checked = config.removeFrames;
 			removeScriptsInput.checked = config.removeScripts;
 			saveRawPageInput.checked = config.saveRawPage;
+			compressHTMLInput.checked = config.compressHTML;
 		}
 
 		function update() {
@@ -60,7 +62,8 @@
 				removeUnusedCSSRules: removeUnusedCSSRulesInput.checked,
 				removeFrames: removeFramesInput.checked,
 				removeScripts: removeScriptsInput.checked,
-				saveRawPage: saveRawPageInput.checked
+				saveRawPage: saveRawPageInput.checked,
+				compressHTML: compressHTMLInput.checked
 			});
 		}
 	});

+ 30 - 0
lib/single-file/single-file-core.js

@@ -90,6 +90,9 @@ const SingleFileCore = (() => {
 			}
 			this.processor.removeDiscardedResources();
 			this.processor.resetCharsetMeta();
+			if (this.options.compressHTML) {
+				this.processor.compressHTML();
+			}
 			if (this.options.insertFaviconLink) {
 				this.processor.insertFaviconLink();
 			}
@@ -347,6 +350,32 @@ const SingleFileCore = (() => {
 			});
 		}
 
+		compressHTML() {
+			const textNodesWalker = this.doc.createTreeWalker(this.doc.documentElement, 4, null, false);
+			let node = textNodesWalker.nextNode();
+			while (node) {
+				let element = node.parentElement;
+				while (element && element.tagName != "PRE") {
+					element = element.parentElement;
+				}
+				if (!element) {
+					node.textContent = node.textContent.replace(/ +/g, " ");
+					node.textContent = node.textContent.replace(/\n+/g, " ");
+				}
+				node = textNodesWalker.nextNode();
+			}
+			const commentNodesWalker = this.doc.createTreeWalker(this.doc.documentElement, 128, null, false);
+			node = commentNodesWalker.nextNode();
+			let removedNodes = [];
+			while (node) {
+				if (node.nodeType == 8) {
+					removedNodes.push(node);
+				}
+				node = commentNodesWalker.nextNode();
+			}
+			removedNodes.forEach(node => node.remove());
+		}
+
 		insertSingleFileCommentNode() {
 			const commentNode = this.doc.createComment("\n Archive processed by SingleFile \n url: " + this.baseURI + " \n saved date: " + new Date() + " \n");
 			this.doc.documentElement.insertBefore(commentNode, this.doc.documentElement.firstChild);
@@ -422,6 +451,7 @@ const SingleFileCore = (() => {
 							jsEnabled: this.options.jsEnabled,
 							removeScripts: this.options.removeScripts,
 							saveRawPage: this.options.saveRawPage,
+							compressHTML: this.options.compressHTML,
 							framesData: this.options.framesData
 						};
 						if (frameData.content) {