UNPKG

7.44 kBJavaScriptView Raw
1var emptyCharacter = '';
2
3var Breaks = require('../options/format').Breaks;
4var Spaces = require('../options/format').Spaces;
5
6var Marker = require('../tokenizer/marker');
7var Token = require('../tokenizer/token');
8
9function supportsAfterClosingBrace(token) {
10 return token[1][1] == 'background' || token[1][1] == 'transform' || token[1][1] == 'src';
11}
12
13function afterClosingBrace(token, valueIndex) {
14 return token[valueIndex][1][token[valueIndex][1].length - 1] == Marker.CLOSE_ROUND_BRACKET;
15}
16
17function afterComma(token, valueIndex) {
18 return token[valueIndex][1] == Marker.COMMA;
19}
20
21function afterSlash(token, valueIndex) {
22 return token[valueIndex][1] == Marker.FORWARD_SLASH;
23}
24
25function beforeComma(token, valueIndex) {
26 return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.COMMA;
27}
28
29function beforeSlash(token, valueIndex) {
30 return token[valueIndex + 1] && token[valueIndex + 1][1] == Marker.FORWARD_SLASH;
31}
32
33function inFilter(token) {
34 return token[1][1] == 'filter' || token[1][1] == '-ms-filter';
35}
36
37function disallowsSpace(context, token, valueIndex) {
38 return !context.spaceAfterClosingBrace && supportsAfterClosingBrace(token) && afterClosingBrace(token, valueIndex) ||
39 beforeSlash(token, valueIndex) ||
40 afterSlash(token, valueIndex) ||
41 beforeComma(token, valueIndex) ||
42 afterComma(token, valueIndex);
43}
44
45function rules(context, tokens) {
46 var store = context.store;
47
48 for (var i = 0, l = tokens.length; i < l; i++) {
49 store(context, tokens[i]);
50
51 if (i < l - 1) {
52 store(context, comma(context));
53 }
54 }
55}
56
57function body(context, tokens) {
58 var lastPropertyAt = lastPropertyIndex(tokens);
59
60 for (var i = 0, l = tokens.length; i < l; i++) {
61 property(context, tokens, i, lastPropertyAt);
62 }
63}
64
65function lastPropertyIndex(tokens) {
66 var index = tokens.length - 1;
67
68 for (; index >= 0; index--) {
69 if (tokens[index][0] != Token.COMMENT) {
70 break;
71 }
72 }
73
74 return index;
75}
76
77function property(context, tokens, position, lastPropertyAt) {
78 var store = context.store;
79 var token = tokens[position];
80
81 var propertyValue = token[2];
82 var isPropertyBlock = propertyValue && propertyValue[0] === Token.PROPERTY_BLOCK;
83
84 var needsSemicolon;
85 if ( context.format ) {
86 if ( context.format.semicolonAfterLastProperty || isPropertyBlock ) {
87 needsSemicolon = true;
88 } else if ( position < lastPropertyAt ) {
89 needsSemicolon = true;
90 } else {
91 needsSemicolon = false;
92 }
93 } else {
94 needsSemicolon = position < lastPropertyAt || isPropertyBlock;
95 }
96
97 var isLast = position === lastPropertyAt;
98
99 switch (token[0]) {
100 case Token.AT_RULE:
101 store(context, token);
102 store(context, semicolon(context, Breaks.AfterProperty, false));
103 break;
104 case Token.AT_RULE_BLOCK:
105 rules(context, token[1]);
106 store(context, openBrace(context, Breaks.AfterRuleBegins, true));
107 body(context, token[2]);
108 store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
109 break;
110 case Token.COMMENT:
111 store(context, token);
112 break;
113 case Token.PROPERTY:
114 store(context, token[1]);
115 store(context, colon(context));
116 if (propertyValue) {
117 value(context, token);
118 }
119 store(context, needsSemicolon ? semicolon(context, Breaks.AfterProperty, isLast) : emptyCharacter);
120 break;
121 case Token.RAW:
122 store(context, token);
123 }
124}
125
126function value(context, token) {
127 var store = context.store;
128 var j, m;
129
130 if (token[2][0] == Token.PROPERTY_BLOCK) {
131 store(context, openBrace(context, Breaks.AfterBlockBegins, false));
132 body(context, token[2][1]);
133 store(context, closeBrace(context, Breaks.AfterBlockEnds, false, true));
134 } else {
135 for (j = 2, m = token.length; j < m; j++) {
136 store(context, token[j]);
137
138 if (j < m - 1 && (inFilter(token) || !disallowsSpace(context, token, j))) {
139 store(context, Marker.SPACE);
140 }
141 }
142 }
143}
144
145function allowsBreak(context, where) {
146 return context.format && context.format.breaks[where];
147}
148
149function allowsSpace(context, where) {
150 return context.format && context.format.spaces[where];
151}
152
153function openBrace(context, where, needsPrefixSpace) {
154 if (context.format) {
155 context.indentBy += context.format.indentBy;
156 context.indentWith = context.format.indentWith.repeat(context.indentBy);
157 return (needsPrefixSpace && allowsSpace(context, Spaces.BeforeBlockBegins) ? Marker.SPACE : emptyCharacter) +
158 Marker.OPEN_CURLY_BRACKET +
159 (allowsBreak(context, where) ? context.format.breakWith : emptyCharacter) +
160 context.indentWith;
161 } else {
162 return Marker.OPEN_CURLY_BRACKET;
163 }
164}
165
166function closeBrace(context, where, beforeBlockEnd, isLast) {
167 if (context.format) {
168 context.indentBy -= context.format.indentBy;
169 context.indentWith = context.format.indentWith.repeat(context.indentBy);
170 return (allowsBreak(context, Breaks.AfterProperty) || beforeBlockEnd && allowsBreak(context, Breaks.BeforeBlockEnds) ? context.format.breakWith : emptyCharacter) +
171 context.indentWith +
172 Marker.CLOSE_CURLY_BRACKET +
173 (isLast ? emptyCharacter : (allowsBreak(context, where) ? context.format.breakWith : emptyCharacter) + context.indentWith);
174 } else {
175 return Marker.CLOSE_CURLY_BRACKET;
176 }
177}
178
179function colon(context) {
180 return context.format ?
181 Marker.COLON + (allowsSpace(context, Spaces.BeforeValue) ? Marker.SPACE : emptyCharacter) :
182 Marker.COLON;
183}
184
185function semicolon(context, where, isLast) {
186 return context.format ?
187 Marker.SEMICOLON + (isLast || !allowsBreak(context, where) ? emptyCharacter : context.format.breakWith + context.indentWith) :
188 Marker.SEMICOLON;
189}
190
191function comma(context) {
192 return context.format ?
193 Marker.COMMA + (allowsBreak(context, Breaks.BetweenSelectors) ? context.format.breakWith : emptyCharacter) + context.indentWith :
194 Marker.COMMA;
195}
196
197function all(context, tokens) {
198 var store = context.store;
199 var token;
200 var isLast;
201 var i, l;
202
203 for (i = 0, l = tokens.length; i < l; i++) {
204 token = tokens[i];
205 isLast = i == l - 1;
206
207 switch (token[0]) {
208 case Token.AT_RULE:
209 store(context, token);
210 store(context, semicolon(context, Breaks.AfterAtRule, isLast));
211 break;
212 case Token.AT_RULE_BLOCK:
213 rules(context, token[1]);
214 store(context, openBrace(context, Breaks.AfterRuleBegins, true));
215 body(context, token[2]);
216 store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
217 break;
218 case Token.NESTED_BLOCK:
219 rules(context, token[1]);
220 store(context, openBrace(context, Breaks.AfterBlockBegins, true));
221 all(context, token[2]);
222 store(context, closeBrace(context, Breaks.AfterBlockEnds, true, isLast));
223 break;
224 case Token.COMMENT:
225 store(context, token);
226 store(context, allowsBreak(context, Breaks.AfterComment) ? context.format.breakWith : emptyCharacter);
227 break;
228 case Token.RAW:
229 store(context, token);
230 break;
231 case Token.RULE:
232 rules(context, token[1]);
233 store(context, openBrace(context, Breaks.AfterRuleBegins, true));
234 body(context, token[2]);
235 store(context, closeBrace(context, Breaks.AfterRuleEnds, false, isLast));
236 break;
237 }
238 }
239}
240
241module.exports = {
242 all: all,
243 body: body,
244 property: property,
245 rules: rules,
246 value: value
247};