Jelajahi Sumber

refactored code to have smaller functions

Gildas 7 tahun lalu
induk
melakukan
1606ba2df0
1 mengubah file dengan 65 tambahan dan 59 penghapusan
  1. 65 59
      lib/single-file/rules-matcher.js

+ 65 - 59
lib/single-file/rules-matcher.js

@@ -34,9 +34,9 @@ this.RulesMatcher = this.RulesMatcher || (() => {
 					if (styleElement.media && styleElement.media != MEDIA_ALL) {
 						const mediaInfo = createMediaInfo(styleElement.media);
 						this.mediaAllInfo.medias.set(styleElement.media, mediaInfo);
-						getMatchedElements(doc, styleElement.sheet.cssRules, mediaInfo, styleIndex);
+						getMatchedElementsRules(doc, styleElement.sheet.cssRules, mediaInfo, styleIndex);
 					} else {
-						getMatchedElements(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex);
+						getMatchedElementsRules(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex);
 					}
 				}
 			});
@@ -53,79 +53,58 @@ this.RulesMatcher = this.RulesMatcher || (() => {
 		}
 	};
 
-	function getMatchedElements(doc, cssRules, mediaInfo, sheetIndex) {
+	function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex) {
 		Array.from(cssRules).forEach((cssRule, ruleIndex) => {
 			if (cssRule.type == CSSRule.MEDIA_RULE) {
 				const ruleMediaInfo = createMediaInfo(cssRule.media);
 				mediaInfo.medias.set(cssRule.media, ruleMediaInfo);
-				getMatchedElements(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex);
+				getMatchedElementsRules(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex);
 			} else if (cssRule.type == CSSRule.STYLE_RULE) {
 				if (cssRule.selectorText) {
 					let selectors = cssWhat.parse(cssRule.selectorText);
 					const selectorsText = selectors.map(selector => cssWhat.stringify([selector]));
-					selectors.forEach((selector) => {
-						const selectorText = cssWhat.stringify([selector]);
-						const matchedElements = doc.querySelectorAll(selectorText);
-						if (matchedElements.length) {
-							matchedElements.forEach(element => {
-								let elementInfo;
-								if (mediaInfo.elements.has(element)) {
-									elementInfo = mediaInfo.elements.get(element);
-								} else {
-									elementInfo = [];
-									const elementStyle = element.getAttribute("style");
-									if (elementStyle) {
-										elementInfo.push({ cssStyle: element.style });
-									}
-									mediaInfo.elements.set(element, elementInfo);
-								}
-								const specificity = computeSpecificity(selector);
-								specificity.ruleIndex = ruleIndex;
-								specificity.sheetIndex = sheetIndex;
-								let ruleInfo = elementInfo.find(ruleInfo => ruleInfo.cssRule == cssRule);
-								if (ruleInfo) {
-									if (compareSpecificity(ruleInfo.specificity, specificity)) {
-										ruleInfo.specificity = specificity;
-										ruleInfo.selectorText = selectorText;
-									}
-								} else {
-									ruleInfo = { cssRule, specificity, selectorText, selectorsText };
-									elementInfo.push(ruleInfo);
-								}
-							});
-						}
-					});
+					selectors.forEach(selector => getMatchedElementsSelector(doc, cssRule, selector, selectorsText, mediaInfo, ruleIndex, sheetIndex));
 				}
 			}
 		});
 	}
 
-	function computeCascade(mediaInfo, parentMediaInfos = []) {
-		mediaInfo.elements.forEach((elementInfo) => {
-			const elementStylesInfo = new Map();
-			elementInfo.forEach(ruleInfo => {
-				if (ruleInfo.cssStyle) {
-					const cssStyle = ruleInfo.cssStyle;
-					const stylesInfo = parseCss.parseAListOfDeclarations(cssStyle.cssText);
-					stylesInfo.forEach(styleInfo => {
-						const important = cssStyle.getPropertyPriority(styleInfo.name) == PRIORITY_IMPORTANT;
-						const styleValue = cssStyle.getPropertyValue(styleInfo.name) + (important ? " !" + PRIORITY_IMPORTANT : "");
-						elementStylesInfo.set(styleInfo.name, { styleValue, cssStyle: ruleInfo.cssStyle });
-					});
+	function getMatchedElementsSelector(doc, cssRule, selector, selectorsText, mediaInfo, ruleIndex, sheetIndex) {
+		const selectorText = cssWhat.stringify([selector]);
+		const matchedElements = doc.querySelectorAll(selectorText);
+		if (matchedElements.length) {
+			matchedElements.forEach(element => {
+				let elementInfo;
+				if (mediaInfo.elements.has(element)) {
+					elementInfo = mediaInfo.elements.get(element);
+				} else {
+					elementInfo = [];
+					const elementStyle = element.getAttribute("style");
+					if (elementStyle) {
+						elementInfo.push({ cssStyle: element.style });
+					}
+					mediaInfo.elements.set(element, elementInfo);
+				}
+				const specificity = computeSpecificity(selector);
+				specificity.ruleIndex = ruleIndex;
+				specificity.sheetIndex = sheetIndex;
+				let ruleInfo = elementInfo.find(ruleInfo => ruleInfo.cssRule == cssRule);
+				if (ruleInfo) {
+					if (compareSpecificity(ruleInfo.specificity, specificity)) {
+						ruleInfo.specificity = specificity;
+						ruleInfo.selectorText = selectorText;
+					}
 				} else {
-					const cssStyle = ruleInfo.cssRule.style;
-					const stylesInfo = parseCss.parseAListOfDeclarations(cssStyle.cssText);
-					stylesInfo.forEach(styleInfo => {
-						const important = cssStyle.getPropertyPriority(styleInfo.name) == PRIORITY_IMPORTANT;
-						const styleValue = cssStyle.getPropertyValue(styleInfo.name) + (important ? " !" + PRIORITY_IMPORTANT : "");
-						let elementStyleInfo = elementStylesInfo.get(styleInfo.name);
-						if (!elementStyleInfo || (important && !elementStyleInfo.important)) {
-							elementStylesInfo.set(styleInfo.name, { styleValue, cssRule: ruleInfo.cssRule, selectorText: ruleInfo.selectorText, selectorsText: ruleInfo.selectorsText });
-						}
-					});
+					ruleInfo = { cssRule, specificity, selectorText, selectorsText };
+					elementInfo.push(ruleInfo);
 				}
 			});
-			elementStylesInfo.forEach((elementStyleInfo, styleName) => {
+		}
+	}
+
+	function computeCascade(mediaInfo, parentMediaInfos = []) {
+		mediaInfo.elements.forEach((elementInfo) => {
+			getStylesInfo(elementInfo).forEach((elementStyleInfo, styleName) => {
 				let ruleInfo, ascendantMedia, allMedia;
 				if (elementStyleInfo.cssRule) {
 					ascendantMedia = [mediaInfo, ...parentMediaInfos].find(media => media.rules.get(elementStyleInfo.cssRule)) || mediaInfo;
@@ -153,6 +132,33 @@ this.RulesMatcher = this.RulesMatcher || (() => {
 		mediaInfo.medias.forEach(childMediaInfo => computeCascade(childMediaInfo, [mediaInfo, ...parentMediaInfos]));
 	}
 
+	function getStylesInfo(elementInfo) {
+		const elementStylesInfo = new Map();
+		elementInfo.forEach(ruleInfo => {
+			if (ruleInfo.cssStyle) {
+				const cssStyle = ruleInfo.cssStyle;
+				const stylesInfo = parseCss.parseAListOfDeclarations(cssStyle.cssText);
+				stylesInfo.forEach(styleInfo => {
+					const important = cssStyle.getPropertyPriority(styleInfo.name) == PRIORITY_IMPORTANT;
+					const styleValue = cssStyle.getPropertyValue(styleInfo.name) + (important ? " !" + PRIORITY_IMPORTANT : "");
+					elementStylesInfo.set(styleInfo.name, { styleValue, cssStyle: ruleInfo.cssStyle });
+				});
+			} else {
+				const cssStyle = ruleInfo.cssRule.style;
+				const stylesInfo = parseCss.parseAListOfDeclarations(cssStyle.cssText);
+				stylesInfo.forEach(styleInfo => {
+					const important = cssStyle.getPropertyPriority(styleInfo.name) == PRIORITY_IMPORTANT;
+					const styleValue = cssStyle.getPropertyValue(styleInfo.name) + (important ? " !" + PRIORITY_IMPORTANT : "");
+					let elementStyleInfo = elementStylesInfo.get(styleInfo.name);
+					if (!elementStyleInfo || (important && !elementStyleInfo.important)) {
+						elementStylesInfo.set(styleInfo.name, { styleValue, cssRule: ruleInfo.cssRule, selectorText: ruleInfo.selectorText, selectorsText: ruleInfo.selectorsText });
+					}
+				});
+			}
+		});
+		return elementStylesInfo;
+	}
+
 	function createMediaInfo(media) {
 		const mediaInfo = { media: media, elements: new Map(), medias: new Map(), rules: new Map() };
 		if (media == MEDIA_ALL) {