From 03c18813c64402688f456e5133339532c98c00d6 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Mon, 9 Jan 2017 15:17:39 +0100 Subject: [PATCH] Adds granular control over level 1 optimizations. Why: * So users can turn them on/off selectively; * still keeping sane defaults for most users. Note: moves `properties.fontWeight` compatibility flag to level 1 optimizations as that's not a compatibility flag, but rather a user preference - see #756. --- README.md | 45 +++- bin/cleancss | 19 +- lib/optimizer/level-1/optimize.js | 74 ++++--- lib/options/optimization-level.js | 19 +- lib/utils/compatibility.js | 1 - test/optimizer/level-1/optimize-test.js | 142 ++++++++++++- test/options/optimization-level-test.js | 266 ++++++++++++++++++++++-- test/utils/compatibility-test.js | 4 - 8 files changed, 515 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 5bc4cfa6..0d6ccfa0 100644 --- a/README.md +++ b/README.md @@ -115,13 +115,30 @@ Level 0 optimizations: cleancss -O0 one.css ``` -Level 1 optimizations: +Level 1 optimizations (default): ```bash cleancss -O1 one.css -cleancss -O1 roundingPrecision:4;specialComments:1 one.css +cleancss -O1 keepQuotes:on;roundingPrecision:4;specialComments:1 one.css +# `cleanupCharsets` controls `@charset` moving to the front of a stylesheet; defaults to `on` +# `keepNegativePaddings` controls negative paddings removal; defaults to `off` +# `keepQuotes` controls keeping quotes when unnecessary; defaults to `off` +# `keepWhitespace` controls keeping unused whitespace; defaults to `off` +# `normalizeUrls` controls URL normalzation; default to `on` +# `optimizeBackground` controls `background` property optimizatons; defaults to `on` +# `optimizeBorderRadius` controls `border-radius` property optimizatons; defaults to `on` +# `optimizeFilter` controls `filter` property optimizatons; defaults to `on` +# `optimizeFont controls `font` property optimizatons; defaults to `on` +# `optimizeFontWeight` controls `font-weight` property optimizatons; defaults to `on` +# `optimizeOutline` controls `outline` property optimizatons; defaults to `on` +# `replaceMultipleZeros` contols removing redundant zeros; defaults to `on` +# `replaceTimeUnits` controls replacing time units with shorter values; defaults to `on +# `replaceZeroUnits` controls replacing zero values with units; defaults to `on` # `roundingPrecision` rounds pixel values to `N` decimal places; `off` disables rounding; defaults to `off` # `specialComments` denotes a number of /*! ... */ comments preserved; defaults to `all` +# `tidyAtRules` controls at-rules (e.g. `@charset`, `@import`) optimizing; defaults to `on` +# `tidyBlockScopes` controls block scopes (e.g. `@media`) optimizing; defaults to `on` +# `tidySelectors` controls selectors optimizing; defaults to `on` ``` Level 2 optimizations: @@ -184,12 +201,29 @@ The output of `minify` method (or the 2nd argument to passed callback) is a hash The `level` option can be either `0`, `1` (default), or `2`, or a fine-grained configuration given via a hash: ```js -// level 1 optimizations +// level 1 optimizations (default) new CleanCSS({ level: { 1: { - roundingPrecision: 3, // rounds pixel values to `N` decimal places; `off` disables rounding; defaults to `off` - specialComments: 0 // denotes a number of /*! ... */ comments preserved; defaults to `all` + cleanupCharsets: true, // controls `@charset` moving to the front of a stylesheet; defaults to `true` + keepNegativePaddings: false, // controls negative paddings removal; defaults to `false` + keepQuotes: false, // controls keeping quotes when unnecessary; defaults to `false` + keepWhitespace: false, // controls keeping unused whitespace; defaults to `false` + normalizeUrls: true, // controls URL normalzation; default to `true` + optimizeBackground: true, // controls `background` property optimizatons; defaults to `true` + optimizeBorderRadius: true, // controls `border-radius` property optimizatons; defaults to `true` + optimizeFilter: true, // controls `filter` property optimizatons; defaults to `true` + optimizeFont: true, // ontrols `font` property optimizatons; defaults to `true` + optimizeFontWeight: true, // controls `font-weight` property optimizatons; defaults to `true` + optimizeOutline: true, // controls `outline` property optimizatons; defaults to `true` + replaceMultipleZeros: true, // contols removing redundant zeros; defaults to `true` + replaceTimeUnits: true, // controls replacing time units with shorter values; defaults to `true` + replaceZeroUnits: true, // controls replacing zero values with units; defaults to `true` + roundingPrecision: false, // rounds pixel values to `N` decimal places; `false` disables rounding; defaults to `false` + specialComments: 'all', // denotes a number of /*! ... */ comments preserved; defaults to `all` + tidyAtRules: true, // controls at-rules (e.g. `@charset`, `@import`) optimizing; defaults to `true` + tidyBlockScopes: true, // controls block scopes (e.g. `@media`) optimizing; defaults to `true` + tidySelectors: true // controls selectors optimizing; defaults to `true` } } }); @@ -397,7 +431,6 @@ with the following options available: * `'[+-]properties.backgroundOriginMerging'` - turn on / off background-origin merging into shorthand * `'[+-]properties.backgroundSizeMerging'` - turn on / off background-size merging into shorthand * `'[+-]properties.colors'` - turn on / off any color optimizations -* `'[+-]properties.fontWeight'` - turn on / off any `font-weight` optimizations * `'[+-]properties.ieBangHack'` - turn on / off IE bang hack removal * `'[+-]properties.iePrefixHack'` - turn on / off IE prefix hack removal * `'[+-]properties.ieSuffixHack'` - turn on / off IE suffix hack removal diff --git a/bin/cleancss b/bin/cleancss index 5a5b4dc9..bb11a713 100755 --- a/bin/cleancss +++ b/bin/cleancss @@ -38,9 +38,26 @@ commands.on('--help', function () { console.log(''); console.log(' Level 1 optimizations:'); console.log(' %> cleancss -O1 one.css'); - console.log(' %> cleancss -O1 roundingPrecision:4;specialComments:1 one.css'); + console.log(' %> cleancss -O1 keepQuotes:on;roundingPrecision:4;specialComments:1 one.css'); + console.log(' %> # `cleanupCharsets` controls `@charset` moving to the front of a stylesheet; defaults to `on`'); + console.log(' %> # `keepNegativePaddings` controls negative paddings removal; defaults to `off`'); + console.log(' %> # `keepQuotes` controls keeping quotes when unnecessary; defaults to `off`'); + console.log(' %> # `keepWhitespace` controls keeping unused whitespace; defaults to `off`'); + console.log(' %> # `normalizeUrls` controls URL normalzation; default to `on`'); + console.log(' %> # `optimizeBackground` controls `background` property optimizatons; defaults to `on`'); + console.log(' %> # `optimizeBorderRadius` controls `border-radius` property optimizatons; defaults to `on`'); + console.log(' %> # `optimizeFilter` controls `filter` property optimizatons; defaults to `on`'); + console.log(' %> # `optimizeFont controls `font` property optimizatons; defaults to `on` '); + console.log(' %> # `optimizeFontWeight` controls `font-weight` property optimizatons; defaults to `on`'); + console.log(' %> # `optimizeOutline` controls `outline` property optimizatons; defaults to `on`'); + console.log(' %> # `replaceMultipleZeros` contols removing redundant zeros; defaults to `on`'); + console.log(' %> # `replaceTimeUnits` controls replacing time units with shorter values; defaults to `on'); + console.log(' %> # `replaceZeroUnits` controls replacing zero values with units; defaults to `on`'); console.log(' %> # `roundingPrecision` rounds pixel values to `N` decimal places; `off` disables rounding; defaults to `off`'); console.log(' %> # `specialComments` denotes a number of /*! ... */ comments preserved; defaults to `all`'); + console.log(' %> # `tidyAtRules` controls at-rules (e.g. `@charset`, `@import`) optimizing; defaults to `on`'); + console.log(' %> # `tidyBlockScopes` controls block scopes (e.g. `@media`) optimizing; defaults to `on`'); + console.log(' %> # `tidySelectors` controls selectors optimizing; defaults to `on`'); console.log(''); console.log(' Level 2 optimizations:'); console.log(' %> cleancss -O2 one.css'); diff --git a/lib/optimizer/level-1/optimize.js b/lib/optimizer/level-1/optimize.js index bd7b2b80..c48c58ab 100644 --- a/lib/optimizer/level-1/optimize.js +++ b/lib/optimizer/level-1/optimize.js @@ -143,7 +143,7 @@ function optimizeColors(name, value, compatibility) { return shortenHex(value); } -function optimizeFilters(property) { +function optimizeFilter(property) { if (property.value.length == 1) { property.value[0][1] = property.value[0][1].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) { return filter.toLowerCase() + suffix; @@ -160,10 +160,11 @@ function optimizeFont(property, options) { var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][1]) > -1 || values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][1]) > -1 || values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][1]) > -1; + var canOptimizeFontWeight = options.level[OptimizationLevel.One].optimizeFontWeight; var normalCount = 0; var toOptimize; - if (!options.compatibility.properties.fontWeight) { + if (!canOptimizeFontWeight) { return; } @@ -205,7 +206,7 @@ function optimizeFont(property, options) { toOptimize = 2; } - if (toOptimize !== undefined) { + if (toOptimize !== undefined && canOptimizeFontWeight) { optimizeFontWeight(property, toOptimize); property.dirty = true; } @@ -250,8 +251,9 @@ function optimizeOutline(property) { } function optimizePixelLengths(_, value, compatibility) { - if (!WHOLE_PIXEL_VALUE.test(value)) + if (!WHOLE_PIXEL_VALUE.test(value)) { return value; + } return value.replace(WHOLE_PIXEL_VALUE, function (match, val) { var newValue; @@ -404,6 +406,7 @@ function removeUrlQuotes(value) { function optimizeBody(properties, context) { var options = context.options; + var levelOptions = options.level[OptimizationLevel.One]; var property, name, type, value; var valueIsUrl; var propertyToken; @@ -432,7 +435,7 @@ function optimizeBody(properties, context) { property.unused = true; } - if (name.indexOf('padding') === 0 && (isNegative(property.value[0]) || isNegative(property.value[1]) || isNegative(property.value[2]) || isNegative(property.value[3]))) { + if (!levelOptions.keepNegativePaddings && name.indexOf('padding') === 0 && (isNegative(property.value[0]) || isNegative(property.value[1]) || isNegative(property.value[2]) || isNegative(property.value[3]))) { property.unused = true; } @@ -463,42 +466,57 @@ function optimizeBody(properties, context) { } if (valueIsUrl) { - value = normalizeUrl(value); - value = options.compatibility.properties.urlQuotes ? - value : - removeUrlQuotes(value); + value = levelOptions.normalizeUrls ? + normalizeUrl(value) : + value; + value = !options.compatibility.properties.urlQuotes ? + removeUrlQuotes(value) : + value; } else if (isQuoted(value)) { - value = removeQuotes(name, value); + value = levelOptions.keepQuotes ? + value : + removeQuotes(name, value); } else { - value = optimizeWhitespace(name, value); + value = levelOptions.keepWhitespace ? + value : + optimizeWhitespace(name, value); value = optimizePrecision(name, value, options.precision); value = optimizePixelLengths(name, value, options.compatibility); - value = optimizeTimeUnits(name, value); - value = optimizeZeroUnits(name, value); + value = levelOptions.replaceTimeUnits ? + optimizeTimeUnits(name, value) : + value; + value = levelOptions.replaceZeroUnits ? + optimizeZeroUnits(name, value) : + value; + if (options.compatibility.properties.zeroUnits) { value = optimizeZeroDegUnit(name, value); value = optimizeUnits(name, value, options.unitsRegexp); } - if (options.compatibility.properties.colors) + + if (options.compatibility.properties.colors) { value = optimizeColors(name, value, options.compatibility); + } } property.value[j][1] = value; } - optimizeMultipleZeros(property); + if (levelOptions.replaceMultipleZeros) { + optimizeMultipleZeros(property); + } - if (name == 'background') { + if (name == 'background' && levelOptions.optimizeBackground) { optimizeBackground(property); - } else if (name.indexOf('border') === 0 && name.indexOf('radius') > 0) { + } else if (name.indexOf('border') === 0 && name.indexOf('radius') > 0 && levelOptions.optimizeBorderRadius) { optimizeBorderRadius(property); - } else if (name == 'filter') { - optimizeFilters(property); - } else if (name == 'font') { + } else if (name == 'filter'&& levelOptions.optimizeFilter) { + optimizeFilter(property); + } else if (name == 'font' && levelOptions.optimizeFont) { optimizeFont(property, options); - } else if (name == 'font-weight' && options.compatibility.properties.fontWeight) { + } else if (name == 'font-weight' && levelOptions.optimizeFontWeight) { optimizeFontWeight(property, 0); - } else if (name == 'outline') { + } else if (name == 'outline' && levelOptions.optimizeOutline) { optimizeOutline(property); } } @@ -611,6 +629,7 @@ function isImport(token) { function level1Optimize(tokens, context) { var options = context.options; + var levelOptions = options.level[OptimizationLevel.One]; var ie7Hack = options.compatibility.selectors.ie7Hack; var adjacentSpace = options.compatibility.selectors.adjacentSpace; var spaceAfterClosingBrace = options.compatibility.properties.spaceAfterClosingBrace; @@ -619,7 +638,7 @@ function level1Optimize(tokens, context) { var afterRules = false; options.unitsRegexp = options.unitsRegexp || buildUnitRegexp(options); - options.precision = options.precision || buildPrecisionOptions(options.level[OptimizationLevel.One].roundingPrecision); + options.precision = options.precision || buildPrecisionOptions(levelOptions.roundingPrecision); options.commentsKept = options.commentsKept || 0; for (var i = 0, l = tokens.length; i < l; i++) { @@ -627,7 +646,8 @@ function level1Optimize(tokens, context) { switch (token[0]) { case Token.AT_RULE: - token[1] = isImport(token) && afterRules ? '' : tidyAtRule(token[1]); + token[1] = isImport(token) && afterRules ? '' : token[1]; + token[1] = levelOptions.tidyAtRules ? tidyAtRule(token[1]) : token[1]; mayHaveCharset = true; break; case Token.AT_RULE_BLOCK: @@ -635,7 +655,7 @@ function level1Optimize(tokens, context) { afterRules = true; break; case Token.BLOCK: - token[1] = tidyBlock(token[1], spaceAfterClosingBrace); + token[1] = levelOptions.tidyBlockScopes ? tidyBlock(token[1], spaceAfterClosingBrace) : token[1]; level1Optimize(token[2], context); afterRules = true; break; @@ -643,7 +663,7 @@ function level1Optimize(tokens, context) { optimizeComment(token, options); break; case Token.RULE: - token[1] = tidyRules(token[1], !ie7Hack, adjacentSpace, beautify, context.warnings); + token[1] = levelOptions.tidySelectors ? tidyRules(token[1], !ie7Hack, adjacentSpace, beautify, context.warnings) : token[1]; optimizeBody(token[2], context); afterRules = true; break; @@ -656,7 +676,7 @@ function level1Optimize(tokens, context) { } } - if (mayHaveCharset) { + if (levelOptions.cleanupCharsets && mayHaveCharset) { cleanupCharsets(tokens); } diff --git a/lib/options/optimization-level.js b/lib/options/optimization-level.js index 74e24f78..9c042879 100644 --- a/lib/options/optimization-level.js +++ b/lib/options/optimization-level.js @@ -11,8 +11,25 @@ var DEFAULTS = {}; DEFAULTS[OptimizationLevel.Zero] = {}; DEFAULTS[OptimizationLevel.One] = { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }; DEFAULTS[OptimizationLevel.Two] = { adjacentRulesMerging: true, diff --git a/lib/utils/compatibility.js b/lib/utils/compatibility.js index 0733b91a..c714d1d1 100644 --- a/lib/utils/compatibility.js +++ b/lib/utils/compatibility.js @@ -8,7 +8,6 @@ var DEFAULTS = { backgroundOriginMerging: true, // background-origin to shorthand backgroundSizeMerging: true, // background-size to shorthand colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red` - fontWeight: true, // normal -> '400' ieBangHack: false, // !ie suffix hacks on IE<8 iePrefixHack: false, // underscore / asterisk prefix hacks on IE ieSuffixHack: false, // \9 suffix hacks on IE6-9 diff --git a/test/optimizer/level-1/optimize-test.js b/test/optimizer/level-1/optimize-test.js index f63d7581..cda11b24 100644 --- a/test/optimizer/level-1/optimize-test.js +++ b/test/optimizer/level-1/optimize-test.js @@ -433,7 +433,7 @@ vows.describe('level 1 optimizations') 'a{font:bold .9em sans-serif}', 'a{font:bold .9em sans-serif}' ] - }, { level: 1, compatibility: { properties: { fontWeight: false } } }) + }, { level: { 1: { optimizeFontWeight: false } } }) ) .addBatch( optimizerContext('ie hacks', { @@ -1023,4 +1023,144 @@ vows.describe('level 1 optimizations') ] }, { level: 1 }) ) + .addBatch( + optimizerContext('@charset cleanup off', { + 'stays where it is': [ + '.block{color:#f10}@charset \'utf-8\';b{font-weight:bolder}', + '.block{color:#f10}@charset \'utf-8\';b{font-weight:bolder}' + ] + }, { level: { 1: { cleanupCharsets: false } } }) + ) + .addBatch( + optimizerContext('negative padding optimizations off', { + 'stays as it is': [ + '.block{padding:-2px}', + '.block{padding:-2px}' + ] + }, { level: { 1: { keepNegativePaddings: true } } }) + ) + .addBatch( + optimizerContext('quotes optimizations off', { + 'stays as it is': [ + '.block{font:"Arial"}', + '.block{font:"Arial"}' + ] + }, { level: { 1: { keepQuotes: true } } }) + ) + .addBatch( + optimizerContext('whitespace optimizations off', { + 'stays as it is': [ + '.block{clip:rect(0, 0, 0, 0)}', + '.block{clip:rect(0, 0, 0, 0)}' + ] + }, { level: { 1: { keepWhitespace: true } } }) + ) + .addBatch( + optimizerContext('URL normalization off', { + 'stays as it is': [ + '.block{background:URL(image.png)}', + '.block{background:URL(image.png)}' + ] + }, { rebase: false, level: { 1: { normalizeUrls: false } } }) + ) + .addBatch( + optimizerContext('background optimizations off', { + 'stays as it is': [ + '.block{background:transparent}', + '.block{background:transparent}' + ] + }, { level: { 1: { optimizeBackground: false } } }) + ) + .addBatch( + optimizerContext('border-radius optimizations off', { + 'stays as it is': [ + '.block{border-radius:2px 3px/2px 3px}', + '.block{border-radius:2px 3px/2px 3px}' + ] + }, { level: { 1: { optimizeBorderRadius: false } } }) + ) + .addBatch( + optimizerContext('filter optimizations off', { + 'stays as it is': [ + '.block{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80)}', + '.block{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80)}' + ] + }, { level: { 1: { optimizeFilter: false } } }) + ) + .addBatch( + optimizerContext('font optimizations off', { + 'stays as it is': [ + '.block{font:normal Arial,sans-serif}', + '.block{font:normal Arial,sans-serif}' + ] + }, { level: { 1: { optimizeFont: false } } }) + ) + .addBatch( + optimizerContext('font-weight optimizations off', { + 'stays as it is': [ + '.block{font-weight:bold}', + '.block{font-weight:bold}' + ], + 'stays as it is in font': [ + '.block{font:normal Arial,sans-serif}', + '.block{font:normal Arial,sans-serif}' + ] + }, { level: { 1: { optimizeFontWeight: false } } }) + ) + .addBatch( + optimizerContext('outline optimizations off', { + 'stays as it is': [ + '.block{outline:none}', + '.block{outline:none}' + ] + }, { level: { 1: { optimizeOutline: false } } }) + ) + .addBatch( + optimizerContext('replace multiple zeros optimization off', { + 'stays as it is': [ + '.block{margin:0 0 0 0}', + '.block{margin:0 0 0 0}' + ] + }, { level: { 1: { replaceMultipleZeros: false } } }) + ) + .addBatch( + optimizerContext('replace time units optimizations off', { + 'stays as it is': [ + '.block{animation-duration:500ms}', + '.block{animation-duration:500ms}' + ] + }, { level: { 1: { replaceTimeUnits: false } } }) + ) + .addBatch( + optimizerContext('replace zero units optimizations off', { + 'stays as it is': [ + '.block{margin:010px}', + '.block{margin:010px}' + ] + }, { level: { 1: { replaceZeroUnits: false } } }) + ) + .addBatch( + optimizerContext('tidy at-rules optimizations off', { + 'stays as it is': [ + '@charset "utf-8";', + '@charset "utf-8";' + ] + }, { level: { 1: { tidyAtRules: false } } }) + ) + .addBatch( + optimizerContext('tidy block scopes optimizations off', { + 'stays as it is': [ + '@media ( min-width: 50px ){.block{color:red}}', + '@media ( min-width: 50px ){.block{color:red}}' + ] + }, { level: { 1: { tidyBlockScopes: false } } }) + ) + .addBatch( + optimizerContext('tidy block scopes optimizations off', { + 'stays as it is': [ + '.block > .another-block{color:red}', + '.block > .another-block{color:red}' + ] + }, { level: { 1: { tidySelectors: false } } }) + ) .export(module); diff --git a/test/options/optimization-level-test.js b/test/options/optimization-level-test.js index 33f26499..bed2f878 100644 --- a/test/options/optimization-level-test.js +++ b/test/options/optimization-level-test.js @@ -19,8 +19,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } }, @@ -47,8 +64,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } }, @@ -64,8 +98,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -106,8 +157,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 0 + specialComments: 0, + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -137,8 +205,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 0 + specialComments: 0, + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -168,8 +253,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 0 + specialComments: 0, + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -199,8 +301,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(3), - specialComments: 0 + specialComments: 0, + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } }, @@ -216,8 +335,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -247,8 +383,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -278,8 +431,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -309,8 +479,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); }, 'has level 2 options': function (levelOptions) { @@ -340,8 +527,25 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } }, @@ -357,6 +561,20 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: { 'ch': 4, 'cm': 4, @@ -375,7 +593,10 @@ vows.describe(optimizationLevelFrom) 'vw': 4, '%': 4 }, - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } }, @@ -391,6 +612,20 @@ vows.describe(optimizationLevelFrom) }, 'has level 1 options': function (levelOptions) { assert.deepEqual(levelOptions['1'], { + cleanupCharsets: true, + keepNegativePaddings: false, + keepQuotes: false, + keepWhitespace: false, + normalizeUrls: true, + optimizeBackground: true, + optimizeBorderRadius: true, + optimizeFilter: true, + optimizeFont: true, + optimizeFontWeight: true, + optimizeOutline: true, + replaceMultipleZeros: true, + replaceTimeUnits: true, + replaceZeroUnits: true, roundingPrecision: { 'ch': 5, 'cm': 5, @@ -409,7 +644,10 @@ vows.describe(optimizationLevelFrom) 'vw': 5, '%': 1 }, - specialComments: 'all' + specialComments: 'all', + tidyAtRules: true, + tidyBlockScopes: true, + tidySelectors: true }); } } diff --git a/test/utils/compatibility-test.js b/test/utils/compatibility-test.js index 123adc8a..ed25cf16 100644 --- a/test/utils/compatibility-test.js +++ b/test/utils/compatibility-test.js @@ -14,7 +14,6 @@ vows.describe(compatibility) assert.isTrue(compat.properties.backgroundClipMerging); assert.isTrue(compat.properties.backgroundOriginMerging); assert.isTrue(compat.properties.backgroundSizeMerging); - assert.isTrue(compat.properties.fontWeight); assert.isFalse(compat.properties.ieBangHack); assert.isFalse(compat.properties.iePrefixHack); assert.isFalse(compat.properties.ieSuffixHack); @@ -88,7 +87,6 @@ vows.describe(compatibility) assert.isTrue(compat.properties.backgroundOriginMerging); assert.isTrue(compat.properties.backgroundSizeMerging); assert.isTrue(compat.properties.colors); - assert.isTrue(compat.properties.fontWeight); assert.isFalse(compat.properties.ieBangHack); assert.isFalse(compat.properties.iePrefixHack); assert.isTrue(compat.properties.ieSuffixHack); @@ -121,7 +119,6 @@ vows.describe(compatibility) assert.isFalse(compat.properties.backgroundOriginMerging); assert.isFalse(compat.properties.backgroundSizeMerging); assert.isTrue(compat.properties.colors); - assert.isTrue(compat.properties.fontWeight); assert.isFalse(compat.properties.ieBangHack); assert.isTrue(compat.properties.iePrefixHack); assert.isTrue(compat.properties.ieSuffixHack); @@ -154,7 +151,6 @@ vows.describe(compatibility) assert.isFalse(compat.properties.backgroundOriginMerging); assert.isFalse(compat.properties.backgroundSizeMerging); assert.isTrue(compat.properties.colors); - assert.isTrue(compat.properties.fontWeight); assert.isTrue(compat.properties.ieBangHack); assert.isTrue(compat.properties.iePrefixHack); assert.isTrue(compat.properties.ieSuffixHack); -- 2.34.1