Skip to content

Commit 712566f

Browse files
committed
v0.0.8
2 parents df97113 + 4ad6315 commit 712566f

File tree

12 files changed

+460
-84
lines changed

12 files changed

+460
-84
lines changed

.csscomb.json

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,27 @@
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,
1112
"sort-order": [
13+
[
14+
"font",
15+
"font-family",
16+
"font-size",
17+
"font-weight",
18+
"font-style",
19+
"font-variant",
20+
"font-size-adjust",
21+
"font-stretch",
22+
"font-effect",
23+
"font-emphasize",
24+
"font-emphasize-position",
25+
"font-emphasize-style",
26+
"font-smooth",
27+
"line-height"
28+
],
1229
[
1330
"position",
1431
"z-index",
@@ -302,22 +319,6 @@
302319
"filter:progid:DXImageTransform.Microsoft.gradient",
303320
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
304321
"text-shadow"
305-
],
306-
[
307-
"font",
308-
"font-family",
309-
"font-size",
310-
"font-weight",
311-
"font-style",
312-
"font-variant",
313-
"font-size-adjust",
314-
"font-stretch",
315-
"font-effect",
316-
"font-emphasize",
317-
"font-emphasize-position",
318-
"font-emphasize-style",
319-
"font-smooth",
320-
"line-height"
321322
]
322323
]
323324
}

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Example configuration:
3434
{
3535
"exclude": ["node_modules/**"],
3636
"colon-space": true,
37+
"rule-indent": true,
38+
"block-indent": true,
3739
"stick-brace": true,
3840
"strip-spaces": true,
3941
"always-semicolon": true
@@ -46,4 +48,6 @@ Run `npm test` for tests.
4648

4749
## Other projects
4850
* https://github.com/senchalabs/cssbeautify
49-
* http://www.codebeautifier.com/
51+
* http://www.codebeautifier.com
52+
* https://github.com/css/gonzales
53+
* https://github.com/css/csso

lib/csscomb.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var cssp = require('cssp');
1+
var gonzales = require('gonzales');
22
var minimatch = require('minimatch');
33
var vow = require('vow');
44
var vfs = require('vow-fs');
@@ -11,11 +11,12 @@ var vfs = require('vow-fs');
1111
var Comb = function() {
1212
this._handlers;
1313
this._options = [
14+
'always-semicolon',
1415
'strip-spaces',
1516
'stick-brace',
1617
'colon-space',
1718
'rule-indent',
18-
'always-semicolon',
19+
'block-indent',
1920
'sort-order'
2021
];
2122
this._config = {};
@@ -54,23 +55,25 @@ Comb.prototype = {
5455
* @returns {Array}
5556
*/
5657
processTree: function(tree) {
57-
this.processNode(['tree', tree]);
58+
this.processNode(['tree', tree], 0);
5859
return tree;
5960
},
6061

6162
/**
6263
* Processes tree node.
6364
* @param {Array} node Tree node
65+
* @param {Number} level Indent level
6466
*/
6567
processNode: function(node, level) {
6668
var _this = this;
6769
node.forEach(function(node) {
6870
if (!Array.isArray(node)) return;
6971
var nodeType = node.shift();
7072
_this._handlers.forEach(function(handler) {
71-
handler.process(nodeType, node);
73+
handler.process(nodeType, node, level);
7274
});
7375
node.unshift(nodeType);
76+
if (nodeType === 'atrulers') level++;
7477
_this.processNode(node, level);
7578
});
7679
},
@@ -82,12 +85,20 @@ Comb.prototype = {
8285
*/
8386
processString: function(text, filename) {
8487
var tree;
88+
var string = JSON.stringify;
89+
if (typeof text === 'undefined') {
90+
throw new Error('Undefined file content ' + filename + ': ' + string(text));
91+
}
8592
try {
86-
tree = this.processTree(cssp.parse(text));
93+
tree = gonzales.srcToCSSP(text);
8794
} catch (e) {
8895
throw new Error('Parsing error at ' + filename + ': ' + e.message);
8996
}
90-
return cssp.translate(tree);
97+
if (typeof tree === 'undefined') {
98+
throw new Error('Undefined tree at ' + filename + ': ' + string(text) + ' => ' + string(tree));
99+
}
100+
tree = this.processTree(tree);
101+
return gonzales.csspToSrc(tree);
91102
},
92103

93104
/**
@@ -117,18 +128,17 @@ Comb.prototype = {
117128
return vfs.listDir(path).then(function(filenames) {
118129
return vow.all(filenames.map(function(filename) {
119130
var fullname = path + '/' + filename;
120-
return vfs.stat(fullname).then(function(stat) {
121-
if (_this._shouldProcess(fullname)) {
131+
if (_this._shouldProcess(fullname)) {
132+
return vfs.stat(fullname).then(function(stat) {
122133
if (stat.isDirectory()) {
123134
return _this.processDirectory(fullname);
124135
} else if (fullname.match(/\.css$/)) {
125136
return vow.when(_this.processFile(fullname)).then(function(errors) {
126137
if (errors) return errors;
127138
});
128139
}
129-
}
130-
return;
131-
});
140+
});
141+
}
132142
})).then(function(results) {
133143
return [].concat.apply([], results);
134144
});

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 = (i < 2 && 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/rule-indent.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
if (nodeType === 'block') {
25+
if (node[0][0] !== 's') {
26+
node.unshift(['s', '']);
27+
}
28+
for (var i = 0; i < node.length; i++) {
29+
var nodeItem = node[i];
30+
if (nodeItem[0] === 'declaration') {
31+
var value = '\n' + new Array(level + 2).join(this._value);
32+
var space = node[i - 1];
33+
var tail;
34+
35+
if (space[0] !== 's') {
36+
space = ['s', ''];
37+
tail = node.splice(i);
38+
tail.unshift(space);
39+
Array.prototype.push.apply(node, tail);
40+
i++;
41+
}
42+
space[1] = space[1].replace(/(\n)?([\t ]+)?$/, value);
43+
}
44+
};
45+
}
46+
}
47+
48+
};

lib/options/stick-brace.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ module.exports = {
2020
* @param {node} node
2121
*/
2222
process: function(nodeType, node) {
23-
if (nodeType === 'selector') {
23+
if (nodeType === 'selector' || nodeType === 'atruler') {
2424
for (var i = node.length; i--;) {
2525
var nodeItem = node[i];
26-
if (nodeItem[0] === 'simpleselector') {
26+
if (nodeItem[0] === 'simpleselector' || nodeItem[0] === 'atrulerq') {
2727
if (nodeItem[nodeItem.length - 1][0] === 's') nodeItem.pop();
2828
nodeItem.push(['s', this._value]);
2929
break;

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "csscomb",
33
"description": "Tool for beautify CSS",
4-
"version": "0.0.7",
4+
"version": "0.0.8",
55
"homepage": "http://csscomb.com/",
66
"author": "Mikhail Troshev <mishanga@yandex-team.ru>",
77
"repository": "https://github.com/csscomb/csscomb.js",
@@ -22,7 +22,7 @@
2222
},
2323
"dependencies": {
2424
"commander": "1.1.1",
25-
"cssp": "1.0.6",
25+
"gonzales": "1.0.6",
2626
"minimatch": "0.2.12",
2727
"vow": "0.3.7",
2828
"vow-fs": "0.1.13"

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+
});

0 commit comments

Comments
 (0)