Quellcode durchsuchen

refactored DOM class

Gildas vor 7 Jahren
Ursprung
Commit
e70ba07b54
2 geänderte Dateien mit 52 neuen und 38 gelöschten Zeilen
  1. 35 16
      lib/single-file/single-file-browser.js
  2. 17 22
      lib/single-file/single-file-core.js

+ 35 - 16
lib/single-file/single-file-browser.js

@@ -84,7 +84,7 @@ this.SingleFile = this.SingleFile || (() => {
 	// DOM
 	// ---
 	class DOM {
-		static create(pageContent, baseURI) {
+		static createDoc(pageContent, baseURI) {
 			const doc = (new DOMParser()).parseFromString(pageContent, "text/html");
 			let baseElement = doc.querySelector("base");
 			if (!baseElement || !baseElement.getAttribute("href")) {
@@ -95,22 +95,41 @@ this.SingleFile = this.SingleFile || (() => {
 				baseElement.setAttribute("href", baseURI);
 				doc.head.insertBefore(baseElement, doc.head.firstChild);
 			}
-			return {
-				DOMParser,
-				document: doc,
-				parseSrcset: srcset => parseSrcset.process(srcset),
-				uglifycss: (content, options) => uglifycss.processString(content, options),
-				lazyLoader: {
-					process: doc => lazyLoader.process(doc),
-					imageSelectors: lazyLoader.imageSelectors
-				},
-				htmlmini: {
-					process: (doc, options) => htmlmini.process(doc, options),
-					postProcess: doc => htmlmini.postProcess(doc),
-				},
-				rulesMinifier: doc => rulesMinifier.process(doc)
-			};
+			return doc;
 		}
+
+		static getParser() {
+			return DOMParser;
+		}
+
+		static htmlminiProcess(doc, options) {
+			return htmlmini.process(doc, options);
+		}
+
+		static htmlminiPostProcess(doc) {
+			return htmlmini.postProcess(doc);
+		}
+
+		static lazyLoader(doc) {
+			return lazyLoader.process(doc);
+		}
+
+		static lazyLoaderImageSelectors() {
+			return lazyLoader.imageSelectors;
+		}
+
+		static rulesMinifier(doc) {
+			return rulesMinifier.process(doc);
+		}
+
+		static uglifycss(content, options) {
+			return uglifycss.processString(content, options);
+		}
+
+		static parseSrcset(srcset) {
+			return parseSrcset.process(srcset);
+		}
+
 		static serialize(doc, compressHTML) {
 			return serializer.process(doc, compressHTML);
 		}

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

@@ -89,7 +89,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 					this.processor.markPreservedElements();
 				}
 			}
-			this.options.content = this.options.content || (this.options.doc ? DOMProcessor.serialize(this.options.doc, false) : null);
+			this.options.content = this.options.content || (this.options.doc ? DOM.serialize(this.options.doc, false) : null);
 			this.onprogress = options.onprogress || (() => { });
 		}
 
@@ -277,17 +277,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			this.baseURI = options.url;
 		}
 
-		static serialize(doc, compressHTML) {
-			return DOM.serialize(doc, compressHTML);
-		}
-
 		async loadPage(pageContent) {
 			if (!pageContent || this.options.saveRawPage) {
 				pageContent = await Download.getContent(this.baseURI, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
 			}
-			this.dom = DOM.create(pageContent, this.baseURI);
-			this.DOMParser = this.dom.DOMParser;
-			this.doc = this.dom.document;
+			this.doc = DOM.createDoc(pageContent, this.baseURI);
 			if (!pageContent && this.doc.querySelector("meta[name=fragment][content=\"!\"]") && !this.baseURI.endsWith("?" + ESCAPED_FRAGMENT) && !this.baseURI.endsWith("&" + ESCAPED_FRAGMENT)) {
 				await DOMProcessor.loadEscapedFragmentPage();
 			}
@@ -329,7 +323,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			if (this.options.displayStats) {
 				size = new Blob([this.doc.documentElement.outerHTML]).size;
 			}
-			const content = DOMProcessor.serialize(this.doc, this.options.compressHTML);
+			const content = DOM.serialize(this.doc, this.options.compressHTML);
 			if (this.options.displayStats) {
 				this.stats.processed.htmlBytes = new Blob([content]).size;
 				this.stats.discarded.htmlBytes += size - this.stats.processed.htmlBytes;
@@ -423,11 +417,12 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		insertNoscriptContents() {
-			if (this.DOMParser) {
+			const DOMParser = DOM.getParser();
+			if (DOMParser) {
 				this.doc.querySelectorAll("noscript").forEach(element => {
 					const fragment = this.doc.createDocumentFragment();
 					Array.from(element.childNodes).forEach(node => {
-						const parsedNode = new this.DOMParser().parseFromString(node.nodeValue, "text/html");
+						const parsedNode = new DOMParser().parseFromString(node.nodeValue, "text/html");
 						Array.from(parsedNode.head.childNodes).concat(Array.from(parsedNode.body.childNodes)).forEach(node => {
 							this.doc.importNode(node);
 							fragment.appendChild(node);
@@ -439,7 +434,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		lazyLoadImages() {
-			this.dom.lazyLoader.process(this.doc);
+			DOM.lazyLoader(this.doc);
 		}
 
 		removeDiscardedResources() {
@@ -529,7 +524,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		}
 
 		removeUnusedCSSRules() {
-			const stats = this.dom.rulesMinifier(this.doc);
+			const stats = DOM.rulesMinifier(this.doc);
 			if (this.options.displayStats) {
 				this.stats.processed.cssRules = stats.processed;
 				this.stats.discarded.cssRules = stats.discarded;
@@ -550,7 +545,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				if (this.options.displayStats) {
 					size = new Blob([this.doc.documentElement.outerHTML]).size;
 				}
-				this.dom.htmlmini.postProcess(this.doc);
+				DOM.htmlminiPostProcess(this.doc);
 				if (this.options.displayStats) {
 					this.stats.discarded.htmlBytes += size - (new Blob([this.doc.documentElement.outerHTML]).size);
 				}
@@ -559,7 +554,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				if (this.options.displayStats) {
 					size = new Blob([this.doc.documentElement.outerHTML]).size;
 				}
-				this.dom.htmlmini.process(this.doc, { preservedSpaceAttributeName: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME });
+				DOM.htmlminiProcess(this.doc, { preservedSpaceAttributeName: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME });
 				if (this.options.displayStats) {
 					this.stats.discarded.htmlBytes += size - (new Blob([this.doc.documentElement.outerHTML]).size);
 				}
@@ -618,7 +613,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image, use"), "xlink:href", this.baseURI),
-				DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI, this.dom.parseSrcset)
+				DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI)
 			];
 			if (!this.options.removeAudioSrc) {
 				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", this.baseURI));
@@ -627,9 +622,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", this.baseURI));
 			}
 			if (this.options.lazyLoadImages) {
-				const imageSelectors = this.dom.lazyLoader.imageSelectors;
+				const imageSelectors = DOM.lazyLoaderImageSelectors();
 				Object.keys(imageSelectors.src).forEach(selector => resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), imageSelectors.src[selector], this.baseURI)));
-				Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI, this.dom.parseSrcset)));
+				Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI)));
 			}
 			await resourcePromises;
 		}
@@ -640,7 +635,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 					this.stats.processed.styleSheets++;
 				}
 				const stylesheetContent = initialization ? await DomProcessorHelper.resolveImportURLs(styleElement.textContent, this.baseURI, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled }) : await DomProcessorHelper.processStylesheet(styleElement.textContent, this.baseURI);
-				styleElement.textContent = !initialization && this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
+				styleElement.textContent = !initialization && this.options.compressCSS ? DOM.uglifycss(stylesheetContent) : stylesheetContent;
 			}));
 		}
 
@@ -747,7 +742,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		async attributeStyles(initialization) {
 			await Promise.all(Array.from(this.doc.querySelectorAll("[style]")).map(async element => {
 				const stylesheetContent = initialization ? await DomProcessorHelper.resolveImportURLs(element.getAttribute("style"), this.baseURI, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled }) : await DomProcessorHelper.processStylesheet(element.getAttribute("style"), this.baseURI);
-				element.setAttribute("style", this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent);
+				element.setAttribute("style", this.options.compressCSS ? DOM.uglifycss(stylesheetContent) : stylesheetContent);
 			}));
 		}
 
@@ -884,9 +879,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}));
 		}
 
-		static async processSrcset(resourceElements, attributeName, baseURI, parseSrcset) {
+		static async processSrcset(resourceElements, attributeName, baseURI) {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
-				const srcset = parseSrcset(resourceElement.getAttribute(attributeName));
+				const srcset = DOM.parseSrcset(resourceElement.getAttribute(attributeName));
 				const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
 					const resourceURL = DomUtil.normalizeURL(srcsetValue.url);
 					if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {