UNPKG

11.6 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _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
9var _comment = require('postcss/lib/comment');
10
11var _comment2 = _interopRequireDefault(_comment);
12
13var _parser = require('postcss/lib/parser');
14
15var _parser2 = _interopRequireDefault(_parser);
16
17var _rule = require('./rule');
18
19var _rule2 = _interopRequireDefault(_rule);
20
21var _findExtendRule = require('./find-extend-rule');
22
23var _findExtendRule2 = _interopRequireDefault(_findExtendRule);
24
25var _isMixinToken = require('./is-mixin-token');
26
27var _isMixinToken2 = _interopRequireDefault(_isMixinToken);
28
29var _lessTokenize = require('./less-tokenize');
30
31var _lessTokenize2 = _interopRequireDefault(_lessTokenize);
32
33function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
35function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
36
37function _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; }
38
39function _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; }
40
41var blockCommentEndPattern = /\*\/$/;
42
43var LessParser = function (_Parser) {
44 _inherits(LessParser, _Parser);
45
46 function LessParser() {
47 _classCallCheck(this, LessParser);
48
49 return _possibleConstructorReturn(this, Object.getPrototypeOf(LessParser).apply(this, arguments));
50 }
51
52 _createClass(LessParser, [{
53 key: 'tokenize',
54 value: function tokenize() {
55 this.tokens = (0, _lessTokenize2.default)(this.input);
56 }
57 }, {
58 key: 'rule',
59 value: function rule(tokens) {
60 tokens.pop();
61
62 var node = new _rule2.default();
63
64 this.init(node, tokens[0][2], tokens[0][3]);
65 node.raws.between = this.spacesFromEnd(tokens);
66 this.raw(node, 'selector', tokens);
67 this.current = node;
68 }
69 }, {
70 key: 'comment',
71 value: function comment(token) {
72 var node = new _comment2.default();
73 var content = token[1];
74 var text = content.slice(2).replace(blockCommentEndPattern, '');
75
76 this.init(node, token[2], token[3]);
77 node.source.end = {
78 line: token[4],
79 column: token[5]
80 };
81
82 node.raws.content = content;
83 node.raws.begin = content[0] + content[1];
84 node.inline = token[6] === 'inline';
85 node.block = !node.inline;
86
87 if (/^\s*$/.test(text)) {
88 node.text = '';
89 node.raws.left = text;
90 node.raws.right = '';
91 } else {
92 var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/);
93
94 node.text = match[2];
95
96 // Add extra spaces to generate a comment in a common style /*[space][text][space]*/
97 node.raws.left = match[1] || ' ';
98 node.raws.right = match[3] || ' ';
99 }
100 }
101
102 /**
103 * @description Create a Rule node
104 * @param options {{start: number, params: Array}}
105 */
106
107 }, {
108 key: 'createRule',
109 value: function createRule(options) {
110 this.rule(this.tokens.slice(options.start, this.pos + 1));
111
112 /**
113 * By default in PostCSS `Rule.params` is `undefined`. There are rules to save the compability with PostCSS:
114 * - Don't set empty params for Rule node.
115 * - Set params fro Rule node only if it can be a mixin or &:extend rule.
116 */
117 if (options.params[0] && (options.isMixin || options.isExtendRule)) {
118 this.raw(this.current, 'params', options.params);
119 }
120 }
121
122 /**
123 * @description Create a Declaration
124 * @param options {{start: number}}
125 */
126
127 }, {
128 key: 'createDeclaration',
129 value: function createDeclaration(options) {
130 this.decl(this.tokens.slice(options.start, this.pos + 1));
131 }
132
133 /**
134 * @description Create a Rule block and close it, because this mixin doesn't have a body
135 * @param options
136 */
137
138 }, {
139 key: 'ruleWithoutBody',
140 value: function ruleWithoutBody(options) {
141 this.createRule(options);
142
143 /**
144 * @description Mark mixin without body.
145 * @type {boolean}
146 */
147 this.current.ruleWithoutBody = true;
148
149 // remove `nodes` property from rules without body
150 // eslint-disable-next-line
151 delete this.current.nodes;
152 this.current.extendRule = this.current.selector.indexOf('&:extend') >= 0;
153 this.current.important = this.current.selector.indexOf('!important') >= 0;
154
155 this.pos--;
156
157 this.end(this.tokens[this.pos]);
158 }
159
160 /**
161 * @description
162 * @param options
163 * @returns {boolean}
164 */
165
166 }, {
167 key: 'processEndOfRule',
168 value: function processEndOfRule(options) {
169 var start = options.start;
170
171
172 if (options.isExtendRule || options.isMixin) {
173 this.ruleWithoutBody(options);
174 return true;
175 }
176
177 if (options.colon) {
178 if (options.isEndOfBlock) {
179 while (this.pos > start) {
180 var token = this.tokens[this.pos][0];
181
182 if (token !== 'space' && token !== 'comment') {
183 break;
184 }
185
186 this.pos -= 1;
187 }
188 }
189
190 this.createDeclaration({ start: start });
191 return true;
192 }
193
194 return false;
195 }
196
197 /* eslint-disable max-statements, complexity */
198
199 }, {
200 key: 'word',
201 value: function word() {
202 var end = false;
203 var colon = false;
204 var bracket = null;
205 var brackets = 0;
206 var start = this.pos;
207 var isMixin = (0, _isMixinToken2.default)(this.tokens[start]);
208 var isExtendRule = Boolean((0, _findExtendRule2.default)(this.tokens, start));
209 var params = [];
210
211 this.pos += 1;
212
213 while (this.pos < this.tokens.length) {
214 var token = this.tokens[this.pos];
215 var type = token[0];
216
217 if (type === '(') {
218 if (!bracket) {
219 bracket = token;
220 }
221
222 brackets += 1;
223 } else if (brackets === 0) {
224 if (type === ';') {
225 var foundEndOfRule = this.processEndOfRule({
226 start: start,
227 params: params,
228 colon: colon,
229 isMixin: isMixin,
230 isExtendRule: isExtendRule
231 });
232
233 if (foundEndOfRule) {
234 return;
235 }
236
237 break;
238 } else if (type === '{') {
239 this.createRule({ start: start, params: params, isMixin: isMixin });
240 return;
241 } else if (type === '}') {
242 this.pos -= 1;
243 end = true;
244 break;
245 } else if (type === ':') {
246 colon = true;
247 }
248 } else if (type === ')') {
249 brackets -= 1;
250 if (brackets === 0) {
251 bracket = null;
252 }
253 }
254
255 if (brackets || type === 'brackets' || params[0]) {
256 params.push(token);
257 }
258
259 this.pos += 1;
260 }
261
262 if (this.pos === this.tokens.length) {
263 this.pos -= 1;
264 end = true;
265 }
266
267 if (brackets > 0) {
268 this.unclosedBracket(bracket);
269 }
270
271 if (end) {
272 var _foundEndOfRule = this.processEndOfRule({
273 start: start,
274 params: params,
275 colon: colon,
276 isMixin: isMixin,
277 isExtendRule: isExtendRule,
278 isEndOfBlock: true
279 });
280
281 if (_foundEndOfRule) {
282 return;
283 }
284 }
285
286 this.unknownWord(start);
287 }
288
289 /* eslint-enable max-statements */
290
291 }, {
292 key: 'loop',
293 value: function loop() {
294 while (this.pos < this.tokens.length) {
295 var token = this.tokens[this.pos];
296
297 switch (token[0]) {
298 case 'word':
299 case ':':
300 this.word();
301 break;
302
303 case '}':
304 this.end(token);
305 break;
306
307 case 'comment':
308 this.comment(token);
309 break;
310
311 case 'at-word':
312 this.atrule(token);
313 break;
314
315 case '{':
316 this.emptyRule(token);
317 break;
318
319 case ';':
320 {
321 var lastNode = this.current && this.current.last;
322
323 // mark semicolon, but don't save it
324 if (lastNode && lastNode.ruleWithoutBody) {
325 lastNode.raws.semicolon = true;
326 } else {
327 this.spaces += token[1];
328 }
329
330 break;
331 }
332 default:
333 this.spaces += token[1];
334 break;
335 }
336
337 this.pos += 1;
338 }
339
340 this.endFile();
341 }
342
343 /* eslint-enable complexity */
344
345 }]);
346
347 return LessParser;
348}(_parser2.default);
349
350exports.default = LessParser;
351module.exports = exports['default'];
\No newline at end of file