* Fixed issue [#416](https://github.com/GoalSmashers/clean-css/issues/416) - accepts hash as `minify` argument.
* Fixed issue [#435](https://github.com/GoalSmashers/clean-css/issues/435) - `background-clip` in shorthand.
* Fixed issue [#439](https://github.com/GoalSmashers/clean-css/issues/439) - `background-origin` in shorthand.
+* Fixed issue [#442](https://github.com/GoalSmashers/clean-css/issues/442) - space before adjacent `nav`.
[3.0.7 / 2015-01-22](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.6...v3.0.7)
==================
* `'[+-]properties.backgroundSizeMerging'` - turn on / off background-size merging into shorthand
* `'[+-]properties.merging'` - turn on / off property merging based on understandability
* `'[+-]properties.spaceAfterClosingBrace'` - turn on / off removing space after closing brace - `url() no-repeat` into `url()no-repeat`
+* `'[+-]selectors.adjacentSpace'` - turn on / off extra space before `nav` element
* `'[+-]selectors.ie7Hack'` - turn on / off IE7 selector hack removal (`*+html...`)
* `'[+-]units.rem'` - turn on / off treating `rem` as a proper unit
AdvancedOptimizer.prototype.mergeAdjacent = function (tokens) {
var forRemoval = [];
var lastToken = { selector: null, body: null };
+ var adjacentSpace = this.options.compatibility.selectors.adjacentSpace;
for (var i = 0, l = tokens.length; i < l; i++) {
var token = tokens[i];
!this.isSpecial(token.metadata.selector) && !this.isSpecial(lastToken.metadata.selector)) {
changeSelectorOf(
lastToken,
- CleanUp.selectors(lastToken.value.concat(token.value), false)
+ CleanUp.selectors(lastToken.value.concat(token.value), false, adjacentSpace)
);
forRemoval.push(i);
} else {
AdvancedOptimizer.prototype.mergeNonAdjacentByBody = function (tokens) {
var candidates = {};
+ var adjacentSpace = this.options.compatibility.selectors.adjacentSpace;
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
if (oldToken && !this.isSpecial(token.metadata.selector) && !this.isSpecial(oldToken.metadata.selector)) {
changeSelectorOf(
token,
- CleanUp.selectors(oldToken.value.concat(token.value), false)
+ CleanUp.selectors(oldToken.value.concat(token.value), false, adjacentSpace)
);
oldToken.body = [];
}
var CleanUp = {
- selectors: function (selectors, removeUnsupported) {
+ selectors: function (selectors, removeUnsupported, adjacentSpace) {
var plain = [];
var tokenized = [];
.replace(/\s*([>\+\~])\s*/g, '$1')
.trim();
+ if (adjacentSpace && reduced.indexOf('nav') > 0)
+ reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1');
+
if (removeUnsupported && (reduced.indexOf('*+html ') != -1 || reduced.indexOf('*:first-child+html ') != -1))
continue;
break;
if (token.kind == 'selector') {
- var newSelectors = CleanUp.selectors(token.value, !options.compatibility.selectors.ie7Hack);
+ var newSelectors = CleanUp.selectors(token.value, !options.compatibility.selectors.ie7Hack, options.compatibility.selectors.adjacentSpace);
token.value = newSelectors.tokenized;
if (token.value.length === 0) {
spaceAfterClosingBrace: false // 'url() no-repeat' to 'url()no-repeat'
},
selectors: {
+ adjacentSpace: false, // div+ nav Android stock browser hack
ie7Hack: false, // *+html hack
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:dir\([a-z-]*\)|:first(?![a-z-])|:fullscreen|:left|:read-only|:read-write|:right)/ // special selectors which prevent merging
},
spaceAfterClosingBrace: true
},
selectors: {
+ adjacentSpace: false,
ie7Hack: false,
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not)/
},
spaceAfterClosingBrace: true
},
selectors: {
+ adjacentSpace: false,
ie7Hack: true,
special: /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:focus|:before|:after|:root|:nth|:first\-of|:last|:only|:empty|:target|:checked|::selection|:enabled|:disabled|:not)/
},
'of supported and unsupported selector': '.one{color:red}.two:last-child{color:red}',
'of two unsupported selectors': '.one:before{color:red}.two:last-child{color:red}'
}, { compatibility: 'ie7' }),
+ 'same bodies - +adjacentSpace': cssContext({
+ 'of two supported selectors': [
+ '.one{color:red}.two + nav{color:red}',
+ '.one,.two+ nav{color:red}'
+ ]
+ }, { compatibility: { selectors: { adjacentSpace: true } } }),
'units - IE8 compatibility': cssContext({
'rems': 'div{padding-top:16px;padding-top:1rem}'
}, { compatibility: 'ie8' }),
'+html': [
'*+html .foo{display:inline}',
null
+ ],
+ 'adjacent nav': [
+ 'div + nav{}',
+ [{ value: 'div+nav' }]
]
})
)
]
}, { compatibility: 'ie7' })
)
+ .addBatch(
+ selectorContext('+adjacentSpace', {
+ 'with whitespace': [
+ 'div + nav{}',
+ [{ value: 'div+ nav' }]
+ ],
+ 'without whitespace': [
+ 'div+nav{}',
+ [{ value: 'div+ nav' }]
+ ]
+ }, { compatibility: { selectors: { adjacentSpace: true } } })
+ )
.addBatch(
propertyContext('@background', {
'none to 0 0': [
]
}, { compatibility: 'ie8' })
)
+ .addBatch(
+ propertyContext('whitespace in compatibility mode', {
+ 'stripped spaces': [
+ 'div{text-shadow:rgba(255,1,1,.5) 1px}',
+ ['text-shadow:rgba(255,1,1,.5) 1px']
+ ]
+ }, { compatibility: 'ie8' })
+ )
.export(module);
'gets default options': function(options) {
assert.isFalse(options.properties.iePrefixHack);
assert.isFalse(options.properties.ieSuffixHack);
+ assert.isFalse(options.selectors.adjacentSpace);
assert.isFalse(options.selectors.ie7Hack);
assert.isFalse(options.properties.backgroundSizeMerging);
assert.isTrue(options.properties.merging);
'gets merged options': function(options) {
assert.isFalse(options.properties.iePrefixHack);
assert.isFalse(options.properties.ieSuffixHack);
+ assert.isFalse(options.selectors.adjacentSpace);
assert.isFalse(options.selectors.ie7Hack);
assert.isFalse(options.properties.backgroundSizeMerging);
assert.isTrue(options.properties.merging);
'gets template options': function(options) {
assert.isTrue(options.properties.iePrefixHack);
assert.isTrue(options.properties.ieSuffixHack);
+ assert.isFalse(options.selectors.adjacentSpace);
assert.isFalse(options.selectors.ie7Hack);
assert.isFalse(options.properties.backgroundSizeMerging);
assert.isFalse(options.properties.merging);
assert.isTrue(options.properties.iePrefixHack);
assert.isTrue(options.properties.ieSuffixHack);
assert.isTrue(options.selectors.ie7Hack);
+ assert.isFalse(options.selectors.adjacentSpace);
assert.isFalse(options.properties.backgroundSizeMerging);
assert.isFalse(options.properties.merging);
assert.isTrue(options.properties.spaceAfterClosingBrace);