Fixes #950 - removing unused `@font-face` at rules.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Tue, 13 Jun 2017 10:56:39 +0000 (12:56 +0200)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Wed, 14 Jun 2017 08:57:04 +0000 (10:57 +0200)
Why:

* A `@font-face` with particular font-family can be declared more than
  once, e.g. when referring different font weights.

History.md
lib/optimizer/level-2/remove-unused-at-rules.js
test/optimizer/level-2/remove-unused-at-rules-test.js

index 545e505..bd53b18 100644 (file)
@@ -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)
 ==================
 
index e60d5e7..7285991 100644 (file)
@@ -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);
   }
 }
 
index 3d2e8c6..4e5ddc0 100644 (file)
@@ -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 } } })
   )