Skip to content

Commit

Permalink
New option: space-before-closing-brace
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyganch committed Jun 9, 2014
1 parent 1e7ceb8 commit a4cba33
Show file tree
Hide file tree
Showing 10 changed files with 217 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 @@ -15,6 +15,7 @@
"space-after-colon": " ",
"space-after-combinator": " ",
"space-after-opening-brace": "\n",
"space-before-closing-brace": "\n",
"space-before-colon": "",
"space-before-combinator": " ",
"space-before-opening-brace": "\n",
Expand Down
39 changes: 39 additions & 0 deletions doc/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,45 @@ a{
color: panda;}
```

## space-before-closing-brace

Set space before `}`.

Acceptable values:

* `{Number}` — number of whitespaces;
* `{String}` — string with whitespaces, tabs or line breaks.

Example: `{ 'space-before-closing-brace': 1 }`

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

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

Example: `{ 'space-before-closing-space': '\n' }`

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

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

## space-before-colon

Set space before `:` in declarations.
Expand Down
1 change: 1 addition & 0 deletions lib/csscomb.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var OPTIONS = [
'space-after-opening-brace',
'sort-order',
'block-indent',
'space-before-closing-brace',
'tab-size',
'unitless-zero',
'vendor-prefix-align'
Expand Down
78 changes: 78 additions & 0 deletions lib/options/space-before-closing-brace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module.exports = (function() {
function getLastWhitespaceNode(node) {
var lastNode = node[node.length - 1];

if (typeof lastNode !== 'object' || lastNode[0] === 'block') return null;
if (lastNode[0] === 's') return lastNode;

return getLastWhitespaceNode(lastNode);
}

return {
name: 'space-before-closing-brace',

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

/**
* Processes tree node.
* @param {String} nodeType
* @param {node} node
* @param {Number} level
*/
process: function(nodeType, node, level) {
if (nodeType !== 'block' && nodeType !== 'atrulers') return;

var value = this.getValue('space-before-closing-brace');

// If found block node stop at the next one for space check
// For the pre-block node, find its last (the deepest) child
var whitespaceNode = getLastWhitespaceNode(node);

if (value.indexOf('\n') > -1) {
var blockIndent = this.getValue('block-indent');
// TODO: Check that it works for '' block indent value <tg>
if (blockIndent) value += new Array(level + 1).join(blockIndent);
}

// If it's spaces, modify this node
// If it's something different from spaces, add a space node to the end

if (whitespaceNode) {
whitespaceNode[1] = value;
} else if (value !== '') {
node.push(['s', value]);
}
},

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

// Loop through node from the end to the beginning:
for (var i = node.length; i--;) {
// If found block node stop for space check:
if (node[i][0] !== 'block' && node[i][0] !== 'atrulers') continue;

// For the block node, find its last (the deepest) child
var whitespaceNode = getLastWhitespaceNode(node[i]);

if (whitespaceNode) {
variants.push(whitespaceNode[1]);
} else {
variants.push('');
}
}

return variants;
}
};
})();

4 changes: 4 additions & 0 deletions test/options/block-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ describe('options/block-indent:', function() {
{}
);
});
it('Valid string value => should set proper space after combnator', function() {
this.comb.configure({ 'block-indent': ' ', 'space-before-closing-brace': '\n' });
this.shouldBeEqual('test.css', 'test-3.expected.css');
});
});
68 changes: 68 additions & 0 deletions test/options/space-before-closing-brace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
describe('options/space-before-closing-brace:', function() {
beforeEach(function() {
this.filename = __filename;
});

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

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

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

it('Integer value => should set proper space before }', function() {
this.comb.configure({ 'space-before-closing-brace': 0 });
this.shouldBeEqual('test.css', 'test.expected.css');
});

it('Valid string value (spaces only) => should set proper space before }', function() {
this.comb.configure({ 'space-before-closing-brace': ' ' });
this.shouldBeEqual('test.css', 'test-2.expected.css');
});

it('Valid string value (spaces and newlines) => should set proper space before }', function() {
this.comb.configure({ 'space-before-closing-brace': '\n ' });
this.shouldBeEqual('test.css', 'test-3.expected.css');
});

it('Should detect no whitespace', function() {
this.shouldDetect(
['space-before-closing-brace'],
'a{top:0}',
{ 'space-before-closing-brace': '' }
);
});

it('Should detect no whitespace (2 blocks)', function() {
this.shouldDetect(
['space-before-closing-brace'],
'a{top:0} b { color: tomato; }',
{ 'space-before-closing-brace': '' }
);
});

it('Should detect whitespace', function() {
this.shouldDetect(
['space-before-closing-brace'],
'a { top:0 }',
{ 'space-before-closing-brace': ' ' }
);
});

it('Should detect whitespace (2 blocks)', function() {
this.shouldDetect(
['space-before-closing-brace'],
'a { top:0 } b{color:tomato;}',
{ 'space-before-closing-brace': ' ' }
);
});
});

5 changes: 5 additions & 0 deletions test/options/space-before-closing-brace/test-2.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
a{top: 0 }
a {top: 0 }

@media print{a{top: 0 } }
@media print { a { top: 0 } }
11 changes: 11 additions & 0 deletions test/options/space-before-closing-brace/test-3.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
a{top: 0
}
a {top: 0
}

@media print{a{top: 0
}
}
@media print { a { top: 0
}
}
5 changes: 5 additions & 0 deletions test/options/space-before-closing-brace/test.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
a{top: 0}
a {top: 0 }

@media print{a{top: 0}}
@media print { a { top: 0 } }
5 changes: 5 additions & 0 deletions test/options/space-before-closing-brace/test.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
a{top: 0}
a {top: 0}

@media print{a{top: 0}}
@media print { a { top: 0}}

0 comments on commit a4cba33

Please sign in to comment.