Extracts 'remove duplicate media queries' optimization into a module.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 21 Jun 2015 13:49:36 +0000 (14:49 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 21 Jun 2015 14:02:36 +0000 (15:02 +0100)
lib/selectors/advanced.js
lib/selectors/remove-duplicate-media-queries.js [new file with mode: 0644]
test/media-queries-test.js [deleted file]
test/selectors/remove-duplicate-media-queries-test.js [new file with mode: 0644]

index 4f55c39..6487106 100644 (file)
@@ -2,7 +2,6 @@ var optimizeProperties = require('../properties/optimizer');
 
 var extractProperties = require('./extractor');
 var canReorder = require('./reorderable').canReorder;
-var stringifyAll = require('../stringifier/one-time').all;
 
 var removeDuplicates = require('./remove-duplicates');
 var mergeAdjacent = require('./merge-adjacent');
@@ -10,30 +9,13 @@ var reduceNonAdjacent = require('./reduce-non-adjacent');
 var mergeNonAdjacentBySelector = require('./merge-non-adjacent-by-selector');
 var mergeNonAdjacentByBody = require('./merge-non-adjacent-by-body');
 var restructure = require('./restructure');
+var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries');
 
 function AdvancedOptimizer(options, context) {
   this.options = options;
   this.validator = context.validator;
 }
 
-AdvancedOptimizer.prototype.removeDuplicateMediaQueries = function (tokens) {
-  var candidates = {};
-
-  for (var i = 0, l = tokens.length; i < l; i++) {
-    var token = tokens[i];
-    if (token[0] != 'block')
-      continue;
-
-    var key = token[1][0] + '%' + stringifyAll(token[2]);
-    var candidate = candidates[key];
-
-    if (candidate)
-      candidate[2] = [];
-
-    candidates[key] = token;
-  }
-};
-
 AdvancedOptimizer.prototype.mergeMediaQueries = function (tokens) {
   var candidates = {};
   var reduced = [];
@@ -141,7 +123,7 @@ AdvancedOptimizer.prototype.optimize = function (tokens) {
     }
 
     if (self.options.mediaMerging) {
-      self.removeDuplicateMediaQueries(tokens);
+      removeDuplicateMediaQueries(tokens);
       var reduced = self.mergeMediaQueries(tokens);
       for (var i = reduced.length - 1; i >= 0; i--) {
         _optimize(reduced[i][2]);
diff --git a/lib/selectors/remove-duplicate-media-queries.js b/lib/selectors/remove-duplicate-media-queries.js
new file mode 100644 (file)
index 0000000..44070b0
--- /dev/null
@@ -0,0 +1,21 @@
+var stringifyAll = require('../stringifier/one-time').all;
+
+function removeDuplicateMediaQueries(tokens) {
+  var candidates = {};
+
+  for (var i = 0, l = tokens.length; i < l; i++) {
+    var token = tokens[i];
+    if (token[0] != 'block')
+      continue;
+
+    var key = token[1][0] + '%' + stringifyAll(token[2]);
+    var candidate = candidates[key];
+
+    if (candidate)
+      candidate[2] = [];
+
+    candidates[key] = token;
+  }
+}
+
+module.exports = removeDuplicateMediaQueries;
diff --git a/test/media-queries-test.js b/test/media-queries-test.js
deleted file mode 100644 (file)
index 35ce906..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-var vows = require('vows');
-var assert = require('assert');
-var CleanCSS = require('../index');
-
-vows.describe('media queries')
-  .addBatch({
-    'different ones': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media print{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}@media print{div{display:block}}');
-      }
-    },
-    'other than @media': {
-      'topic': function () {
-        return new CleanCSS().minify('@font-face{font-family:A}@font-face{font-family:B}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@font-face{font-family:A}@font-face{font-family:B}');
-      }
-    },
-    'with empty selector': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}div{}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}');
-      }
-    }
-  })
-  .addBatch({
-    'same two adjacent': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}div{display:block}}');
-      }
-    },
-    'same three adjacent': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media screen{div{display:block}}@media screen{body{width:100%}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}div{display:block}body{width:100%}}');
-      }
-    },
-    'same two with selectors in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}body{width:100%}.one{height:100px}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, 'body{width:100%}.one{height:100px}@media screen{a{color:red}div{display:block}}');
-      }
-    },
-    'same two with other @media in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media (min-width:1024px){body{width:100%}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media (min-width:1024px){body{width:100%}}@media screen{a{color:red}div{display:block}}');
-      }
-    },
-    'same two with breaking properties in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}.one{color:#00f}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}.one{color:#00f}@media screen{div{display:block}}');
-      }
-    },
-    'same two with breaking @media in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media (min-width:1024px){.one{color:#00f}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}@media (min-width:1024px){.one{color:#00f}}@media screen{div{display:block}}');
-      }
-    },
-    'same two with breaking nested @media in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media (min-width:1024px){@media screen{.one{color:#00f}}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}@media (min-width:1024px){@media screen{.one{color:#00f}}}@media screen{div{display:block}}');
-      }
-    },
-    'intermixed': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media (min-width:1024px){p{width:100%}}@media screen{div{display:block}}@media (min-width:1024px){body{height:100%}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}div{display:block}}@media (min-width:1024px){p{width:100%}body{height:100%}}');
-      }
-    },
-    'same two with overriding shorthand in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{font-size:10px}}@media (min-width:1024px){.one{font:12px Helvetica}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{font-size:10px}}@media (min-width:1024px){.one{font:12px Helvetica}}@media screen{div{display:block}}');
-      }
-    },
-    'same two with different component property in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{font-size:10px}}@media (min-width:1024px){.one{font-weight:700}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media (min-width:1024px){.one{font-weight:700}}@media screen{a{font-size:10px}div{display:block}}');
-      }
-    },
-    'same two with same values as moved in between': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media (min-width:1024px){.one{color:red}}@media screen{div{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media (min-width:1024px){.one{color:red}}@media screen{a{color:red}div{display:block}}');
-      }
-    },
-    'duplicated but non-mergeable': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}.one{color:#000}@media screen{a{color:red}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '.one{color:#000}@media screen{a{color:red}}');
-      }
-    },
-    'many duplicated but non-mergeable': {
-      'topic': function () {
-        return new CleanCSS().minify('@media print{a{color:#fff}}@media screen{a{color:red}}.one{color:#000}@media screen{a{color:red}}@media print{a{display:block}}@media print{a{color:#fff}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '.one{color:#000}@media screen{a{color:red}}@media print{a{display:block;color:#fff}}');
-      }
-    }
-  })
-  .addBatch({
-    'further optimizations': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}@media screen{a{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red;display:block}}');
-      }
-    }
-  })
-  .addBatch({
-    'with comments': {
-      'topic': function () {
-        return new CleanCSS().minify('@media screen{a{color:red}}/*! a comment */@media screen{a{display:block}}');
-      },
-      'get merged': function (minified) {
-        assert.equal(minified.styles, '/*! a comment */@media screen{a{color:red;display:block}}');
-      }
-    }
-  })
-  .addBatch({
-    'disabled': {
-      'topic': function () {
-        return new CleanCSS({ mediaMerging: false }).minify('@media screen{a{color:red}}@media screen{a{display:block}}');
-      },
-      'keeps @media intact': function (minified) {
-        assert.equal(minified.styles, '@media screen{a{color:red}}@media screen{a{display:block}}');
-      }
-    }
-  }).export(module);
diff --git a/test/selectors/remove-duplicate-media-queries-test.js b/test/selectors/remove-duplicate-media-queries-test.js
new file mode 100644 (file)
index 0000000..f07cd0d
--- /dev/null
@@ -0,0 +1,41 @@
+var vows = require('vows');
+var optimizerContext = require('../test-helper').optimizerContext;
+
+vows.describe('remove duplicate media queries')
+  .addBatch(
+    optimizerContext('advanced on', {
+      'adjacent': [
+        '@media screen{a{color:red}}@media screen{a{color:red}}',
+        '@media screen{a{color:red}}'
+      ],
+      'non-adjacent': [
+        '@media screen{a{color:red}}@media print{a{color:#fff}}@media screen{a{color:red}}',
+        '@media print{a{color:#fff}}@media screen{a{color:red}}'
+      ],
+      'single non-mergeable': [
+        '@media screen{a{color:red}}.one{color:#000}@media screen{a{color:red}}',
+        '.one{color:#000}@media screen{a{color:red}}'
+      ],
+      'many non-mergeable': [
+        '@media print{a{color:#fff}}@media screen{a{color:red}}.one{color:#000}@media screen{a{color:red}}@media print{a{display:block}}@media print{a{color:#fff}}',
+        '.one{color:#000}@media screen{a{color:red}}@media print{a{display:block;color:#fff}}'
+      ]
+    })
+  )
+  .addBatch(
+    optimizerContext('advanced off', {
+      'keeps content same': [
+        '@media screen{a{color:red}}@media screen{a{color:red}}',
+        '@media screen{a{color:red}}@media screen{a{color:red}}'
+      ]
+    }, { advanced: false })
+  )
+  .addBatch(
+    optimizerContext('media merging off', {
+      'keeps content same': [
+        '@media screen{a{color:red}}@media screen{a{color:red}}',
+        '@media screen{a{color:red}}@media screen{a{color:red}}'
+      ]
+    }, { mediaMerging: false })
+  )
+  .export(module);