* Adds a warning on an incorrect content or a closing parenthesis.
* Fixed issue [#163](https://github.com/GoalSmashers/clean-css/issues/163) - round pixels to 2nd decimal place.
* Fixed issue [#165](https://github.com/GoalSmashers/clean-css/issues/165) - extra space after trailing parenthesis.
+[2.0.2 / 2013-xx-xx (UNRELEASED)](https://github.com/GoalSmashers/clean-css/compare/v2.0.1...HEAD)
+==================
+
+* Fixed issue [#177](https://github.com/GoalSmashers/clean-css/issues/177) - process broken content correctly.
+
[2.0.1 / 2013-11-14](https://github.com/GoalSmashers/clean-css/compare/v2.0.0...v2.0.1)
==================
if (!options.noAdvanced) {
replace(function optimizeSelectors() {
- data = new SelectorsOptimizer(data, {
+ data = new SelectorsOptimizer(data, context, {
keepBreaks: options.keepBreaks,
lineBreak: lineBreak,
selectorsMergeMode: options.selectorsMergeMode
var Tokenizer = require('./tokenizer');
var PropertyOptimizer = require('../properties/optimizer');
-module.exports = function Optimizer(data, options) {
+module.exports = function Optimizer(data, context, options) {
var specialSelectors = {
'*': /\-(moz|ms|o|webkit)\-/,
'ie8': /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:not|:target|:visited|:empty|:first\-of|:last|:nth|:only|:root)/
return {
process: function() {
- var tokenized = new Tokenizer(data).process();
+ var tokenized = new Tokenizer(data, context).process();
optimize(tokenized);
return rebuild(tokenized);
}
/* jshint latedef: false */
-module.exports = function Tokenizer(data) {
+module.exports = function Tokenizer(data, minifyContext) {
var chunker = new Chunker(data, 128);
var chunk = chunker.next();
tokenized.push({ selector: selector, body: body });
} else if (what == 'bodyEnd') {
// extra closing brace at the top level can be safely ignored
- if (context.mode == 'top' && data[context.cursor] == '}') {
- context.cursor += 1;
+ if (context.mode == 'top') {
+ var at = context.cursor;
+ var warning = chunk[context.cursor] == '}' ?
+ 'Unexpected \'}\' in \'' + chunk.substring(at - 20, at + 20) + '\'. Ignoring.' :
+ 'Unexpected content: \'' + chunk.substring(at, nextSpecial + 1) + '\'. Ignoring.';
+
+ minifyContext.warnings.push(warning);
+ context.cursor = nextSpecial + 1;
continue;
}
assert.match(minifier.warnings[0], /Both 'root' and output file given/);
}
},
+ 'warnings on extra closing brace': {
+ topic: function() {
+ var minifier = new CleanCSS();
+ var minified = minifier.minify('a{display:block}}');
+ this.callback(null, minified, minifier);
+ },
+ 'should minify correctly': function(error, minified) {
+ assert.equal(minified, 'a{display:block}');
+ },
+ 'should raise no errors': function(error, minified, minifier) {
+ assert.equal(minifier.errors.length, 0);
+ },
+ 'should raise one warning': function(error, minified, minifier) {
+ assert.equal(minifier.warnings.length, 1);
+ assert.equal(minifier.warnings[0], 'Unexpected \'}\' in \'a{display:block}}\'. Ignoring.');
+ }
+ },
+ 'warnings on unexpected body': {
+ topic: function() {
+ var minifier = new CleanCSS();
+ var minified = minifier.minify('a{display:block}color:#535353}p{color:red}');
+ this.callback(null, minified, minifier);
+ },
+ 'should minify correctly': function(error, minified) {
+ assert.equal(minified, 'a{display:block}p{color:red}');
+ },
+ 'should raise no errors': function(error, minified, minifier) {
+ assert.equal(minifier.errors.length, 0);
+ },
+ 'should raise one warning': function(error, minified, minifier) {
+ assert.equal(minifier.warnings.length, 1);
+ assert.equal(minifier.warnings[0], 'Unexpected content: \'color:#535353}\'. Ignoring.');
+ }
+ },
'no errors': {
topic: function() {
var minifier = new CleanCSS();