Explorar o código

remove duplicate declarations

Gildas %!s(int64=7) %!d(string=hai) anos
pai
achega
28df3e0e7e
Modificáronse 2 ficheiros con 30 adicións e 29 borrados
  1. 27 26
      lib/single-file/css-matched-rules.js
  2. 3 3
      lib/single-file/css-rules-minifier.js

+ 27 - 26
lib/single-file/css-matched-rules.js

@@ -232,28 +232,28 @@ this.matchedRules = this.matchedRules || (() => {
 	}
 
 	function computeCascade(mediaInfo, parentMediaInfo, mediaAllInfo, stylesheet) {
-		mediaInfo.elements.forEach((elementInfo, element) => getStylesInfo(elementInfo, stylesheet, element).forEach((elementStyleInfo, styleName) => {
-			if (elementStyleInfo.selectorInfo.ruleInfo || mediaInfo == mediaAllInfo) {
+		mediaInfo.elements.forEach((elementInfo, element) => getStylesInfo(elementInfo, stylesheet, element).forEach((declarations, property) => {
+			if (declarations.selectorInfo.ruleInfo || mediaInfo == mediaAllInfo) {
 				let info;
-				if (elementStyleInfo.selectorInfo.ruleInfo) {
-					info = elementStyleInfo.selectorInfo.ruleInfo;
+				if (declarations.selectorInfo.ruleInfo) {
+					info = declarations.selectorInfo.ruleInfo;
 					const cssRule = info.cssRule;
 					const ascendantMedia = [mediaInfo, ...parentMediaInfo].find(media => media.rules.get(cssRule)) || mediaInfo;
 					ascendantMedia.rules.set(cssRule, info);
 					if (cssRule) {
-						info.matchedSelectors.add(elementStyleInfo.selectorInfo.selectorText);
+						info.matchedSelectors.add(declarations.selectorInfo.selectorText);
 					}
 				} else {
-					info = elementStyleInfo.selectorInfo.styleInfo;
+					info = declarations.selectorInfo.styleInfo;
 					const cssStyle = info.cssStyle;
 					const matchedStyleInfo = mediaAllInfo.matchedStyles.get(cssStyle);
 					if (!matchedStyleInfo) {
 						mediaAllInfo.matchedStyles.set(cssStyle, info);
 					}
 				}
-				const styleValue = info.style.get(styleName);
+				const styleValue = info.style.get(property);
 				if (!styleValue) {
-					info.style.set(styleName, elementStyleInfo.styleValue);
+					info.style.set(property, declarations.styleValue);
 				}
 			}
 		}));
@@ -262,29 +262,30 @@ this.matchedRules = this.matchedRules || (() => {
 	}
 
 	function getStylesInfo(elementInfo, stylesheet/*, element */) {
-		const elementStylesInfo = new Map();
+		const stylesInfo = new Map();
 		elementInfo.forEach(selectorInfo => {
 			if (selectorInfo.styleInfo) {
-				const cssStyle = selectorInfo.styleInfo.cssStyle;
-				cssStyle.children.forEach(declaration => {
-					if (declaration.type == "Declaration" && !invalidDeclaration(cssTree.generate(declaration), stylesheet)) {
-						const styleValue = cssTree.generate(declaration);
-						elementStylesInfo.set(declaration.property, { selectorInfo, styleValue, important: declaration.important });
-					}
-				});
+				processDeclarations(selectorInfo.styleInfo.cssStyle.children, selectorInfo);
 			} else {
-				selectorInfo.ruleInfo.cssRule.block.children.forEach(declaration => {
-					if (declaration.type == "Declaration" && !invalidDeclaration(cssTree.generate(declaration), stylesheet)) {
-						const styleValue = cssTree.generate(declaration.value);
-						const elementStyleInfo = elementStylesInfo.get(declaration.property);
-						if (styleValue.trim() && (!elementStyleInfo || (declaration.important && !elementStyleInfo.important))) {
-							elementStylesInfo.set(declaration.property, { selectorInfo, styleValue, important: declaration.important });
-						}
-					}
-				});
+				processDeclarations(selectorInfo.ruleInfo.cssRule.block.children, selectorInfo);
 			}
 		});
-		return elementStylesInfo;
+		return stylesInfo;
+
+		function processDeclarations(declarations, selectorInfo) {
+			const processedProperties = new Set();
+			for (let declaration = declarations.tail; declaration; declaration = declaration.prev) {
+				const declarationData = declaration.data;
+				if (declarationData.type == "Declaration" && !processedProperties.has(declarationData.property) && !invalidDeclaration(cssTree.generate(declarationData), stylesheet)) {
+					const styleValue = cssTree.generate(declarationData.value);
+					const elementStyleInfo = stylesInfo.get(declarationData);
+					if (styleValue.trim() && (!elementStyleInfo || (declarationData.important && !elementStyleInfo.important))) {
+						stylesInfo.set(declarationData, { selectorInfo, styleValue, important: declarationData.important });
+						processedProperties.add(declarationData.property);
+					}
+				}
+			}
+		}
 	}
 
 	function invalidDeclaration(declarationText, stylesheet) {

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

@@ -95,8 +95,8 @@ this.cssRulesMinifier = this.cssRulesMinifier || (() => {
 	function processRuleInfo(cssRule, ruleInfo, pseudoSelectors) {
 		const removedDeclarations = [];
 		const removedSelectors = [];
-		for (let declaration = cssRule.block.children.head; declaration; declaration = declaration.next) {
-			if (!ruleInfo.style.get(declaration.data.property)) {
+		for (let declaration = cssRule.block.children.tail; declaration; declaration = declaration.prev) {
+			if (!ruleInfo.style.get(declaration.data)) {
 				removedDeclarations.push(declaration);
 			}
 		}
@@ -116,7 +116,7 @@ this.cssRulesMinifier = this.cssRulesMinifier || (() => {
 		if (styleInfo) {
 			let propertyFound;
 			for (let declaration = cssStyle.children.head; declaration && !propertyFound; declaration = declaration.next) {
-				if (!styleInfo.style.get(declaration.data.property)) {
+				if (!styleInfo.style.get(declaration.data)) {
 					removedDeclarations.push(declaration);
 				}
 			}