Fixes #210 - adds temporary workaround for aggressive property merging.
authorJakub Pawlowicz <jakub@goalsmashers.com>
Sun, 8 Jun 2014 13:24:04 +0000 (14:24 +0100)
committerJakub Pawlowicz <jakub@goalsmashers.com>
Sun, 8 Jun 2014 13:46:49 +0000 (14:46 +0100)
Using `--skip-aggressive-merging` / `noAggressiveMerging` switch skips property merging based on order.
Will be fixed in #290.

History.md
README.md
bin/cleancss
lib/clean.js
lib/properties/optimizer.js
lib/selectors/optimizer.js
test/binary-test.js
test/unit-test.js

index 9cb0396..200be59 100644 (file)
@@ -14,6 +14,7 @@
 * Fixed issue [#184](https://github.com/GoalSmashers/clean-css/issues/184) - uses `!important` for optimization opportunities.
 * Fixed issue [#190](https://github.com/GoalSmashers/clean-css/issues/190) - uses shorthand to override another shorthand.
 * Fixed issue [#197](https://github.com/GoalSmashers/clean-css/issues/197) - adds borders merging by understandability.
+* Fixed issue [#210](https://github.com/GoalSmashers/clean-css/issues/210) - adds temporary workaround for aggressive merging.
 * Fixed issue [#246](https://github.com/GoalSmashers/clean-css/issues/246) - removes IE hacks when not in compatibility mode.
 * Fixed issue [#247](https://github.com/GoalSmashers/clean-css/issues/247) - removes deprecated `selectorsMergeMode` switch.
 * Refixed issue [#250](https://github.com/GoalSmashers/clean-css/issues/250) - based on new quotation marks removal.
index 79d1979..ad2e270 100644 (file)
--- a/README.md
+++ b/README.md
@@ -71,6 +71,7 @@ cleancss [options] source-file, [source-file, ...]
 --skip-rebase                   Disable URLs rebasing
 --skip-advanced                 Disable advanced optimizations - selector & property merging,
                                 reduction, etc.
+--skip-aggressive-merging       Disable properties merging based on their order
 --rounding-precision [value]    Rounding precision, defaults to 2
 -c, --compatibility [ie7|ie8]   Force compatibility mode
 -d, --debug                     Shows debug information (minification time & compression efficiency)
index 8def84d..c3f2c2a 100755 (executable)
@@ -24,6 +24,7 @@ commands
   .option('-s, --skip-import', 'Disable @import processing')
   .option('--skip-rebase', 'Disable URLs rebasing')
   .option('--skip-advanced', 'Disable advanced optimizations - selector & property merging, reduction, etc.')
+  .option('--skip-aggressive-merging', 'Disable properties merging based on their order')
   .option('--rounding-precision [value]', 'Rounding precision, defaults to 2', parseInt)
   .option('-c, --compatibility [ie7|ie8]', 'Force compatibility mode')
   .option('-t, --timeout [seconds]', 'Per connection timeout when fetching remote @imports (defaults to 5 seconds)')
@@ -75,6 +76,8 @@ if (commands.skipRebase)
   cleanOptions.noRebase = true;
 if (commands.skipAdvanced)
   cleanOptions.noAdvanced = true;
+if (commands.skipAggressiveMerging)
+  cleanOptions.noAggressiveMerging = true;
 if (commands.compatibility)
   cleanOptions.compatibility = commands.compatibility;
 if (commands.roundingPrecision !== undefined)
index c276076..bc4bb39 100644 (file)
@@ -343,7 +343,8 @@ var minify = function(data, callback) {
       data = new SelectorsOptimizer(data, context, {
         keepBreaks: options.keepBreaks,
         lineBreak: lineBreak,
-        compatibility: options.compatibility
+        compatibility: options.compatibility,
+        aggressiveMerging: !options.noAggressiveMerging
       }).process();
     });
   }
index 1de0447..aea10b5 100644 (file)
@@ -3,7 +3,7 @@ var processableInfo = require('./processable');
 var overrideCompactor = require('./override-compactor');
 var shorthandCompactor = require('./shorthand-compactor');
 
-module.exports = function Optimizer(compatibility) {
+module.exports = function Optimizer(compatibility, aggressiveMerging) {
   var overridable = {
     'animation-delay': ['animation'],
     'animation-direction': ['animation'],
@@ -187,7 +187,7 @@ module.exports = function Optimizer(compatibility) {
       // e.g. a{display:inline-block;display:-moz-inline-box}
       // however if `mergeablePosition` yields true then the rule does not apply
       // (e.g merging two adjacent selectors: `a{display:block}a{display:block}`)
-      if (_property != lastProperty || mergeablePosition(i)) {
+      if (aggressiveMerging && _property != lastProperty || mergeablePosition(i)) {
         while (true) {
           toOverridePosition = properties.indexOf(_property, toOverridePosition);
           if (toOverridePosition == -1)
index 25f1c31..d7d5167 100644 (file)
@@ -10,7 +10,7 @@ module.exports = function Optimizer(data, context, options) {
 
   var minificationsMade = [];
 
-  var propertyOptimizer = new PropertyOptimizer(options.compatibility);
+  var propertyOptimizer = new PropertyOptimizer(options.compatibility, options.aggressiveMerging);
 
   var cleanUpSelector = function(selectors) {
     if (selectors.indexOf(',') == -1)
index e9731a3..3927e86 100644 (file)
@@ -307,5 +307,17 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({
         assert.equal(stdout, 'div{width:1px}');
       }
     })
+  },
+  'neighbour merging': {
+    'of (yet) unmergeable properties': pipedContext('a{display:inline-block;color:red;display:-moz-block}', '--skip-aggressive-merging', {
+      'gets right result': function(error, stdout) {
+        assert.equal(stdout, 'a{display:inline-block;color:red;display:-moz-block}');
+      }
+    }),
+    'of mergeable properties': pipedContext('a{background:red;display:block;background:white}', '--skip-aggressive-merging', {
+      'gets right result': function(error, stdout) {
+        assert.equal(stdout, 'a{display:block;background:#fff}');
+      }
+    })
   }
 });
index 3d129da..83f833f 100644 (file)
@@ -1452,6 +1452,13 @@ title']{display:block}",
       'a{display:none;border:1px solid #fff!important}'
     ]
   }),
+  'duplicate properties with aggressive merging disabled': cssContext({
+    'of (yet) unmergeable properties': 'a{display:inline-block;color:red;display:-moz-block}',
+    'of mergeable properties': [
+      'a{background:red;display:block;background:white}',
+      'a{display:block;background:#fff}'
+    ]
+  }, { noAggressiveMerging: true }),
   'same selectors': cssContext({
     'of two non-adjacent selectors': '.one{color:red}.two{color:#00f}.one{font-weight:700}',
     'of two adjacent single selectors': [