Skip to content

Commit

Permalink
Merge branch 'master' into rename
Browse files Browse the repository at this point in the history
# Conflicts:
#	lib/compressor/index.js
  • Loading branch information
lahmatiy committed Jun 22, 2016
2 parents dd26920 + 96896f9 commit 82ca18c
Show file tree
Hide file tree
Showing 21 changed files with 158 additions and 38 deletions.
18 changes: 9 additions & 9 deletions lib/compressor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var rename = require('./rename');
var restructureBlock = require('./restructure');
var walkRules = require('../utils/walk').rules;

function readRulesChunk(rules, firstAtrulesAllowed, specialComments) {
function readRulesChunk(rules, specialComments) {
var buffer = new List();
var nonSpaceTokenInBuffer = false;
var protectedComment;
Expand Down Expand Up @@ -39,17 +39,17 @@ function readRulesChunk(rules, firstAtrulesAllowed, specialComments) {
comment: protectedComment,
stylesheet: {
type: 'StyleSheet',
firstAtrulesAllowed: firstAtrulesAllowed,
info: null,
rules: buffer
}
};
}

function compressChunk(ast, usageData, renameSettings, logger) {
function compressChunk(ast, firstAtrulesAllowed, usageData, renameSettings, logger) {
var seed = 1;
ast.firstAtrulesAllowed = ast.firstAtrulesAllowed;
walkRules(ast, function() {
if (!this.stylesheet.id) {
walkRules(ast, function markStylesheets() {
if ('id' in this.stylesheet === false) {
this.stylesheet.firstAtrulesAllowed = firstAtrulesAllowed;
this.stylesheet.id = seed++;
}
});
Expand Down Expand Up @@ -89,7 +89,7 @@ function wrapBlock(block) {
}

module.exports = function compress(ast, options) {
ast = ast || { type: 'StyleSheet', rules: new List() };
ast = ast || { type: 'StyleSheet', info: null, rules: new List() };
options = options || {};

var logger = typeof options.logger === 'function' ? options.logger : Function();
Expand All @@ -116,10 +116,10 @@ module.exports = function compress(ast, options) {
}

do {
chunk = readRulesChunk(inputRules, firstAtrulesAllowed, Boolean(specialComments));
chunk = readRulesChunk(inputRules, Boolean(specialComments));

logger('Compress block #' + (chunkNum++), null, true);
compressChunk(chunk.stylesheet, usageData, rename, logger);
compressChunk(chunk.stylesheet, firstAtrulesAllowed, usageData, rename, logger);

// structure optimisations
if (restructure) {
Expand Down
4 changes: 4 additions & 0 deletions lib/compressor/restructure/4-restructShorthand.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ TRBL.prototype.getValueSequence = function(value, count) {
case 'Percentage':
break;

case 'Function':
special = child.name;
break;

case 'Space':
return false; // ignore space

Expand Down
41 changes: 28 additions & 13 deletions lib/compressor/restructure/8-restructRuleset.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ function calcDeclarationsLength(tokens) {
);
}

function inList(selector) {
return selector.compareMarker in this;
}

function processRuleset(node, item, list) {
var avoidRulesMerge = this.stylesheet.avoidRulesMerge;
var selectors = node.selector.selectors;
var block = node.block;
var skippedCompareMarkers = Object.create(null);
var disallowDownMarkers = Object.create(null);
var allowMergeUp = true;
var allowMergeDown = true;

list.prevUntil(item.prev, function(prev, prevItem) {
// skip non-ruleset node if safe
Expand All @@ -48,13 +46,17 @@ function processRuleset(node, item, list) {
return true;
}

allowMergeDown = !prevSelectors.some(function(selector) {
return selector.compareMarker in disallowDownMarkers;
});

// try prev ruleset if simpleselectors has no equal specifity and element selector
if (prevSelectors.some(inList, skippedCompareMarkers)) {
if (!allowMergeDown && !allowMergeUp) {
return true;
}

// try to join by selectors
if (utils.isEqualLists(prevSelectors, selectors)) {
if (allowMergeUp && utils.isEqualLists(prevSelectors, selectors)) {
prevBlock.declarations.appendList(block.declarations);
list.remove(item);
return true;
Expand All @@ -68,8 +70,11 @@ function processRuleset(node, item, list) {
if (diff.eq.length) {
if (!diff.ne1.length && !diff.ne2.length) {
// equal blocks
utils.addSelectors(selectors, prevSelectors);
list.remove(prevItem);
if (allowMergeDown) {
utils.addSelectors(selectors, prevSelectors);
list.remove(prevItem);
}

return true;
} else if (!avoidRulesMerge) { /* probably we don't need to prevent those merges for @keyframes
TODO: need to be checked */
Expand All @@ -79,7 +84,7 @@ function processRuleset(node, item, list) {
var selectorLength = calcSelectorLength(selectors);
var blockLength = calcDeclarationsLength(diff.eq); // declarations length

if (selectorLength < blockLength) {
if (allowMergeUp && selectorLength < blockLength) {
utils.addSelectors(prevSelectors, selectors);
block.declarations = new List(diff.ne1);
}
Expand All @@ -88,7 +93,7 @@ function processRuleset(node, item, list) {
var selectorLength = calcSelectorLength(prevSelectors);
var blockLength = calcDeclarationsLength(diff.eq); // declarations length

if (selectorLength < blockLength) {
if (allowMergeDown && selectorLength < blockLength) {
utils.addSelectors(selectors, prevSelectors);
prevBlock.declarations = new List(diff.ne2);
}
Expand All @@ -105,7 +110,7 @@ function processRuleset(node, item, list) {

// create new ruleset if declarations length greater than
// ruleset description overhead
if (blockLength >= newBlockLength) {
if (allowMergeDown && blockLength >= newBlockLength) {
var newRuleset = {
type: 'Ruleset',
info: {},
Expand All @@ -127,8 +132,18 @@ function processRuleset(node, item, list) {
}
}

if (allowMergeUp) {
// TODO: disallow up merge only if any property interception only (i.e. diff.ne2overrided.length > 0);
// await property families to find property interception correctly
allowMergeUp = !prevSelectors.some(function(prevSelector) {
return selectors.some(function(selector) {
return selector.compareMarker === prevSelector.compareMarker;
});
});
}

prevSelectors.each(function(data) {
skippedCompareMarkers[data.compareMarker] = true;
disallowDownMarkers[data.compareMarker] = true;
});
});
};
Expand Down
29 changes: 16 additions & 13 deletions lib/parser/scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ var RIGHT_CURLY_BRACE = 125;
var WHITESPACE = 1;
var PUNCTUATOR = 2;
var DIGIT = 3;
var STRING_SQ = 4;
var STRING_DQ = 5;
var STRING = 4;

var PUNCTUATION = {
9: TokenType.Tab, // '\t'
Expand Down Expand Up @@ -82,8 +81,8 @@ SYMBOL_CATEGORY[N] = WHITESPACE;
SYMBOL_CATEGORY[R] = WHITESPACE;
SYMBOL_CATEGORY[F] = WHITESPACE;

SYMBOL_CATEGORY[QUOTE] = STRING_SQ;
SYMBOL_CATEGORY[DOUBLE_QUOTE] = STRING_DQ;
SYMBOL_CATEGORY[QUOTE] = STRING;
SYMBOL_CATEGORY[DOUBLE_QUOTE] = STRING;

//
// scanner
Expand Down Expand Up @@ -124,17 +123,18 @@ Scanner.prototype = {
return token !== null && token.type === type;
},
next: function() {
this.prevToken = this.token;
var newToken = null;

if (this.buffer.length !== 0) {
this.token = this.buffer.shift();
newToken = this.buffer.shift();
} else if (!this.eof) {
this.token = this.getToken();
} else {
this.token = null;
newToken = this.getToken();
}

return this.token;
this.prevToken = this.token;
this.token = newToken;

return newToken;
},

tokenize: function() {
Expand Down Expand Up @@ -162,8 +162,7 @@ Scanner.prototype = {
value = this.readDecimalNumber();
break;

case STRING_SQ:
case STRING_DQ:
case STRING:
type = TokenType.String;
value = this.readString(code);
break;
Expand All @@ -175,7 +174,7 @@ Scanner.prototype = {

case PUNCTUATOR:
if (code === SLASH) {
next = this.source.charCodeAt(this.pos + 1);
next = this.pos + 1 < this.source.length ? this.source.charCodeAt(this.pos + 1) : 0;

if (next === STAR) { // /*
type = TokenType.Comment;
Expand Down Expand Up @@ -374,4 +373,8 @@ Scanner.prototype = {
}
};

// warm up tokenizer to elimitate code branches that never execute
// fix soft deoptimizations (insufficient type feedback)
new Scanner('\n\r\r\n\f//""\'\'/**/1a;.{url(a)}').lookup(1e3);

module.exports = Scanner;
5 changes: 5 additions & 0 deletions test/fixture/compress/disjoin/1.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ b {
height: 50px;
}
}

/*!
better solution
a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}@media (min-width:400px){a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}}
*/
6 changes: 5 additions & 1 deletion test/fixture/compress/disjoin/1.min.css
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}@media (min-width:400px){a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}}
a{color:red;width:200px}foo{border:none}b,foo{color:#00f;width:200px;height:50px}@media (min-width:400px){a{color:red;width:200px}foo{border:none}b,foo{color:#00f;width:200px;height:50px}}
/*!
better solution
a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}@media (min-width:400px){a,b,foo{color:red;width:200px}foo{border:none}b,foo{color:#00f;height:50px}}
*/
2 changes: 1 addition & 1 deletion test/fixture/compress/issue/134.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/fixture/compress/restructure.merge/15.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.a .b {
opacity: 1;
}
.foo {
opacity: 0;
color: #ff0000;
}
.bar {
opacity: 1;
display: block;
}
1 change: 1 addition & 0 deletions test/fixture/compress/restructure.merge/15.min.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.a .b{opacity:1}.foo{opacity:0;color:red}.bar{opacity:1;display:block}
12 changes: 12 additions & 0 deletions test/fixture/compress/restructure.merge/16.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.a .b {
opacity: 1;
display: inline;
}
.foo {
opacity: 0;
color: #ff0000;
}
.bar {
opacity: 1;
display: block;
}
1 change: 1 addition & 0 deletions test/fixture/compress/restructure.merge/16.min.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.a .b{opacity:1;display:inline}.foo{opacity:0;color:red}.bar{opacity:1;display:block}
12 changes: 12 additions & 0 deletions test/fixture/compress/restructure.merge/17.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.a .b {
opacity: 1;
display: inline;
}
.b .a {
opacity: 0;
color: #ff0000;
}
.bar {
opacity: 1;
display: block;
}
1 change: 1 addition & 0 deletions test/fixture/compress/restructure.merge/17.min.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.a .b,.bar{opacity:1;display:inline}.b .a{opacity:0;color:red}.bar{display:block}
12 changes: 12 additions & 0 deletions test/fixture/compress/restructure.merge/18.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.a .b {
opacity: 1;
display: inline;
}
.c .b .a {
opacity: 0;
color: #ff0000;
}
.bar {
opacity: 1;
display: block;
}
1 change: 1 addition & 0 deletions test/fixture/compress/restructure.merge/18.min.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.a .b,.bar{opacity:1;display:inline}.c .b .a{opacity:0;color:red}.bar{display:block}
19 changes: 19 additions & 0 deletions test/fixture/compress/trbl/issue297.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.a {
padding: 10px;
padding: calc(1px + 2px);
}

.b {
padding: 20px;
padding: 50px;
}

.c {
padding: calc(20px + 10px);
padding: calc(10px + 7px);
}

.d {
padding: calc(20px + 10px);
padding: 50px;
}
1 change: 1 addition & 0 deletions test/fixture/compress/trbl/issue297.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/fixture/usage/scopes-3.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.a .b {
opacity: 1;
}
.foo {
opacity: 0;
color: #ff0000;
}
.bar {
opacity: 1;
display: block;
}
6 changes: 6 additions & 0 deletions test/fixture/usage/scopes-3.css.usage
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"scopes": [
["a", "b"],
["foo", "bar"]
]
}
1 change: 1 addition & 0 deletions test/fixture/usage/scopes-3.min.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.a .b{opacity:1}.foo{opacity:0;color:red}.bar{opacity:1;display:block}
2 changes: 1 addition & 1 deletion test/rename.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function createRenameTest(name, test) {
}
};

describe.only('rename', function() {
describe('rename', function() {
it('basic', function() {
var result = csso.minify('.foo, .bar.foo, foo:not(.bar) { color: foo }', {
rename: { classes: true }
Expand Down

0 comments on commit 82ca18c

Please sign in to comment.