Procházet zdrojové kódy

made CSS rules walking more tolerant to faults

Gildas před 7 roky
rodič
revize
13866de75a

+ 16 - 14
lib/single-file/css-fonts-minifier.js

@@ -214,7 +214,7 @@ this.fontsMinifier = this.fontsMinifier || (() => {
 		const removedRules = [];
 		for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
 			const ruleData = cssRule.data;
-			if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.prelude) {
+			if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.prelude && ruleData.prelude.children) {
 				const mediaText = cssTree.generate(ruleData.prelude);
 				processFontFaceRules(ruleData.block.children, fontsDetails, mediaText, stats);
 			} else if (ruleData.type == "Atrule" && ruleData.name == "font-face" && (media.includes("all") || media.includes("screen"))) {
@@ -379,19 +379,21 @@ this.fontsMinifier = this.fontsMinifier || (() => {
 
 	function getPseudoElementsContent(doc, cssRules) {
 		return cssRules.toArray().map(cssRule => {
-			if (cssRule.type == "Atrule" && cssRule.name == "media" && cssRule.block) {
-				return getPseudoElementsContent(doc, cssRule.block.children);
-			} else if (cssRule.type == "Rule") {
-				const selector = cssTree.generate(cssRule.prelude); // TODO use OM
-				if (testPseudoElements(selector)) {
-					const value = docHelper.removeQuotes(getPropertyValue(cssRule, "content") || "");
-					if (value) {
-						const styleElement = doc.createElement("style");
-						styleElement.textContent = "tmp { content:\"" + value + "\"}";
-						doc.documentElement.appendChild(styleElement);
-						let content = docHelper.removeQuotes(styleElement.sheet.cssRules[0].style.getPropertyValue("content"));
-						styleElement.remove();
-						return content;
+			if (cssRule.block && cssRule.block.children && cssRule.prelude && cssRule.prelude.children) {
+				if (cssRule.type == "Atrule" && cssRule.name == "media") {
+					return getPseudoElementsContent(doc, cssRule.block.children);
+				} else if (cssRule.type == "Rule") {
+					const selector = cssTree.generate(cssRule.prelude); // TODO use OM
+					if (testPseudoElements(selector)) {
+						const value = docHelper.removeQuotes(getPropertyValue(cssRule, "content") || "");
+						if (value) {
+							const styleElement = doc.createElement("style");
+							styleElement.textContent = "tmp { content:\"" + value + "\"}";
+							doc.documentElement.appendChild(styleElement);
+							let content = docHelper.removeQuotes(styleElement.sheet.cssRules[0].style.getPropertyValue("content"));
+							styleElement.remove();
+							return content;
+						}
 					}
 				}
 			}

+ 17 - 15
lib/single-file/css-matched-rules.js

@@ -87,21 +87,23 @@ this.matchedRules = this.matchedRules || (() => {
 			log("  -- STARTED getMatchedElementsRules", " index =", sheetIndex, "rules.length =", cssRules.length);
 		}
 		cssRules.forEach(cssRule => {
-			if (cssRule.type == "Atrule" && cssRule.name == "media" && cssRule.prelude && cssRule.block) {
-				const mediaText = cssTree.generate(cssRule.prelude);
-				const ruleMediaInfo = createMediaInfo(mediaText);
-				mediaInfo.medias.set("rule-" + sheetIndex + "-" + mediaIndex + "-" + mediaText, ruleMediaInfo);
-				mediaIndex++;
-				getMatchedElementsRules(doc, cssRule.block.children, ruleMediaInfo, sheetIndex, docStyle, matchedElementsCache);
-			} else if (cssRule.type == "Rule" && cssRule.prelude.children) {
-				const selectors = cssRule.prelude.children.toArray();
-				const selectorsText = cssRule.prelude.children.toArray().map(selector => cssTree.generate(selector));
-				const ruleInfo = { cssRule, mediaInfo, ruleIndex, sheetIndex, matchedSelectors: new Set(), style: new Map(), selectors, selectorsText };
-				ruleIndex++;
-				for (let selector = cssRule.prelude.children.head, selectorIndex = 0; selector; selector = selector.next, selectorIndex++) {
-					const selectorText = selectorsText[selectorIndex];
-					const selectorInfo = { selector, selectorText, ruleInfo };
-					getMatchedElementsSelector(doc, selectorInfo, docStyle, matchedElementsCache);
+			if (cssRule.block && cssRule.block.children && cssRule.prelude && cssRule.prelude.children) {
+				if (cssRule.type == "Atrule" && cssRule.name == "media") {
+					const mediaText = cssTree.generate(cssRule.prelude);
+					const ruleMediaInfo = createMediaInfo(mediaText);
+					mediaInfo.medias.set("rule-" + sheetIndex + "-" + mediaIndex + "-" + mediaText, ruleMediaInfo);
+					mediaIndex++;
+					getMatchedElementsRules(doc, cssRule.block.children, ruleMediaInfo, sheetIndex, docStyle, matchedElementsCache);
+				} else if (cssRule.type == "Rule" && cssRule.prelude.children) {
+					const selectors = cssRule.prelude.children.toArray();
+					const selectorsText = cssRule.prelude.children.toArray().map(selector => cssTree.generate(selector));
+					const ruleInfo = { cssRule, mediaInfo, ruleIndex, sheetIndex, matchedSelectors: new Set(), style: new Map(), selectors, selectorsText };
+					ruleIndex++;
+					for (let selector = cssRule.prelude.children.head, selectorIndex = 0; selector; selector = selector.next, selectorIndex++) {
+						const selectorText = selectorsText[selectorIndex];
+						const selectorInfo = { selector, selectorText, ruleInfo };
+						getMatchedElementsSelector(doc, selectorInfo, docStyle, matchedElementsCache);
+					}
 				}
 			}
 		});

+ 1 - 1
lib/single-file/css-medias-minifier.js

@@ -41,7 +41,7 @@ this.mediasMinifier = this.mediasMinifier || (() => {
 	function processRules(cssRules, stats, removedRules = []) {
 		for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
 			const cssRuleData = cssRule.data;
-			if (cssRuleData.type == "Atrule" && cssRuleData.name == "media" && cssRuleData.block && cssRuleData.prelude) {
+			if (cssRuleData.type == "Atrule" && cssRuleData.name == "media" && cssRuleData.block && cssRuleData.block.children && cssRuleData.prelude && cssRuleData.prelude.children) {
 				stats.processed++;
 				if (matchesMediaType(cssTree.generate(cssRuleData.prelude), "screen")) {
 					processRules(cssRuleData.block.children, stats, removedRules);

+ 15 - 13
lib/single-file/css-rules-minifier.js

@@ -64,22 +64,24 @@ this.cssRulesMinifier = this.cssRulesMinifier || (() => {
 		const removedCssRules = [];
 		for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
 			const cssRuleData = cssRule.data;
-			if (cssRuleData.type == "Atrule" && cssRuleData.name == "media" && cssRuleData.block && cssRuleData.prelude) {
-				const mediaText = cssTree.generate(cssRuleData.prelude);
-				processRules(cssRuleData.block.children, sheetIndex, mediaInfo.medias.get("rule-" + sheetIndex + "-" + mediaRuleIndex + "-" + mediaText));
-				if (!cssRuleData.prelude.children.getSize() || !cssRuleData.block.children.getSize()) {
-					removedCssRules.push(cssRule);
-				}
-				mediaRuleIndex++;
-			} else if (cssRuleData.type == "Rule") {
-				const ruleInfo = mediaInfo.rules.get(cssRuleData);
-				if (!ruleInfo && !mediaInfo.pseudoSelectors.has(cssRuleData)) {
-					removedCssRules.push(cssRule);
-				} else if (ruleInfo) {
-					processRuleInfo(cssRuleData, ruleInfo);
+			if (cssRuleData.block && cssRuleData.block.children && cssRuleData.prelude && cssRuleData.prelude.children) {
+				if (cssRuleData.type == "Atrule" && cssRuleData.name == "media") {
+					const mediaText = cssTree.generate(cssRuleData.prelude);
+					processRules(cssRuleData.block.children, sheetIndex, mediaInfo.medias.get("rule-" + sheetIndex + "-" + mediaRuleIndex + "-" + mediaText));
 					if (!cssRuleData.prelude.children.getSize() || !cssRuleData.block.children.getSize()) {
 						removedCssRules.push(cssRule);
 					}
+					mediaRuleIndex++;
+				} else if (cssRuleData.type == "Rule") {
+					const ruleInfo = mediaInfo.rules.get(cssRuleData);
+					if (!ruleInfo && !mediaInfo.pseudoSelectors.has(cssRuleData)) {
+						removedCssRules.push(cssRule);
+					} else if (ruleInfo) {
+						processRuleInfo(cssRuleData, ruleInfo);
+						if (!cssRuleData.prelude.children.getSize() || !cssRuleData.block.children.getSize()) {
+							removedCssRules.push(cssRule);
+						}
+					}
 				}
 			}
 		}