Skip to content

Commit

Permalink
v2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mishanga committed Dec 23, 2013
2 parents 83112bd + 89a7f8a commit cac347b
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 2.0.1 - 2013-12-23
- Fix for `remove-empty-rulesets` option (#133)

## 2.0.0 - 2013-12-18
**Great thanks for @tonyganch and @kizu!**
- Use Gonzales PE to parse *.scss and *.less files
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ p[href^='https://']:before { content: 'secure' }
Acceptable values: `{Boolean}` `true`
Example: `{ "remove-empty-rulesets": true }` - remove rulesets that have no declarations or comments.
Example: `{ "remove-empty-rulesets": true }` - remove rulesets that have nothing but spaces.
`a { color: red; } p { /* hey */ } b { }` → `a { color: red; } p { /* hey */ } `
Expand Down
28 changes: 25 additions & 3 deletions lib/options/remove-empty-rulesets.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,26 @@ module.exports = {

_removeEmptyRulesets: function(nodeContent) {
var i = nodeContent.length;
// Loop through node and try to find a ruleset:
while (i--) {
if (this._isRuleset(nodeContent[i]) && this._isEmptyRuleset(nodeContent[i])) {
var node = nodeContent[i];
if (!this._isRuleset(node)) continue;
// If a ruleset is found, try to find its nested rulesets and remove
// all empty ones:
var j = node.length;
while (j--) {
// Nested rulesets are located inside blocks, that's why look
// for blocks only:
var blockNode = node[j];
if (blockNode[0] !== 'block') continue;
blockNode.shift();
this._processStylesheetContent(blockNode);
blockNode.unshift('block');
node[j] = blockNode;
}
// If after removing all empty nested rulesets the parent has also
// become empty, remove it too:
if (this._isEmptyRuleset(node)) {
nodeContent.splice(i, 1);
}
}
Expand All @@ -60,10 +78,10 @@ module.exports = {
},

/**
* Block considered empty when it has no declarations or comments.
* Block is considered empty when it has nothing but spaces.
*/
_isEmptyBlock: function(node) {
return !node.some(this._isDeclarationOrComment);
return node.length === 1 || !node.some(this._isNotWhitespace);
},

_isDeclarationOrComment: function(node) {
Expand All @@ -82,6 +100,10 @@ module.exports = {
return node[0] === 's';
},

_isNotWhitespace: function(node) {
return typeof node === 'object' && node[0] !== 's';
},

/**
* Detects the value of an option at the tree node.
* This option is treated as `true` by default, but any trailing space would invalidate it.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "csscomb",
"description": "CSS coding style formatter",
"version": "2.0.0",
"version": "2.0.1",
"homepage": "http://csscomb.com/",
"author": "Mikhail Troshev <[email protected]>",
"repository": "https://github.com/csscomb/csscomb.js",
Expand Down
35 changes: 35 additions & 0 deletions test/remove-empty-rulesets-scss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
var Comb = require('../lib/csscomb');
var assert = require('assert');
var fs = require('fs');

describe('options/remove-empty-rulesets (scss)', function() {
var comb = new Comb({ 'remove-empty-rulesets': true });
var input;
var expected;

function readFile(path) {
return fs.readFileSync('test/remove-empty-rulesets-scss/' + path, 'utf8');
}

it('Should not remove rulesets which contain only includes', function() {
input = readFile('include.scss', 'utf-8');
assert.equal(comb.processString(input, 'scss'), input);
});

it('Should remove rulesets with contain only empty nested rules', function() {
input = readFile('empty-nested-rule.scss', 'utf-8');
expected = readFile('empty-nested-rule.expected.scss', 'utf-8');
assert.equal(comb.processString(input, 'scss'), expected);
});

it('Should not remove rulesets with non-empty nested rules. Test 1', function() {
input = readFile('nested-rule-1.scss', 'utf-8');
assert.equal(comb.processString(input, 'scss'), input);
});

it('Should not remove rulesets with non-empty nested rules. Test 2', function() {
input = readFile('nested-rule-2.scss', 'utf-8');
expected = readFile('nested-rule-2.expected.scss', 'utf-8');
assert.equal(comb.processString(input, 'scss'), expected);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

5 changes: 5 additions & 0 deletions test/remove-empty-rulesets-scss/empty-nested-rule.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.parent {
.child {
.grandchild { }
}
}
4 changes: 4 additions & 0 deletions test/remove-empty-rulesets-scss/include.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.parent {
@include mix-all;
@include mix-top;
}
6 changes: 6 additions & 0 deletions test/remove-empty-rulesets-scss/nested-rule-1.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.parent {
.child {
@include mix-all;
@include mix-top;
}
}
7 changes: 7 additions & 0 deletions test/remove-empty-rulesets-scss/nested-rule-2.expected.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.parent {
.child1 {
@include mix-all;
@include mix-top;
}

}
9 changes: 9 additions & 0 deletions test/remove-empty-rulesets-scss/nested-rule-2.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.parent {
.child1 {
@include mix-all;
@include mix-top;
}
.child2 {
.grandchild { }
}
}
4 changes: 4 additions & 0 deletions test/remove-empty-rulesets.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ describe('options/remove-empty-rulesets', function() {
assert.equal(comb.processString(' b {} '), ' ');
});

it('should remove ruleset with spaces', function() {
assert.equal(comb.processString(' b { } '), ' ');
});

it('should leave ruleset with declarations', function() {
assert.equal(comb.processString('a { width: 10px; }\nb {} '), 'a { width: 10px; }\n ');
});
Expand Down

0 comments on commit cac347b

Please sign in to comment.