0182f7241fe2f36b9e7221da9896f5b0bac99173
[yaffs-website] / node_modules / uncss / node_modules / postcss / lib / stringifier.js
1 'use strict';
2
3 exports.__esModule = true;
4
5 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7 var defaultRaw = {
8     colon: ': ',
9     indent: '    ',
10     beforeDecl: '\n',
11     beforeRule: '\n',
12     beforeOpen: ' ',
13     beforeClose: '\n',
14     beforeComment: '\n',
15     after: '\n',
16     emptyBody: '',
17     commentLeft: ' ',
18     commentRight: ' '
19 };
20
21 function capitalize(str) {
22     return str[0].toUpperCase() + str.slice(1);
23 }
24
25 var Stringifier = function () {
26     function Stringifier(builder) {
27         _classCallCheck(this, Stringifier);
28
29         this.builder = builder;
30     }
31
32     Stringifier.prototype.stringify = function stringify(node, semicolon) {
33         this[node.type](node, semicolon);
34     };
35
36     Stringifier.prototype.root = function root(node) {
37         this.body(node);
38         if (node.raws.after) this.builder(node.raws.after);
39     };
40
41     Stringifier.prototype.comment = function comment(node) {
42         var left = this.raw(node, 'left', 'commentLeft');
43         var right = this.raw(node, 'right', 'commentRight');
44         this.builder('/*' + left + node.text + right + '*/', node);
45     };
46
47     Stringifier.prototype.decl = function decl(node, semicolon) {
48         var between = this.raw(node, 'between', 'colon');
49         var string = node.prop + between + this.rawValue(node, 'value');
50
51         if (node.important) {
52             string += node.raws.important || ' !important';
53         }
54
55         if (semicolon) string += ';';
56         this.builder(string, node);
57     };
58
59     Stringifier.prototype.rule = function rule(node) {
60         this.block(node, this.rawValue(node, 'selector'));
61     };
62
63     Stringifier.prototype.atrule = function atrule(node, semicolon) {
64         var name = '@' + node.name;
65         var params = node.params ? this.rawValue(node, 'params') : '';
66
67         if (typeof node.raws.afterName !== 'undefined') {
68             name += node.raws.afterName;
69         } else if (params) {
70             name += ' ';
71         }
72
73         if (node.nodes) {
74             this.block(node, name + params);
75         } else {
76             var end = (node.raws.between || '') + (semicolon ? ';' : '');
77             this.builder(name + params + end, node);
78         }
79     };
80
81     Stringifier.prototype.body = function body(node) {
82         var last = node.nodes.length - 1;
83         while (last > 0) {
84             if (node.nodes[last].type !== 'comment') break;
85             last -= 1;
86         }
87
88         var semicolon = this.raw(node, 'semicolon');
89         for (var i = 0; i < node.nodes.length; i++) {
90             var child = node.nodes[i];
91             var before = this.raw(child, 'before');
92             if (before) this.builder(before);
93             this.stringify(child, last !== i || semicolon);
94         }
95     };
96
97     Stringifier.prototype.block = function block(node, start) {
98         var between = this.raw(node, 'between', 'beforeOpen');
99         this.builder(start + between + '{', node, 'start');
100
101         var after = void 0;
102         if (node.nodes && node.nodes.length) {
103             this.body(node);
104             after = this.raw(node, 'after');
105         } else {
106             after = this.raw(node, 'after', 'emptyBody');
107         }
108
109         if (after) this.builder(after);
110         this.builder('}', node, 'end');
111     };
112
113     Stringifier.prototype.raw = function raw(node, own, detect) {
114         var value = void 0;
115         if (!detect) detect = own;
116
117         // Already had
118         if (own) {
119             value = node.raws[own];
120             if (typeof value !== 'undefined') return value;
121         }
122
123         var parent = node.parent;
124
125         // Hack for first rule in CSS
126         if (detect === 'before') {
127             if (!parent || parent.type === 'root' && parent.first === node) {
128                 return '';
129             }
130         }
131
132         // Floating child without parent
133         if (!parent) return defaultRaw[detect];
134
135         // Detect style by other nodes
136         var root = node.root();
137         if (!root.rawCache) root.rawCache = {};
138         if (typeof root.rawCache[detect] !== 'undefined') {
139             return root.rawCache[detect];
140         }
141
142         if (detect === 'before' || detect === 'after') {
143             return this.beforeAfter(node, detect);
144         } else {
145             var method = 'raw' + capitalize(detect);
146             if (this[method]) {
147                 value = this[method](root, node);
148             } else {
149                 root.walk(function (i) {
150                     value = i.raws[own];
151                     if (typeof value !== 'undefined') return false;
152                 });
153             }
154         }
155
156         if (typeof value === 'undefined') value = defaultRaw[detect];
157
158         root.rawCache[detect] = value;
159         return value;
160     };
161
162     Stringifier.prototype.rawSemicolon = function rawSemicolon(root) {
163         var value = void 0;
164         root.walk(function (i) {
165             if (i.nodes && i.nodes.length && i.last.type === 'decl') {
166                 value = i.raws.semicolon;
167                 if (typeof value !== 'undefined') return false;
168             }
169         });
170         return value;
171     };
172
173     Stringifier.prototype.rawEmptyBody = function rawEmptyBody(root) {
174         var value = void 0;
175         root.walk(function (i) {
176             if (i.nodes && i.nodes.length === 0) {
177                 value = i.raws.after;
178                 if (typeof value !== 'undefined') return false;
179             }
180         });
181         return value;
182     };
183
184     Stringifier.prototype.rawIndent = function rawIndent(root) {
185         if (root.raws.indent) return root.raws.indent;
186         var value = void 0;
187         root.walk(function (i) {
188             var p = i.parent;
189             if (p && p !== root && p.parent && p.parent === root) {
190                 if (typeof i.raws.before !== 'undefined') {
191                     var parts = i.raws.before.split('\n');
192                     value = parts[parts.length - 1];
193                     value = value.replace(/[^\s]/g, '');
194                     return false;
195                 }
196             }
197         });
198         return value;
199     };
200
201     Stringifier.prototype.rawBeforeComment = function rawBeforeComment(root, node) {
202         var value = void 0;
203         root.walkComments(function (i) {
204             if (typeof i.raws.before !== 'undefined') {
205                 value = i.raws.before;
206                 if (value.indexOf('\n') !== -1) {
207                     value = value.replace(/[^\n]+$/, '');
208                 }
209                 return false;
210             }
211         });
212         if (typeof value === 'undefined') {
213             value = this.raw(node, null, 'beforeDecl');
214         }
215         return value;
216     };
217
218     Stringifier.prototype.rawBeforeDecl = function rawBeforeDecl(root, node) {
219         var value = void 0;
220         root.walkDecls(function (i) {
221             if (typeof i.raws.before !== 'undefined') {
222                 value = i.raws.before;
223                 if (value.indexOf('\n') !== -1) {
224                     value = value.replace(/[^\n]+$/, '');
225                 }
226                 return false;
227             }
228         });
229         if (typeof value === 'undefined') {
230             value = this.raw(node, null, 'beforeRule');
231         }
232         return value;
233     };
234
235     Stringifier.prototype.rawBeforeRule = function rawBeforeRule(root) {
236         var value = void 0;
237         root.walk(function (i) {
238             if (i.nodes && (i.parent !== root || root.first !== i)) {
239                 if (typeof i.raws.before !== 'undefined') {
240                     value = i.raws.before;
241                     if (value.indexOf('\n') !== -1) {
242                         value = value.replace(/[^\n]+$/, '');
243                     }
244                     return false;
245                 }
246             }
247         });
248         return value;
249     };
250
251     Stringifier.prototype.rawBeforeClose = function rawBeforeClose(root) {
252         var value = void 0;
253         root.walk(function (i) {
254             if (i.nodes && i.nodes.length > 0) {
255                 if (typeof i.raws.after !== 'undefined') {
256                     value = i.raws.after;
257                     if (value.indexOf('\n') !== -1) {
258                         value = value.replace(/[^\n]+$/, '');
259                     }
260                     return false;
261                 }
262             }
263         });
264         return value;
265     };
266
267     Stringifier.prototype.rawBeforeOpen = function rawBeforeOpen(root) {
268         var value = void 0;
269         root.walk(function (i) {
270             if (i.type !== 'decl') {
271                 value = i.raws.between;
272                 if (typeof value !== 'undefined') return false;
273             }
274         });
275         return value;
276     };
277
278     Stringifier.prototype.rawColon = function rawColon(root) {
279         var value = void 0;
280         root.walkDecls(function (i) {
281             if (typeof i.raws.between !== 'undefined') {
282                 value = i.raws.between.replace(/[^\s:]/g, '');
283                 return false;
284             }
285         });
286         return value;
287     };
288
289     Stringifier.prototype.beforeAfter = function beforeAfter(node, detect) {
290         var value = void 0;
291         if (node.type === 'decl') {
292             value = this.raw(node, null, 'beforeDecl');
293         } else if (node.type === 'comment') {
294             value = this.raw(node, null, 'beforeComment');
295         } else if (detect === 'before') {
296             value = this.raw(node, null, 'beforeRule');
297         } else {
298             value = this.raw(node, null, 'beforeClose');
299         }
300
301         var buf = node.parent;
302         var depth = 0;
303         while (buf && buf.type !== 'root') {
304             depth += 1;
305             buf = buf.parent;
306         }
307
308         if (value.indexOf('\n') !== -1) {
309             var indent = this.raw(node, null, 'indent');
310             if (indent.length) {
311                 for (var step = 0; step < depth; step++) {
312                     value += indent;
313                 }
314             }
315         }
316
317         return value;
318     };
319
320     Stringifier.prototype.rawValue = function rawValue(node, prop) {
321         var value = node[prop];
322         var raw = node.raws[prop];
323         if (raw && raw.value === value) {
324             return raw.raw;
325         } else {
326             return value;
327         }
328     };
329
330     return Stringifier;
331 }();
332
333 exports.default = Stringifier;
334 module.exports = exports['default'];