Bladeren bron

fixed regression

Gildas 7 jaren geleden
bovenliggende
commit
48cf6ff3c2
1 gewijzigde bestanden met toevoegingen van 145 en 135 verwijderingen
  1. 145 135
      lib/single-file/single-file-core.js

+ 145 - 135
lib/single-file/single-file-core.js

@@ -68,6 +68,58 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 	// -------------
 	// PageProcessor
 	// -------------
+	const STAGES = [{
+		sync: [
+			{ action: "removeUIElements" },
+			{ action: "replaceStyleContents" },
+			{ option: "removeFrames", action: "removeFrames" },
+			{ option: "removeImports", action: "removeImports" },
+			{ option: "removeScripts", action: "removeScripts" },
+			{ action: "removeDiscardedResources" },
+			{ action: "resetCharsetMeta" },
+			{ option: "compressHTML", action: "compressHTML" },
+			{ action: "insertFaviconLink" },
+			{ action: "resolveHrefs" },
+			{ action: "replaceCanvasElements" },
+			{ option: "removeHiddenElements", action: "removeHiddenElements" }
+		],
+		async: [
+			{ action: "inlineStylesheets" },
+			{ action: "linkStylesheets" },
+			{ action: "attributeStyles" },
+			{ option: "!removeFrames", action: "frames" },
+			{ option: "!removeImports", action: "htmlImports" }
+		]
+	}, {
+		sync: [
+			{ option: "removeUnusedStyles", action: "removeUnusedStyles" },
+			{ option: "compressHTML", action: "compressHTML" },
+			{ option: "removeAlternativeFonts", action: "removeAlternativeFonts" },
+			{ option: "compressCSS", action: "compressCSS" },
+		],
+		async: [
+			{ action: "inlineStylesheets" },
+			{ action: "attributeStyles" },
+			{ action: "pageResources" },
+			{ option: "!removeScripts", action: "scripts" }
+		]
+	}, {
+		sync: [
+			{ option: "lazyLoadImages", action: "lazyLoadImages" },
+			{ option: "removeAlternativeFonts", action: "postRemoveAlternativeFonts" }
+		],
+		async: [
+			{ option: "!removeFrames", action: "frames" },
+			{ option: "!removeImports", action: "htmlImports" },
+		]
+	}, {
+		sync: [
+			{ option: "compressHTML", action: "postCompressHTML" },
+			{ option: "insertSingleFileComment", action: "insertSingleFileComment" },
+			{ action: "removeDefaultHeadTags" }
+		]
+	}];
+
 	class PageProcessor {
 		constructor(options) {
 			this.options = options;
@@ -90,54 +142,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 
 		async initialize() {
 			this.onprogress(new ProgressEvent(RESOURCES_INITIALIZING, { pageURL: this.options.url }));
-			this.processor.removeUIElements();
-			this.processor.replaceStyleContents();
-			if (this.options.removeFrames) {
-				this.processor.removeFrames();
-			}
-			if (this.options.removeImports) {
-				this.processor.removeImports();
-			}
-			if (this.options.removeScripts) {
-				this.processor.removeScripts();
-			}
-			this.processor.removeDiscardedResources();
-			this.processor.resetCharsetMeta();
-			if (this.options.compressHTML) {
-				this.processor.compressHTML();
-			}
-			if (this.options.insertFaviconLink) {
-				this.processor.insertFaviconLink();
-			}
-			this.processor.resolveHrefs();
-			this.processor.replaceCanvasElements();
-			if (this.options.removeHiddenElements) {
-				this.processor.removeHiddenElements(this.options.sessionId);
-			}
-			const initializationPromises = [this.processor.inlineStylesheets(true), this.processor.linkStylesheets(), this.processor.attributeStyles(true)];
-			if (!this.options.removeFrames && this.options.framesData) {
-				initializationPromises.push(this.processor.frames(true));
-			}
-			await Promise.all(initializationPromises);
-			if (this.options.removeUnusedStyles) {
-				this.processor.removeUnusedStyles();
-			}
-			if (!this.options.removeImports) {
-				initializationPromises.push(this.processor.htmlImports(true));
-			}
-			if (this.options.compressHTML) {
-				this.processor.compressHTML();
-			}
-			if (this.options.removeAlternativeFonts) {
-				this.processor.removeAlternativeFonts();
-			}
-			if (this.options.compressCSS) {
-				this.processor.compressCSS();
-			}
-			this.pendingPromises = [this.processor.inlineStylesheets(), this.processor.attributeStyles(), this.processor.pageResources()];
-			if (!this.options.removeScripts) {
-				this.pendingPromises.push(this.processor.scripts());
-			}
+			await this.executeStage(0);
+			this.pendingPromises = this.executeStage(1);
 			if (this.options.doc) {
 				DOM.postProcessDoc(this.options.doc, this.options);
 				this.options.doc = null;
@@ -147,40 +153,35 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		async preparePageData() {
-			await this.processor.retrieveResources(
-				details => {
-					details.pageURL = this.options.url;
-					this.onprogress(new ProgressEvent(RESOURCE_LOADED, details));
-				});
-			await this.pendingPromises;
-			if (this.options.lazyLoadImages) {
-				this.processor.lazyLoadImages();
-			}
-			if (this.options.removeAlternativeFonts) {
-				this.processor.removeAlternativeFonts(true);
-				if (this.options.compressCSS) {
-					this.processor.compressCSS();
-				}
-			}
-			if (!this.options.removeFrames && this.options.framesData) {
-				await this.processor.frames();
-			}
-			if (!this.options.removeImports) {
-				await this.processor.htmlImports();
-			}
-			if (this.options.compressHTML) {
-				this.processor.compressHTML(true);
-			}
-			if (this.options.insertSingleFileComment) {
-				this.processor.insertSingleFileCommentNode();
+			if (!this.options.windowId) {
+				await this.processor.retrieveResources(
+					details => {
+						details.pageURL = this.options.url;
+						this.onprogress(new ProgressEvent(RESOURCE_LOADED, details));
+					});
 			}
-			this.processor.removeDefaultHeadTags();
+			await this.pendingPromises;
+			await this.executeStage(2);
+			await this.executeStage(3);
 		}
 
 		getPageData() {
 			this.onprogress(new ProgressEvent(PAGE_ENDED, { pageURL: this.options.url }));
 			return this.processor.getPageData();
 		}
+
+		async executeStage(step) {
+			STAGES[step].sync.forEach(task => this.executeTask(task, !step));
+			if (STAGES[step].async) {
+				return Promise.all(STAGES[step].async.map(task => this.executeTask(task, !step)));
+			}
+		}
+
+		executeTask(task, initialization) {
+			if (!task.option || ((task.option.startsWith("!") && !this.options[task.option]) || this.options[task.option])) {
+				return this.processor[task.action](initialization);
+			}
+		}
 	}
 
 	// --------
@@ -388,35 +389,42 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			this.stats.set("discarded", "cssRules", stats.discarded);
 		}
 
-		removeAlternativeFonts(secondPass) {
-			DOM.minifyFonts(this.doc, secondPass);
+		removeAlternativeFonts() {
+			DOM.minifyFonts(this.doc);
+		}
+
+		postRemoveAlternativeFonts() {
+			DOM.minifyFonts(this.doc, true);
+			if (this.options.compressCSS) {
+				this.compressCSS();
+			}
 		}
 
-		removeHiddenElements(sessionId) {
-			const hiddenElements = this.doc.querySelectorAll("[" + DOM.removedContentAttributeName(sessionId) + "]");
+		removeHiddenElements() {
+			const hiddenElements = this.doc.querySelectorAll("[" + DOM.removedContentAttributeName(this.options.sessionId) + "]");
 			this.stats.set("discarded", "hiddenElements", hiddenElements.length);
 			hiddenElements.forEach(element => element.remove());
 		}
 
-		compressHTML(postProcess) {
-			if (postProcess) {
-				let size;
-				if (this.options.displayStats) {
-					size = DOM.getContentSize(this.doc.documentElement.outerHTML);
-				}
-				DOM.postMinifyHTML(this.doc);
-				if (this.options.displayStats) {
-					this.stats.add("discarded", "htmlBytes", size - DOM.getContentSize(this.doc.documentElement.outerHTML));
-				}
-			} else {
-				let size;
-				if (this.options.displayStats) {
-					size = DOM.getContentSize(this.doc.documentElement.outerHTML);
-				}
-				DOM.minifyHTML(this.doc, { preservedSpaceAttributeName: DOM.preservedSpaceAttributeName(this.options.sessionId) });
-				if (this.options.displayStats) {
-					this.stats.add("discarded", "htmlBytes", size - DOM.getContentSize(this.doc.documentElement.outerHTML));
-				}
+		compressHTML() {
+			let size;
+			if (this.options.displayStats) {
+				size = DOM.getContentSize(this.doc.documentElement.outerHTML);
+			}
+			DOM.minifyHTML(this.doc, { preservedSpaceAttributeName: DOM.preservedSpaceAttributeName(this.options.sessionId) });
+			if (this.options.displayStats) {
+				this.stats.add("discarded", "htmlBytes", size - DOM.getContentSize(this.doc.documentElement.outerHTML));
+			}
+		}
+
+		postCompressHTML() {
+			let size;
+			if (this.options.displayStats) {
+				size = DOM.getContentSize(this.doc.documentElement.outerHTML);
+			}
+			DOM.postMinifyHTML(this.doc);
+			if (this.options.displayStats) {
+				this.stats.add("discarded", "htmlBytes", size - DOM.getContentSize(this.doc.documentElement.outerHTML));
 			}
 		}
 
@@ -431,7 +439,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			});
 		}
 
-		insertSingleFileCommentNode() {
+		insertSingleFileComment() {
 			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);
 		}
@@ -522,46 +530,48 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		async frames(initialization) {
-			const frameElements = Array.from(this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"));
-			await Promise.all(frameElements.map(async frameElement => {
-				DomProcessorHelper.setFrameEmptySrc(frameElement);
-				frameElement.setAttribute("sandbox", "");
-				const frameWindowId = frameElement.getAttribute(DOM.windowIdAttributeName(this.options.sessionId));
-				if (frameWindowId) {
-					const frameData = this.options.framesData.find(frame => frame.windowId == frameWindowId);
-					if (frameData) {
-						if (initialization) {
-							const options = Object.create(this.options);
-							options.insertSingleFileComment = false;
-							options.insertFaviconLink = false;
-							options.doc = null;
-							options.win = null;
-							options.url = frameData.baseURI;
-							options.windowId = frameWindowId;
-							if (frameData.content) {
-								options.content = frameData.content;
-								options.canvasData = frameData.canvasData;
-								options.stylesheetContents = frameData.stylesheetContents;
-								frameData.processor = new PageProcessor(options);
-								frameData.frameElement = frameElement;
-								await frameData.processor.loadPage();
-								return frameData.processor.initialize();
-							}
-						} else {
-							if (frameData.processor) {
-								this.stats.add("processed", "frames", 1);
-								await frameData.processor.preparePageData();
-								const pageData = await frameData.processor.getPageData();
-								frameElement.removeAttribute(DOM.windowIdAttributeName(this.options.sessionId));
-								DomProcessorHelper.setFrameContent(frameElement, pageData.content);
-								this.stats.addAll(pageData);
+			if (this.options.framesData) {
+				const frameElements = Array.from(this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"));
+				await Promise.all(frameElements.map(async frameElement => {
+					DomProcessorHelper.setFrameEmptySrc(frameElement);
+					frameElement.setAttribute("sandbox", "");
+					const frameWindowId = frameElement.getAttribute(DOM.windowIdAttributeName(this.options.sessionId));
+					if (frameWindowId) {
+						const frameData = this.options.framesData.find(frame => frame.windowId == frameWindowId);
+						if (frameData) {
+							if (initialization) {
+								const options = Object.create(this.options);
+								options.insertSingleFileComment = false;
+								options.insertFaviconLink = false;
+								options.doc = null;
+								options.win = null;
+								options.url = frameData.baseURI;
+								options.windowId = frameWindowId;
+								if (frameData.content) {
+									options.content = frameData.content;
+									options.canvasData = frameData.canvasData;
+									options.stylesheetContents = frameData.stylesheetContents;
+									frameData.processor = new PageProcessor(options);
+									frameData.frameElement = frameElement;
+									await frameData.processor.loadPage();
+									return frameData.processor.initialize();
+								}
 							} else {
-								this.stats.add("discarded", "frames", 1);
+								if (frameData.processor) {
+									this.stats.add("processed", "frames", 1);
+									await frameData.processor.preparePageData();
+									const pageData = await frameData.processor.getPageData();
+									frameElement.removeAttribute(DOM.windowIdAttributeName(this.options.sessionId));
+									DomProcessorHelper.setFrameContent(frameElement, pageData.content);
+									this.stats.addAll(pageData);
+								} else {
+									this.stats.add("discarded", "frames", 1);
+								}
 							}
 						}
 					}
-				}
-			}));
+				}));
+			}
 		}
 
 		async htmlImports(initialization) {