* Adds a better non-adjacent optimizer compatible with the upcoming new property optimizer.
+[2.1.2 / 2014-xx-xx (UNRELEASED)](https://github.com/GoalSmashers/clean-css/compare/v2.1.1...v2.1.2)
+==================
+
+* Fixed issue [#245](https://github.com/GoalSmashers/clean-css/issues/245) - incorrect handling of backslash IE hack.
+
[2.1.1 / 2014-02-18](https://github.com/GoalSmashers/clean-css/compare/v2.1.0...v2.1.1)
==================
data = new SelectorsOptimizer(data, context, {
keepBreaks: options.keepBreaks,
lineBreak: lineBreak,
- selectorsMergeMode: mergeMode
+ selectorsMergeMode: mergeMode,
+ compatibility: options.compatibility
}).process();
});
}
-module.exports = function Optimizer() {
+module.exports = function Optimizer(compatibility) {
var overridable = {
'animation-delay': ['animation'],
'animation-direction': ['animation'],
'-webkit-transition-timing-function': ['-webkit-transition']
};
+ var IE_BACKSLASH_HACK = '\\9';
+
var overrides = {};
for (var granular in overridable) {
for (var i = 0; i < overridable[granular].length; i++) {
var tokens = body.split(';');
var keyValues = [];
- if (tokens.length < 2)
+ if (tokens.length === 0 || (tokens.length == 1 && tokens[0].indexOf(IE_BACKSLASH_HACK) == -1))
return;
for (var i = 0, l = tokens.length; i < l; i++) {
keyValues.push([
token.substring(0, firstColon),
token.substring(firstColon + 1),
- token.indexOf('!important') > -1
+ token.indexOf('!important') > -1,
+ token.indexOf(IE_BACKSLASH_HACK, firstColon + 1) > 0
]);
}
var token = tokens[i];
var property = token[0];
var isImportant = token[2];
+ var isIEHack = token[3];
var _property = (property == '-ms-filter' || property == 'filter') ?
(lastProperty == 'background' || lastProperty == 'background-image' ? lastProperty : property) :
property;
var toOverridePosition = 0;
+ if (!compatibility && isIEHack)
+ continue;
+
// comment is necessary - we assume that if two properties are one after another
// then it is intentional way of redefining property which may not be widely supported
// e.g. a{display:inline-block;display:-moz-inline-box}
if (toOverridePosition == -1)
break;
+ var lastToken = merged[toOverridePosition];
+ var wasIEHack = lastToken[3];
+
if (merged[toOverridePosition][2] && !isImportant)
continue tokensLoop;
+ if (compatibility && !wasIEHack && isIEHack)
+ break;
+
merged.splice(toOverridePosition, 1);
properties.splice(toOverridePosition, 1);
}
var minificationsMade = [];
- var propertyOptimizer = new PropertyOptimizer();
+ var propertyOptimizer = new PropertyOptimizer(options.compatibility);
var cleanUpSelector = function(selectors) {
if (selectors.indexOf(',') == -1)
],
'border\'s none to none': 'a{border:none}p{border-top:none}',
'background:transparent to zero': [
- 'a{background:transparent}p{background transparent url(logo.png)}',
- 'a{background:0 0}p{background transparent url(logo.png)}'
+ 'a{background:transparent}p{background:transparent url(logo.png)}',
+ 'a{background:0 0}p{background:transparent url(logo.png)}'
],
'outline:none to outline:0': [
'a{outline:none}',
"a{font:12px/16px Helvetica-Regular,Arial-Bold}"
]
}),
+ 'IE hacks': cssContext({
+ 'star': 'a{*color:#fff}',
+ 'unserscore': 'a{_color:#fff}',
+ 'backslash': 'a{color:#fff\\9}',
+ 'overriding by a star': 'a{color:red;display:block;*color:#fff}',
+ 'overriding by a unserscore': 'a{color:red;display:block;_color:#fff}',
+ 'overriding by a backslash': 'a{color:red;display:block;color:#fff\\9}',
+ 'overriding !important by a star': 'a{color:red!important;display:block;*color:#fff}',
+ 'overriding !important by a unserscore': 'a{color:red!important;display:block;_color:#fff}',
+ 'overriding !important by a backslash': [
+ 'a{color:red!important;display:block;color:#fff\\9}',
+ 'a{color:red!important;display:block}',
+ ],
+ 'overriding a star': [
+ 'a{*color:red;display:block;*color:#fff}',
+ 'a{display:block;*color:#fff}'
+ ],
+ 'overriding a unserscore': [
+ 'a{_color:red;display:block;_color:#fff}',
+ 'a{display:block;_color:#fff}'
+ ],
+ 'overriding a backslash': [
+ 'a{color:red\\9;display:block;color:#fff\\9}',
+ 'a{display:block;color:#fff\\9}'
+ ],
+ 'overriding a star by a non-ajacent selector': 'a{color:red}.one{display:block}a{*color:#fff}',
+ 'overriding a unserscore by a non-ajacent selector': 'a{color:red}.one{display:block}a{_color:#fff}',
+ 'overriding a backslash by a non-ajacent selector': 'a{color:red}.one{display:block}a{color:#fff\\9}'
+ }, { compatibility: 'ie8' }),
+ 'IE hacks without IE compatibility': cssContext({
+ 'star': 'a{*color:#fff}', // See #246
+ 'unserscore': 'a{_color:#fff}', // See #246
+ 'backslash': [
+ 'a{color:#fff\\9}',
+ ''
+ ]
+ }),
'animations': cssContext({
'shorten': [
'@keyframes test\n{ from\n { width:100px; }\n to { width:200px; }\n}',