UNPKG

9.42 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 _findExtendRule = require('./find-extend-rule');
18
19var _findExtendRule2 = _interopRequireDefault(_findExtendRule);
20
21var _isMixinToken = require('./is-mixin-token');
22
23var _isMixinToken2 = _interopRequireDefault(_isMixinToken);
24
25var _lessTokenize = require('./less-tokenize');
26
27var _lessTokenize2 = _interopRequireDefault(_lessTokenize);
28
29function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30
31function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32
33function _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; }
34
35function _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; }
36
37var blockCommentEndPattern = /\*\/$/;
38
39var LessParser = function (_Parser) {
40 _inherits(LessParser, _Parser);
41
42 function LessParser() {
43 _classCallCheck(this, LessParser);
44
45 return _possibleConstructorReturn(this, Object.getPrototypeOf(LessParser).apply(this, arguments));
46 }
47
48 _createClass(LessParser, [{
49 key: 'tokenize',
50 value: function tokenize() {
51 this.tokens = (0, _lessTokenize2.default)(this.input);
52 }
53 }, {
54 key: 'comment',
55 value: function comment(token) {
56 var node = new _comment2.default();
57 var content = token[1];
58 var text = content.slice(2).replace(blockCommentEndPattern, '');
59
60 this.init(node, token[2], token[3]);
61 node.source.end = {
62 line: token[4],
63 column: token[5]
64 };
65
66 node.raws.content = content;
67 node.raws.begin = content[0] + content[1];
68 node.inline = token[6] === 'inline';
69 node.block = !node.inline;
70
71 if (/^\s*$/.test(text)) {
72 node.text = '';
73 node.raws.left = text;
74 node.raws.right = '';
75 } else {
76 var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/);
77
78 node.text = match[2];
79
80 // Add extra spaces to generate a comment in a common style /*[space][text][space]*/
81 node.raws.left = match[1] || ' ';
82 node.raws.right = match[3] || ' ';
83 }
84 }
85
86 /**
87 * @description Create a Rule node
88 * @param options {{start: number, params: Array}}
89 */
90
91 }, {
92 key: 'createRule',
93 value: function createRule(options) {
94 this.rule(this.tokens.slice(options.start, this.pos + 1));
95
96 /**
97 * By default in PostCSS `Rule.params` is `undefined`. There are rules to save the compability with PostCSS:
98 * - Don't set empty params for Rule node.
99 * - Set params fro Rule node only if it can be a mixin or &:extend rule.
100 */
101 if (options.params[0] && (options.isMixin || options.isExtendRule)) {
102 this.raw(this.current, 'params', options.params);
103 }
104 }
105
106 /**
107 * @description Create a Declaration
108 * @param options {{start: number}}
109 */
110
111 }, {
112 key: 'createDeclaration',
113 value: function createDeclaration(options) {
114 this.decl(this.tokens.slice(options.start, this.pos + 1));
115 }
116
117 /**
118 * @description Create a Rule block and close it, because this mixin doesn't have a body
119 * @param options
120 */
121
122 }, {
123 key: 'ruleWithoutBody',
124 value: function ruleWithoutBody(options) {
125 this.createRule(options);
126
127 /**
128 * @description Mark mixin without body.
129 * @type {boolean}
130 */
131 this.current.ruleWithoutBody = true;
132 this.current.extendRule = this.current.selector.indexOf('&:extend') >= 0;
133 this.current.important = this.current.selector.indexOf('!important') >= 0;
134 this.end(this.tokens[this.pos]);
135 }
136
137 /**
138 * @description
139 * @param options
140 * @returns {boolean}
141 */
142
143 }, {
144 key: 'processEndOfRule',
145 value: function processEndOfRule(options) {
146 var start = options.start;
147
148
149 if (options.isExtendRule || options.isMixin) {
150 this.ruleWithoutBody(options);
151 return true;
152 }
153
154 if (options.colon) {
155 if (options.isEndOfBlock) {
156 while (this.pos > start) {
157 var token = this.tokens[this.pos][0];
158
159 if (token !== 'space' && token !== 'comment') {
160 break;
161 }
162
163 this.pos -= 1;
164 }
165 }
166
167 this.createDeclaration({ start: start });
168 return true;
169 }
170
171 return false;
172 }
173
174 /* eslint-disable max-statements, complexity */
175
176 }, {
177 key: 'word',
178 value: function word() {
179 var end = false;
180 var colon = false;
181 var bracket = null;
182 var brackets = 0;
183 var start = this.pos;
184 var isMixin = (0, _isMixinToken2.default)(this.tokens[start]);
185 var isExtendRule = Boolean((0, _findExtendRule2.default)(this.tokens, start));
186 var params = [];
187
188 this.pos += 1;
189
190 while (this.pos < this.tokens.length) {
191 var token = this.tokens[this.pos];
192 var type = token[0];
193
194 if (type === '(') {
195 if (!bracket) {
196 bracket = token;
197 }
198
199 brackets += 1;
200 } else if (brackets === 0) {
201 if (type === ';') {
202
203 var foundEndOfRule = this.processEndOfRule({
204 start: start,
205 params: params,
206 colon: colon,
207 isMixin: isMixin,
208 isExtendRule: isExtendRule
209 });
210
211 if (foundEndOfRule) {
212 return;
213 }
214
215 break;
216 } else if (type === '{') {
217 this.createRule({ start: start, params: params, isMixin: isMixin });
218 return;
219 } else if (type === '}') {
220 this.pos -= 1;
221 end = true;
222 break;
223 } else if (type === ':') {
224 colon = true;
225 }
226 } else if (type === ')') {
227 brackets -= 1;
228 if (brackets === 0) {
229 bracket = null;
230 }
231 }
232
233 if (brackets || type === 'brackets' || params[0]) {
234 params.push(token);
235 }
236
237 this.pos += 1;
238 }
239
240 if (this.pos === this.tokens.length) {
241 this.pos -= 1;
242 end = true;
243 }
244
245 if (brackets > 0) {
246 this.unclosedBracket(bracket);
247 }
248
249 if (end) {
250 var _foundEndOfRule = this.processEndOfRule({
251 start: start,
252 params: params,
253 colon: colon,
254 isMixin: isMixin,
255 isExtendRule: isExtendRule,
256 isEndOfBlock: true
257 });
258
259 if (_foundEndOfRule) {
260 return;
261 }
262 }
263
264 this.unknownWord(start);
265 }
266
267 /* eslint-enable max-statements, complexity */
268
269 }]);
270
271 return LessParser;
272}(_parser2.default);
273
274exports.default = LessParser;
275module.exports = exports['default'];
\No newline at end of file