Skip to content

Commit a4bfb14

Browse files
committed
Added option for whitespaces around combinators, closes #52
1 parent 900e565 commit a4bfb14

File tree

7 files changed

+251
-4
lines changed

7 files changed

+251
-4
lines changed

.csscomb.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"colon-space": true,
99
"color-case": "lower",
1010
"color-shorthand": true,
11+
"combinator-space": true,
1112
"element-case": "lower",
1213
"leading-zero": false,
1314
"rule-indent": true,

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,44 @@ b { color: #ffcc00 }
164164
b { color: #fc0 }
165165
```
166166
167+
### combinator-space
168+
169+
Available values:
170+
* `{Boolean}`: `true` sets one space, `false` removes the spaces.
171+
* `{String}`: any combination of whitespaces.
172+
* `{Array}` with two `{String}` values: for setting left and right whitespace.
173+
174+
Example: `{ "combinator-space": true }`
175+
176+
```css
177+
/* before */
178+
a>b { color: red }
179+
180+
/* after */
181+
a > b { color: red }
182+
```
183+
184+
Example: `{ "combinator-space": "" }`
185+
186+
```css
187+
/* before */
188+
a > b { color: red }
189+
190+
/* after */
191+
a>b { color: red }
192+
```
193+
194+
Example: `{ "combinator-space": [" ", "\n"] }`
195+
196+
```css
197+
/* before */
198+
a>b { color: red }
199+
200+
/* after */
201+
a >
202+
b { color: red }
203+
```
204+
167205
### element-case
168206
169207
Available values: `{String}` `lower` or `upper`

lib/csscomb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var Comb = function() {
1919
'strip-spaces',
2020
'stick-brace',
2121
'colon-space',
22+
'combinator-space',
2223
'rule-indent',
2324
'block-indent',
2425
'unitless-zero',

lib/options/combinator-space.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
3+
/**
4+
* Sets handler value.
5+
*
6+
* @param {String|Boolean|Array} value Option value
7+
* @returns {Object}
8+
*/
9+
setValue: function(value) {
10+
this._value = false;
11+
if (value === true) value = ' ';
12+
if (value === false) value = '';
13+
if (typeof value === 'string' && value.match(/^[ \t\n]*$/)) {
14+
this._value = [value, value];
15+
}
16+
if (value.constructor === Array) this._value = value;
17+
if (!this._value) return;
18+
return this;
19+
},
20+
21+
/**
22+
* Processes tree node.
23+
* @param {String} nodeType
24+
* @param {node} node
25+
*/
26+
process: function(nodeType, node) {
27+
if (nodeType === 'selector') {
28+
for (var i = node.length; i--;) {
29+
var subSelector = node[i];
30+
for (var j = subSelector.length; j--;) {
31+
if (subSelector[j][0] === 'combinator') {
32+
// Working with the whitespace after the combinator
33+
if (subSelector[j + 1][0] === 's') {
34+
subSelector[j + 1][1] = this._value[1];
35+
} else {
36+
subSelector.splice(j + 1, 0, ['s', this._value[1]]);
37+
}
38+
// Working with the whitespace before the combinator
39+
if (subSelector[j - 1][0] === 's') {
40+
subSelector[j - 1][1] = this._value[0];
41+
} else {
42+
subSelector.splice(j, 0, ['s', this._value[0]]);
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
49+
50+
};

test/combinator-space.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
var Comb = require('../lib/csscomb');
2+
var assert = require('assert');
3+
4+
describe('options/combinator-space', function() {
5+
var comb;
6+
beforeEach(function() {
7+
comb = new Comb();
8+
});
9+
it('Invalid String should not change space around combinator', function() {
10+
comb.configure({ 'combinator-space': 'foobar' });
11+
assert.equal(
12+
comb.processString(
13+
'a >b { color: red }' +
14+
'a ~b { color: red }' +
15+
'a +b { color: red }'
16+
),
17+
'a >b { color: red }' +
18+
'a ~b { color: red }' +
19+
'a +b { color: red }'
20+
);
21+
});
22+
it('True Boolean value should set space around combinator to one space', function() {
23+
comb.configure({ 'combinator-space': true });
24+
assert.equal(
25+
comb.processString(
26+
'a>b { color: red }' +
27+
'a> b { color: red }' +
28+
'a >b { color: red }' +
29+
'a+b { color: red }' +
30+
'a+ b { color: red }' +
31+
'a +b { color: red }' +
32+
'a~b { color: red }' +
33+
'a~ b { color: red }' +
34+
'a ~b { color: red }' +
35+
'a ~b+ c>d { color: red }'
36+
),
37+
'a > b { color: red }' +
38+
'a > b { color: red }' +
39+
'a > b { color: red }' +
40+
'a + b { color: red }' +
41+
'a + b { color: red }' +
42+
'a + b { color: red }' +
43+
'a ~ b { color: red }' +
44+
'a ~ b { color: red }' +
45+
'a ~ b { color: red }' +
46+
'a ~ b + c > d { color: red }'
47+
);
48+
});
49+
it('False Boolean value should remove spaces around combinator', function() {
50+
comb.configure({ 'combinator-space': false });
51+
assert.equal(
52+
comb.processString(
53+
'a>b { color: red }' +
54+
'a> b { color: red }' +
55+
'a >b { color: red }' +
56+
'a+b { color: red }' +
57+
'a+ b { color: red }' +
58+
'a +b { color: red }' +
59+
'a~b { color: red }' +
60+
'a~ b { color: red }' +
61+
'a ~b { color: red }' +
62+
'a ~b+ c>d { color: red }'
63+
),
64+
'a>b { color: red }' +
65+
'a>b { color: red }' +
66+
'a>b { color: red }' +
67+
'a+b { color: red }' +
68+
'a+b { color: red }' +
69+
'a+b { color: red }' +
70+
'a~b { color: red }' +
71+
'a~b { color: red }' +
72+
'a~b { color: red }' +
73+
'a~b+c>d { color: red }'
74+
);
75+
});
76+
it('String `` value should remove spaces around combinator', function() {
77+
comb.configure({ 'combinator-space': '' });
78+
assert.equal(
79+
comb.processString(
80+
'a>b { color: red }' +
81+
'a> b { color: red }' +
82+
'a >b { color: red }' +
83+
'a+b { color: red }' +
84+
'a+ b { color: red }' +
85+
'a +b { color: red }' +
86+
'a~b { color: red }' +
87+
'a~ b { color: red }' +
88+
'a ~b { color: red }' +
89+
'a ~b+ c>d { color: red }'
90+
),
91+
'a>b { color: red }' +
92+
'a>b { color: red }' +
93+
'a>b { color: red }' +
94+
'a+b { color: red }' +
95+
'a+b { color: red }' +
96+
'a+b { color: red }' +
97+
'a~b { color: red }' +
98+
'a~b { color: red }' +
99+
'a~b { color: red }' +
100+
'a~b+c>d { color: red }'
101+
);
102+
});
103+
it('String ` ` value should set two spaces around combinator', function() {
104+
comb.configure({ 'combinator-space': ' ' });
105+
assert.equal(
106+
comb.processString(
107+
'a>b { color: red }' +
108+
'a> b { color: red }' +
109+
'a >b { color: red }' +
110+
'a+b { color: red }' +
111+
'a+ b { color: red }' +
112+
'a +b { color: red }' +
113+
'a~b { color: red }' +
114+
'a~ b { color: red }' +
115+
'a ~b { color: red }' +
116+
'a ~b+ c>d { color: red }'
117+
),
118+
'a > b { color: red }' +
119+
'a > b { color: red }' +
120+
'a > b { color: red }' +
121+
'a + b { color: red }' +
122+
'a + b { color: red }' +
123+
'a + b { color: red }' +
124+
'a ~ b { color: red }' +
125+
'a ~ b { color: red }' +
126+
'a ~ b { color: red }' +
127+
'a ~ b + c > d { color: red }'
128+
);
129+
});
130+
it('Array value should set different spaces around combinator', function() {
131+
comb.configure({ 'combinator-space': [' ', '\n'] });
132+
assert.equal(
133+
comb.processString(
134+
'a>b { color: red }' +
135+
'a> b { color: red }' +
136+
'a >b { color: red }' +
137+
'a+b { color: red }' +
138+
'a+ b { color: red }' +
139+
'a +b { color: red }' +
140+
'a~b { color: red }' +
141+
'a~ b { color: red }' +
142+
'a ~b { color: red }' +
143+
'a ~b+ c>d { color: red }'
144+
),
145+
'a >\nb { color: red }' +
146+
'a >\nb { color: red }' +
147+
'a >\nb { color: red }' +
148+
'a +\nb { color: red }' +
149+
'a +\nb { color: red }' +
150+
'a +\nb { color: red }' +
151+
'a ~\nb { color: red }' +
152+
'a ~\nb { color: red }' +
153+
'a ~\nb { color: red }' +
154+
'a ~\nb +\nc >\nd { color: red }'
155+
);
156+
});
157+
});

test/integral.expect.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@ div
120120
padding: 0;
121121
}
122122
/* foo */
123-
div p
123+
div ~ p
124124
{
125125
font-size: 1px;
126126

127127
top: 0;
128128
}
129-
div p em
129+
div > p + em
130130
{
131131
/* upline comment*/
132132
font-style: italic;

test/integral.origin.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ div {
104104
padding:0;
105105
margin:0;
106106
}
107-
/* foo */ div p {
107+
/* foo */ div~p {
108108
font-size:1px;
109109
top:0
110110
}
111-
div P EM {
111+
div> P +EM {
112112
/* upline comment*/
113113
font-style:italic;
114114

0 commit comments

Comments
 (0)