Skip to content

Commit 2f67ded

Browse files
committed
option: block-indent
1 parent cb1621b commit 2f67ded

File tree

8 files changed

+234
-26
lines changed

8 files changed

+234
-26
lines changed

.csscomb.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
],
66
"colon-space": true,
77
"rule-indent": true,
8+
"block-indent": true,
89
"stick-brace": "\n",
910
"strip-spaces": true,
1011
"always-semicolon": true,

lib/csscomb.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var Comb = function() {
1616
'stick-brace',
1717
'colon-space',
1818
'rule-indent',
19+
'block-indent',
1920
'sort-order'
2021
];
2122
this._config = {};
@@ -68,11 +69,11 @@ Comb.prototype = {
6869
node.forEach(function(node) {
6970
if (!Array.isArray(node)) return;
7071
var nodeType = node.shift();
71-
if (nodeType === 'atrulers') level++;
7272
_this._handlers.forEach(function(handler) {
7373
handler.process(nodeType, node, level);
7474
});
7575
node.unshift(nodeType);
76+
if (nodeType === 'atrulers') level++;
7677
_this.processNode(node, level);
7778
});
7879
},

lib/options/block-indent.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module.exports = {
2+
3+
/**
4+
* Sets handler value.
5+
*
6+
* @param {String|Number|Boolean} value Option value
7+
* @returns {Object}
8+
*/
9+
setValue: function(value) {
10+
this._value = false;
11+
if (value === true) value = 4;
12+
if (typeof value === 'number' && value === Math.abs(Math.round(value))) value = new Array(value + 1).join(' ');
13+
if (typeof value === 'string' && value.match(/^[ \t]*$/)) this._value = value;
14+
if (!this._value) return;
15+
return this;
16+
},
17+
18+
/**
19+
* Processes tree node.
20+
* @param {String} nodeType
21+
* @param {node} node
22+
*/
23+
process: function(nodeType, node, level) {
24+
// Add right space before closing brace
25+
if (nodeType === 'atrulers' || nodeType === 'block') {
26+
var value = '\n' + new Array(level + 1).join(this._value);
27+
if (node[node.length - 1][0] === 's') node.pop();
28+
node.push(['s', value]);
29+
}
30+
31+
// Add right space before rule declaration
32+
if (nodeType === 'stylesheet' || nodeType === 'atrulers') {
33+
// Level up hack
34+
if (nodeType === 'atrulers') level++;
35+
36+
// Prevent line break at file start
37+
var isFirst;
38+
if (nodeType === 'stylesheet') {
39+
var first = node[0];
40+
if (first[0] !== 's' || first[1].match('\n') === null) isFirst = true;
41+
}
42+
43+
for (var i = 0; i < node.length; i++) {
44+
var nodeItem = node[i];
45+
if (nodeItem[0] === 'atruler' || nodeItem[0] === 'ruleset') {
46+
var value = (isFirst ? '' : '\n') + new Array(level + 1).join(this._value);
47+
isFirst = false;
48+
49+
var space = node[i - 1];
50+
if (!space || space[0] !== 's') {
51+
space = ['s', ''];
52+
if (i) {
53+
var tail = node.splice(i);
54+
tail.unshift(space);
55+
Array.prototype.push.apply(node, tail);
56+
i++;
57+
}
58+
}
59+
space[1] = space[1].replace(/(\n)?([\t ]+)?$/, value);
60+
}
61+
}
62+
}
63+
64+
// Add space before block opening brace
65+
if (nodeType === 'simpleselector') {
66+
var space = node[node.length - 1];
67+
if (space[0] === 's' && space[1].match('\n')) {
68+
space[1] += new Array(level + 1).join(this._value);
69+
}
70+
}
71+
}
72+
73+
};

lib/options/stick-brace.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ module.exports = {
3030
}
3131
}
3232
}
33-
34-
if (nodeType === 'block' || nodeType === 'atrulers') {
35-
if (node[node.length - 1][0] === 's') node.pop();
36-
node.push(['s', '\n']);
37-
}
3833
}
3934

4035
};

test/block-indent.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
var Comb = require('../lib/csscomb');
2+
var assert = require('assert');
3+
4+
describe('options/block-indent', function() {
5+
var comb;
6+
beforeEach(function() {
7+
comb = new Comb();
8+
});
9+
it('Invalid Number value should not change space after brace', function() {
10+
comb.configure({ 'block-indent': 3.5 });
11+
assert.equal(
12+
comb.processString('a { color: red }'),
13+
'a { color: red }'
14+
);
15+
});
16+
it('Invalid String value should not change space after brace', function() {
17+
comb.configure({ 'block-indent': 'foobar' });
18+
assert.equal(
19+
comb.processString('a { color: red }'),
20+
'a { color: red }'
21+
);
22+
});
23+
it('True Boolean value should set 4 spaces indent', function() {
24+
comb.configure({ 'block-indent': true });
25+
assert.equal(
26+
comb.processString(' \n a { color: red } @media all { .input__control { color: #000;\n}\n}'),
27+
' \na { color: red \n}\n@media all {\n .input__control { color: #000;\n }\n}'
28+
);
29+
});
30+
it('Valid Number value should set equal space after brace', function() {
31+
comb.configure({ 'block-indent': 3 });
32+
assert.equal(
33+
comb.processString(' a\n{ color: red } @media all { .input__control\n{ color: #000;\n}\n}'),
34+
'a\n{ color: red \n}\n@media all {\n .input__control\n { color: #000;\n }\n}'
35+
);
36+
});
37+
it('Valid String value should set equal space after brace', function() {
38+
comb.configure({ 'block-indent': '\t' });
39+
assert.equal(
40+
comb.processString(' a { color: red } @media all { .input__control\n{ color: #000;\n}\n}'),
41+
'a { color: red \n}\n@media all {\n\t.input__control\n\t{ color: #000;\n\t}\n}'
42+
);
43+
});
44+
});

test/integral.expect.css

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,92 @@
1+
@media all and (min-width:0px)
2+
{
3+
/* :before — бордер */
4+
.radio-button_theme_normal .radio-button__radio:before
5+
{
6+
background: rgba(0,0,0,0.4);
7+
background: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
8+
background: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0, rgba(0,0,0,0.4) 100%);
9+
background: -o-linear-gradient(top, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
10+
background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
11+
12+
-moz-box-shadow: 0 1px 0 rgba(0,0,0,.07);
13+
box-shadow: 0 1px 0 rgba(0,0,0,.07);
14+
}
15+
16+
/* :after — фон */
17+
.radio-button_theme_normal .radio-button__radio:after
18+
{
19+
background: #fff;
20+
background: -webkit-linear-gradient(top, #fff 0,#eee 100%);
21+
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
22+
background: -o-linear-gradient(top, #fff 0,#eee 100%);
23+
background: linear-gradient(to bottom, #fff 0,#eee 100%);
24+
}
25+
26+
/* _focused_yes */
27+
.radio-button_theme_normal .radio-button__radio_focused_yes:before
28+
{
29+
-moz-box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07);
30+
box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07);
31+
}
32+
}
33+
134
/* Фигурные скобки. Вариант 1 */
235
a, b, i /* foobar */
336
{
437
padding: 0;
538
margin: 0;
639
}
7-
div p
40+
div p
841
{
942
font-size: 1px;
1043
top: 0;
1144
}
12-
div p em
45+
div p em
1346
{
1447
font-style: italic;
1548
border-bottom: 1px solid red;
1649
}
1750

51+
@media all and (min-width:0px)
52+
{
53+
/* В нажатом состоянии смещается вниз на 1px вся кнопка, текст не смещается */
54+
.button_pressed_yes.button_shadow_yes
55+
{
56+
top: 1px;
57+
}
58+
59+
.button_pressed_yes.button_shadow_yes .button__text
60+
{
61+
top: 0;
62+
}
63+
}
64+
1865
@media all /* media */
1966
{ /* foobar */
20-
.input__control
21-
{
67+
.input__control
68+
{
2269
color: #000;
2370
font-size: 100%;
2471
margin: 0;
2572
position: relative;
2673
width: 100%;
2774
z-index: 3;
28-
}
75+
}
2976
}
3077

3178
@media screen and (min-width: 35em) /* screen */,
3279
print and (min-width: 40em) /* print */
3380
{ /* foobar */
34-
.input__control
35-
{
81+
.input__control
82+
{
3683
-moz-box-sizing: border-box;
3784
background: none;
3885
border: 0;
3986
box-sizing: border-box;
4087
outline: 0;
4188
padding: 0.4em 0;
42-
}
89+
}
4390
}
4491

4592
/* Фигурные скобки. Вариант 2 */
@@ -48,12 +95,12 @@ div
4895
padding: 0;
4996
margin: 0;
5097
}
51-
div p
98+
div p
5299
{
53100
font-size: 1px;
54101
top: 0;
55102
}
56-
div p em
103+
div p em
57104
{
58105
font-style: italic;/* inline comment*/
59106
border-bottom: 1px solid red;
@@ -65,25 +112,26 @@ div
65112
padding: 0;
66113
margin: 0;
67114
}
68-
/* foo */ div p
115+
/* foo */
116+
div p
69117
{
70118
font-size: 1px;
71119
top: 0;
72120
}
73-
div p em
121+
div p em
74122
{
75123
/* upline comment*/
76124
font-style: italic;
77125

78126
border-bottom: 1px solid red; /* trololo */ /* trololo */
79127
}
80128

81-
a
129+
a
82130
{
83131
top: 0;/* ololo */
84132
margin: 0;
85133
}
86-
b
134+
b
87135
{
88136
top: 0/* trololo */;
89137
margin: 0;

test/integral.origin.css

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
1+
@media all and (min-width:0px) {
2+
/* :before — бордер */
3+
.radio-button_theme_normal .radio-button__radio:before
4+
{
5+
background: rgba(0,0,0,0.4);
6+
background: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
7+
background: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0, rgba(0,0,0,0.4) 100%);
8+
background: -o-linear-gradient(top, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
9+
background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
10+
11+
-moz-box-shadow: 0 1px 0 rgba(0,0,0,.07);
12+
box-shadow: 0 1px 0 rgba(0,0,0,.07);
13+
}
14+
15+
/* :after — фон */
16+
.radio-button_theme_normal .radio-button__radio:after
17+
{
18+
background: #fff;
19+
background: -webkit-linear-gradient(top, #fff 0,#eee 100%);
20+
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
21+
background: -o-linear-gradient(top, #fff 0,#eee 100%);
22+
background: linear-gradient(to bottom, #fff 0,#eee 100%);
23+
}
24+
25+
/* _focused_yes */
26+
.radio-button_theme_normal .radio-button__radio_focused_yes:before
27+
{
28+
-moz-box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07);
29+
box-shadow: 0 0 6px 2px rgba(255,204,0,.7), 0 1px 0 rgba(0,0,0,.07);
30+
}
31+
32+
}
33+
134
/* Фигурные скобки. Вариант 1 */
235
a, b, i /* foobar */ {
336
padding:0;
@@ -12,6 +45,19 @@ a, b, i /* foobar */ {
1245
border-bottom:1px solid red;
1346
}
1447

48+
@media all and (min-width:0px){
49+
/* В нажатом состоянии смещается вниз на 1px вся кнопка, текст не смещается */
50+
.button_pressed_yes.button_shadow_yes
51+
{
52+
top: 1px;
53+
}
54+
55+
.button_pressed_yes.button_shadow_yes .button__text
56+
{
57+
top: 0;
58+
}
59+
}
60+
1561
@media all /* media */
1662
{ /* foobar */
1763
.input__control

test/stick-brace.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('options/stick-brace', function() {
1717
comb.configure({ 'stick-brace': true });
1818
assert.equal(
1919
comb.processString('a{color:red }'),
20-
'a {color:red \n}'
20+
'a {color:red }'
2121
);
2222
});
2323
it('Valid String value should set equal space after brace', function() {
@@ -27,14 +27,14 @@ describe('options/stick-brace', function() {
2727
'a{ color: red }' +
2828
'a, b /* i */ { color: red; }' +
2929
'a \t\t \n{color:red\n \n}' +
30-
'a /* foo */ {color:red ; \n \n\t}' +
30+
'a /* foo */ {color:red ;\n}' +
3131
'@media all { .input__control { color: #000;\n \n }\t}'
3232
),
33-
'a\n{ color: red \n}' +
34-
'a, b /* i */\n{ color: red;\n}' +
35-
'a\n{color:red\n \n\n}' +
33+
'a\n{ color: red }' +
34+
'a, b /* i */\n{ color: red; }' +
35+
'a\n{color:red\n \n}' +
3636
'a /* foo */\n{color:red ;\n}' +
37-
'@media all\n{ .input__control\n{ color: #000;\n}\n}'
37+
'@media all\n{ .input__control\n{ color: #000;\n \n }\t}'
3838
);
3939
});
4040
});

0 commit comments

Comments
 (0)