Skip to content

Commit

Permalink
Refixes #556 - IE backslash hacks.
Browse files Browse the repository at this point in the history
Apparently turning all backslash hacks into `\9` hack is not desirable
strategy, as, for example, `\0` hack has a different meaning.
  • Loading branch information
jakubpawlowicz committed Mar 20, 2017
1 parent 3f211cd commit 4d7ca3c
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 38 deletions.
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -2,6 +2,7 @@
==================

* Fixed issue [#917](https://github.com/jakubpawlowicz/clean-css/issues/917) - prevents grid area unquoting.
* Refixed issue [#556](https://github.com/jakubpawlowicz/clean-css/issues/917) - IE backslash hacks.

[4.0.9 / 2017-03-15](https://github.com/jakubpawlowicz/clean-css/compare/v4.0.8...v4.0.9)
==================
Expand Down
6 changes: 3 additions & 3 deletions lib/optimizer/level-1/optimize.js
Expand Up @@ -445,9 +445,9 @@ function optimizeBody(properties, context) {
}

if (property.hack && (
(property.hack == Hack.ASTERISK || property.hack == Hack.UNDERSCORE) && !options.compatibility.properties.iePrefixHack ||
property.hack == Hack.BACKSLASH && !options.compatibility.properties.ieSuffixHack ||
property.hack == Hack.BANG && !options.compatibility.properties.ieBangHack)) {
(property.hack[0] == Hack.ASTERISK || property.hack[0] == Hack.UNDERSCORE) && !options.compatibility.properties.iePrefixHack ||
property.hack[0] == Hack.BACKSLASH && !options.compatibility.properties.ieSuffixHack ||
property.hack[0] == Hack.BANG && !options.compatibility.properties.ieBangHack)) {
property.unused = true;
}

Expand Down
5 changes: 4 additions & 1 deletion lib/optimizer/level-2/properties/override-properties.js
Expand Up @@ -251,7 +251,10 @@ function overrideProperties(properties, withMerging, compatibility, validator) {
if (left.hack && !right.hack && !right.important || !left.hack && !left.important && right.hack)
continue;

if (left.important == right.important && left.hack != right.hack)
if (left.important == right.important && left.hack[0] != right.hack[0])
continue;

if (left.important == right.important && (left.hack[0] != right.hack[0] || (left.hack[1] && left.hack[1] != right.hack[1])))
continue;

if (hasInherit(right))
Expand Down
12 changes: 6 additions & 6 deletions lib/optimizer/restore-from-optimizing.js
Expand Up @@ -3,7 +3,7 @@ var Hack = require('./hack');
var Marker = require('../tokenizer/marker');

var ASTERISK_HACK = '*';
var BACKSLASH_HACK = '\\9';
var BACKSLASH_HACK = '\\';
var IMPORTANT_TOKEN = '!important';
var UNDERSCORE_HACK = '_';
var BANG_HACK = '!ie';
Expand Down Expand Up @@ -55,13 +55,13 @@ function restoreImportant(property) {
}

function restoreHack(property) {
if (property.hack == Hack.UNDERSCORE) {
if (property.hack[0] == Hack.UNDERSCORE) {
property.name = UNDERSCORE_HACK + property.name;
} else if (property.hack == Hack.ASTERISK) {
} else if (property.hack[0] == Hack.ASTERISK) {
property.name = ASTERISK_HACK + property.name;
} else if (property.hack == Hack.BACKSLASH) {
property.value[property.value.length - 1][1] += BACKSLASH_HACK;
} else if (property.hack == Hack.BANG) {
} else if (property.hack[0] == Hack.BACKSLASH) {
property.value[property.value.length - 1][1] += BACKSLASH_HACK + property.hack[1];
} else if (property.hack[0] == Hack.BANG) {
property.value[property.value.length - 1][1] += Marker.SPACE + BANG_HACK;
}
}
Expand Down
32 changes: 16 additions & 16 deletions lib/optimizer/wrap-for-optimizing.js
Expand Up @@ -82,26 +82,26 @@ function isMultiplex(property) {
return false;
}

function hackType(property) {
var type = false;
function hackFrom(property) {
var match = false;
var name = property[1][1];
var lastValue = property[property.length - 1];

if (name[0] == Match.UNDERSCORE) {
type = Hack.UNDERSCORE;
match = [Hack.UNDERSCORE];
} else if (name[0] == Match.ASTERISK) {
type = Hack.ASTERISK;
match = [Hack.ASTERISK];
} else if (lastValue[1][0] == Match.BANG && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN)) {
type = Hack.BANG;
match = [Hack.BANG];
} else if (lastValue[1].indexOf(Match.BANG) > 0 && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN) && Match.BANG_SUFFIX_PATTERN.test(lastValue[1])) {
type = Hack.BANG;
match = [Hack.BANG];
} else if (lastValue[1].indexOf(Match.BACKSLASH) > 0 && lastValue[1].indexOf(Match.BACKSLASH) == lastValue[1].length - Match.BACKSLASH.length - 1) {
type = Hack.BACKSLASH;
match = [Hack.BACKSLASH, lastValue[1].substring(lastValue[1].indexOf(Match.BACKSLASH) + 1)];
} else if (lastValue[1].indexOf(Match.BACKSLASH) === 0 && lastValue[1].length == 2) {
type = Hack.BACKSLASH;
match = [Hack.BACKSLASH, lastValue[1].substring(1)];
}

return type;
return match;
}

function isImportant(property) {
Expand Down Expand Up @@ -142,10 +142,10 @@ function stripPrefixHack(property) {
property[1][1] = property[1][1].substring(1);
}

function stripSuffixHack(property, hackType) {
function stripSuffixHack(property, hackFrom) {
var lastValue = property[property.length - 1];
lastValue[1] = lastValue[1]
.substring(0, lastValue[1].indexOf(hackType == Hack.BACKSLASH ? Match.BACKSLASH : Match.BANG))
.substring(0, lastValue[1].indexOf(hackFrom[0] == Hack.BACKSLASH ? Match.BACKSLASH : Match.BANG))
.trim();

if (lastValue[1].length === 0) {
Expand All @@ -159,18 +159,18 @@ function wrapSingle(property) {
stripImportant(property);
}

var hackProperty = hackType(property);
if (hackProperty == Hack.ASTERISK || hackProperty == Hack.UNDERSCORE) {
var whichHack = hackFrom(property);
if (whichHack[0] == Hack.ASTERISK || whichHack[0] == Hack.UNDERSCORE) {
stripPrefixHack(property);
} else if (hackProperty == Hack.BACKSLASH || hackProperty == Hack.BANG) {
stripSuffixHack(property, hackProperty);
} else if (whichHack[0] == Hack.BACKSLASH || whichHack[0] == Hack.BANG) {
stripSuffixHack(property, whichHack);
}

return {
block: property[2] && property[2][0] == Token.PROPERTY_BLOCK,
components: [],
dirty: false,
hack: hackProperty,
hack: whichHack,
important: importantProperty,
name: property[1][1],
multiplex: property.length > 3 ? isMultiplex(property) : false,
Expand Down
24 changes: 20 additions & 4 deletions test/optimizer/level-1/optimize-test.js
Expand Up @@ -513,7 +513,11 @@ vows.describe('level 1 optimizations')
'a{*width:101px}',
''
],
'backslash': [
'\\0 backslash': [
'a{width:101px\\0}',
''
],
'\\9 backslash': [
'a{width:101px\\9}',
''
],
Expand All @@ -537,7 +541,11 @@ vows.describe('level 1 optimizations')
'a{*width:101px}',
''
],
'backslash': [
'\\0 backslash': [
'a{width:101px\\0}',
'a{width:101px\\0}'
],
'\\9 backslash': [
'a{width:101px\\9}',
'a{width:101px\\9}'
],
Expand All @@ -557,7 +565,11 @@ vows.describe('level 1 optimizations')
'a{*width:101px}',
'a{*width:101px}'
],
'backslash': [
'\\0 backslash': [
'a{width:101px\\0}',
'a{width:101px\\0}'
],
'\\9 backslash': [
'a{width:101px\\9}',
'a{width:101px\\9}'
],
Expand All @@ -577,7 +589,11 @@ vows.describe('level 1 optimizations')
'a{*width:101px}',
'a{*width:101px}'
],
'backslash': [
'\\0 backslash': [
'a{width:101px\\0}',
'a{width:101px\\0}'
],
'\\9 backslash': [
'a{width:101px\\9}',
'a{width:101px\\9}'
],
Expand Down
12 changes: 12 additions & 0 deletions test/optimizer/level-2/optimize-test.js
Expand Up @@ -23,9 +23,21 @@ vows.describe('level 2 optimizer')
'units': [
'.one{width:1px;width:1rem;display:block}.two{color:red}.one{width:2px;width:1.1rem}',
'.one{display:block;width:1.1rem}.two{color:red}'
],
'backslash hacks': [
'.block{color:red\\9;color:#0f0\\0}',
''
]
}, { level: 2 })
)
.addBatch(
optimizerContext('in ie8 compatibility mode', {
'backslash hacks': [
'.block{color:red\\9;color:#0f0\\0}',
'.block{color:red\\9;color:#0f0\\0}'
]
}, { compatibility: 'ie8', level: 2 })
)
.addBatch(
optimizerContext('level 2 off', {
'repeated' : [
Expand Down
16 changes: 8 additions & 8 deletions test/optimizer/wrap-for-optimizing-test.js
Expand Up @@ -346,7 +346,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].name, 'color');
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'underscore');
assert.deepEqual(wrapped[0].hack, ['underscore']);
}
},
'star hack': {
Expand All @@ -366,7 +366,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].name, 'color');
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'asterisk');
assert.deepEqual(wrapped[0].hack, ['asterisk']);
}
},
'backslash hack': {
Expand All @@ -386,7 +386,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
assert.deepEqual(wrapped[0].hack, ['backslash', '9']);
}
},
'backslash hack - single value': {
Expand Down Expand Up @@ -427,7 +427,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
assert.deepEqual(wrapped[0].hack, ['backslash', '9']);
}
},
'bang hack': {
Expand All @@ -447,7 +447,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'bang');
assert.deepEqual(wrapped[0].hack, ['bang']);
},
'is not important': function (wrapped) {
assert.isFalse(wrapped[0].important);
Expand All @@ -470,7 +470,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'bang');
assert.deepEqual(wrapped[0].hack, ['bang']);
},
'is not important': function (wrapped) {
assert.isFalse(wrapped[0].important);
Expand All @@ -494,7 +494,7 @@ vows.describe(wrapForOptimizing)
assert.deepEqual(wrapped[0].value, [['property-value', '0']]);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'bang');
assert.deepEqual(wrapped[0].hack, ['bang']);
},
'is not important': function (wrapped) {
assert.isFalse(wrapped[0].important);
Expand All @@ -520,7 +520,7 @@ vows.describe(wrapForOptimizing)
assert.isTrue(wrapped[0].important);
},
'is a hack': function (wrapped) {
assert.equal(wrapped[0].hack, 'backslash');
assert.deepEqual(wrapped[0].hack, ['backslash', '9']);
}
},
'source map': {
Expand Down

0 comments on commit 4d7ca3c

Please sign in to comment.