Skip to content

Commit

Permalink
New option: space-before-opening-brace
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyganch committed Jun 9, 2014
1 parent b35c1a6 commit ea49b87
Show file tree
Hide file tree
Showing 9 changed files with 231 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 @@ -16,6 +16,7 @@
"space-after-combinator": " ",
"space-before-colon": "",
"space-before-combinator": " ",
"space-before-opening-brace": "\n",
"strip-spaces": true,
"unitless-zero": true,
"vendor-prefix-align": true,
Expand Down
38 changes: 38 additions & 0 deletions doc/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,44 @@ p
> a { color: panda; }
```

## space-before-opening-brace

Set space before `{`.

Acceptable values:

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

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

```scss
// Before:
a{
color: panda;
}

// After:
a {
color: panda;
}
```

Example: `{ 'space-before-opening-brace': '\n' }`

```scss
// Before:
a{
color: panda;
}

// After:
a
{
color: panda;
}
```

## strip-spaces

Whether to trim trailing spaces.
Expand Down
1 change: 1 addition & 0 deletions lib/csscomb.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var OPTIONS = [
'space-before-combinator',
'space-before-colon',
'space-after-colon',
'space-before-opening-brace',
'sort-order',
'block-indent',
'unitless-zero',
Expand Down
81 changes: 81 additions & 0 deletions lib/options/space-before-opening-brace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
module.exports = (function() {
/**
* Gets the last (the deepest) whitespace node.
*
* @param {node} node
* @returns {node|undefined} If no whitespace node is found, returns
* `undefined`
*/
function getLastWhitespaceNode(node) {
var lastNode = node[node.length - 1];

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

return getLastWhitespaceNode(lastNode);
}

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

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

/**
* Processes tree node.
*
* @param {String} nodeType
* @param {node} node
*/
process: function(nodeType, node) {
var value = this.getValue('space-before-opening-brace');

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

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

// 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[i - 1].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 at the next one for space check:
if (node[i][0] !== 'block' && node[i][0] !== 'atrulers') continue;

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

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

return variants;
}
};
})();
84 changes: 84 additions & 0 deletions test/options/space-before-opening-brace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
describe('options/space-before-opening-brace:', function() {
beforeEach(function() {
this.filename = __filename;
});

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

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

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

it('Integer value => should set proper space before {', function() {
this.comb.configure({ 'space-before-opening-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-opening-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-opening-brace': '\n ' });
this.shouldBeEqual('test.css', 'test-3.expected.css');
});

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

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

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

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

it('Should detect no whitespace (3 blocks)', function() {
this.shouldDetect(
['space-before-opening-brace'],
'a {top:0} b{left:0} c{right:0}',
{ 'space-before-opening-brace': '' }
);
});

it('Should detect whitespace (3 blocks)', function() {
this.shouldDetect(
['space-before-opening-brace'],
'a{top:0} b {left:0} c {right:0}',
{ 'space-before-opening-brace': ' ' }
);
});
});

5 changes: 5 additions & 0 deletions test/options/space-before-opening-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-opening-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-opening-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-opening-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 ea49b87

Please sign in to comment.