Skip to content

Commit cf02982

Browse files
committed
option: sort-order
1 parent 4ad6315 commit cf02982

File tree

3 files changed

+335
-10
lines changed

3 files changed

+335
-10
lines changed

lib/options/sort-order.js

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
module.exports = {
2+
3+
/**
4+
* Internal. Smart split bunch on '\n' symbols;
5+
* @param {Array} bunch
6+
* @param {Boolean} isPrevDeclExists
7+
*/
8+
_splitBunch: function(bunch, isPrevDeclExists) {
9+
10+
var nextBunch = [];
11+
var declAlready = false;
12+
var flag = false;
13+
var item;
14+
var indexOf;
15+
16+
for (var i = 0; i < bunch.length; ++i) {
17+
if (flag) { nextBunch.push(bunch[i]); continue; }
18+
if (bunch[i][0] == 'declaration') { declAlready = true; }
19+
20+
if (isPrevDeclExists && !declAlready) continue;
21+
if (bunch[i][0] != 's') continue;
22+
23+
var indexOfNewLine = bunch[i][1].indexOf('\n');
24+
25+
if (indexOfNewLine == -1) continue;
26+
27+
nextBunch.push(['s', bunch[i][1].substr(indexOfNewLine + 1)]);
28+
bunch[i][1] = bunch[i][1].substr(0, indexOfNewLine + 1);
29+
30+
flag = i + 1;
31+
}
32+
33+
if (nextBunch.length == 1 && nextBunch[0][0] == 's') {
34+
item = nextBunch[0];
35+
indexOf = item[1].lastIndexOf('\n')
36+
37+
indexOf != -1 && (item[1] = item[1].substr(indexOf + 1));
38+
}
39+
40+
flag && bunch.splice(flag);
41+
42+
return nextBunch;
43+
44+
},
45+
46+
/**
47+
* Internal. Create extended node in format of list
48+
* {
49+
* data:[,,declaration,]
50+
* decl: declarationPropertyName
51+
* };
52+
* @param {node} node
53+
*/
54+
_createNodeExt: function(node) {
55+
56+
var extNode = [];
57+
var bunch = [];
58+
var nextBunch;
59+
var prevDeclPropertyName;
60+
61+
node.forEach(function(node) {
62+
63+
if (node[0] == 'declaration') {
64+
nextBunch = this._splitBunch(bunch, prevDeclPropertyName);
65+
extNode.push({ data: bunch, decl: prevDeclPropertyName });
66+
bunch = nextBunch;
67+
prevDeclPropertyName = node[1][1][1];
68+
}
69+
70+
bunch.push(node);
71+
72+
}, this);
73+
74+
nextBunch = this._splitBunch(bunch, prevDeclPropertyName);
75+
extNode.push({ data: bunch, decl: prevDeclPropertyName });
76+
nextBunch.length && extNode.push({ data: nextBunch });
77+
78+
return extNode;
79+
80+
},
81+
82+
/**
83+
* Internal. Add delimiter at the end of groups of properties
84+
* @param {extNode} extNodePrev
85+
* @param {extNode} extNode
86+
*/
87+
_addGroupDelimiter: function(extNodePrev, extNode) {
88+
89+
if (!extNodePrev.decl || !extNode.decl) return;
90+
91+
var indexA = this._order[extNodePrev.decl];
92+
var indexB = this._order[extNode.decl];
93+
var isGroupBorder = indexA && indexB && indexA.group != indexB.group;
94+
95+
if (isGroupBorder)
96+
extNode.data.unshift(['s', '\n']);
97+
98+
},
99+
100+
/**
101+
* Internal. apply extNode back at common format node.
102+
* @param {node} node
103+
* @param {extNode} extNode
104+
*/
105+
_applyNodeExt: function(node, extNode) {
106+
107+
node.splice(0, node.length);
108+
109+
extNode.forEach(function(item, i) {
110+
i > 0 && this._addGroupDelimiter(extNode[i - 1], item);
111+
node.push.apply(node, item.data);
112+
}, this);
113+
114+
},
115+
116+
/**
117+
* Sets handler value.
118+
*
119+
* @param {Array} value Option value
120+
* @returns {Object}
121+
*/
122+
setValue: function(value) {
123+
124+
if (!value) return;
125+
126+
this._order = {}
127+
value.forEach(function(group, groupIndex){
128+
group.forEach(function(prop, propIndex) {
129+
this._order[prop] = { group: groupIndex, prop: propIndex };
130+
}, this)
131+
}, this);
132+
133+
return this;
134+
135+
},
136+
137+
/**
138+
* Processes tree node.
139+
* @param {String} nodeType
140+
* @param {node} node
141+
*/
142+
process: function(nodeType, node) {
143+
144+
if (nodeType !== 'block') return;
145+
146+
var order = this._order;
147+
var nodeExt = this._createNodeExt(node);
148+
var firstSymbols = nodeExt[0].decl || nodeExt.shift();
149+
var lastSymbols = nodeExt[nodeExt.length - 1].decl || nodeExt.pop();
150+
151+
nodeExt.sort(function(a, b) {
152+
153+
var indexA = order[a.decl] || { prop: -1 };
154+
var indexB = order[b.decl] || { prop: -1 };
155+
var groupDelta = indexA.group - indexB.group;
156+
var propDelta = indexA.prop - indexB.prop;
157+
158+
return groupDelta !== 0 ? groupDelta : propDelta;
159+
160+
});
161+
162+
firstSymbols && nodeExt.unshift(firstSymbols);
163+
lastSymbols && nodeExt.push(lastSymbols);
164+
165+
this._applyNodeExt(node, nodeExt);
166+
167+
}
168+
169+
};

test/integral.expect.css

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
background: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0, rgba(0,0,0,0.4) 100%);
1010
background: -o-linear-gradient(top, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
1111
background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0,rgba(0,0,0,0.4) 100%);
12-
1312
-moz-box-shadow: 0 1px 0 rgba(0,0,0,.07);
1413
box-shadow: 0 1px 0 rgba(0,0,0,.07);
1514
}
@@ -35,17 +34,19 @@
3534
/* Фигурные скобки. Вариант 1 */
3635
a, b, i /* foobar */
3736
{
38-
padding: 0;
3937
margin: 0;
38+
padding: 0;
4039
}
4140
div p
4241
{
4342
font-size: 1px;
43+
4444
top: 0;
4545
}
4646
div p em
4747
{
4848
font-style: italic;
49+
4950
border-bottom: 1px solid red;
5051
}
5152

@@ -67,12 +68,15 @@ div p em
6768
{ /* foobar */
6869
.input__control
6970
{
70-
color: #000;
7171
font-size: 100%;
72-
margin: 0;
72+
7373
position: relative;
74-
width: 100%;
7574
z-index: 3;
75+
76+
width: 100%;
77+
margin: 0;
78+
79+
color: #000;
7680
}
7781
}
7882

@@ -82,41 +86,45 @@ div p em
8286
.input__control
8387
{
8488
-moz-box-sizing: border-box;
85-
background: none;
86-
border: 0;
8789
box-sizing: border-box;
88-
outline: 0;
8990
padding: 0.4em 0;
91+
92+
border: 0;
93+
outline: 0;
94+
background: none;
9095
}
9196
}
9297

9398
/* Фигурные скобки. Вариант 2 */
9499
div
95100
{
96-
padding: 0;
97101
margin: 0;
102+
padding: 0;
98103
}
99104
div p
100105
{
101106
font-size: 1px;
107+
102108
top: 0;
103109
}
104110
div p em
105111
{
106112
font-style: italic;/* inline comment*/
113+
107114
border-bottom: 1px solid red;
108115
}
109116

110117
/* Фигурные скобки. Вариант 3 */
111118
div
112119
{
113-
padding: 0;
114120
margin: 0;
121+
padding: 0;
115122
}
116123
/* foo */
117124
div p
118125
{
119126
font-size: 1px;
127+
120128
top: 0;
121129
}
122130
div p em
@@ -130,10 +138,12 @@ div p em
130138
a
131139
{
132140
top: 0;/* ololo */
141+
133142
margin: 0;
134143
}
135144
b
136145
{
137146
top: 0/* trololo */;
147+
138148
margin: 0;
139149
}

0 commit comments

Comments
 (0)