diff --git a/History.md b/History.md index 545e505d6..bd53b1869 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,11 @@ * Adds `process` method for compatibility with optimize-css-assets-webpack-plugin. +[4.1.4 / 2017-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.3...4.1) +================== + +* Fixed issue [#950](https://github.com/jakubpawlowicz/clean-css/issues/950) - bug in removing unused `@font-face` rules. + [4.1.3 / 2017-05-18](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.2...v4.1.3) ================== diff --git a/lib/optimizer/level-2/remove-unused-at-rules.js b/lib/optimizer/level-2/remove-unused-at-rules.js index e60d5e7c2..7285991a4 100644 --- a/lib/optimizer/level-2/remove-unused-at-rules.js +++ b/lib/optimizer/level-2/remove-unused-at-rules.js @@ -19,7 +19,8 @@ function removeUnusedAtRules(tokens, context) { function removeUnusedAtRule(tokens, matchCallback, markCallback, context) { var atRules = {}; var atRule; - var token; + var atRuleTokens; + var atRuleToken; var zeroAt; var i, l; @@ -34,9 +35,13 @@ function removeUnusedAtRule(tokens, matchCallback, markCallback, context) { markUsedAtRules(tokens, markCallback, atRules, context); for (atRule in atRules) { - token = atRules[atRule]; - zeroAt = token[0] == Token.AT_RULE ? 1 : 2; - token[zeroAt] = []; + atRuleTokens = atRules[atRule]; + + for (i = 0, l = atRuleTokens.length; i < l; i++) { + atRuleToken = atRuleTokens[i]; + zeroAt = atRuleToken[0] == Token.AT_RULE ? 1 : 2; + atRuleToken[zeroAt] = []; + } } } @@ -60,7 +65,8 @@ function matchCounterStyle(token, atRules) { if (token[0] == Token.AT_RULE_BLOCK && token[1][0][1].indexOf('@counter-style') === 0) { match = token[1][0][1].split(' ')[1]; - atRules[match] = token; + atRules[match] = atRules[match] || []; + atRules[match].push(token); } } @@ -102,7 +108,8 @@ function matchFontFace(token, atRules) { if (property[1][1] == 'font-family') { match = property[2][1].toLowerCase(); - atRules[match] = token; + atRules[match] = atRules[match] || []; + atRules[match].push(token); break; } } @@ -155,7 +162,8 @@ function matchKeyframe(token, atRules) { if (token[0] == Token.NESTED_BLOCK && keyframeRegex.test(token[1][0][1])) { match = token[1][0][1].split(' ')[1]; - atRules[match] = token; + atRules[match] = atRules[match] || []; + atRules[match].push(token); } } @@ -200,7 +208,8 @@ function matchNamespace(token, atRules) { if (token[0] == Token.AT_RULE && token[1].indexOf('@namespace') === 0) { match = token[1].split(' ')[1]; - atRules[match] = token; + atRules[match] = atRules[match] || []; + atRules[match].push(token); } } 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 3d2e8c6d8..4e5ddc0e7 100644 --- a/test/optimizer/level-2/remove-unused-at-rules-test.js +++ b/test/optimizer/level-2/remove-unused-at-rules-test.js @@ -71,6 +71,10 @@ vows.describe('remove unused at rules') 'one used with !important': [ '@font-face{font-family:test}.block{font:16px test!important}', '@font-face{font-family:test}.block{font:16px test!important}' + ], + 'one used declaration in another @font-face': [ + '@font-face{font-family:test;font-weight:normal}@font-face{font-family:test;font-weight:bold}', + '' ] }, { level: { 2: { removeUnusedAtRules: true } } }) )