From b8b8ca8d50a4aa7cb98bcf94cd950405395aa3a3 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sat, 8 Nov 2014 12:23:08 +0000 Subject: [PATCH] Adds `--skip-shorthand-compacting`/`shorthandComacting` option for disabling shorthand compacting. * Also disables shorthand compacting for source maps as it is not defined well enough, yet. --- History.md | 1 + README.md | 2 ++ bin/cleancss | 3 ++ lib/clean.js | 1 + lib/properties/optimizer.js | 8 ++++-- lib/selectors/optimizers/advanced.js | 2 +- test/binary-test.js | 7 +++++ test/selectors/optimizer-test.js | 1 + test/source-map-test.js | 41 +++++++++++++++++++++++++++- 9 files changed, 62 insertions(+), 4 deletions(-) diff --git a/History.md b/History.md index 5b087831..0a5199e5 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,7 @@ * Adds more granular control over compatibility settings. * Adds support for @counter-style at-rule. +* Adds `--skip-shorthand-compacting`/`shorthandComacting` option for disabling shorthand compacting. * Allows `target` option to be a path to a folder instead of a file. * Allows disabling rounding precision. By [@superlukas](https://github.com/superlukas). * Breaks 2.x compatibility for using CleanCSS as a function. diff --git a/README.md b/README.md index 5e444a98..e9efb27f 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ cleancss [options] source-file, [source-file, ...] --skip-advanced Disable advanced optimizations - selector & property merging, reduction, etc. --skip-aggressive-merging Disable properties merging based on their order +--skip-shorthand-compacting Disable shorthand compacting --rounding-precision [N] Rounds to `N` decimal places. Defaults to 2. -1 disables rounding. -c, --compatibility [ie7|ie8] Force compatibility mode (see Readme for advanced examples) -d, --debug Shows debug information (minification time & compression efficiency) @@ -148,6 +149,7 @@ CleanCSS constructor accepts a hash as a parameter, i.e., * `relativeTo` - path to __resolve__ relative `@import` rules and URLs * `root` - path to __resolve__ absolute `@import` rules and __rebase__ relative URLs * `roundingPrecision` - rounding precision; defaults to `2`; `-1` disables rounding +* `shorthandCompacting` - set to false to skip shorthand compacting (default is true unless sourceMap is set when it's false) * `sourceMap` - exposes source map under `sourceMap` property, e.g. `new CleanCSS().minify(source).sourceMap` (default is false) * `target` - path to a folder or an output file to which __rebase__ all URLs diff --git a/bin/cleancss b/bin/cleancss index a1b6ffe9..19df3f01 100755 --- a/bin/cleancss +++ b/bin/cleancss @@ -25,6 +25,7 @@ commands .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('--skip-shorthand-compacting', 'Disable shorthand compacting') .option('--rounding-precision [n]', 'Rounds to `N` decimal places. Defaults to 2. -1 disables rounding.', parseInt) .option('-c, --compatibility [ie7|ie8]', 'Force compatibility mode (see Readme for advanced examples)') .option('-t, --timeout [seconds]', 'Per connection timeout when fetching remote @imports (defaults to 5 seconds)') @@ -78,6 +79,8 @@ if (commands.skipAdvanced) cleanOptions.advanced = false; if (commands.skipAggressiveMerging) cleanOptions.aggressiveMerging = false; +if (commands.skipShorthandCompacting) + cleanOptions.shorthandCompacting = false; if (commands.compatibility) cleanOptions.compatibility = commands.compatibility; if (commands.roundingPrecision !== undefined) diff --git a/lib/clean.js b/lib/clean.js index 1db575b7..babb0f2a 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -35,6 +35,7 @@ var CleanCSS = module.exports = function CleanCSS(options) { relativeTo: options.relativeTo, root: options.root, roundingPrecision: options.roundingPrecision, + shorthandCompacting: !!options.sourceMap ? false : (undefined === options.shorthandCompacting ? true : !!options.shorthandCompacting), sourceMap: !!options.sourceMap, target: options.target }; diff --git a/lib/properties/optimizer.js b/lib/properties/optimizer.js index df833477..12fb1286 100644 --- a/lib/properties/optimizer.js +++ b/lib/properties/optimizer.js @@ -5,7 +5,7 @@ var shorthandCompactor = require('./shorthand-compactor'); function valueMapper(object) { return object.value; } -module.exports = function Optimizer(compatibility, aggressiveMerging, context) { +module.exports = function Optimizer(options, context) { var overridable = { 'animation-delay': ['animation'], 'animation-direction': ['animation'], @@ -103,6 +103,10 @@ module.exports = function Optimizer(compatibility, aggressiveMerging, context) { '-webkit-transition-timing-function': ['-webkit-transition'] }; + var compatibility = options.compatibility; + var aggressiveMerging = options.aggressiveMerging; + var shorthandCompacting = options.shorthandCompacting; + var IE_BACKSLASH_HACK = '\\9'; var processable = processableInfo.processable(compatibility); @@ -275,7 +279,7 @@ module.exports = function Optimizer(compatibility, aggressiveMerging, context) { var optimized = optimize(tokenized, allowAdjacent); var rebuilt = rebuild(optimized); - return compactProperties && rebuilt.compactFurther ? + return shorthandCompacting && compactProperties && rebuilt.compactFurther ? compact(rebuilt.tokenized) : rebuilt; } diff --git a/lib/selectors/optimizers/advanced.js b/lib/selectors/optimizers/advanced.js index d05d3f81..68188aed 100644 --- a/lib/selectors/optimizers/advanced.js +++ b/lib/selectors/optimizers/advanced.js @@ -4,7 +4,7 @@ var CleanUp = require('./clean-up'); function AdvancedOptimizer(options, context) { this.options = options; this.minificationsMade = []; - this.propertyOptimizer = new PropertyOptimizer(this.options.compatibility, this.options.aggressiveMerging, context); + this.propertyOptimizer = new PropertyOptimizer(this.options, context); } function changeBodyOf(token, newBody) { diff --git a/test/binary-test.js b/test/binary-test.js index 7a5047a4..fd876311 100644 --- a/test/binary-test.js +++ b/test/binary-test.js @@ -329,5 +329,12 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({ assert.equal(stdout, 'a{display:block;background:#fff}'); } }) + }, + 'shorthand compacting': { + 'of (yet) unmergeable properties': pipedContext('a{background:url(image.png);background-color:red}', '--skip-shorthand-compacting', { + 'gets right result': function(error, stdout) { + assert.equal(stdout, 'a{background:url(image.png);background-color:red}'); + } + }) } }); diff --git a/test/selectors/optimizer-test.js b/test/selectors/optimizer-test.js index bd7ab2c7..e68fb8c6 100644 --- a/test/selectors/optimizer-test.js +++ b/test/selectors/optimizer-test.js @@ -9,6 +9,7 @@ function optimizerContext(group, specs, options) { var context = {}; options = options || {}; + options.shorthandCompacting = true; options.compatibility = new Compatibility(options.compatibility).toOptions(); function optimized(target) { diff --git a/test/source-map-test.js b/test/source-map-test.js index 0654acfc..31169691 100644 --- a/test/source-map-test.js +++ b/test/source-map-test.js @@ -153,6 +153,45 @@ vows.describe('source-map') }; assert.deepEqual(mapping, minified.sourceMap._mappings[6]); } - } + }, + 'shorthands': { + 'topic': new CleanCSS({ sourceMap: true }).minify('a{background:url(image.png);background-color:red}'), + 'should have 3 mappings': function(minified) { + assert.equal(3, minified.sourceMap._mappings.length); + }, + 'should have selector mapping': function (minified) { + var mapping = { + generatedLine: 1, + generatedColumn: 1, + originalLine: 1, + originalColumn: 1, + source: '__stdin__.css', + name: 'a' + }; + assert.deepEqual(mapping, minified.sourceMap._mappings[0]); + }, + 'should have _background_ mapping': function (minified) { + var mapping = { + generatedLine: 1, + generatedColumn: 3, + originalLine: 1, + originalColumn: 3, + source: '__stdin__.css', + name: 'background:url(image.png)' + }; + assert.deepEqual(mapping, minified.sourceMap._mappings[1]); + }, + 'should have _background-color_ mapping': function (minified) { + var mapping = { + generatedLine: 1, + generatedColumn: 29, + originalLine: 1, + originalColumn: 29, + source: '__stdin__.css', + name: 'background-color:red' + }; + assert.deepEqual(mapping, minified.sourceMap._mappings[2]); + } + }, }) .export(module); -- 2.34.1