Pārlūkot izejas kodu

don't handle web components as separate documents

Gildas 6 gadi atpakaļ
vecāks
revīzija
690ec3d5c6

+ 1 - 1
lib/single-file/modules/css-matched-rules.js

@@ -45,7 +45,7 @@ this.matchedRules = this.matchedRules || (() => {
 						const mediaInfo = createMediaInfo(stylesheetInfo.mediaText);
 						this.mediaAllInfo.medias.set("style-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaInfo);
 						getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, styles, matchedElementsCache, workStyleElement);
-					} else {
+					} else if (!stylesheetInfo.scoped) {
 						getMatchedElementsRules(doc, cssRules, this.mediaAllInfo, sheetIndex, styles, matchedElementsCache, workStyleElement);
 					}
 				}

+ 3 - 1
lib/single-file/modules/css-rules-minifier.js

@@ -45,7 +45,9 @@ this.cssRulesMinifier = this.cssRulesMinifier || (() => {
 						if (cssRules) {
 							stats.processed += cssRules.getSize();
 							stats.discarded += cssRules.getSize();
-							processRules(cssRules, sheetIndex, mediaInfo);
+							if (!stylesheetInfo.scoped) {
+								processRules(cssRules, sheetIndex, mediaInfo);
+							}
 							stats.discarded -= cssRules.getSize();
 						}
 						sheetIndex++;

+ 40 - 87
lib/single-file/single-file-core.js

@@ -99,13 +99,13 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			{ option: "insertFaviconLink", action: "insertFaviconLink" },
 			{ action: "replaceCanvasElements" },
 			{ action: "insertFonts" },
+			{ action: "insertShadowRootContents" },
 			{ option: "removeHiddenElements", action: "removeHiddenElements" },
 			{ action: "resolveHrefs" },
 			{ action: "resolveStyleAttributeURLs" }
 		],
 		parallel: [
 			{ action: "resolveStylesheetURLs" },
-			{ action: "resolveShadowRootURLs" },
 			{ option: "!removeFrames", action: "resolveFrameURLs" },
 			{ option: "!removeImports", action: "resolveHtmlImportURLs" }
 		]
@@ -128,7 +128,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 		],
 		parallel: [
 			{ option: "!removeFrames", action: "processFrames" },
-			{ action: "processShadowRoots" },
 			{ option: "!removeImports", action: "processHtmlImports" },
 		]
 	}, {
@@ -804,7 +803,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 					if (element.media) {
 						mediaText = element.media.toLowerCase();
 					}
-					this.stylesheets.set(element, { mediaText });
+					const stylesheetInfo = { mediaText };
+					this.stylesheets.set(element, stylesheetInfo);
+					if (element.closest("[" + WC_ATTRIBUTE_NAME + "]")) {
+						stylesheetInfo.scoped = true;
+					}
 					const options = { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled, url: this.options.url, charset: this.charset, compressCSS: this.options.compressCSS };
 					let stylesheetContent;
 					if (element.tagName.toLowerCase() == "link") {
@@ -825,7 +828,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 						if (this.options.compressCSS) {
 							ProcessorHelper.removeSingleLineCssComments(stylesheet);
 						}
-						this.stylesheets.get(element).stylesheet = stylesheet;
+						stylesheetInfo.stylesheet = stylesheet;
 					} else {
 						this.stylesheets.delete(element);
 					}
@@ -877,44 +880,44 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}
 		}
 
-		async resolveShadowRootURLs() {
-			const rootOptions = this.options;
-			const batchRequest = this.batchRequest;
+		insertShadowRootContents() {
+			const doc = this.doc;
+			const options = this.options;
 			if (this.options.shadowRootsData && this.options.shadowRootsData.length) {
-				await resolveURLs(this.doc);
+				processElement(this.doc);
+				const scriptElement = doc.createElement("script");
+				scriptElement.setAttribute(WC_ATTRIBUTE_NAME, "");
+				scriptElement.textContent = `(()=>{processNode(document);function processNode(node){node.querySelectorAll("template[${WC_ATTRIBUTE_NAME}]").forEach(element=>{const shadowRoot=element.parentElement.attachShadow({mode:"open"});shadowRoot.innerHTML=element.innerHTML;element.remove();processNode(shadowRoot)})}})()`;
+				doc.body.appendChild(scriptElement);
 			}
 
-			async function resolveURLs(rootElement) {
-				const shadowRootElements = Array.from((rootElement.querySelectorAll("[" + docUtil.SHADOW_ROOT_ATTRIBUTE_NAME + "]")));
-				await Promise.all(shadowRootElements.map(async element => {
+			function processElement(element) {
+				const shadowRootElements = Array.from((element.querySelectorAll("[" + docUtil.SHADOW_ROOT_ATTRIBUTE_NAME + "]")));
+				shadowRootElements.forEach(element => {
 					const id = element.getAttribute(docUtil.SHADOW_ROOT_ATTRIBUTE_NAME);
-					const shadowRootData = rootOptions.shadowRootsData[Number(id)];
-					const options = Object.create(rootOptions);
-					options.insertSingleFileComment = false;
-					options.insertFaviconLink = false;
-					options.doc = null;
-					options.win = null;
-					options.url = options.baseURI = rootOptions.url;
-					if (shadowRootData.content) {
-						const doc = docUtil.parseDocContent(shadowRootData.content);
-						const docData = docUtil.preProcessDoc(doc, options.win, options);
-						options.content = docUtil.serialize(doc);
-						docUtil.postProcessDoc(doc, options);
-						options.postersData = docData.postersData;
-						options.canvasData = docData.canvasData;
-						options.stylesheetsData = docData.stylesheetsData;
-						options.fontsData = docData.fontsData;
-						options.imageData = docData.imageData;
-						options.usedFonts = docData.usedFonts;
-						options.shadowRootsData = docData.shadowRootsData;
-						shadowRootData.processor = new Runner(options);
-						shadowRootData.element = element;
-						await shadowRootData.processor.loadPage();
-						await shadowRootData.processor.initialize();
-						shadowRootData.maxResources = batchRequest.getMaxResources();
-						await resolveURLs(shadowRootData.processor.getDocument());
+					const shadowRootData = options.shadowRootsData[Number(id)];
+					if (shadowRootData) {
+						const templateElement = doc.createElement("template");
+						templateElement.setAttribute(WC_ATTRIBUTE_NAME, "");
+						const shadowDoc = docUtil.parseDocContent(shadowRootData.content);
+						if (shadowDoc.head) {
+							const metaCharset = shadowDoc.head.querySelector("meta[charset]");
+							if (metaCharset) {
+								metaCharset.remove();
+							}
+							shadowDoc.head.childNodes.forEach(node => templateElement.appendChild(shadowDoc.importNode(node, true)));
+						}
+						if (shadowDoc.body) {
+							shadowDoc.body.childNodes.forEach(node => templateElement.appendChild(shadowDoc.importNode(node, true)));
+						}
+						processElement(templateElement);
+						if (element.firstChild) {
+							element.insertBefore(templateElement, element.firstChild);
+						} else {
+							element.appendChild(templateElement);
+						}
 					}
-				}));
+				});
 			}
 		}
 
@@ -1065,56 +1068,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}
 		}
 
-		async processShadowRoots() {
-			const rootDoc = this.doc;
-			const options = this.options;
-			const stats = this.stats;
-			if (this.options.shadowRootsData && this.options.shadowRootsData.length) {
-				await processRootElement(this.doc);
-				const scriptElement = rootDoc.createElement("script");
-				scriptElement.textContent = `(()=>{processNode(document);function processNode(node){node.querySelectorAll("[${WC_ATTRIBUTE_NAME}]").forEach(element=>{const shadowRoot=element.parentElement.attachShadow({mode:"open"});shadowRoot.innerHTML=element.innerHTML;element.remove();processNode(shadowRoot)})}})()`;
-				this.doc.body.appendChild(scriptElement);
-			}
-
-			async function processRootElement(rootElement) {
-				const shadowRootElements = Array.from(rootElement.querySelectorAll("[" + docUtil.SHADOW_ROOT_ATTRIBUTE_NAME + "]"));
-				await Promise.all(shadowRootElements.map(async element => {
-					const id = element.getAttribute(docUtil.SHADOW_ROOT_ATTRIBUTE_NAME);
-					if (id) {
-						const shadowRootData = options.shadowRootsData[Number(id)];
-						if (shadowRootData) {
-							options.shadowRootsData = options.shadowRootsData.filter(shadowRootData => shadowRootData.id != id);
-							if (shadowRootData.processor) {
-								stats.add("processed", "shadow root elements", 1);
-								await shadowRootData.processor.run();
-								const doc = shadowRootData.processor.getDocument();
-								const templateElement = rootDoc.createElement("template");
-								templateElement.setAttribute(WC_ATTRIBUTE_NAME, "");
-								if (doc.head) {
-									const metaCharset = doc.head.querySelector("meta[charset]");
-									if (metaCharset) {
-										metaCharset.remove();
-									}
-									doc.head.childNodes.forEach(node => templateElement.appendChild(doc.importNode(node, true)));
-								}
-								if (doc.body) {
-									doc.body.childNodes.forEach(node => templateElement.appendChild(doc.importNode(node, true)));
-								}
-								await processRootElement(templateElement);
-								if (element.firstChild) {
-									element.insertBefore(templateElement, element.firstChild);
-								} else {
-									element.appendChild(templateElement);
-								}
-							} else {
-								stats.add("discarded", "shadow root elements", 1);
-							}
-						}
-					}
-				}));
-			}
-		}
-
 		async processHtmlImports() {
 			const linkElements = Array.from(this.doc.querySelectorAll("link[rel=import][href]"));
 			await Promise.all(linkElements.map(async linkElement => {