Skip to content

Commit cac347b

Browse files
committed
v2.0.1
2 parents 83112bd + 89a7f8a commit cac347b

12 files changed

+101
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## 2.0.1 - 2013-12-23
4+
- Fix for `remove-empty-rulesets` option (#133)
5+
36
## 2.0.0 - 2013-12-18
47
**Great thanks for @tonyganch and @kizu!**
58
- Use Gonzales PE to parse *.scss and *.less files

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ p[href^='https://']:before { content: 'secure' }
522522
523523
Acceptable values: `{Boolean}` `true`
524524
525-
Example: `{ "remove-empty-rulesets": true }` - remove rulesets that have no declarations or comments.
525+
Example: `{ "remove-empty-rulesets": true }` - remove rulesets that have nothing but spaces.
526526
527527
`a { color: red; } p { /* hey */ } b { }` → `a { color: red; } p { /* hey */ } `
528528

lib/options/remove-empty-rulesets.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,26 @@ module.exports = {
3232

3333
_removeEmptyRulesets: function(nodeContent) {
3434
var i = nodeContent.length;
35+
// Loop through node and try to find a ruleset:
3536
while (i--) {
36-
if (this._isRuleset(nodeContent[i]) && this._isEmptyRuleset(nodeContent[i])) {
37+
var node = nodeContent[i];
38+
if (!this._isRuleset(node)) continue;
39+
// If a ruleset is found, try to find its nested rulesets and remove
40+
// all empty ones:
41+
var j = node.length;
42+
while (j--) {
43+
// Nested rulesets are located inside blocks, that's why look
44+
// for blocks only:
45+
var blockNode = node[j];
46+
if (blockNode[0] !== 'block') continue;
47+
blockNode.shift();
48+
this._processStylesheetContent(blockNode);
49+
blockNode.unshift('block');
50+
node[j] = blockNode;
51+
}
52+
// If after removing all empty nested rulesets the parent has also
53+
// become empty, remove it too:
54+
if (this._isEmptyRuleset(node)) {
3755
nodeContent.splice(i, 1);
3856
}
3957
}
@@ -60,10 +78,10 @@ module.exports = {
6078
},
6179

6280
/**
63-
* Block considered empty when it has no declarations or comments.
81+
* Block is considered empty when it has nothing but spaces.
6482
*/
6583
_isEmptyBlock: function(node) {
66-
return !node.some(this._isDeclarationOrComment);
84+
return node.length === 1 || !node.some(this._isNotWhitespace);
6785
},
6886

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

103+
_isNotWhitespace: function(node) {
104+
return typeof node === 'object' && node[0] !== 's';
105+
},
106+
85107
/**
86108
* Detects the value of an option at the tree node.
87109
* This option is treated as `true` by default, but any trailing space would invalidate it.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "csscomb",
33
"description": "CSS coding style formatter",
4-
"version": "2.0.0",
4+
"version": "2.0.1",
55
"homepage": "http://csscomb.com/",
66
"author": "Mikhail Troshev <mishanga@yandex-team.ru>",
77
"repository": "https://github.com/csscomb/csscomb.js",

test/remove-empty-rulesets-scss.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
var Comb = require('../lib/csscomb');
2+
var assert = require('assert');
3+
var fs = require('fs');
4+
5+
describe('options/remove-empty-rulesets (scss)', function() {
6+
var comb = new Comb({ 'remove-empty-rulesets': true });
7+
var input;
8+
var expected;
9+
10+
function readFile(path) {
11+
return fs.readFileSync('test/remove-empty-rulesets-scss/' + path, 'utf8');
12+
}
13+
14+
it('Should not remove rulesets which contain only includes', function() {
15+
input = readFile('include.scss', 'utf-8');
16+
assert.equal(comb.processString(input, 'scss'), input);
17+
});
18+
19+
it('Should remove rulesets with contain only empty nested rules', function() {
20+
input = readFile('empty-nested-rule.scss', 'utf-8');
21+
expected = readFile('empty-nested-rule.expected.scss', 'utf-8');
22+
assert.equal(comb.processString(input, 'scss'), expected);
23+
});
24+
25+
it('Should not remove rulesets with non-empty nested rules. Test 1', function() {
26+
input = readFile('nested-rule-1.scss', 'utf-8');
27+
assert.equal(comb.processString(input, 'scss'), input);
28+
});
29+
30+
it('Should not remove rulesets with non-empty nested rules. Test 2', function() {
31+
input = readFile('nested-rule-2.scss', 'utf-8');
32+
expected = readFile('nested-rule-2.expected.scss', 'utf-8');
33+
assert.equal(comb.processString(input, 'scss'), expected);
34+
});
35+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.parent {
2+
.child {
3+
.grandchild { }
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.parent {
2+
@include mix-all;
3+
@include mix-top;
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.parent {
2+
.child {
3+
@include mix-all;
4+
@include mix-top;
5+
}
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.parent {
2+
.child1 {
3+
@include mix-all;
4+
@include mix-top;
5+
}
6+
7+
}

0 commit comments

Comments
 (0)