Skip to content

Commit

Permalink
New option: block-indent
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyganch committed Jun 9, 2014
1 parent 447479e commit 5ed9b55
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/csscomb.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"node_modules/**"
],
"always-semicolon": true,
"block-indent": " ",
"color-case": "lower",
"color-shorthand": true,
"element-case": "lower",
Expand Down
54 changes: 54 additions & 0 deletions doc/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,60 @@ div {
}
```

## block-indent

Set indent for code inside blocks, including media queries and nested rules.

Acceptable values:

* `{Number}` — number os whitespaces;
* `{String}` — string with whitespaces and tabs. Note that line breaks are not
allowed here.

Example: `{ 'block-indent': 4 }`

```scss
// Before:
a {
top: 0;
p {
color: tomato;
position: happy;
}
}

// After:
a {
top: 0;
p {
color: tomato;
position: happy;
}
}
```

Example: `{ 'block-indent': '' }`

```scss
// Before:
a {
top: 0;
p {
color: tomato;
position: happy;
}
}

// After:
a {
top: 0;
p {
color: tomato;
position: happy;
}
}
```

## color-case

Unify case of hexadecimal colors.
Expand Down
1 change: 1 addition & 0 deletions lib/csscomb.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var OPTIONS = [
'strip-spaces',
'eof-newline',
'sort-order',
'block-indent',
'unitless-zero',
'vendor-prefix-align'
];
Expand Down
77 changes: 77 additions & 0 deletions lib/options/block-indent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module.exports = {
name: 'block-indent',

accepts: {
number: true,
string: /^[ \t]*$/
},

/**
* Processes tree node.
*
* @param {String} nodeType
* @param {node} node
* @param {Number} level
*/
process: function process(nodeType, node, level) {
var spaces;

if (nodeType === 'stylesheet') {
for (var i = node.length; i--;) {
var whitespaceNode = node[i];

if (whitespaceNode[0] !== 's') continue;

spaces = whitespaceNode[1].replace(/\n[ \t]+/gm, '\n');
if (spaces === '') {
node.splice(i, 1);
} else {
whitespaceNode[1] = spaces;
}
}
return;
}

// Continue only with space nodes inside {...}:
if (level === 0 || nodeType !== 's') return;

// Remove all whitespaces and tabs, leave only new lines:
spaces = node[0].replace(/[ \t]/gm, '');

if (!spaces) return;

spaces += new Array(level + 1).join(this.getValue('block-indent'));
node[0] = spaces;
},

/**
* Detects the value of an option at the tree node.
*
* @param {String} nodeType
* @param {node} node
* @param {Number} level
*/
detect: function(nodeType, node, level) {
var result = [];

// Continue only with non-empty {...} blocks:
if (nodeType !== 'atrulers' && nodeType !== 'block' || !node.length) return;

for (var i = node.length; i--;) {
var whitespaceNode = node[i];
if (whitespaceNode[0] !== 's') continue;

var spaces = whitespaceNode[1];
var lastIndex = spaces.lastIndexOf('\n');

// Do not continue if there is no line break:
if (lastIndex < 0) continue;

// Number of spaces from beginning of line:
var spacesLength = spaces.slice(lastIndex + 1).length;
result.push(new Array(spacesLength / (level + 1) + 1).join(' '));
}

return result;
}
};
62 changes: 62 additions & 0 deletions test/options/block-indent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
describe('options/block-indent:', function() {
beforeEach(function() {
this.filename = __filename;
});

it('Array value => should not change anything', function() {
this.comb.configure({ 'block-indent': ['', ' '] });
this.shouldBeEqual('test.css');
});

it('Invalid string value => should not change anything', function() {
this.comb.configure({ 'block-indent': ' nani ' });
this.shouldBeEqual('test.css');
});

it('Float number value => should not change anything', function() {
this.comb.configure({ 'block-indent': 3.5 });
this.shouldBeEqual('test.css');
});

it('Integer value => should set proper number of spaces', function() {
this.comb.configure({ 'block-indent': 0 });
this.shouldBeEqual('test.css', 'test.expected.css');
});

it('Valid string value => should set proper number of spaces', function() {
this.comb.configure({ 'block-indent': ' ' });
this.shouldBeEqual('test.css', 'test-2.expected.css');
});

it('Should detect nothing with an empty block, test 1', function() {
this.shouldDetect(
['block-indent'],
'a{ }',
{}
);
});

it('Should detect nothing with an empty block, test 2', function() {
this.shouldDetect(
['block-indent'],
'a{}',
{}
);
});

it('Should detect correct number of spaces', function() {
this.shouldDetect(
['block-indent'],
'a{\n top: 0;\n color: tomato;\n}',
{ 'block-indent': ' ' }
);
});

it('Should detect no indent for one-line code', function() {
this.shouldDetect(
['block-indent'],
'a{ top: 0; color: tomato; }',
{}
);
});
});
30 changes: 30 additions & 0 deletions test/options/block-indent/test-2.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
a {color: tomato; top: 0;}

a { color: tomato;
top: 0; }

a { color: tomato;
top: 0; }

a {
color: tomato;
top: 0; }

a {
color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

@media print { a {color: tomato; top: 0; } }

@media print {
a {
color: tomato;
top: 0;
}
}
36 changes: 36 additions & 0 deletions test/options/block-indent/test-3.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
a {color: tomato; top: 0;
}

a { color: tomato;
top: 0;
}

a { color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

@media print { a {color: tomato; top: 0;
}
}

@media print {
a {
color: tomato;
top: 0;
}
}
30 changes: 30 additions & 0 deletions test/options/block-indent/test.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
a {color: tomato; top: 0;}

a { color: tomato;
top: 0; }

a { color: tomato;
top: 0; }

a {
color: tomato;
top: 0; }

a {
color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

@media print { a {color: tomato; top: 0; } }

@media print {
a {
color: tomato;
top: 0;
}
}
30 changes: 30 additions & 0 deletions test/options/block-indent/test.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
a {color: tomato; top: 0;}

a { color: tomato;
top: 0; }

a { color: tomato;
top: 0; }

a {
color: tomato;
top: 0; }

a {
color: tomato;
top: 0;
}

a {
color: tomato;
top: 0;
}

@media print { a {color: tomato; top: 0; } }

@media print {
a {
color: tomato;
top: 0;
}
}

0 comments on commit 5ed9b55

Please sign in to comment.