.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / postcss-less / dist / less-parser.js
1 'use strict';
2
3 Object.defineProperty(exports, "__esModule", {
4   value: true
5 });
6
7 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
9 var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
10
11 var _comment = require('postcss/lib/comment');
12
13 var _comment2 = _interopRequireDefault(_comment);
14
15 var _import2 = require('./import');
16
17 var _import3 = _interopRequireDefault(_import2);
18
19 var _parser = require('postcss/lib/parser');
20
21 var _parser2 = _interopRequireDefault(_parser);
22
23 var _rule = require('./rule');
24
25 var _rule2 = _interopRequireDefault(_rule);
26
27 var _root = require('./root');
28
29 var _root2 = _interopRequireDefault(_root);
30
31 var _findExtendRule = require('./find-extend-rule');
32
33 var _findExtendRule2 = _interopRequireDefault(_findExtendRule);
34
35 var _isMixinToken = require('./is-mixin-token');
36
37 var _isMixinToken2 = _interopRequireDefault(_isMixinToken);
38
39 var _lessTokenize = require('./less-tokenize');
40
41 var _lessTokenize2 = _interopRequireDefault(_lessTokenize);
42
43 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
44
45 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
46
47 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
48
49 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
50
51 var blockCommentEndPattern = /\*\/$/;
52
53 var LessParser = function (_Parser) {
54   _inherits(LessParser, _Parser);
55
56   function LessParser(input) {
57     _classCallCheck(this, LessParser);
58
59     var _this = _possibleConstructorReturn(this, (LessParser.__proto__ || Object.getPrototypeOf(LessParser)).call(this, input));
60
61     _this.root = new _root2.default();
62     _this.current = _this.root;
63     _this.root.source = { input: input, start: { line: 1, column: 1 } };
64     return _this;
65   }
66
67   _createClass(LessParser, [{
68     key: 'atrule',
69     value: function atrule(token) {
70       if (token[1] === '@import') {
71         this.import(token);
72       } else {
73         _get(LessParser.prototype.__proto__ || Object.getPrototypeOf(LessParser.prototype), 'atrule', this).call(this, token);
74       }
75     }
76   }, {
77     key: 'comment',
78     value: function comment(token) {
79       var node = new _comment2.default();
80       var content = token[1];
81       var text = content.slice(2).replace(blockCommentEndPattern, '');
82
83       this.init(node, token[2], token[3]);
84       node.source.end = {
85         line: token[4],
86         column: token[5]
87       };
88
89       node.raws.content = content;
90       node.raws.begin = content[0] + content[1];
91       node.inline = token[6] === 'inline';
92       node.block = !node.inline;
93
94       if (/^\s*$/.test(text)) {
95         node.text = '';
96         node.raws.left = text;
97         node.raws.right = '';
98       } else {
99         var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/);
100
101         node.text = match[2];
102
103         // Add extra spaces to generate a comment in a common style /*[space][text][space]*/
104         node.raws.left = match[1] || ' ';
105         node.raws.right = match[3] || ' ';
106       }
107     }
108
109     /**
110      * @description Create a Declaration
111      * @param options {{start: number}}
112      */
113
114   }, {
115     key: 'createDeclaration',
116     value: function createDeclaration(options) {
117       this.decl(this.tokens.slice(options.start, this.pos + 1));
118     }
119
120     /**
121      * @description Create a Rule node
122      * @param options {{start: number, params: Array}}
123      */
124
125   }, {
126     key: 'createRule',
127     value: function createRule(options) {
128
129       var semi = this.tokens[this.pos][0] === ';';
130       var end = this.pos + (options.empty && semi ? 2 : 1);
131       var tokens = this.tokens.slice(options.start, end);
132       var node = this.rule(tokens);
133
134       /**
135        * By default in PostCSS `Rule.params` is `undefined`.
136        * To preserve compability with PostCSS:
137        *  - Don't set empty params for a Rule.
138        *  - Set params for a Rule only if it can be a mixin or &:extend rule.
139        */
140       if (options.params[0] && (options.mixin || options.extend)) {
141         this.raw(node, 'params', options.params);
142       }
143
144       if (options.empty) {
145         // if it's an empty mixin or extend, it must have a semicolon
146         // (that's the only way we get to this point)
147         if (semi) {
148           node.raws.semicolon = this.semicolon = true;
149           node.selector = node.selector.replace(/;$/, '');
150         }
151
152         if (options.extend) {
153           node.extend = true;
154         }
155
156         if (options.mixin) {
157           node.mixin = true;
158         }
159
160         /**
161          * @description Mark mixin without declarations.
162          * @type {boolean}
163          */
164         node.empty = true;
165
166         // eslint-disable-next-line
167         delete this.current.nodes;
168
169         if (/!\s*important/i.test(node.selector)) {
170           node.important = true;
171
172           if (/\s*!\s*important/i.test(node.selector)) {
173             node.raws.important = node.selector.match(/(\s*!\s*important)/i)[1];
174           }
175
176           node.selector = node.selector.replace(/\s*!\s*important/i, '');
177         }
178
179         // rules don't have trailing semicolons in vanilla css, so they get
180         // added to this.spaces by the parser loop, so don't step back.
181         if (!semi) {
182           this.pos--;
183         }
184
185         this.end(this.tokens[this.pos]);
186       }
187     }
188   }, {
189     key: 'end',
190     value: function end(token) {
191       var node = this.current;
192
193       // if a Rule contains other Rules (mixins, extends) and those have
194       // semicolons, assert that the parent Rule has a semicolon
195       if (node.nodes && node.nodes.length && node.last.raws.semicolon && !node.last.nodes) {
196         this.semicolon = true;
197       }
198
199       _get(LessParser.prototype.__proto__ || Object.getPrototypeOf(LessParser.prototype), 'end', this).call(this, token);
200     }
201   }, {
202     key: 'import',
203     value: function _import(token) {
204       /* eslint complexity: 0 */
205       var last = false,
206           open = false,
207           end = { line: 0, column: 0 };
208
209       var directives = [];
210       var node = new _import3.default();
211
212       node.name = token[1].slice(1);
213
214       this.init(node, token[2], token[3]);
215
216       this.pos += 1;
217
218       while (this.pos < this.tokens.length) {
219         var tokn = this.tokens[this.pos];
220
221         if (tokn[0] === ';') {
222           end = { line: tokn[2], column: tokn[3] };
223           node.raws.semicolon = true;
224           break;
225         } else if (tokn[0] === '{') {
226           open = true;
227           break;
228         } else if (tokn[0] === '}') {
229           this.end(tokn);
230           break;
231         } else if (tokn[0] === 'brackets') {
232           if (node.urlFunc) {
233             node.importPath = tokn[1].replace(/[()]/g, '');
234           } else {
235             directives.push(tokn);
236           }
237         } else if (tokn[0] === 'space') {
238           if (directives.length) {
239             node.raws.between = tokn[1];
240           } else if (node.urlFunc) {
241             node.raws.beforeUrl = tokn[1];
242           } else if (node.importPath) {
243             if (node.urlFunc) {
244               node.raws.afterUrl = tokn[1];
245             } else {
246               node.raws.after = tokn[1];
247             }
248           } else {
249             node.raws.afterName = tokn[1];
250           }
251         } else if (tokn[0] === 'word' && tokn[1] === 'url') {
252           node.urlFunc = true;
253         } else {
254           if (tokn[0] !== '(' && tokn[0] !== ')') {
255             node.importPath = tokn[1];
256           }
257         }
258
259         if (this.pos === this.tokens.length) {
260           last = true;
261           break;
262         }
263
264         this.pos += 1;
265       }
266
267       if (node.raws.between && !node.raws.afterName) {
268         node.raws.afterName = node.raws.between;
269         node.raws.between = '';
270       }
271
272       node.source.end = end;
273
274       if (directives.length) {
275         this.raw(node, 'directives', directives);
276
277         if (last) {
278           token = directives[directives.length - 1];
279           node.source.end = { line: token[4], column: token[5] };
280           this.spaces = node.raws.between;
281           node.raws.between = '';
282         }
283       } else {
284         node.directives = '';
285       }
286
287       if (open) {
288         node.nodes = [];
289         this.current = node;
290       }
291     }
292
293     /* eslint-disable max-statements, complexity */
294
295   }, {
296     key: 'other',
297     value: function other() {
298       var brackets = [];
299       var params = [];
300       var start = this.pos;
301
302       var end = false,
303           colon = false,
304           bracket = null;
305
306       // we need pass "()" as spaces
307       // However we can override method Parser.loop, but it seems less maintainable
308       if (this.tokens[start][0] === 'brackets') {
309         this.spaces += this.tokens[start][1];
310         return;
311       }
312
313       var mixin = (0, _isMixinToken2.default)(this.tokens[start]);
314       var extend = Boolean((0, _findExtendRule2.default)(this.tokens, start));
315
316       while (this.pos < this.tokens.length) {
317         var token = this.tokens[this.pos];
318         var type = token[0];
319
320         if (type === '(' || type === '[') {
321           if (!bracket) {
322             bracket = token;
323           }
324
325           brackets.push(type === '(' ? ')' : ']');
326         } else if (brackets.length === 0) {
327           if (type === ';') {
328             var foundEndOfRule = this.ruleEnd({
329               start: start,
330               params: params,
331               colon: colon,
332               mixin: mixin,
333               extend: extend
334             });
335
336             if (foundEndOfRule) {
337               return;
338             }
339
340             break;
341           } else if (type === '{') {
342             this.createRule({ start: start, params: params, mixin: mixin });
343             return;
344           } else if (type === '}') {
345             this.pos -= 1;
346             end = true;
347             break;
348           } else if (type === ':') {
349             colon = true;
350           }
351         } else if (type === brackets[brackets.length - 1]) {
352           brackets.pop();
353           if (brackets.length === 0) {
354             bracket = null;
355           }
356         }
357
358         // we don't want to add params for pseudo-selectors that utilize parens (#56)
359         // if ((extend || !colon) && (brackets.length > 0 || type === 'brackets' || params[0])) {
360         //   params.push(token);
361         // }
362
363         // we don't want to add params for pseudo-selectors that utilize parens (#56) or bracket selectors (#96)
364         if ((extend || !colon) && (brackets.length > 0 || type === 'brackets' || params[0]) && brackets[0] !== ']') {
365           params.push(token);
366         }
367
368         this.pos += 1;
369       }
370
371       if (this.pos === this.tokens.length) {
372         this.pos -= 1;
373         end = true;
374       }
375
376       if (brackets.length > 0) {
377         this.unclosedBracket(bracket);
378       }
379
380       // dont process an end of rule if there's only one token and it's unknown (#64)
381       if (end && this.tokens.length > 1) {
382         // Handle the case where the there is only a single token in the end rule.
383         if (start === this.pos) {
384           this.pos += 1;
385         }
386
387         var _foundEndOfRule = this.ruleEnd({
388           start: start,
389           params: params,
390           colon: colon,
391           mixin: mixin,
392           extend: extend,
393           isEndOfBlock: true
394         });
395
396         if (_foundEndOfRule) {
397           return;
398         }
399       }
400
401       this.unknownWord(start);
402     }
403   }, {
404     key: 'rule',
405     value: function rule(tokens) {
406       tokens.pop();
407
408       var node = new _rule2.default();
409
410       this.init(node, tokens[0][2], tokens[0][3]);
411
412       //node.raws.between = this.spacesFromEnd(tokens);
413       node.raws.between = this.spacesAndCommentsFromEnd(tokens);
414
415       this.raw(node, 'selector', tokens);
416       this.current = node;
417
418       return node;
419     }
420   }, {
421     key: 'ruleEnd',
422     value: function ruleEnd(options) {
423       var start = options.start;
424
425
426       if (options.extend || options.mixin) {
427         this.createRule(Object.assign(options, { empty: true }));
428         return true;
429       }
430
431       if (options.colon) {
432         if (options.isEndOfBlock) {
433           while (this.pos > start) {
434             var token = this.tokens[this.pos][0];
435
436             if (token !== 'space' && token !== 'comment') {
437               break;
438             }
439
440             this.pos -= 1;
441           }
442         }
443
444         this.createDeclaration({ start: start });
445         return true;
446       }
447
448       return false;
449     }
450   }, {
451     key: 'tokenize',
452     value: function tokenize() {
453       this.tokens = (0, _lessTokenize2.default)(this.input);
454     }
455
456     /* eslint-enable max-statements, complexity */
457
458   }]);
459
460   return LessParser;
461 }(_parser2.default);
462
463 exports.default = LessParser;
464 module.exports = exports['default'];