diff --git a/History.md b/History.md index f62ad26aa..10bc5cd2b 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +[4.1.9 / 2017-09-19](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.8...v4.1.9) +================== + +* Fixed issue [#971](https://github.com/jakubpawlowicz/clean-css/issues/971) - edge case in removing unused at rules. + [4.1.8 / 2017-09-02](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.7...v4.1.8) ================== diff --git a/lib/optimizer/level-2/remove-unused-at-rules.js b/lib/optimizer/level-2/remove-unused-at-rules.js index 7285991a4..71d916da8 100644 --- a/lib/optimizer/level-2/remove-unused-at-rules.js +++ b/lib/optimizer/level-2/remove-unused-at-rules.js @@ -8,6 +8,11 @@ var Token = require('../../tokenizer/token'); var animationNameRegex = /^(\-moz\-|\-o\-|\-webkit\-)?animation-name$/; var animationRegex = /^(\-moz\-|\-o\-|\-webkit\-)?animation$/; var keyframeRegex = /^@(\-moz\-|\-o\-|\-webkit\-)?keyframes /; +var optionalMatchingQuotesRegex = /^(['"]?)(.*)\1$/; + +function removeQuotes(value) { + return value.replace(optionalMatchingQuotesRegex, '$2'); +} function removeUnusedAtRules(tokens, context) { removeUnusedAtRule(tokens, matchCounterStyle, markCounterStylesAsUsed, context); @@ -107,7 +112,7 @@ function matchFontFace(token, atRules) { property = token[2][i]; if (property[1][1] == 'font-family') { - match = property[2][1].toLowerCase(); + match = removeQuotes(property[2][1].toLowerCase()); atRules[match] = atRules[match] || []; atRules[match].push(token); break; @@ -134,7 +139,7 @@ function markFontFacesAsUsed(atRules) { component = wrappedProperty.components[6]; for (j = 0, m = component.value.length; j < m; j++) { - normalizedMatch = component.value[j][1].toLowerCase(); + normalizedMatch = removeQuotes(component.value[j][1].toLowerCase()); if (normalizedMatch in atRules) { delete atRules[normalizedMatch]; @@ -146,7 +151,7 @@ function markFontFacesAsUsed(atRules) { if (property[1][1] == 'font-family') { for (j = 2, m = property.length; j < m; j++) { - normalizedMatch = property[j][1].toLowerCase(); + normalizedMatch = removeQuotes(property[j][1].toLowerCase()); if (normalizedMatch in atRules) { delete atRules[normalizedMatch]; diff --git a/package.json b/package.json index def796cb2..62c4cdcc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clean-css", - "version": "4.1.8", + "version": "4.1.9", "author": "Jakub Pawlowicz (http://twitter.com/jakubpawlowicz)", "description": "A well-tested CSS minifier", "license": "MIT", diff --git a/test/optimizer/level-2/remove-unused-at-rules-test.js b/test/optimizer/level-2/remove-unused-at-rules-test.js index 4e5ddc0e7..3a5a27064 100644 --- a/test/optimizer/level-2/remove-unused-at-rules-test.js +++ b/test/optimizer/level-2/remove-unused-at-rules-test.js @@ -40,10 +40,18 @@ vows.describe('remove unused at rules') '@font-face{font-family:test}.block{font-family:test}', '@font-face{font-family:test}.block{font-family:test}' ], + 'one used quoted declaration in font-family': [ + '@font-face{font-family:"test test"}.block{font-family:"test test"}', + '@font-face{font-family:"test test"}.block{font-family:"test test"}' + ], 'one used declaration in font-family with different case': [ '@font-face{font-family:test}.block{font-family:Test}', '@font-face{font-family:test}.block{font-family:Test}' ], + 'one used quoted declaration in font-family with different quotes': [ + '@font-face{font-family:"test test"}.block{font-family:\'test test\'}', + '@font-face{font-family:"test test"}.block{font-family:\'test test\'}' + ], 'one used declaration in multi-valued font-family': [ '@font-face{font-family:test}.block{font-family:Arial,test,sans-serif}', '@font-face{font-family:test}.block{font-family:Arial,test,sans-serif}'