==================
* Adds more detailed error & warning messages on top of the new tokenizer.
+* Disables restructuring optimizations by default until optimized in #533.
* Fixes a bug ignoring incorrect properties in complex restructuring.
* Requires Node.js 4.0+ to run.
* Removes `benchmark` API option as total time is always reported under `stats` property.
cleancss -O2 one.css
cleancss -O2 mediaMerging:off;restructuring:off;semanticMerging:on;shorthandCompacting:off one.css
# `mediaMerging` controls `@media` merging behavior; defaults to `on` (alias to `true`)
-# `restructuring` controls content restructuring behavior; defaults `on` (alias to `true`)
+# `restructuring` controls content restructuring behavior; defaults `off` (alias to `false`)
# `semanticMerging` controls semantic merging behavior; defaults to `off` (alias to `false`)
# `shorthandCompacting` controls shorthand compacting behavior; defaults to `on` (alias to `true`)
```
level: {
2: {
mediaMerging: true, // controls `@media` merging behavior; defaults to true
- restructuring: false, // controls content restructuring behavior; defaults to true
+ restructuring: false, // controls content restructuring behavior; defaults to false
semanticMerging: false, // controls semantic merging behavior; defaults to false
shorthandCompacting: true // controls shorthand compacting behavior; defaults to true
}
console.log(' %> cleancss -O2 one.css');
console.log(' %> cleancss -O2 mediaMerging:off;restructuring:off;semanticMerging:on;shorthandCompacting:off one.css');
console.log(' %> # `mediaMerging` controls `@media` merging behavior; defaults to `on` (alias to `true`)');
- console.log(' %> # `restructuring` controls content restructuring behavior; defaults to `on` (alias to `true`)');
+ console.log(' %> # `restructuring` controls content restructuring behavior; defaults to `off` (alias to `false`)');
console.log(' %> # `semanticMerging` controls semantic merging behavior; defaults to `off` (alias to `false`)');
console.log(' %> # `shorthandCompacting` controls shorthand compacting behavior; defaults to `on` (alias to `true`)');
};
DEFAULTS[OptimizationLevel.Two] = {
mediaMerging: true,
- restructuring: true,
+ restructuring: false,
semanticMerging: false,
shorthandCompacting: true
};
new CleanCSS({
compatibility: isIE7Mode ? 'ie7' : '*',
keepBreaks: true,
- level: 2
+ level: {
+ 2: {
+ restructuring: true
+ }
+ }
}).minify(data.input, this.callback.bind(null, data));
},
'outputs right content': function (data, error, output) {
new CleanCSS({
compatibility: isIE7Mode ? 'ie7' : '*',
keepBreaks: true,
- level: 2,
+ level: {
+ 2: {
+ restructuring: true
+ }
+ },
sourceMap: true
}).minify(data.input, this.callback.bind(null, data));
},
'minifying via CLI': {
'topic': function (data) {
exec(
- '__DIRECT__=1 ./bin/cleancss -b -O2 ' + (isIE7Mode ? '-c ie7 ' : '') + path.join(dir, filename),
+ '__DIRECT__=1 ./bin/cleancss -b -O2 restructuring:on ' + (isIE7Mode ? '-c ie7 ' : '') + path.join(dir, filename),
{ maxBuffer: 500 * 1024 },
this.callback.bind(null, data)
);
})
})
.addBatch({
- 'skip restructuring optimizations': pipedContext('div{margin-top:0}.one{margin:0}.two{display:block;margin-top:0}', '-O2 restructuring:off', {
+ 'enable restructuring optimizations': pipedContext('div{margin-top:0}.one{margin:0}.two{display:block;margin-top:0}', '-O2 restructuring:on', {
'should do basic optimizations only': function (error, stdout) {
- assert.equal(stdout, 'div{margin-top:0}.one{margin:0}.two{display:block;margin-top:0}');
+ assert.equal(stdout, '.two,div{margin-top:0}.one{margin:0}.two{display:block}');
}
})
})
'.one{color:red;margin:0}.two{color:red}.one{margin:0}',
'.one,.two{color:red}.one{margin:0}'
]
- }, { level: 2 })
+ }, { level: { 2: { restructuring: true } } })
)
.addBatch(
optimizerContext('units - IE8 compatibility', {
],
'two same bodies over a block': [
'.one{color:red}@media print{.two{display:block}}.three{color:red}',
- '.one,.three{color:red}@media print{.two{display:block}}'
+ '.one{color:red}@media print{.two{display:block}}.three{color:red}'
],
'two rules with latter with suffix properties': [
'a{display:none}a{display:none;visibility:hidden}',
]
}, { level: 2 })
)
+ .addBatch(
+ optimizerContext('with level 2 on - and restructuring on', {
+ 'two same bodies over a block': [
+ '.one{color:red}@media print{.two{display:block}}.three{color:red}',
+ '.one,.three{color:red}@media print{.two{display:block}}'
+ ],
+ }, { level: { 2: { restructuring: true } } })
+ )
.addBatch(
optimizerContext('with level 2 off', {
'same context': [
'.block1__element{color:#000}.block1__element--modifier{color:red}.block2{color:#000;display:block;width:100%}'
// '.block1__element,.block2{color:#000}.block1__element--modifier{color:red}.block2{display:block;width:100%}' - pending #588
]
- }, { level: { 2: { semanticMerging: true } } })
+ }, { level: { 2: { restructuring: true, semanticMerging: true } } })
)
.addBatch(
optimizerContext('IE8 compatibility', {
],
'multiple selectors': [
'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}',
- '.one,a,p{color:red}a{margin:0}a,p{padding:0}'
+ 'a{margin:0;color:red}.one{color:red}a,p{color:red;padding:0}'
],
'with one redefined property': [
'a{color:red;display:block}.one{color:red}a{color:#fff;margin:2px}',
'a{padding:10px}.one{color:red}a{}',
'a{padding:10px}.one{color:red}'
],
- 'when overriden by a complex selector': [
- 'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}',
- '.one,a,p{color:red}a{margin:0}a,p{padding:0}'
- ],
- 'when overriden by complex selectors': [
+ 'when overriden by a complex selectors': [
'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}.one,a{color:#fff}',
'a{margin:0}a,p{color:red;padding:0}.one,a{color:#fff}'
],
]
}, { level: 2 })
)
+ .addBatch(
+ optimizerContext('level 2 on and restructuring on', {
+ 'multiple selectors': [
+ 'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}',
+ '.one,a,p{color:red}a{margin:0}a,p{padding:0}'
+ ],
+ 'when overriden by a complex selectors': [
+ 'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}.one,a{color:#fff}',
+ 'a{margin:0}a,p{color:red;padding:0}.one,a{color:#fff}'
+ ]
+ }, { level: { 2: { restructuring: true } } })
+ )
.addBatch(
optimizerContext('level 2 on and aggressive merging off', {
'non-adjacent with multi selectors': [
'a{padding:10px;margin:0;color:red}.one{color:red}a,p{color:red;padding:0}',
'.one,a,p{color:red}a{padding:10px;margin:0}a,p{padding:0}'
]
- }, { aggressiveMerging: false, level: 2 })
+ }, { aggressiveMerging: false, level: { 2: { restructuring: true } } })
)
.addBatch(
optimizerContext('level 2 off', {
'.one{border-color:#000;border-bottom-color:rgb(0,0,0,.2)}.two{border-color:#fff;border-bottom-color:rgb(0,0,0,.2)}',
'.one{border-color:#000;border-bottom-color:rgb(0,0,0,.2)}.two{border-color:#fff;border-bottom-color:rgb(0,0,0,.2)}'
]
- }, { level: 2 })
+ }, { level: { 2: { restructuring: true } } })
)
.addBatch(
optimizerContext('level 2 off', {
'has level 2 options': function (levelOptions) {
assert.deepEqual(levelOptions['2'], {
mediaMerging: true,
- restructuring: true,
+ restructuring: false,
semanticMerging: false,
shorthandCompacting: true
});
'has level 2 options': function (levelOptions) {
assert.deepEqual(levelOptions['2'], {
mediaMerging: true,
- restructuring: true,
+ restructuring: false,
semanticMerging: false,
shorthandCompacting: true
});
'has level 2 options': function (levelOptions) {
assert.deepEqual(levelOptions['2'], {
mediaMerging: false,
- restructuring: true,
+ restructuring: false,
semanticMerging: true,
shorthandCompacting: true
});
'has level 2 options': function (levelOptions) {
assert.deepEqual(levelOptions['2'], {
mediaMerging: false,
- restructuring: true,
+ restructuring: false,
semanticMerging: true,
shorthandCompacting: true
});
'level 2 optimizations': {
'new property in restructuring': {
'topic': function () {
- return new CleanCSS({ level: 2, sourceMap: true }).minify('a{color:#000}div{color:red}.one{display:block}.two{display:inline;color:red}');
+ return new CleanCSS({ level: { 2: { restructuring: true } }, sourceMap: true }).minify('a{color:#000}div{color:red}.one{display:block}.two{display:inline;color:red}');
},
'has right output': function (minified) {
assert.equal(minified.styles, 'a{color:#000}.two,div{color:red}.one{display:block}.two{display:inline}');