1 (function webpackUniversalModuleDefinition(root, factory) {
2 if(typeof exports === 'object' && typeof module === 'object')
3 module.exports = factory();
4 else if(typeof define === 'function' && define.amd)
6 else if(typeof exports === 'object')
7 exports["gonzales"] = factory();
9 root["gonzales"] = factory();
11 return /******/ (function(modules) { // webpackBootstrap
12 /******/ // The module cache
13 /******/ var installedModules = {};
15 /******/ // The require function
16 /******/ function __webpack_require__(moduleId) {
18 /******/ // Check if module is in cache
19 /******/ if(installedModules[moduleId])
20 /******/ return installedModules[moduleId].exports;
22 /******/ // Create a new module (and put it into the cache)
23 /******/ var module = installedModules[moduleId] = {
25 /******/ id: moduleId,
26 /******/ loaded: false
29 /******/ // Execute the module function
30 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
32 /******/ // Flag the module as loaded
33 /******/ module.loaded = true;
35 /******/ // Return the exports of the module
36 /******/ return module.exports;
40 /******/ // expose the modules object (__webpack_modules__)
41 /******/ __webpack_require__.m = modules;
43 /******/ // expose the module cache
44 /******/ __webpack_require__.c = installedModules;
46 /******/ // __webpack_public_path__
47 /******/ __webpack_require__.p = "";
49 /******/ // Load entry module and return exports
50 /******/ return __webpack_require__(0);
52 /************************************************************************/
55 /***/ (function(module, exports, __webpack_require__) {
59 var Node = __webpack_require__(1);
60 var parse = __webpack_require__(7);
63 createNode: function createNode(options) {
64 return new Node(options);
71 /***/ (function(module, exports, __webpack_require__) {
76 * @param {string} type
77 * @param {array|string} content
78 * @param {number} line
79 * @param {number} column
83 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; }; }();
85 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
87 var Node = function () {
88 function Node(options) {
89 _classCallCheck(this, Node);
91 this.type = options.type;
92 this.content = options.content;
93 this.syntax = options.syntax;
95 if (options.start) this.start = options.start;
96 if (options.end) this.end = options.end;
100 * @param {String} type Node type
101 * @return {Boolean} Whether there is a child node of given type
105 Node.prototype.contains = function contains(type) {
106 if (!Array.isArray(this.content)) {
110 return this.content.some(function (node) {
111 return node.type === type;
116 * @param {String} type Node type
117 * @param {Function} callback Function to call for every found node
121 Node.prototype.eachFor = function eachFor(type, callback) {
122 if (!Array.isArray(this.content)) return;
124 if (typeof type !== 'string') {
129 var l = this.content.length;
132 for (var i = l; i--;) {
133 if (breakLoop === null) break;
135 if (!type || this.content[i] && this.content[i].type === type) breakLoop = callback(this.content[i], i, this);
138 if (breakLoop === null) return null;
142 * @param {String} type
143 * @return {?Node} First child node or `null` if nothing's been found.
147 Node.prototype.first = function first(type) {
148 if (!Array.isArray(this.content)) return null;
150 if (!type) return this.content[0];
153 var l = this.content.length;
156 if (this.content[i].type === type) return this.content[i];
163 * @param {String} type Node type
164 * @param {Function} callback Function to call for every found node
168 Node.prototype.forEach = function forEach(type, callback) {
169 if (!Array.isArray(this.content)) return;
171 if (typeof type !== 'string') {
177 var l = this.content.length;
181 if (breakLoop === null) break;
183 if (!type || this.content[i] && this.content[i].type === type) breakLoop = callback(this.content[i], i, this);
186 if (breakLoop === null) return null;
190 * @param {Number} index
195 Node.prototype.get = function get(index) {
196 if (!Array.isArray(this.content)) return null;
198 var node = this.content[index];
199 return node ? node : null;
203 * @param {Number} index
208 Node.prototype.insert = function insert(index, node) {
209 if (!Array.isArray(this.content)) return;
211 this.content.splice(index, 0, node);
215 * @param {String} type
216 * @return {Boolean} Whether the node is of given type
220 Node.prototype.is = function is(type) {
221 return this.type === type;
225 * @param {String} type
226 * @return {?Node} Last child node or `null` if nothing's been found.
230 Node.prototype.last = function last(type) {
231 if (!Array.isArray(this.content)) return null;
233 var i = this.content.length;
234 if (!type) return this.content[i - 1];
237 if (this.content[i].type === type) return this.content[i];
244 * Number of child nodes.
250 * @param {Number} index
253 Node.prototype.removeChild = function removeChild(index) {
254 if (!Array.isArray(this.content)) return;
256 var removedChild = this.content.splice(index, 1);
261 Node.prototype.toJson = function toJson() {
262 return JSON.stringify(this, false, 2);
265 Node.prototype.toString = function toString() {
266 var stringify = void 0;
269 stringify = __webpack_require__(2)("./" + this.syntax + '/stringify');
271 var message = 'Syntax "' + this.syntax + '" is not supported yet, sorry';
272 return console.error(message);
275 return stringify(this);
279 * @param {Function} callback
283 Node.prototype.traverse = function traverse(callback, index) {
284 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
285 var parent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
292 callback(this, index, parent, level);
294 if (!Array.isArray(this.content)) return;
296 for (var i = 0, l = this.content.length; i < l; i++) {
297 breakLoop = this.content[i].traverse(callback, i, level, this);
298 if (breakLoop === null) break;
300 // If some nodes were removed or added:
301 if (x = this.content.length - l) {
307 if (breakLoop === null) return null;
310 Node.prototype.traverseByType = function traverseByType(type, callback) {
311 this.traverse(function (node) {
312 if (node.type === type) callback.apply(node, arguments);
316 Node.prototype.traverseByTypes = function traverseByTypes(types, callback) {
317 this.traverse(function (node) {
318 if (types.indexOf(node.type) !== -1) callback.apply(node, arguments);
322 _createClass(Node, [{
324 get: function get() {
325 if (!Array.isArray(this.content)) return 0;
326 return this.content.length;
333 module.exports = Node;
337 /***/ (function(module, exports, __webpack_require__) {
340 "./css/stringify": 3,
341 "./less/stringify": 4,
342 "./sass/stringify": 5,
343 "./scss/stringify": 6
345 function webpackContext(req) {
346 return __webpack_require__(webpackContextResolve(req));
348 function webpackContextResolve(req) {
349 return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
351 webpackContext.keys = function webpackContextKeys() {
352 return Object.keys(map);
354 webpackContext.resolve = webpackContextResolve;
355 module.exports = webpackContext;
356 webpackContext.id = 2;
361 /***/ (function(module, exports) {
365 module.exports = function stringify(tree) {
366 // TODO: Better error message
367 if (!tree) throw new Error('We need tree to translate');
370 var type = tree.type;
371 if (_unique[type]) return _unique[type](tree);
372 if (typeof tree.content === 'string') return tree.content;
373 if (Array.isArray(tree.content)) return _composite(tree.content);
377 function _composite(t, i) {
382 for (; i < t.length; i++) {
388 'arguments': function _arguments(t) {
389 return '(' + _composite(t.content) + ')';
391 'atkeyword': function atkeyword(t) {
392 return '@' + _composite(t.content);
394 'attributeSelector': function attributeSelector(t) {
395 return '[' + _composite(t.content) + ']';
397 'block': function block(t) {
398 return '{' + _composite(t.content) + '}';
400 'brackets': function brackets(t) {
401 return '[' + _composite(t.content) + ']';
403 'class': function _class(t) {
404 return '.' + _composite(t.content);
406 'color': function color(t) {
407 return '#' + t.content;
409 'customProperty': function customProperty(t) {
410 return '--' + t.content;
412 'expression': function expression(t) {
413 return 'expression(' + t.content + ')';
415 'id': function id(t) {
416 return '#' + _composite(t.content);
418 'multilineComment': function multilineComment(t) {
419 return '/*' + t.content + '*/';
421 'nthSelector': function nthSelector(t) {
422 return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
424 'parentheses': function parentheses(t) {
425 return '(' + _composite(t.content) + ')';
427 'percentage': function percentage(t) {
428 return _composite(t.content) + '%';
430 'pseudoClass': function pseudoClass(t) {
431 return ':' + _composite(t.content);
433 'pseudoElement': function pseudoElement(t) {
434 return '::' + _composite(t.content);
436 'universalSelector': function universalSelector(t) {
437 return _composite(t.content) + '*';
439 'uri': function uri(t) {
440 return 'url(' + _composite(t.content) + ')';
449 /***/ (function(module, exports) {
453 module.exports = function stringify(tree) {
454 // TODO: Better error message
455 if (!tree) throw new Error('We need tree to translate');
458 var type = tree.type;
459 if (_unique[type]) return _unique[type](tree);
460 if (typeof tree.content === 'string') return tree.content;
461 if (Array.isArray(tree.content)) return _composite(tree.content);
465 function _composite(t, i) {
470 for (; i < t.length; i++) {
476 'arguments': function _arguments(t) {
477 return '(' + _composite(t.content) + ')';
479 'atkeyword': function atkeyword(t) {
480 return '@' + _composite(t.content);
482 'attributeSelector': function attributeSelector(t) {
483 return '[' + _composite(t.content) + ']';
485 'block': function block(t) {
486 return '{' + _composite(t.content) + '}';
488 'brackets': function brackets(t) {
489 return '[' + _composite(t.content) + ']';
491 'class': function _class(t) {
492 return '.' + _composite(t.content);
494 'color': function color(t) {
495 return '#' + t.content;
497 'escapedString': function escapedString(t) {
498 return '~' + t.content;
500 'expression': function expression(t) {
501 return 'expression(' + t.content + ')';
503 'id': function id(t) {
504 return '#' + _composite(t.content);
506 'interpolatedVariable': function interpolatedVariable(t) {
507 return '@{' + _composite(t.content) + '}';
509 'multilineComment': function multilineComment(t) {
510 return '/*' + t.content + '*/';
512 'nthSelector': function nthSelector(t) {
513 return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
515 'parentheses': function parentheses(t) {
516 return '(' + _composite(t.content) + ')';
518 'percentage': function percentage(t) {
519 return _composite(t.content) + '%';
521 'pseudoClass': function pseudoClass(t) {
522 return ':' + _composite(t.content);
524 'pseudoElement': function pseudoElement(t) {
525 return '::' + _composite(t.content);
527 'singlelineComment': function singlelineComment(t) {
528 return '/' + '/' + t.content;
530 'universalSelector': function universalSelector(t) {
531 return _composite(t.content) + '*';
533 'uri': function uri(t) {
534 return 'url(' + _composite(t.content) + ')';
536 'variable': function variable(t) {
537 return '@' + _composite(t.content);
539 'variablesList': function variablesList(t) {
540 return _composite(t.content) + '...';
549 /***/ (function(module, exports) {
553 module.exports = function stringify(tree) {
554 // TODO: Better error message
555 if (!tree) throw new Error('We need tree to translate');
558 var type = tree.type;
559 if (_unique[type]) return _unique[type](tree);
560 if (typeof tree.content === 'string') return tree.content;
561 if (Array.isArray(tree.content)) return _composite(tree.content);
565 function _composite(t, i) {
570 for (; i < t.length; i++) {
576 'arguments': function _arguments(t) {
577 return '(' + _composite(t.content) + ')';
579 'atkeyword': function atkeyword(t) {
580 return '@' + _composite(t.content);
582 'attributeSelector': function attributeSelector(t) {
583 return '[' + _composite(t.content) + ']';
585 'block': function block(t) {
586 return _composite(t.content);
588 'brackets': function brackets(t) {
589 return '[' + _composite(t.content) + ']';
591 'class': function _class(t) {
592 return '.' + _composite(t.content);
594 'color': function color(t) {
595 return '#' + t.content;
597 'customProperty': function customProperty(t) {
598 return '--' + t.content;
600 'expression': function expression(t) {
601 return 'expression(' + t.content + ')';
603 'functionsList': function functionsList(t) {
604 return _composite(t.content) + '...';
606 'id': function id(t) {
607 return '#' + _composite(t.content);
609 'interpolation': function interpolation(t) {
610 return '#{' + _composite(t.content) + '}';
612 'multilineComment': function multilineComment(t) {
613 var lines = t.content.split('\n');
616 if (lines.length > 1) {
617 var lastLine = lines[lines.length - 1];
618 if (lastLine.length < t.end.column) {
621 } else if (t.content.length + 4 === t.end.column - t.start.column + 1) {
625 return '/*' + t.content + close;
627 'nthSelector': function nthSelector(t) {
628 return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
630 'parentheses': function parentheses(t) {
631 return '(' + _composite(t.content) + ')';
633 'percentage': function percentage(t) {
634 return _composite(t.content) + '%';
636 'placeholder': function placeholder(t) {
637 return '%' + _composite(t.content);
639 'pseudoClass': function pseudoClass(t) {
640 return ':' + _composite(t.content);
642 'pseudoElement': function pseudoElement(t) {
643 return '::' + _composite(t.content);
645 'singlelineComment': function singlelineComment(t) {
646 return '/' + '/' + t.content;
648 'universalSelector': function universalSelector(t) {
649 return _composite(t.content) + '*';
651 'uri': function uri(t) {
652 return 'url(' + _composite(t.content) + ')';
654 'variable': function variable(t) {
655 return '$' + _composite(t.content);
657 'variablesList': function variablesList(t) {
658 return _composite(t.content) + '...';
667 /***/ (function(module, exports) {
671 module.exports = function stringify(tree) {
672 // TODO: Better error message
673 if (!tree) throw new Error('We need tree to translate');
676 var type = tree.type;
677 if (_unique[type]) return _unique[type](tree);
678 if (typeof tree.content === 'string') return tree.content;
679 if (Array.isArray(tree.content)) return _composite(tree.content);
683 function _composite(t, i) {
688 for (; i < t.length; i++) {
694 'arguments': function _arguments(t) {
695 return '(' + _composite(t.content) + ')';
697 'atkeyword': function atkeyword(t) {
698 return '@' + _composite(t.content);
700 'attributeSelector': function attributeSelector(t) {
701 return '[' + _composite(t.content) + ']';
703 'block': function block(t) {
704 return '{' + _composite(t.content) + '}';
706 'brackets': function brackets(t) {
707 return '[' + _composite(t.content) + ']';
709 'class': function _class(t) {
710 return '.' + _composite(t.content);
712 'color': function color(t) {
713 return '#' + t.content;
715 'customProperty': function customProperty(t) {
716 return '--' + t.content;
718 'expression': function expression(t) {
719 return 'expression(' + t.content + ')';
721 'functionsList': function functionsList(t) {
722 return _composite(t.content) + '...';
724 'id': function id(t) {
725 return '#' + _composite(t.content);
727 'interpolation': function interpolation(t) {
728 return '#{' + _composite(t.content) + '}';
730 'multilineComment': function multilineComment(t) {
731 return '/*' + t.content + '*/';
733 'nthSelector': function nthSelector(t) {
734 return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
736 'parentheses': function parentheses(t) {
737 return '(' + _composite(t.content) + ')';
739 'percentage': function percentage(t) {
740 return _composite(t.content) + '%';
742 'placeholder': function placeholder(t) {
743 return '%' + _composite(t.content);
745 'pseudoClass': function pseudoClass(t) {
746 return ':' + _composite(t.content);
748 'pseudoElement': function pseudoElement(t) {
749 return '::' + _composite(t.content);
751 'singlelineComment': function singlelineComment(t) {
752 return '/' + '/' + t.content;
754 'universalSelector': function universalSelector(t) {
755 return _composite(t.content) + '*';
757 'uri': function uri(t) {
758 return 'url(' + _composite(t.content) + ')';
760 'variable': function variable(t) {
761 return '$' + _composite(t.content);
763 'variablesList': function variablesList(t) {
764 return _composite(t.content) + '...';
773 /***/ (function(module, exports, __webpack_require__) {
777 var ParsingError = __webpack_require__(8);
778 var syntaxes = __webpack_require__(10);
780 var isInteger = Number.isInteger || function (value) {
781 return typeof value === 'number' && Math.floor(value) === value;
785 * @param {String} css
786 * @param {Object} options
787 * @return {Object} AST
789 function parser(css, options) {
790 if (typeof css !== 'string') throw new Error('Please, pass a string to parse');else if (!css) return __webpack_require__(29)();
792 var syntax = options && options.syntax || 'css';
793 var context = options && options.context || 'stylesheet';
794 var tabSize = options && options.tabSize;
795 if (!isInteger(tabSize) || tabSize < 1) tabSize = 1;
797 var syntaxParser = syntaxes[syntax];
800 var message = 'Syntax "' + syntax + '" is not supported yet, sorry';
801 return console.error(message);
804 var getTokens = syntaxParser.tokenizer;
805 var mark = syntaxParser.mark;
806 var parse = syntaxParser.parse;
808 var tokens = getTokens(css, tabSize);
813 ast = parse(tokens, context);
815 if (!e.syntax) throw e;
816 throw new ParsingError(e, css);
822 module.exports = parser;
826 /***/ (function(module, exports, __webpack_require__) {
830 var parserPackage = __webpack_require__(9);
834 * @param {String} css
836 function ParsingError(e, css) {
838 this.syntax = e.syntax;
842 ParsingError.prototype = {
857 name: 'Parsing error',
867 version: parserPackage.version,
873 var LINES_AROUND = 2;
876 var currentLineNumber = this.line;
877 var start = currentLineNumber - 1 - LINES_AROUND;
878 var end = currentLineNumber + LINES_AROUND;
879 var lines = this.css_.split(/\r\n|\r|\n/);
881 for (var i = start; i < end; i++) {
885 var mark = ln === currentLineNumber ? '*' : ' ';
886 result.push(ln + mark + '| ' + line);
889 return result.join('\n');
896 if (this.customMessage_) {
897 return this.customMessage_;
899 var message = 'Please check validity of the block';
900 if (typeof this.line === 'number') message += ' starting from line #' + this.line;
905 set message(message) {
906 this.customMessage_ = message;
912 toString: function toString() {
913 return [this.name + ': ' + this.message, '', this.context, '', 'Syntax: ' + this.syntax, 'Gonzales PE version: ' + this.version].join('\n');
917 module.exports = ParsingError;
921 /***/ (function(module, exports) {
923 module.exports = {"name":"gonzales-pe","description":"Gonzales Preprocessor Edition (fast CSS parser)","version":"4.3.0","homepage":"http://github.com/tonyganch/gonzales-pe","bugs":"http://github.com/tonyganch/gonzales-pe/issues","license":"MIT","author":{"name":"Tony Ganch","email":"tonyganch+github@gmail.com","url":"http://tonyganch.com"},"main":"./lib/gonzales","repository":{"type":"git","url":"http://github.com/tonyganch/gonzales-pe.git"},"scripts":{"autofix-tests":"bash ./scripts/build.sh && bash ./scripts/autofix-tests.sh","build":"bash ./scripts/build.sh","init":"bash ./scripts/init.sh","lint":"bash ./scripts/lint.sh","log":"bash ./scripts/log.sh","prepublishOnly":"bash ./scripts/build.sh","test":"bash ./scripts/test.sh","watch":"bash ./scripts/watch.sh"},"bin":{"gonzales":"./bin/gonzales.js"},"dependencies":{"minimist":"^1.2.5"},"devDependencies":{"babel-core":"^6.18.2","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","coffee-script":"~1.7.1","eslint":"^3.0.0","jscs":"2.1.0","jshint":"2.10.2","json-loader":"^0.5.3","mocha":"2.2.x","webpack":"^1.12.2","webpack-closure-compiler":"^2.0.2"},"engines":{"node":">=0.6.0"},"files":["MIT-LICENSE.txt","bin/gonzales.js","lib/gonzales.js"]}
927 /***/ (function(module, exports, __webpack_require__) {
932 css: __webpack_require__(11),
933 less: __webpack_require__(17),
934 sass: __webpack_require__(21),
935 scss: __webpack_require__(25)
940 /***/ (function(module, exports, __webpack_require__) {
944 exports.__esModule = true;
946 mark: __webpack_require__(12),
947 parse: __webpack_require__(14),
948 stringify: __webpack_require__(3),
949 tokenizer: __webpack_require__(16)
951 module.exports = exports['default'];
955 /***/ (function(module, exports, __webpack_require__) {
959 var TokenType = __webpack_require__(13);
962 * Mark whitespaces and comments
963 * @param {Array} tokens
965 function markSpacesAndComments(tokens) {
966 var tokensLength = tokens.length;
967 var spaces = [-1, -1];
968 var type; // Current token's type
970 // For every token in the token list, mark spaces and line breaks
971 // as spaces (set both `ws` and `sc` flags). Mark multiline comments
973 // If there are several spaces or tabs or line breaks or multiline
974 // comments in a row, group them: take the last one's index number
975 // and save it to the first token in the group as a reference:
976 // e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
977 // for a group of whitespaces and comments.
978 for (var i = 0; i < tokensLength; i++) {
979 type = tokens[i].type;
981 if (type === TokenType.Space || type === TokenType.Tab || type === TokenType.Newline) {
982 markSpace(tokens, i, spaces);
983 } else if (type === TokenType.CommentML) {
984 markComment(tokens, i, spaces);
986 markEndOfSpacesAndComments(tokens, i, spaces);
990 markEndOfSpacesAndComments(tokens, i, spaces);
993 function markSpace(tokens, i, spaces) {
994 var token = tokens[i];
998 if (spaces[0] === -1) spaces[0] = i;
999 if (spaces[1] === -1) spaces[1] = i;
1002 function markComment(tokens, i, spaces) {
1004 tokens[i].sc = true;
1007 tokens[ws].ws_last = i - 1;
1012 function markEndOfSpacesAndComments(tokens, i, spaces) {
1016 tokens[ws].ws_last = i - 1;
1020 tokens[sc].sc_last = i - 1;
1027 * @param {Array} tokens
1029 function markBrackets(tokens) {
1030 var tokensLength = tokens.length;
1031 var ps = []; // Parentheses
1032 var sbs = []; // Square brackets
1033 var cbs = []; // Curly brackets
1034 var t = void 0; // Current token
1036 // For every token in the token list, if we meet an opening (left)
1037 // bracket, push its index number to a corresponding array.
1038 // If we then meet a closing (right) bracket, look at the corresponding
1039 // array. If there are any elements (records about previously met
1040 // left brackets), take a token of the last left bracket (take
1041 // the last index number from the array and find a token with
1042 // this index number) and save right bracket's index as a reference:
1043 for (var i = 0; i < tokensLength; i++) {
1047 if (type === TokenType.LeftParenthesis) {
1049 } else if (type === TokenType.RightParenthesis) {
1052 tokens[t.left].right = i;
1054 } else if (type === TokenType.LeftSquareBracket) {
1056 } else if (type === TokenType.RightSquareBracket) {
1059 tokens[t.left].right = i;
1061 } else if (type === TokenType.LeftCurlyBracket) {
1063 } else if (type === TokenType.RightCurlyBracket) {
1066 tokens[t.left].right = i;
1073 * @param {Array} tokens
1075 function markTokens(tokens) {
1076 // Mark paired brackets:
1077 markBrackets(tokens);
1078 // Mark whitespaces and comments:
1079 markSpacesAndComments(tokens);
1082 module.exports = markTokens;
1086 /***/ (function(module, exports) {
1093 StringSQ: 'StringSQ',
1094 StringDQ: 'StringDQ',
1095 CommentML: 'CommentML',
1096 CommentSL: 'CommentSL',
1102 ExclamationMark: 'ExclamationMark', // !
1103 QuotationMark: 'QuotationMark', // "
1104 NumberSign: 'NumberSign', // #
1105 DollarSign: 'DollarSign', // $
1106 PercentSign: 'PercentSign', // %
1107 Ampersand: 'Ampersand', // &
1108 Apostrophe: 'Apostrophe', // '
1109 LeftParenthesis: 'LeftParenthesis', // (
1110 RightParenthesis: 'RightParenthesis', // )
1111 Asterisk: 'Asterisk', // *
1112 PlusSign: 'PlusSign', // +
1113 Comma: 'Comma', // ,
1114 HyphenMinus: 'HyphenMinus', // -
1115 FullStop: 'FullStop', // .
1116 Solidus: 'Solidus', // /
1117 Colon: 'Colon', // :
1118 Semicolon: 'Semicolon', // ;
1119 LessThanSign: 'LessThanSign', // <
1120 EqualsSign: 'EqualsSign', // =
1121 EqualitySign: 'EqualitySign', // ==
1122 InequalitySign: 'InequalitySign', // !=
1123 GreaterThanSign: 'GreaterThanSign', // >
1124 QuestionMark: 'QuestionMark', // ?
1125 CommercialAt: 'CommercialAt', // @
1126 LeftSquareBracket: 'LeftSquareBracket', // [
1127 ReverseSolidus: 'ReverseSolidus', // \
1128 RightSquareBracket: 'RightSquareBracket', // ]
1129 CircumflexAccent: 'CircumflexAccent', // ^
1130 LowLine: 'LowLine', // _
1131 LeftCurlyBracket: 'LeftCurlyBracket', // {
1132 VerticalLine: 'VerticalLine', // |
1133 RightCurlyBracket: 'RightCurlyBracket', // }
1134 Tilde: 'Tilde', // ~
1136 Identifier: 'Identifier',
1137 DecimalNumber: 'DecimalNumber'
1142 /***/ (function(module, exports, __webpack_require__) {
1146 var Node = __webpack_require__(1);
1147 var NodeType = __webpack_require__(15);
1148 var TokenType = __webpack_require__(13);
1153 var tokens = void 0;
1158 var tokensLength = void 0;
1166 'atkeyword': function atkeyword() {
1167 return checkAtkeyword(pos) && getAtkeyword();
1169 'atrule': function atrule() {
1170 return checkAtrule(pos) && getAtrule();
1172 'attributeSelector': function attributeSelector() {
1173 return checkAttributeSelector(pos) && getAttributeSelector();
1175 'block': function block() {
1176 return checkBlock(pos) && getBlock();
1178 'brackets': function brackets() {
1179 return checkBrackets(pos) && getBrackets();
1181 'class': function _class() {
1182 return checkClass(pos) && getClass();
1184 'combinator': function combinator() {
1185 return checkCombinator(pos) && getCombinator();
1187 'commentML': function commentML() {
1188 return checkCommentML(pos) && getCommentML();
1190 'declaration': function declaration() {
1191 return checkDeclaration(pos) && getDeclaration();
1193 'declDelim': function declDelim() {
1194 return checkDeclDelim(pos) && getDeclDelim();
1196 'delim': function delim() {
1197 return checkDelim(pos) && getDelim();
1199 'dimension': function dimension() {
1200 return checkDimension(pos) && getDimension();
1202 'expression': function expression() {
1203 return checkExpression(pos) && getExpression();
1205 'function': function _function() {
1206 return checkFunction(pos) && getFunction();
1208 'ident': function ident() {
1209 return checkIdent(pos) && getIdent();
1211 'important': function important() {
1212 return checkImportant(pos) && getImportant();
1214 'namespace': function namespace() {
1215 return checkNamespace(pos) && getNamespace();
1217 'number': function number() {
1218 return checkNumber(pos) && getNumber();
1220 'operator': function operator() {
1221 return checkOperator(pos) && getOperator();
1223 'parentheses': function parentheses() {
1224 return checkParentheses(pos) && getParentheses();
1226 'percentage': function percentage() {
1227 return checkPercentage(pos) && getPercentage();
1229 'progid': function progid() {
1230 return checkProgid(pos) && getProgid();
1232 'property': function property() {
1233 return checkProperty(pos) && getProperty();
1235 'propertyDelim': function propertyDelim() {
1236 return checkPropertyDelim(pos) && getPropertyDelim();
1238 'pseudoc': function pseudoc() {
1239 return checkPseudoc(pos) && getPseudoc();
1241 'pseudoe': function pseudoe() {
1242 return checkPseudoe(pos) && getPseudoe();
1244 'ruleset': function ruleset() {
1245 return checkRuleset(pos) && getRuleset();
1248 return checkS(pos) && getS();
1250 'selector': function selector() {
1251 return checkSelector(pos) && getSelector();
1253 'shash': function shash() {
1254 return checkShash(pos) && getShash();
1256 'string': function string() {
1257 return checkString(pos) && getString();
1259 'stylesheet': function stylesheet() {
1260 return checkStylesheet(pos) && getStylesheet();
1262 'unary': function unary() {
1263 return checkUnary(pos) && getUnary();
1265 'unicodeRange': function unicodeRange() {
1266 return checkUnicodeRange(pos) && getUnicodeRange();
1268 'universalSelector': function universalSelector() {
1269 return checkUniversalSelector(pos) && getUniversalSelector();
1271 'urange': function urange() {
1272 return checkUrange(pos) && getUrange();
1274 'uri': function uri() {
1275 return checkUri(pos) && getUri();
1277 'value': function value() {
1278 return checkValue(pos) && getValue();
1280 'vhash': function vhash() {
1281 return checkVhash(pos) && getVhash();
1286 * Stop parsing and display error
1287 * @param {Number=} i Token's index number
1289 function throwError(i) {
1290 var ln = tokens[i].ln;
1292 throw { line: ln, syntax: 'css' };
1296 * @param {Object} exclude
1297 * @param {Number} i Token's index number
1300 function checkExcluding(exclude, i) {
1303 while (i < tokensLength) {
1304 if (exclude[tokens[i++].type]) break;
1307 return i - start - 2;
1311 * @param {Number} start
1312 * @param {Number} finish
1315 function joinValues(start, finish) {
1318 for (var i = start; i < finish + 1; i++) {
1319 s += tokens[i].value;
1326 * @param {Number} start
1327 * @param {Number} num
1330 function joinValues2(start, num) {
1331 if (start + num - 1 >= tokensLength) return;
1335 for (var i = 0; i < num; i++) {
1336 s += tokens[start + i].value;
1342 function getLastPosition(content, line, column, colOffset) {
1343 return typeof content === 'string' ? getLastPositionForString(content, line, column, colOffset) : getLastPositionForArray(content, line, column, colOffset);
1346 function getLastPositionForString(content, line, column, colOffset) {
1350 position = [line, column];
1351 if (colOffset) position[1] += colOffset - 1;
1355 var lastLinebreak = content.lastIndexOf('\n');
1356 var endsWithLinebreak = lastLinebreak === content.length - 1;
1357 var splitContent = content.split('\n');
1358 var linebreaksCount = splitContent.length - 1;
1359 var prevLinebreak = linebreaksCount === 0 || linebreaksCount === 1 ? -1 : content.length - splitContent[linebreaksCount - 1].length - 2;
1362 var offset = endsWithLinebreak ? linebreaksCount - 1 : linebreaksCount;
1363 position[0] = line + offset;
1366 if (endsWithLinebreak) {
1367 offset = prevLinebreak !== -1 ? content.length - prevLinebreak : content.length - 1;
1369 offset = linebreaksCount !== 0 ? content.length - lastLinebreak - column - 1 : content.length - 1;
1371 position[1] = column + offset;
1373 if (!colOffset) return position;
1375 if (endsWithLinebreak) {
1377 position[1] = colOffset;
1379 position[1] += colOffset;
1385 function getLastPositionForArray(content, line, column, colOffset) {
1386 var position = void 0;
1388 if (content.length === 0) {
1389 position = [line, column];
1391 var c = content[content.length - 1];
1392 if (c.hasOwnProperty('end')) {
1393 position = [c.end.line, c.end.column];
1395 position = getLastPosition(c.content, line, column);
1399 if (!colOffset) return position;
1401 if (tokens[pos - 1] && tokens[pos - 1].type !== 'Newline') {
1402 position[1] += colOffset;
1411 function newNode(type, content, line, column, end) {
1412 if (!end) end = getLastPosition(content, line, column);
1429 * @param {Number} i Token's index number
1432 function checkAny(i) {
1435 if (l = checkBrackets(i)) tokens[i].any_child = 1;else if (l = checkParentheses(i)) tokens[i].any_child = 2;else if (l = checkString(i)) tokens[i].any_child = 3;else if (l = checkPercentage(i)) tokens[i].any_child = 4;else if (l = checkDimension(i)) tokens[i].any_child = 5;else if (l = checkUnicodeRange(i)) tokens[i].any_child = 13;else if (l = checkNumber(i)) tokens[i].any_child = 6;else if (l = checkUri(i)) tokens[i].any_child = 7;else if (l = checkExpression(i)) tokens[i].any_child = 8;else if (l = checkFunction(i)) tokens[i].any_child = 9;else if (l = checkIdent(i)) tokens[i].any_child = 10;else if (l = checkClass(i)) tokens[i].any_child = 11;else if (l = checkUnary(i)) tokens[i].any_child = 12;
1444 var childType = tokens[pos].any_child;
1446 if (childType === 1) return getBrackets();
1447 if (childType === 2) return getParentheses();
1448 if (childType === 3) return getString();
1449 if (childType === 4) return getPercentage();
1450 if (childType === 5) return getDimension();
1451 if (childType === 13) return getUnicodeRange();
1452 if (childType === 6) return getNumber();
1453 if (childType === 7) return getUri();
1454 if (childType === 8) return getExpression();
1455 if (childType === 9) return getFunction();
1456 if (childType === 10) return getIdent();
1457 if (childType === 11) return getClass();
1458 if (childType === 12) return getUnary();
1464 function getArguments() {
1465 var type = NodeType.ArgumentsType;
1466 var token = tokens[pos];
1467 var line = token.ln;
1468 var column = token.col;
1475 while (pos < tokensLength && tokens[pos].type !== TokenType.RightParenthesis) {
1476 if (checkDeclaration(pos)) content.push(getDeclaration());else if (checkArgument(pos)) {
1477 body = getArgument();
1478 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
1479 } else if (checkClass(pos)) content.push(getClass());else throwError(pos);
1482 var end = getLastPosition(content, line, column, 1);
1487 return newNode(type, content, line, column, end);
1491 * @param {Number} i Token's index number
1494 function checkArgument(i) {
1497 if (l = checkVhash(i)) tokens[i].argument_child = 1;else if (l = checkCustomProperty(i)) tokens[i].argument_child = 2;else if (l = checkAny(i)) tokens[i].argument_child = 3;else if (l = checkSC(i)) tokens[i].argument_child = 4;else if (l = checkOperator(i)) tokens[i].argument_child = 5;
1505 function getArgument() {
1506 var childType = tokens[pos].argument_child;
1508 if (childType === 1) return getVhash();
1509 if (childType === 2) return getCustomProperty();
1510 if (childType === 3) return getAny();
1511 if (childType === 4) return getSC();
1512 if (childType === 5) return getOperator();
1516 * Check if token is part of an @-word (e.g. `@import`, `@include`)
1517 * @param {Number} i Token's index number
1520 function checkAtkeyword(i) {
1523 // Check that token is `@`:
1524 if (i >= tokensLength || tokens[i++].type !== TokenType.CommercialAt) return 0;
1526 return (l = checkIdent(i)) ? l + 1 : 0;
1530 * Get node with @-word
1533 function getAtkeyword() {
1534 var type = NodeType.AtkeywordType;
1535 var token = tokens[pos];
1536 var line = token.ln;
1537 var column = token.col;
1542 var content = [getIdent()];
1544 return newNode(type, content, line, column);
1548 * Check if token is a part of an @-rule
1549 * @param {Number} i Token's index number
1550 * @return {Number} Length of @-rule
1552 function checkAtrule(i) {
1555 if (i >= tokensLength) return 0;
1557 // If token already has a record of being part of an @-rule,
1558 // return the @-rule's length:
1559 if (tokens[i].atrule_l !== undefined) return tokens[i].atrule_l;
1561 // If token is part of an @-rule, save the rule's type to token.
1563 if (l = checkKeyframesRule(i)) tokens[i].atrule_type = 4;
1564 // @-rule with ruleset:
1565 else if (l = checkAtruler(i)) tokens[i].atrule_type = 1;
1567 else if (l = checkAtruleb(i)) tokens[i].atrule_type = 2;
1568 // Single-line @-rule:
1569 else if (l = checkAtrules(i)) tokens[i].atrule_type = 3;else return 0;
1571 // If token is part of an @-rule, save the rule's length to token:
1572 tokens[i].atrule_l = l;
1578 * Get node with @-rule
1581 function getAtrule() {
1582 var childType = tokens[pos].atrule_type;
1584 if (childType === 1) return getAtruler(); // @-rule with ruleset
1585 if (childType === 2) return getAtruleb(); // Block @-rule
1586 if (childType === 3) return getAtrules(); // Single-line @-rule
1587 if (childType === 4) return getKeyframesRule();
1591 * Check if token is part of a block @-rule
1592 * @param {Number} i Token's index number
1593 * @return {Number} Length of the @-rule
1595 function checkAtruleb(i) {
1599 if (i >= tokensLength) return 0;
1601 if (l = checkAtkeyword(i)) i += l;else return 0;
1603 if (l = checkTsets(i)) i += l;
1605 if (l = checkBlock(i)) i += l;else return 0;
1611 * Get node with a block @-rule
1614 function getAtruleb() {
1615 var type = NodeType.AtruleType;
1616 var token = tokens[pos];
1617 var line = token.ln;
1618 var column = token.col;
1619 var content = [].concat(getAtkeyword(), getTsets(), getBlock());
1621 return newNode(type, content, line, column);
1625 * Check if token is part of an @-rule with ruleset
1626 * @param {Number} i Token's index number
1627 * @return {Number} Length of the @-rule
1629 function checkAtruler(i) {
1633 if (i >= tokensLength) return 0;
1635 if (l = checkAtkeyword(i)) i += l;else return 0;
1637 if (l = checkTsets(i)) i += l;
1639 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
1641 if (l = checkAtrulers(i)) i += l;
1643 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
1649 * Get node with an @-rule with ruleset
1652 function getAtruler() {
1653 var type = NodeType.AtruleType;
1654 var token = tokens[pos];
1655 var line = token.ln;
1656 var column = token.col;
1657 var content = [].concat(getAtkeyword(), getTsets(), getAtrulers());
1659 return newNode(type, content, line, column);
1663 * @param {Number} i Token's index number
1666 function checkAtrulers(i) {
1670 if (i >= tokensLength) return 0;
1672 if (l = checkSC(i)) i += l;
1674 while (i < tokensLength) {
1675 if (l = checkSC(i)) tokens[i].atrulers_child = 1;else if (l = checkAtrule(i)) tokens[i].atrulers_child = 2;else if (l = checkRuleset(i)) tokens[i].atrulers_child = 3;else break;
1679 if (i < tokensLength) tokens[i].atrulers_end = 1;
1681 if (l = checkSC(i)) i += l;
1689 function getAtrulers() {
1690 var type = NodeType.BlockType;
1691 var token = tokens[pos];
1692 var line = token.ln;
1693 var column = token.col;
1699 content = content.concat(getSC());
1701 while (pos < tokensLength && !tokens[pos].atrulers_end) {
1702 var childType = tokens[pos].atrulers_child;
1703 if (childType === 1) content = content.concat(getSC());else if (childType === 2) content.push(getAtrule());else if (childType === 3) content.push(getRuleset());else break;
1706 content = content.concat(getSC());
1708 var end = getLastPosition(content, line, column, 1);
1713 return newNode(type, content, line, column, end);
1717 * @param {Number} i Token's index number
1720 function checkAtrules(i) {
1724 if (i >= tokensLength) return 0;
1726 if (l = checkAtkeyword(i)) i += l;else return 0;
1728 if (l = checkTsets(i)) i += l;
1736 function getAtrules() {
1737 var type = NodeType.AtruleType;
1738 var token = tokens[pos];
1739 var line = token.ln;
1740 var column = token.col;
1741 var content = [].concat(getAtkeyword(), getTsets());
1743 return newNode(type, content, line, column);
1747 * Check if token is part of a block (e.g. `{...}`).
1748 * @param {Number} i Token's index number
1749 * @return {Number} Length of the block
1751 function checkBlock(i) {
1752 return i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket ? tokens[i].right - i + 1 : 0;
1756 * Get node with a block
1759 function getBlock() {
1760 var type = NodeType.BlockType;
1761 var token = tokens[pos];
1762 var line = token.ln;
1763 var column = token.col;
1764 var end = tokens[pos].right;
1771 if (checkBlockdecl(pos)) content = content.concat(getBlockdecl());else throwError(pos);
1774 var end_ = getLastPosition(content, line, column, 1);
1777 return newNode(type, content, line, column, end_);
1781 * Check if token is part of a declaration (property-value pair)
1782 * @param {Number} i Token's index number
1783 * @return {Number} Length of the declaration
1785 function checkBlockdecl(i) {
1788 if (i >= tokensLength) return 0;
1790 if (l = checkBlockdecl1(i)) tokens[i].bd_type = 1;else if (l = checkBlockdecl2(i)) tokens[i].bd_type = 2;else if (l = checkBlockdecl3(i)) tokens[i].bd_type = 3;else if (l = checkBlockdecl4(i)) tokens[i].bd_type = 4;else return 0;
1798 function getBlockdecl() {
1799 var childType = tokens[pos].bd_type;
1801 if (childType === 1) return getBlockdecl1();
1802 if (childType === 2) return getBlockdecl2();
1803 if (childType === 3) return getBlockdecl3();
1804 if (childType === 4) return getBlockdecl4();
1808 * @param {Number} i Token's index number
1811 function checkBlockdecl1(i) {
1815 if (l = checkSC(i)) i += l;
1817 if (l = checkDeclaration(i)) tokens[i].bd_kind = 1;else if (l = checkAtrule(i)) tokens[i].bd_kind = 2;else return 0;
1821 if (l = checkSC(i)) i += l;
1823 if (i < tokensLength && (l = checkDeclDelim(i))) i += l;else return 0;
1825 if (l = checkSC(i)) i += l;else return 0;
1833 function getBlockdecl1() {
1835 var content = void 0;
1837 switch (tokens[pos].bd_kind) {
1839 content = getDeclaration();
1842 content = getAtrule();
1846 return sc.concat(content, getSC(), getDeclDelim(), getSC());
1850 * @param {Number} i Token's index number
1853 function checkBlockdecl2(i) {
1857 if (l = checkSC(i)) i += l;
1859 if (l = checkDeclaration(i)) tokens[i].bd_kind = 1;else if (l = checkAtrule(i)) tokens[i].bd_kind = 2;else return 0;
1863 if (l = checkSC(i)) i += l;
1871 function getBlockdecl2() {
1873 var content = void 0;
1875 switch (tokens[pos].bd_kind) {
1877 content = getDeclaration();
1880 content = getAtrule();
1884 return sc.concat(content, getSC());
1888 * @param {Number} i Token's index number
1891 function checkBlockdecl3(i) {
1895 if (l = checkSC(i)) i += l;
1897 if (l = checkDeclDelim(i)) i += l;else return 0;
1899 if (l = checkSC(i)) i += l;
1907 function getBlockdecl3() {
1908 return [].concat(getSC(), getDeclDelim(), getSC());
1912 * @param {Number} i Token's index number
1915 function checkBlockdecl4(i) {
1922 function getBlockdecl4() {
1927 * Check if token is part of text inside square brackets, e.g. `[1]`
1928 * @param {Number} i Token's index number
1931 function checkBrackets(i) {
1932 if (i >= tokensLength) return 0;
1937 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
1939 if (i < tokens[start].right) {
1940 var l = checkTsets(i);
1941 if (l) i += l;else return 0;
1951 * Get node with text inside square brackets, e.g. `[1]`
1954 function getBrackets() {
1955 var type = NodeType.BracketsType;
1956 var token = tokens[pos];
1957 var line = token.ln;
1958 var column = token.col;
1959 var right = token.right;
1966 content = getTsets();
1969 var end = getLastPosition(content, line, column, 1);
1974 return newNode(type, content, line, column, end);
1978 * Check if token is part of a class selector (e.g. `.abc`)
1979 * @param {Number} i Token's index number
1980 * @return {Number} Length of the class selector
1982 function checkClass(i) {
1986 if (i >= tokensLength) return 0;
1988 if (tokens[i].class_l) return tokens[i].class_l;
1991 if (tokens[i].type === TokenType.FullStop) i++;else return 0;
1993 if (l = checkIdent(i)) {
1994 tokens[start].class_l = l + 1;
1998 tokens[start].classEnd = i;
2004 * Get node with a class selector
2007 function getClass() {
2008 var type = NodeType.ClassType;
2009 var token = tokens[pos];
2010 var line = token.ln;
2011 var column = token.col;
2016 var content = [getIdent()];
2018 return newNode(type, content, line, column);
2021 function checkCombinator(i) {
2022 if (i >= tokensLength) return 0;
2025 if (l = checkCombinator1(i)) tokens[i].combinatorType = 1;else if (l = checkCombinator2(i)) tokens[i].combinatorType = 2;else if (l = checkCombinator3(i)) tokens[i].combinatorType = 3;else if (l = checkCombinator4(i)) tokens[i].combinatorType = 4;
2030 function getCombinator() {
2031 var type = tokens[pos].combinatorType;
2032 if (type === 1) return getCombinator1();
2033 if (type === 2) return getCombinator2();
2034 if (type === 3) return getCombinator3();
2035 if (type === 4) return getCombinator4();
2044 function checkCombinator1(i) {
2045 if (i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign) return 3;
2053 function getCombinator1() {
2054 var type = NodeType.CombinatorType;
2055 var token = tokens[pos];
2056 var line = token.ln;
2057 var column = token.col;
2058 var content = '>>>';
2063 return newNode(type, content, line, column);
2073 function checkCombinator2(i) {
2074 if (i + 1 >= tokensLength) return 0;
2076 if (tokens[i].type === TokenType.VerticalLine && tokens[i + 1].type === TokenType.VerticalLine) return 2;
2078 if (tokens[i].type === TokenType.GreaterThanSign && tokens[i + 1].type === TokenType.GreaterThanSign) return 2;
2086 function getCombinator2() {
2087 var type = NodeType.CombinatorType;
2088 var token = tokens[pos];
2089 var line = token.ln;
2090 var column = token.col;
2091 var content = '' + token.value + tokens[pos + 1].value;
2096 return newNode(type, content, line, column);
2107 function checkCombinator3(i) {
2108 var type = tokens[i].type;
2109 if (type === TokenType.PlusSign || type === TokenType.GreaterThanSign || type === TokenType.Tilde) return 1;else return 0;
2115 function getCombinator3() {
2116 var type = NodeType.CombinatorType;
2117 var token = tokens[pos];
2118 var line = token.ln;
2119 var column = token.col;
2120 var content = token.value;
2125 return newNode(type, content, line, column);
2131 function checkCombinator4(i) {
2134 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
2137 if (l = checkIdent(i)) i += l;else return 0;
2139 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
2147 function getCombinator4() {
2148 var type = NodeType.CombinatorType;
2149 var token = tokens[pos];
2150 var line = token.ln;
2151 var column = token.col;
2156 var ident = getIdent();
2161 var content = '/' + ident.content + '/';
2163 return newNode(type, content, line, column);
2167 * Check if token is a multiline comment.
2168 * @param {Number} i Token's index number
2169 * @return {Number} `1` if token is a multiline comment, otherwise `0`
2171 function checkCommentML(i) {
2172 return i < tokensLength && tokens[i].type === TokenType.CommentML ? 1 : 0;
2176 * Get node with a multiline comment
2179 function getCommentML() {
2180 var type = NodeType.CommentMLType;
2181 var token = tokens[pos];
2182 var line = token.ln;
2183 var column = token.col;
2184 var content = tokens[pos].value.substring(2);
2185 var l = content.length;
2187 if (content.charAt(l - 2) === '*' && content.charAt(l - 1) === '/') content = content.substring(0, l - 2);
2189 var end = getLastPosition(content, line, column, 2);
2190 if (end[0] === line) end[1] += 2;
2193 return newNode(type, content, line, column, end);
2197 * Check if token is part of a declaration (property-value pair)
2198 * @param {Number} i Token's index number
2199 * @return {Number} Length of the declaration
2201 function checkDeclaration(i) {
2205 if (i >= tokensLength) return 0;
2207 if (l = checkProperty(i)) i += l;else return 0;
2209 if (l = checkSC(i)) i += l;
2211 if (l = checkPropertyDelim(i)) i++;else return 0;
2213 if (l = checkSC(i)) i += l;
2215 if (l = checkValue(i)) i += l;else return 0;
2221 * Get node with a declaration
2224 function getDeclaration() {
2225 var type = NodeType.DeclarationType;
2226 var token = tokens[pos];
2227 var line = token.ln;
2228 var column = token.col;
2229 var content = [].concat(getProperty(), getSC(), getPropertyDelim(), getSC(), getValue());
2231 return newNode(type, content, line, column);
2235 * Check if token is a semicolon
2236 * @param {Number} i Token's index number
2237 * @return {Number} `1` if token is a semicolon, otherwise `0`
2239 function checkDeclDelim(i) {
2240 return i < tokensLength && tokens[i].type === TokenType.Semicolon ? 1 : 0;
2244 * Get node with a semicolon
2247 function getDeclDelim() {
2248 var type = NodeType.DeclDelimType;
2249 var token = tokens[pos];
2250 var line = token.ln;
2251 var column = token.col;
2256 return newNode(type, content, line, column);
2260 * Check if token is a comma
2261 * @param {Number} i Token's index number
2262 * @return {Number} `1` if token is a comma, otherwise `0`
2264 function checkDelim(i) {
2265 return i < tokensLength && tokens[i].type === TokenType.Comma ? 1 : 0;
2269 * Get node with a comma
2272 function getDelim() {
2273 var type = NodeType.DelimType;
2274 var token = tokens[pos];
2275 var line = token.ln;
2276 var column = token.col;
2281 return newNode(type, content, line, column);
2285 * Check if token is part of a number with dimension unit (e.g. `10px`)
2286 * @param {Number} i Token's index number
2289 function checkDimension(i) {
2290 var ln = checkNumber(i);
2293 if (i >= tokensLength || !ln || i + ln >= tokensLength) return 0;
2295 return (li = checkUnit(i + ln)) ? ln + li : 0;
2299 * Get node of a number with dimension unit
2302 function getDimension() {
2303 var type = NodeType.DimensionType;
2304 var token = tokens[pos];
2305 var line = token.ln;
2306 var column = token.col;
2307 var content = [getNumber(), getUnit()];
2309 return newNode(type, content, line, column);
2313 * @param {Number} i Token's index number
2316 function checkExpression(i) {
2319 if (i >= tokensLength || tokens[i++].value !== 'expression' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) {
2323 return tokens[i].right - start + 1;
2329 function getExpression() {
2330 var type = NodeType.ExpressionType;
2331 var token = tokens[pos];
2332 var line = token.ln;
2333 var column = token.col;
2337 var content = joinValues(pos + 1, tokens[pos].right - 1);
2338 var end = getLastPosition(content, line, column, 1);
2340 if (end[0] === line) end[1] += 11;
2341 pos = tokens[pos].right + 1;
2343 return newNode(type, content, line, column, end);
2347 * @param {Number} i Token's index number
2350 function checkFunction(i) {
2354 if (i >= tokensLength) return 0;
2356 if (l = checkIdent(i)) i += l;else return 0;
2358 return i < tokensLength && tokens[i].type === TokenType.LeftParenthesis ? tokens[i].right - start + 1 : 0;
2364 function getFunction() {
2365 var type = NodeType.FunctionType;
2366 var token = tokens[pos];
2367 var line = token.ln;
2368 var column = token.col;
2369 var content = [].concat(getIdent(), getArguments());
2371 return newNode(type, content, line, column);
2375 * Check if token is part of an identifierÑŽ
2376 * Grammar from CSS spec:
2378 * nonascii [\240-\377]
2379 * unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])?
2380 * escape {unicode}|\\[^\r\n\f0-9a-f]
2381 * nmstart [_a-z]|{nonascii}|{escape}
2382 * nmchar [_a-z0-9-]|{nonascii}|{escape}
2383 * ident -?{nmstart}{nmchar}*
2385 * @param {number} i Token's index number
2386 * @return {number} Length of the identifier
2388 function checkIdent(i) {
2391 if (i >= tokensLength) return 0;
2393 if (tokens[i].type === TokenType.HyphenMinus) i++;
2395 if (tokens[i].type === TokenType.LowLine || tokens[i].type === TokenType.Identifier) i++;else return 0;
2397 for (; i < tokensLength; i++) {
2398 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
2401 tokens[start].ident_last = i - 1;
2407 * Get node with an identifier
2410 function getIdent() {
2411 var type = NodeType.IdentType;
2412 var token = tokens[pos];
2413 var line = token.ln;
2414 var column = token.col;
2415 var content = joinValues(pos, tokens[pos].ident_last);
2417 pos = tokens[pos].ident_last + 1;
2419 return newNode(type, content, line, column);
2423 * Check if token is part of `!important` word
2424 * @param {Number} i Token's index number
2427 function checkImportant(i) {
2431 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
2433 if (l = checkSC(i)) i += l;
2435 if (tokens[i].value === 'important') {
2436 tokens[start].importantEnd = i;
2437 return i - start + 1;
2444 * Get node with `!important` word
2447 function getImportant() {
2448 var type = NodeType.ImportantType;
2449 var token = tokens[pos];
2450 var line = token.ln;
2451 var column = token.col;
2452 var content = joinValues(pos, token.importantEnd);
2454 pos = token.importantEnd + 1;
2456 return newNode(type, content, line, column);
2460 * Check a single keyframe block - `5% {}`
2464 function checkKeyframesBlock(i) {
2468 if (i >= tokensLength) return 0;
2470 if (l = checkKeyframesSelectorsGroup(i)) i += l;else return 0;
2472 if (l = checkSC(i)) i += l;
2474 if (l = checkBlock(i)) i += l;else return 0;
2480 * Get a single keyframe block - `5% {}`
2483 function getKeyframesBlock() {
2484 var type = NodeType.RulesetType;
2485 var token = tokens[pos];
2486 var line = token.ln;
2487 var column = token.col;
2488 var content = [].concat(getKeyframesSelectorsGroup(), getSC(), getBlock());
2490 return newNode(type, content, line, column);
2494 * Check all keyframe blocks - `5% {} 100% {}`
2498 function checkKeyframesBlocks(i) {
2502 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
2504 if (l = checkSC(i)) i += l;
2506 if (l = checkKeyframesBlock(i)) i += l;else return 0;
2508 while (tokens[i].type !== TokenType.RightCurlyBracket) {
2509 if (l = checkSC(i)) i += l;else if (l = checkKeyframesBlock(i)) i += l;else break;
2512 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
2518 * Get all keyframe blocks - `5% {} 100% {}`
2521 function getKeyframesBlocks() {
2522 var type = NodeType.BlockType;
2523 var token = tokens[pos];
2524 var line = token.ln;
2525 var column = token.col;
2526 var keyframesBlocksEnd = token.right;
2532 while (pos < keyframesBlocksEnd) {
2533 if (checkSC(pos)) content = content.concat(getSC());else if (checkKeyframesBlock(pos)) content.push(getKeyframesBlock());
2536 var end = getLastPosition(content, line, column, 1);
2541 return newNode(type, content, line, column, end);
2545 * Check if token is part of a @keyframes rule.
2546 * @param {Number} i Token's index number
2547 * @return {Number} Length of the @keyframes rule
2549 function checkKeyframesRule(i) {
2553 if (i >= tokensLength) return 0;
2555 if (l = checkAtkeyword(i)) i += l;else return 0;
2557 var atruleName = joinValues2(i - l, l);
2558 if (atruleName.toLowerCase().indexOf('keyframes') === -1) return 0;
2560 if (l = checkSC(i)) i += l;else return 0;
2562 if (l = checkIdent(i)) i += l;else return 0;
2564 if (l = checkSC(i)) i += l;
2566 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
2574 function getKeyframesRule() {
2575 var type = NodeType.AtruleType;
2576 var token = tokens[pos];
2577 var line = token.ln;
2578 var column = token.col;
2579 var content = [].concat(getAtkeyword(), getSC(), getIdent(), getSC(), getKeyframesBlocks());
2581 return newNode(type, content, line, column);
2585 * Check a single keyframe selector - `5%`, `from` etc
2589 function checkKeyframesSelector(i) {
2593 if (i >= tokensLength) return 0;
2595 if (l = checkIdent(i)) {
2596 // Valid selectors are only `from` and `to`.
2597 var selector = joinValues2(i, l);
2598 if (selector !== 'from' && selector !== 'to') return 0;
2601 tokens[start].keyframesSelectorType = 1;
2602 } else if (l = checkPercentage(i)) {
2604 tokens[start].keyframesSelectorType = 2;
2613 * Get a single keyframe selector
2616 function getKeyframesSelector() {
2617 var keyframesSelectorType = NodeType.KeyframesSelectorType;
2618 var selectorType = NodeType.SelectorType;
2619 var token = tokens[pos];
2620 var line = token.ln;
2621 var column = token.col;
2624 if (token.keyframesSelectorType === 1) {
2625 content.push(getIdent());
2627 content.push(getPercentage());
2630 var keyframesSelector = newNode(keyframesSelectorType, content, line, column);
2632 return newNode(selectorType, [keyframesSelector], line, column);
2636 * Check the keyframe's selector groups
2640 function checkKeyframesSelectorsGroup(i) {
2644 if (l = checkKeyframesSelector(i)) i += l;else return 0;
2646 while (i < tokensLength) {
2647 var spaceBefore = checkSC(i);
2648 var comma = checkDelim(i + spaceBefore);
2651 var spaceAfter = checkSC(i + spaceBefore + comma);
2652 if (l = checkKeyframesSelector(i + spaceBefore + comma + spaceAfter)) {
2653 i += spaceBefore + comma + spaceAfter + l;
2657 tokens[start].selectorsGroupEnd = i;
2663 * Get the keyframe's selector groups
2664 * @returns {Array} An array of keyframe selectors
2666 function getKeyframesSelectorsGroup() {
2667 var selectorsGroup = [];
2668 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
2670 selectorsGroup.push(getKeyframesSelector());
2672 while (pos < selectorsGroupEnd) {
2673 selectorsGroup = selectorsGroup.concat(getSC(), getDelim(), getSC(), getKeyframesSelector());
2676 return selectorsGroup;
2680 * Check if token is a namespace sign (`|`)
2681 * @param {Number} i Token's index number
2682 * @return {Number} `1` if token is `|`, `0` if not
2684 function checkNamespace(i) {
2685 return i < tokensLength && tokens[i].type === TokenType.VerticalLine ? 1 : 0;
2689 * Get node with a namespace sign
2692 function getNamespace() {
2693 var type = NodeType.NamespaceType;
2694 var token = tokens[pos];
2695 var line = token.ln;
2696 var column = token.col;
2701 return newNode(type, content, line, column);
2705 * @param {Number} i Token's index number
2708 function checkNmName2(i) {
2709 if (tokens[i].type === TokenType.Identifier) return 1;else if (tokens[i].type !== TokenType.DecimalNumber) return 0;
2713 return i < tokensLength && tokens[i].type === TokenType.Identifier ? 2 : 1;
2719 function getNmName2() {
2720 var s = tokens[pos].value;
2722 if (tokens[pos++].type === TokenType.DecimalNumber && pos < tokensLength && tokens[pos].type === TokenType.Identifier) s += tokens[pos++].value;
2728 * Check if token is part of a number
2729 * @param {Number} i Token's index number
2730 * @return {Number} Length of number
2732 function checkNumber(i) {
2733 if (i >= tokensLength) return 0;
2735 if (tokens[i].number_l) return tokens[i].number_l;
2738 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && (!tokens[i + 1] || tokens[i + 1] && tokens[i + 1].type !== TokenType.FullStop)) {
2739 tokens[i].number_l = 1;
2744 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && (!tokens[i + 2] || tokens[i + 2].type !== TokenType.DecimalNumber)) {
2745 tokens[i].number_l = 2;
2750 if (i < tokensLength && tokens[i].type === TokenType.FullStop && tokens[i + 1].type === TokenType.DecimalNumber) {
2751 tokens[i].number_l = 2;
2756 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && tokens[i + 2] && tokens[i + 2].type === TokenType.DecimalNumber) {
2757 tokens[i].number_l = 3;
2765 * Get node with number
2768 function getNumber() {
2769 var type = NodeType.NumberType;
2770 var token = tokens[pos];
2771 var line = token.ln;
2772 var column = token.col;
2773 var l = tokens[pos].number_l;
2776 for (var j = 0; j < l; j++) {
2777 content += tokens[pos + j].value;
2782 return newNode(type, content, line, column);
2786 * Check if token is an operator (`/`, `,`, `:`, `=`, `*`).
2787 * @param {Number} i Token's index number
2788 * @return {Number} `1` if token is an operator, otherwise `0`
2790 function checkOperator(i) {
2791 if (i >= tokensLength) return 0;
2793 switch (tokens[i].type) {
2794 case TokenType.Solidus:
2795 case TokenType.Comma:
2796 case TokenType.Colon:
2797 case TokenType.EqualsSign:
2798 case TokenType.Asterisk:
2806 * Get node with an operator
2809 function getOperator() {
2810 var type = NodeType.OperatorType;
2811 var token = tokens[pos];
2812 var line = token.ln;
2813 var column = token.col;
2814 var content = token.value;
2818 return newNode(type, content, line, column);
2822 * Check if token is part of text inside parentheses, e.g. `(1)`
2823 * @param {Number} i Token's index number
2826 function checkParentheses(i) {
2827 if (i >= tokensLength) return 0;
2830 var right = tokens[i].right;
2833 if (tokens[i].type === TokenType.LeftParenthesis) i++;else return 0;
2836 var l = checkTsets(i);
2837 if (l) i += l;else return 0;
2847 * Get node with text inside parentheses, e.g. `(1)`
2850 function getParentheses() {
2851 var type = NodeType.ParenthesesType;
2852 var token = tokens[pos];
2853 var line = token.ln;
2854 var column = token.col;
2855 var right = token.right;
2862 content = getTsets();
2865 var end = getLastPosition(content, line, column, 1);
2870 return newNode(type, content, line, column, end);
2874 * Check if token is part of a number with percent sign (e.g. `10%`)
2875 * @param {Number} i Token's index number
2878 function checkPercentage(i) {
2882 if (i >= tokensLength) return 0;
2884 if (l = checkNumber(i)) i += l;else return 0;
2886 if (i >= tokensLength) return 0;
2889 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
2895 * Get node of number with percent sign
2898 function getPercentage() {
2899 var type = NodeType.PercentageType;
2900 var token = tokens[pos];
2901 var line = token.ln;
2902 var column = token.col;
2903 var content = [getNumber()];
2904 var end = getLastPosition(content, line, column, 1);
2909 return newNode(type, content, line, column, end);
2913 * @param {Number} i Token's index number
2916 function checkProgid(i) {
2920 if (i >= tokensLength) return 0;
2922 if (joinValues2(i, 6) === 'progid:DXImageTransform.Microsoft.') i += 6;else return 0;
2924 if (l = checkIdent(i)) i += l;else return 0;
2926 if (l = checkSC(i)) i += l;
2928 if (tokens[i].type === TokenType.LeftParenthesis) {
2929 tokens[start].progid_end = tokens[i].right;
2930 i = tokens[i].right + 1;
2939 function getProgid() {
2940 var type = NodeType.ProgidType;
2941 var token = tokens[pos];
2942 var line = token.ln;
2943 var column = token.col;
2944 var progid_end = token.progid_end;
2945 var content = joinValues(pos, progid_end);
2947 pos = progid_end + 1;
2949 return newNode(type, content, line, column);
2953 * Check if token is part of a property
2954 * @param {Number} i Token's index number
2955 * @return {Number} Length of the property
2957 function checkProperty(i) {
2961 if (l = checkProperty1(i)) tokens[start].propertyType = 1;else if (l = checkProperty2(i)) tokens[start].propertyType = 2;
2967 * Get node with a property
2970 function getProperty() {
2971 var type = tokens[pos].propertyType;
2973 if (type === 1) return getProperty1();
2974 if (type === 2) return getProperty2();
2978 * Check if token is part of a property
2979 * @param {Number} i Token's index number
2980 * @return {Number} Length of the property
2982 function checkProperty1(i) {
2986 if (i >= tokensLength) return 0;
2988 if (l = checkIdent(i)) i += l;else return 0;
2994 * Get node with a property
2997 function getProperty1() {
2998 var type = NodeType.PropertyType;
2999 var token = tokens[pos];
3000 var line = token.ln;
3001 var column = token.col;
3002 var content = [getIdent()];
3004 return newNode(type, content, line, column);
3008 * Check if token is part of a custom property
3009 * @param {Number} i Token's index number
3010 * @return {Number} Length of the property
3012 function checkProperty2(i) {
3013 return checkCustomProperty(i);
3017 * Get node with a custom property
3020 function getProperty2() {
3021 return getCustomProperty();
3025 * Check if token is part of a custom property
3026 * @param {Number} i Token's index number
3027 * @return {Number} Length of the property
3029 function checkCustomProperty(i) {
3033 if (i >= tokensLength) return 0;
3035 if (tokens[i].type !== TokenType.HyphenMinus || tokens[i + 1] && tokens[i + 1].type !== TokenType.HyphenMinus) return 0;
3040 if (l = checkIdent(i)) i += l;else return 0;
3046 * Get node with a custom property
3049 function getCustomProperty() {
3050 var type = NodeType.CustomPropertyType;
3051 var token = tokens[pos];
3052 var line = token.ln;
3053 var column = token.col;
3058 var content = [getIdent()];
3060 return newNode(type, content, line, column);
3064 * Check if token is a colon
3065 * @param {Number} i Token's index number
3066 * @return {Number} `1` if token is a colon, otherwise `0`
3068 function checkPropertyDelim(i) {
3069 return i < tokensLength && tokens[i].type === TokenType.Colon ? 1 : 0;
3073 * Get node with a colon
3076 function getPropertyDelim() {
3077 var type = NodeType.PropertyDelimType;
3078 var token = tokens[pos];
3079 var line = token.ln;
3080 var column = token.col;
3086 return newNode(type, content, line, column);
3090 * @param {Number} i Token's index number
3093 function checkPseudo(i) {
3094 return checkPseudoe(i) || checkPseudoc(i);
3100 function getPseudo() {
3101 if (checkPseudoe(pos)) return getPseudoe();
3102 if (checkPseudoc(pos)) return getPseudoc();
3106 * @param {Number} i Token's index number
3109 function checkPseudoe(i) {
3113 if (i >= tokensLength || tokens[i].type !== TokenType.Colon || i >= tokensLength || tokens[i + 1].type !== TokenType.Colon) return 0;
3115 if (l = checkPseudoElement1(i)) tokens[i].pseudoElementType = 1;else if (l = checkPseudoElement2(i)) tokens[i].pseudoElementType = 2;else return 0;
3123 function getPseudoe() {
3124 var childType = tokens[pos].pseudoElementType;
3125 if (childType === 1) return getPseudoElement1();
3126 if (childType === 2) return getPseudoElement2();
3130 * (1) `::slotted(selector)`
3131 * (2) `::slotted(selector, selector)`
3133 function checkPseudoElement1(i) {
3140 if (i >= tokensLength) return 0;
3142 if (l = checkIdent(i)) i += l;else return 0;
3144 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
3146 var right = tokens[i].right;
3151 if (l = checkSC(i)) i += l;
3153 if (l = checkSelectorsGroup(i)) i += l;else return 0;
3155 if (l = checkSC(i)) i += l;
3157 if (i !== right) return 0;
3166 * (1) `::slotted(selector)`
3167 * (2) `::slotted(selector, selector)`
3169 function getPseudoElement1() {
3170 var type = NodeType.PseudoeType;
3171 var token = tokens[pos];
3172 var line = token.ln;
3173 var column = token.col;
3179 content.push(getIdent());
3182 var _type = NodeType.ArgumentsType;
3183 var _token = tokens[pos];
3184 var _line = _token.ln;
3185 var _column = _token.col;
3190 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
3192 var end = getLastPosition(selectorContent, _line, _column, 1);
3193 var args = newNode(_type, selectorContent, _line, _column, end);
3200 return newNode(type, content, line, column);
3203 function checkPseudoElement2(i) {
3210 if (l = checkIdent(i)) i += l;else return 0;
3218 function getPseudoElement2() {
3219 var type = NodeType.PseudoeType;
3220 var token = tokens[pos];
3221 var line = token.ln;
3222 var column = token.col;
3227 var content = [getIdent()];
3229 return newNode(type, content, line, column);
3233 * @param {Number} i Token's index number
3236 function checkPseudoc(i) {
3239 if (i >= tokensLength || tokens[i].type !== TokenType.Colon) return 0;
3241 if (l = checkPseudoClass1(i)) tokens[i].pseudoClassType = 1;else if (l = checkPseudoClass2(i)) tokens[i].pseudoClassType = 2;else if (l = checkPseudoClass3(i)) tokens[i].pseudoClassType = 3;else if (l = checkPseudoClass4(i)) tokens[i].pseudoClassType = 4;else if (l = checkPseudoClass5(i)) tokens[i].pseudoClassType = 5;else if (l = checkPseudoClass6(i)) tokens[i].pseudoClassType = 6;else return 0;
3249 function getPseudoc() {
3250 var childType = tokens[pos].pseudoClassType;
3251 if (childType === 1) return getPseudoClass1();
3252 if (childType === 2) return getPseudoClass2();
3253 if (childType === 3) return getPseudoClass3();
3254 if (childType === 4) return getPseudoClass4();
3255 if (childType === 5) return getPseudoClass5();
3256 if (childType === 6) return getPseudoClass6();
3260 * (1) `:panda(selector)`
3261 * (2) `:panda(selector, selector)`
3263 function checkPseudoClass1(i) {
3270 if (i >= tokensLength) return 0;
3272 if (l = checkIdent(i)) i += l;else return 0;
3274 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
3276 var right = tokens[i].right;
3281 if (l = checkSC(i)) i += l;
3283 if (l = checkSelectorsGroup(i)) i += l;else return 0;
3285 if (l = checkSC(i)) i += l;
3287 if (i !== right) return 0;
3298 function getPseudoClass1() {
3299 var type = NodeType.PseudocType;
3300 var token = tokens[pos];
3301 var line = token.ln;
3302 var column = token.col;
3308 content.push(getIdent());
3311 var _type2 = NodeType.ArgumentsType;
3312 var _token2 = tokens[pos];
3313 var _line2 = _token2.ln;
3314 var _column2 = _token2.col;
3319 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
3321 var end = getLastPosition(selectorContent, _line2, _column2, 1);
3322 var args = newNode(_type2, selectorContent, _line2, _column2, end);
3329 return newNode(type, content, line, column);
3333 * (1) `:nth-child(odd)`
3334 * (2) `:nth-child(even)`
3335 * (3) `:lang(de-DE)`
3337 function checkPseudoClass2(i) {
3344 if (i >= tokensLength) return 0;
3346 if (l = checkIdent(i)) i += l;else return 0;
3348 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
3350 var right = tokens[i].right;
3355 if (l = checkSC(i)) i += l;
3357 if (l = checkIdent(i)) i += l;else return 0;
3359 if (l = checkSC(i)) i += l;
3361 if (i !== right) return 0;
3369 function getPseudoClass2() {
3370 var type = NodeType.PseudocType;
3371 var token = tokens[pos];
3372 var line = token.ln;
3373 var column = token.col;
3379 content.push(getIdent());
3384 var l = tokens[pos].ln;
3385 var c = tokens[pos].col;
3386 var value = [].concat(getSC(), getIdent(), getSC());
3388 var end = getLastPosition(value, l, c, 1);
3389 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
3395 return newNode(type, content, line, column);
3399 * (-) `:nth-child(-3n + 2)`
3401 function checkPseudoClass3(i) {
3408 if (i >= tokensLength) return 0;
3410 if (l = checkIdent(i)) i += l;else return 0;
3412 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
3414 var right = tokens[i].right;
3419 if (l = checkSC(i)) i += l;
3421 if (l = checkUnary(i)) i += l;
3423 if (i >= tokensLength) return 0;
3424 if (tokens[i].type === TokenType.DecimalNumber) i++;
3426 if (i >= tokensLength) return 0;
3427 if (tokens[i].value === 'n') i++;else return 0;
3429 if (l = checkSC(i)) i += l;
3431 if (i >= tokensLength) return 0;
3433 if (tokens[i].type === TokenType.PlusSign || tokens[i].type === TokenType.HyphenMinus) i++;else return 0;
3435 if (l = checkSC(i)) i += l;
3437 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
3439 if (l = checkSC(i)) i += l;
3441 if (i !== right) return 0;
3449 function getPseudoClass3() {
3450 var type = NodeType.PseudocType;
3451 var token = tokens[pos];
3452 var line = token.ln;
3453 var column = token.col;
3459 content.push(getIdent());
3461 var l = tokens[pos].ln;
3462 var c = tokens[pos].col;
3468 value = value.concat(getSC());
3470 if (checkUnary(pos)) value.push(getUnary());
3471 if (checkNumber(pos)) value.push(getNumber());
3474 var _l = tokens[pos].ln;
3475 var _c = tokens[pos].col;
3476 var _content = tokens[pos].value;
3477 var ident = newNode(NodeType.IdentType, _content, _l, _c);
3482 value = value.concat(getSC());
3484 if (checkUnary(pos)) value.push(getUnary());
3486 value = value.concat(getSC());
3488 if (checkNumber(pos)) value.push(getNumber());
3490 value = value.concat(getSC());
3492 var end = getLastPosition(value, l, c, 1);
3493 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
3499 return newNode(type, content, line, column);
3503 * (-) `:nth-child(-3n)`
3505 function checkPseudoClass4(i) {
3512 if (i >= tokensLength) return 0;
3514 if (l = checkIdent(i)) i += l;else return 0;
3516 if (i >= tokensLength) return 0;
3517 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
3519 var right = tokens[i].right;
3524 if (l = checkSC(i)) i += l;
3526 if (l = checkUnary(i)) i += l;
3527 if (tokens[i].type === TokenType.DecimalNumber) i++;
3529 if (tokens[i].value === 'n') i++;else return 0;
3531 if (l = checkSC(i)) i += l;
3533 if (i !== right) return 0;
3541 function getPseudoClass4() {
3542 var type = NodeType.PseudocType;
3543 var token = tokens[pos];
3544 var line = token.ln;
3545 var column = token.col;
3551 content.push(getIdent());
3553 var l = tokens[pos].ln;
3554 var c = tokens[pos].col;
3560 value = value.concat(getSC());
3562 if (checkUnary(pos)) value.push(getUnary());
3563 if (checkNumber(pos)) value.push(getNumber());
3564 if (checkIdent(pos)) value.push(getIdent());
3566 value = value.concat(getSC());
3568 var end = getLastPosition(value, l, c, 1);
3569 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
3575 return newNode(type, content, line, column);
3579 * (-) `:nth-child(+8)`
3581 function checkPseudoClass5(i) {
3588 if (i >= tokensLength) return 0;
3590 if (l = checkIdent(i)) i += l;else return 0;
3592 if (i >= tokensLength) return 0;
3593 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
3595 var right = tokens[i].right;
3600 if (l = checkSC(i)) i += l;
3602 if (l = checkUnary(i)) i += l;
3603 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
3605 if (l = checkSC(i)) i += l;
3607 if (i !== right) return 0;
3615 function getPseudoClass5() {
3616 var type = NodeType.PseudocType;
3617 var token = tokens[pos];
3618 var line = token.ln;
3619 var column = token.col;
3625 content.push(getIdent());
3627 var l = tokens[pos].ln;
3628 var c = tokens[pos].col;
3634 value = value.concat(getSC());
3636 if (checkUnary(pos)) value.push(getUnary());
3637 if (checkNumber(pos)) value.push(getNumber());
3639 value = value.concat(getSC());
3641 var end = getLastPosition(value, l, c, 1);
3642 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
3648 return newNode(type, content, line, column);
3654 function checkPseudoClass6(i) {
3661 if (i >= tokensLength) return 0;
3663 if (l = checkIdent(i)) i += l;else return 0;
3668 function getPseudoClass6() {
3669 var type = NodeType.PseudocType;
3670 var token = tokens[pos];
3671 var line = token.ln;
3672 var column = token.col;
3677 var content = [getIdent()];
3679 return newNode(type, content, line, column);
3683 * @param {Number} i Token's index number
3686 function checkRuleset(i) {
3690 if (i >= tokensLength) return 0;
3692 if (l = checkSelectorsGroup(i)) i += l;else return 0;
3694 if (l = checkSC(i)) i += l;
3696 if (l = checkBlock(i)) i += l;else return 0;
3704 function getRuleset() {
3705 var type = NodeType.RulesetType;
3706 var token = tokens[pos];
3707 var line = token.ln;
3708 var column = token.col;
3709 var content = [].concat(getSelectorsGroup(), getSC(), getBlock());
3711 return newNode(type, content, line, column);
3715 * Check if token is marked as a space (if it's a space or a tab
3718 * @return {Number} Number of spaces in a row starting with the given token.
3720 function checkS(i) {
3721 return i < tokensLength && tokens[i].ws ? tokens[i].ws_last - i + 1 : 0;
3725 * Get node with spaces
3729 var type = NodeType.SType;
3730 var token = tokens[pos];
3731 var line = token.ln;
3732 var column = token.col;
3733 var content = joinValues(pos, tokens[pos].ws_last);
3735 pos = tokens[pos].ws_last + 1;
3737 return newNode(type, content, line, column);
3741 * Check if token is a space or a comment.
3742 * @param {Number} i Token's index number
3743 * @return {Number} Number of similar (space or comment) tokens
3744 * in a row starting with the given token.
3746 function checkSC(i) {
3747 if (i >= tokensLength) return 0;
3752 while (i < tokensLength) {
3753 if (l = checkS(i)) tokens[i].sc_child = 1;else if (l = checkCommentML(i)) tokens[i].sc_child = 2;else break;
3763 * Get node with spaces and comments
3769 if (pos >= tokensLength) return sc;
3771 while (pos < tokensLength) {
3772 var childType = tokens[pos].sc_child;
3774 if (childType === 1) sc.push(getS());else if (childType === 2) sc.push(getCommentML());else break;
3781 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
3783 * @param {Number} i Token's index number
3786 function checkShash(i) {
3790 if (i >= tokensLength) return 0;
3792 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
3794 if (l = checkIdent(i)) i += l;else return 0;
3800 * Get node with a hexadecimal number (e.g. `#fff`) inside a simple
3804 function getShash() {
3805 var type = NodeType.ShashType;
3806 var token = tokens[pos];
3807 var line = token.ln;
3808 var column = token.col;
3813 var content = [getIdent()];
3815 return newNode(type, content, line, column);
3819 * Check if token is part of a string (text wrapped in quotes)
3820 * @param {Number} i Token's index number
3821 * @return {Number} `1` if token is part of a string, `0` if not
3823 function checkString(i) {
3824 if (i >= tokensLength) return 0;
3826 if (tokens[i].type === TokenType.StringSQ || tokens[i].type === TokenType.StringDQ) {
3835 * @return {Array} `['string', x]` where `x` is a string (including
3838 function getString() {
3839 var type = NodeType.StringType;
3840 var token = tokens[pos];
3841 var line = token.ln;
3842 var column = token.col;
3843 var content = token.value;
3847 return newNode(type, content, line, column);
3851 * Validate stylesheet: it should consist of any number (0 or more) of
3852 * rulesets (sets of rules with selectors), @-rules, whitespaces or
3854 * @param {Number} i Token's index number
3857 function checkStylesheet(i) {
3861 while (i < tokensLength) {
3862 if (l = checkSC(i)) tokens[i].stylesheet_child = 1;else if (l = checkRuleset(i)) tokens[i].stylesheet_child = 2;else if (l = checkAtrule(i)) tokens[i].stylesheet_child = 3;else if (l = checkDeclDelim(i)) tokens[i].stylesheet_child = 4;else throwError(i);
3871 * @return {Array} `['stylesheet', x]` where `x` is all stylesheet's
3874 function getStylesheet() {
3875 var type = NodeType.StylesheetType;
3876 var token = tokens[pos];
3877 var line = token.ln;
3878 var column = token.col;
3881 while (pos < tokensLength) {
3882 var childType = tokens[pos].stylesheet_child;
3884 if (childType === 1) content = content.concat(getSC());
3885 if (childType === 2) content.push(getRuleset());
3886 if (childType === 3) content.push(getAtrule());
3887 if (childType === 4) content.push(getDeclDelim());
3890 return newNode(type, content, line, column);
3894 * @param {Number} i Token's index number
3897 function checkTset(i) {
3900 if (l = checkVhash(i)) tokens[i].tset_child = 1;else if (l = checkAny(i)) tokens[i].tset_child = 2;else if (l = checkSC(i)) tokens[i].tset_child = 3;else if (l = checkOperator(i)) tokens[i].tset_child = 4;
3908 function getTset() {
3909 var childType = tokens[pos].tset_child;
3911 if (childType === 1) return getVhash();
3912 if (childType === 2) return getAny();
3913 if (childType === 3) return getSC();
3914 if (childType === 4) return getOperator();
3918 * @param {Number} i Token's index number
3921 function checkTsets(i) {
3925 if (i >= tokensLength) return 0;
3927 while (l = checkTset(i)) {
3931 tokens[start].tsets_end = i;
3938 function getTsets() {
3942 if (pos >= tokensLength) return content;
3944 var end = tokens[pos].tsets_end;
3947 if (typeof t.content === 'string') content.push(t);else content = content.concat(t);
3954 * Check if token is an unary (arithmetical) sign (`+` or `-`)
3955 * @param {Number} i Token's index number
3956 * @return {Number} `1` if token is an unary sign, `0` if not
3958 function checkUnary(i) {
3959 if (i >= tokensLength) return 0;
3961 if (tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.PlusSign) {
3969 * Get node with an unary (arithmetical) sign (`+` or `-`)
3970 * @return {Array} `['unary', x]` where `x` is an unary sign
3971 * converted to string.
3973 function getUnary() {
3974 var type = NodeType.OperatorType;
3975 var token = tokens[pos];
3976 var line = token.ln;
3977 var column = token.col;
3978 var content = token.value;
3982 return newNode(type, content, line, column);
3986 * Check if token is a unicode range (single or multiple <urange> nodes)
3987 * @param {number} i Token's index
3988 * @return {number} Unicode range node's length
3990 function checkUnicodeRange(i) {
3994 if (i >= tokensLength) return 0;
3996 if (l = checkUrange(i)) i += l;else return 0;
3998 while (i < tokensLength) {
3999 var spaceBefore = checkSC(i);
4000 var comma = checkDelim(i + spaceBefore);
4003 var spaceAfter = checkSC(i + spaceBefore + comma);
4004 if (l = checkUrange(i + spaceBefore + comma + spaceAfter)) {
4005 i += spaceBefore + comma + spaceAfter + l;
4013 * Get a unicode range node
4016 function getUnicodeRange() {
4017 var type = NodeType.UnicodeRangeType;
4018 var token = tokens[pos];
4019 var line = token.ln;
4020 var column = token.col;
4023 while (pos < tokensLength) {
4024 if (checkSC(pos)) content = content.concat(getSC());else if (checkDelim(pos)) content.push(getDelim());else if (checkUrange(pos)) content.push(getUrange());else break;
4027 return newNode(type, content, line, column);
4031 * Check if token is unit
4032 * @param {Number} i Token's index number
4035 function checkUnit(i) {
4036 var units = ['em', 'ex', 'ch', 'rem', 'vh', 'vw', 'vmin', 'vmax', 'px', 'mm', 'q', 'cm', 'in', 'pt', 'pc', 'deg', 'grad', 'rad', 'turn', 's', 'ms', 'Hz', 'kHz', 'dpi', 'dpcm', 'dppx'];
4038 return units.indexOf(tokens[i].value) !== -1 ? 1 : 0;
4042 * Get unit node of type ident
4043 * @return {Node} An ident node containing the unit value
4045 function getUnit() {
4046 var type = NodeType.IdentType;
4047 var token = tokens[pos];
4048 var line = token.ln;
4049 var column = token.col;
4050 var content = token.value;
4054 return newNode(type, content, line, column);
4058 * Check if token is a u-range (part of a unicode-range)
4062 * @param {number} i Token's index
4063 * @return {number} Urange node's length
4065 function checkUrange(i) {
4069 if (i >= tokensLength) return 0;
4071 // Check for unicode prefix (u+ or U+)
4072 if (tokens[i].value === 'U' || tokens[i].value === 'u') i += 1;else return 0;
4074 if (i >= tokensLength) return 0;
4076 if (tokens[i].value === '+') i += 1;else return 0;
4078 while (i < tokensLength) {
4079 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = _checkUnicodeWildcard(i)) i += l;else break;
4082 tokens[start].urangeEnd = i - 1;
4088 * Get a u-range node (part of a unicode-range)
4091 function getUrange() {
4093 var type = NodeType.UrangeType;
4094 var token = tokens[pos];
4095 var line = token.ln;
4096 var column = token.col;
4099 content = joinValues(startPos, tokens[startPos].urangeEnd);
4100 pos = tokens[startPos].urangeEnd + 1;
4102 return newNode(type, content, line, column);
4106 * Check for unicode wildcard characters `?`
4107 * @param {number} i Token's index
4108 * @return {number} Wildcard length
4110 function _checkUnicodeWildcard(i) {
4113 if (i >= tokensLength) return 0;
4115 while (i < tokensLength) {
4116 if (tokens[i].type === TokenType.QuestionMark) i += 1;else break;
4123 * Check if token is part of URI (e.g. `url('/css/styles.css')`)
4124 * @param {Number} i Token's index number
4125 * @return {Number} Length of URI
4127 function checkUri(i) {
4130 if (i >= tokensLength || tokens[i].value !== 'url') return 0;
4135 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
4137 return tokens[i].right - start + 1;
4142 * @return {Array} `['uri', x]` where `x` is URI's nodes (without `url`
4143 * and braces, e.g. `['string', ''/css/styles.css'']`).
4147 var uriExcluding = {};
4152 var rawContent = void 0;
4157 uriExcluding[TokenType.Space] = 1;
4158 uriExcluding[TokenType.Tab] = 1;
4159 uriExcluding[TokenType.Newline] = 1;
4160 uriExcluding[TokenType.LeftParenthesis] = 1;
4161 uriExcluding[TokenType.RightParenthesis] = 1;
4163 if (checkUri1(pos)) {
4164 uri = [].concat(getSC(), getString(), getSC());
4166 uri = checkSC(pos) ? getSC() : [];
4167 l = checkExcluding(uriExcluding, pos);
4168 rawContent = joinValues(pos, pos + l);
4170 raw = newNode(NodeType.RawType, rawContent, t.ln, t.col);
4176 if (checkSC(pos)) uri = uri.concat(getSC());
4179 t = tokens[startPos];
4182 var end = getLastPosition(uri, line, column, 1);
4185 return newNode(NodeType.UriType, uri, line, column, end);
4189 * @param {Number} i Token's index number
4192 function checkUri1(i) {
4196 if (i >= tokensLength) return 0;
4198 if (l = checkSC(i)) i += l;
4200 if (tokens[i].type !== TokenType.StringDQ && tokens[i].type !== TokenType.StringSQ) return 0;
4204 if (l = checkSC(i)) i += l;
4210 * Check if token is part of a value
4211 * @param {Number} i Token's index number
4212 * @return {Number} Length of the value
4214 function checkValue(i) {
4220 while (i < tokensLength) {
4224 if (l = _checkValue(_i)) i += l + s;else break;
4227 tokens[start].value_end = i;
4235 function getValue() {
4236 var type = NodeType.ValueType;
4237 var token = tokens[pos];
4238 var line = token.ln;
4239 var column = token.col;
4240 var end = tokens[pos].value_end;
4244 if (tokens[pos].value_child) content.push(_getValue());else content = content.concat(getSC());
4247 return newNode(type, content, line, column);
4251 * @param {Number} i Token's index number
4254 function _checkValue(i) {
4257 if (l = checkProgid(i)) tokens[i].value_child = 1;else if (l = checkVhash(i)) tokens[i].value_child = 2;else if (l = checkAny(i)) tokens[i].value_child = 3;else if (l = checkOperator(i)) tokens[i].value_child = 4;else if (l = checkImportant(i)) tokens[i].value_child = 5;
4265 function _getValue() {
4266 var childType = tokens[pos].value_child;
4267 if (childType === 1) return getProgid();
4268 if (childType === 2) return getVhash();
4269 if (childType === 3) return getAny();
4270 if (childType === 4) return getOperator();
4271 if (childType === 5) return getImportant();
4275 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
4277 * @param {Number} i Token's index number
4280 function checkVhash(i) {
4284 if (i >= tokensLength) return 0;
4287 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
4289 if (l = checkNmName2(i)) i += l;else return 0;
4295 * Get node with a hexadecimal number (e.g. `#fff`) inside some value
4296 * @return {Array} `['vhash', x]` where `x` is a hexadecimal number
4297 * converted to string (without `#`, e.g. `'fff'`).
4299 function getVhash() {
4300 var type = NodeType.VhashType;
4301 var token = tokens[pos];
4302 var line = token.ln;
4303 var column = token.col;
4308 var content = getNmName2();
4309 var end = getLastPosition(content, line, column + 1);
4310 return newNode(type, content, line, column, end);
4313 function checkSelectorsGroup(i) {
4314 if (i >= tokensLength) return 0;
4318 var selectorCounter = 0;
4319 var delimCounter = 0;
4321 if (l = checkSelector(i)) {
4326 while (i < tokensLength) {
4329 var tempLength = void 0;
4331 var spaceBefore = checkSC(tempIndex);
4333 if (tempLength = checkDelim(tempIndex + spaceBefore)) {
4334 tempIndex += spaceBefore + tempLength;
4337 if (tempLength = checkSC(tempIndex)) tempIndex += tempLength;
4338 if (tempLength = checkSelector(tempIndex)) {
4339 tempIndex += tempLength;
4344 i += tempIndex - tempStart;
4347 tokens[start].selectorsGroupEnd = i;
4348 tokens[start].selectorsGroupSelectorCount = selectorCounter;
4349 tokens[start].selectorsGroupDelimCount = delimCounter;
4354 function getSelectorsGroup() {
4355 var selectorsGroup = [];
4356 var selectorCounter = 0;
4357 var delimCounter = 0;
4359 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
4360 var selectorCount = tokens[pos].selectorsGroupSelectorCount;
4361 var delimCount = tokens[pos].selectorsGroupDelimCount;
4363 selectorsGroup.push(getSelector());
4366 while (pos < selectorsGroupEnd) {
4367 if (delimCounter < delimCount) {
4368 selectorsGroup = selectorsGroup.concat(getSC());
4369 selectorsGroup = selectorsGroup.concat(getDelim());
4372 selectorsGroup = selectorsGroup.concat(getSC());
4374 if (selectorCounter < selectorCount) {
4375 selectorsGroup = selectorsGroup.concat(getSelector());
4381 return selectorsGroup;
4384 function checkSelector(i) {
4385 if (i >= tokensLength) return 0;
4390 if (l = checkCompoundSelector(i)) i += l;else return 0;
4392 while (i < tokensLength) {
4393 var spaceBefore = checkSC(i);
4394 var comma = checkCombinator(i + spaceBefore);
4395 if (!spaceBefore && !comma) break;
4397 var spaceAfter = checkSC(i + spaceBefore + comma);
4398 if (l = checkCompoundSelector(i + spaceBefore + comma + spaceAfter)) {
4399 i += spaceBefore + comma + spaceAfter + l;
4403 tokens[start].selectorEnd = i;
4407 function getSelector() {
4408 var type = NodeType.SelectorType;
4409 var token = tokens[pos];
4410 var line = token.ln;
4411 var column = token.col;
4412 var selectorEnd = token.selectorEnd;
4413 var content = getCompoundSelector();
4415 while (pos < selectorEnd) {
4416 content = content.concat(getSC());
4417 if (checkCombinator(pos)) content.push(getCombinator());
4418 content = content.concat(getSC(), getCompoundSelector());
4421 return newNode(type, content, line, column);
4424 function checkCompoundSelector(i) {
4427 if (l = checkCompoundSelector1(i)) {
4428 tokens[i].compoundSelectorType = 1;
4429 } else if (l = checkCompoundSelector2(i)) {
4430 tokens[i].compoundSelectorType = 2;
4436 function getCompoundSelector() {
4437 var type = tokens[pos].compoundSelectorType;
4438 if (type === 1) return getCompoundSelector1();
4439 if (type === 2) return getCompoundSelector2();
4442 function checkCompoundSelector1(i) {
4443 if (i >= tokensLength) return 0;
4448 if (l = checkUniversalSelector(i) || checkTypeSelector(i)) i += l;else return 0;
4450 while (i < tokensLength) {
4451 var _l2 = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i);
4452 if (_l2) i += _l2;else break;
4455 tokens[start].compoundSelectorEnd = i;
4460 function getCompoundSelector1() {
4462 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
4464 if (checkUniversalSelector(pos)) sequence.push(getUniversalSelector());else sequence.push(getTypeSelector());
4466 while (pos < compoundSelectorEnd) {
4467 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());
4473 function checkCompoundSelector2(i) {
4474 if (i >= tokensLength) return 0;
4478 while (i < tokensLength) {
4479 var l = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i);
4481 if (l) i += l;else break;
4484 tokens[start].compoundSelectorEnd = i;
4489 function getCompoundSelector2() {
4491 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
4493 while (pos < compoundSelectorEnd) {
4494 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());else break;
4500 function checkUniversalSelector(i) {
4501 if (i >= tokensLength) return 0;
4506 if (l = checkNamePrefix(i)) i += l;
4508 if (tokens[i].type === TokenType.Asterisk) i++;else return 0;
4513 function getUniversalSelector() {
4514 var type = NodeType.UniversalSelectorType;
4515 var token = tokens[pos];
4516 var line = token.ln;
4517 var column = token.col;
4521 if (checkNamePrefix(pos)) {
4522 content.push(getNamePrefix());
4523 end = getLastPosition(content, line, column, 1);
4528 return newNode(type, content, line, column, end);
4531 function checkTypeSelector(i) {
4532 if (i >= tokensLength) return 0;
4537 if (l = checkNamePrefix(i)) i += l;
4539 if (l = checkIdent(i)) i += l;else return 0;
4544 function getTypeSelector() {
4545 var type = NodeType.TypeSelectorType;
4546 var token = tokens[pos];
4547 var line = token.ln;
4548 var column = token.col;
4551 if (checkNamePrefix(pos)) content.push(getNamePrefix());
4553 content.push(getIdent());
4555 return newNode(type, content, line, column);
4558 function checkAttributeSelector(i) {
4560 if (l = checkAttributeSelector1(i)) tokens[i].attributeSelectorType = 1;else if (l = checkAttributeSelector2(i)) tokens[i].attributeSelectorType = 2;
4565 function getAttributeSelector() {
4566 var type = tokens[pos].attributeSelectorType;
4567 if (type === 1) return getAttributeSelector1();else return getAttributeSelector2();
4571 * (1) `[panda=nani]`
4572 * (2) `[panda='nani']`
4573 * (3) `[panda='nani' i]`
4576 function checkAttributeSelector1(i) {
4579 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
4582 if (l = checkSC(i)) i += l;
4584 if (l = checkAttributeName(i)) i += l;else return 0;
4586 if (l = checkSC(i)) i += l;
4588 if (l = checkAttributeMatch(i)) i += l;else return 0;
4590 if (l = checkSC(i)) i += l;
4592 if (l = checkAttributeValue(i)) i += l;else return 0;
4594 if (l = checkSC(i)) i += l;
4596 if (l = checkAttributeFlags(i)) {
4598 if (l = checkSC(i)) i += l;
4601 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
4606 function getAttributeSelector1() {
4607 var type = NodeType.AttributeSelectorType;
4608 var token = tokens[pos];
4609 var line = token.ln;
4610 var column = token.col;
4616 content = content.concat(getSC(), getAttributeName(), getSC(), getAttributeMatch(), getSC(), getAttributeValue(), getSC());
4618 if (checkAttributeFlags(pos)) {
4619 content.push(getAttributeFlags());
4620 content = content.concat(getSC());
4626 var end = getLastPosition(content, line, column, 1);
4627 return newNode(type, content, line, column, end);
4633 function checkAttributeSelector2(i) {
4636 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
4639 if (l = checkSC(i)) i += l;
4641 if (l = checkAttributeName(i)) i += l;else return 0;
4643 if (l = checkSC(i)) i += l;
4645 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
4650 function getAttributeSelector2() {
4651 var type = NodeType.AttributeSelectorType;
4652 var token = tokens[pos];
4653 var line = token.ln;
4654 var column = token.col;
4660 content = content.concat(getSC(), getAttributeName(), getSC());
4665 var end = getLastPosition(content, line, column, 1);
4666 return newNode(type, content, line, column, end);
4669 function checkAttributeName(i) {
4673 if (l = checkNamePrefix(i)) i += l;
4675 if (l = checkIdent(i)) i += l;else return 0;
4680 function getAttributeName() {
4681 var type = NodeType.AttributeNameType;
4682 var token = tokens[pos];
4683 var line = token.ln;
4684 var column = token.col;
4687 if (checkNamePrefix(pos)) content.push(getNamePrefix());
4688 content.push(getIdent());
4690 return newNode(type, content, line, column);
4693 function checkAttributeMatch(i) {
4695 if (l = checkAttributeMatch1(i)) tokens[i].attributeMatchType = 1;else if (l = checkAttributeMatch2(i)) tokens[i].attributeMatchType = 2;
4700 function getAttributeMatch() {
4701 var type = tokens[pos].attributeMatchType;
4702 if (type === 1) return getAttributeMatch1();else return getAttributeMatch2();
4705 function checkAttributeMatch1(i) {
4708 var type = tokens[i].type;
4709 if (type === TokenType.Tilde || type === TokenType.VerticalLine || type === TokenType.CircumflexAccent || type === TokenType.DollarSign || type === TokenType.Asterisk) i++;else return 0;
4711 if (tokens[i].type === TokenType.EqualsSign) i++;else return 0;
4716 function getAttributeMatch1() {
4717 var type = NodeType.AttributeMatchType;
4718 var token = tokens[pos];
4719 var line = token.ln;
4720 var column = token.col;
4721 var content = tokens[pos].value + tokens[pos + 1].value;
4724 return newNode(type, content, line, column);
4727 function checkAttributeMatch2(i) {
4728 if (tokens[i].type === TokenType.EqualsSign) return 1;else return 0;
4731 function getAttributeMatch2() {
4732 var type = NodeType.AttributeMatchType;
4733 var token = tokens[pos];
4734 var line = token.ln;
4735 var column = token.col;
4739 return newNode(type, content, line, column);
4742 function checkAttributeValue(i) {
4743 return checkString(i) || checkIdent(i);
4746 function getAttributeValue() {
4747 var type = NodeType.AttributeValueType;
4748 var token = tokens[pos];
4749 var line = token.ln;
4750 var column = token.col;
4753 if (checkString(pos)) content.push(getString());else content.push(getIdent());
4755 return newNode(type, content, line, column);
4758 function checkAttributeFlags(i) {
4759 return checkIdent(i);
4762 function getAttributeFlags() {
4763 var type = NodeType.AttributeFlagsType;
4764 var token = tokens[pos];
4765 var line = token.ln;
4766 var column = token.col;
4767 var content = [getIdent()];
4769 return newNode(type, content, line, column);
4772 function checkNamePrefix(i) {
4773 if (i >= tokensLength) return 0;
4776 if (l = checkNamePrefix1(i)) tokens[i].namePrefixType = 1;else if (l = checkNamePrefix2(i)) tokens[i].namePrefixType = 2;
4781 function getNamePrefix() {
4782 var type = tokens[pos].namePrefixType;
4783 if (type === 1) return getNamePrefix1();else return getNamePrefix2();
4788 * (2) `panda<comment>|`
4790 function checkNamePrefix1(i) {
4794 if (l = checkNamespacePrefix(i)) i += l;else return 0;
4796 if (l = checkCommentML(i)) i += l;
4798 if (l = checkNamespaceSeparator(i)) i += l;else return 0;
4803 function getNamePrefix1() {
4804 var type = NodeType.NamePrefixType;
4805 var token = tokens[pos];
4806 var line = token.ln;
4807 var column = token.col;
4810 content.push(getNamespacePrefix());
4812 if (checkCommentML(pos)) content.push(getCommentML());
4814 content.push(getNamespaceSeparator());
4816 return newNode(type, content, line, column);
4822 function checkNamePrefix2(i) {
4823 return checkNamespaceSeparator(i);
4826 function getNamePrefix2() {
4827 var type = NodeType.NamePrefixType;
4828 var token = tokens[pos];
4829 var line = token.ln;
4830 var column = token.col;
4831 var content = [getNamespaceSeparator()];
4833 return newNode(type, content, line, column);
4840 function checkNamespacePrefix(i) {
4841 if (i >= tokensLength) return 0;
4845 if (tokens[i].type === TokenType.Asterisk) return 1;else if (l = checkIdent(i)) return l;else return 0;
4848 function getNamespacePrefix() {
4849 var type = NodeType.NamespacePrefixType;
4850 var token = tokens[pos];
4851 var line = token.ln;
4852 var column = token.col;
4855 if (token.type === TokenType.Asterisk) {
4856 var asteriskNode = newNode(NodeType.IdentType, '*', line, column);
4857 content.push(asteriskNode);
4859 } else if (checkIdent(pos)) content.push(getIdent());
4861 return newNode(type, content, line, column);
4867 function checkNamespaceSeparator(i) {
4868 if (i >= tokensLength) return 0;
4870 if (tokens[i].type !== TokenType.VerticalLine) return 0;
4872 // Return false if `|=` - [attr|=value]
4873 if (tokens[i + 1] && tokens[i + 1].type === TokenType.EqualsSign) return 0;
4878 function getNamespaceSeparator() {
4879 var type = NodeType.NamespaceSeparatorType;
4880 var token = tokens[pos];
4881 var line = token.ln;
4882 var column = token.col;
4886 return newNode(type, content, line, column);
4889 module.exports = function (_tokens, context) {
4891 tokensLength = tokens.length;
4894 return contexts[context]();
4899 /***/ (function(module, exports) {
4904 ArgumentsType: 'arguments',
4905 AtkeywordType: 'atkeyword',
4906 AtruleType: 'atrule',
4907 AttributeSelectorType: 'attributeSelector',
4908 AttributeNameType: 'attributeName',
4909 AttributeFlagsType: 'attributeFlags',
4910 AttributeMatchType: 'attributeMatch',
4911 AttributeValueType: 'attributeValue',
4913 BracketsType: 'brackets',
4915 CombinatorType: 'combinator',
4916 CommentMLType: 'multilineComment',
4917 CommentSLType: 'singlelineComment',
4918 ConditionType: 'condition',
4919 ConditionalStatementType: 'conditionalStatement',
4920 CustomPropertyType: 'customProperty',
4921 DeclarationType: 'declaration',
4922 DeclDelimType: 'declarationDelimiter',
4923 DefaultType: 'default',
4924 DelimType: 'delimiter',
4925 DimensionType: 'dimension',
4926 EscapedStringType: 'escapedString',
4927 ExtendType: 'extend',
4928 ExpressionType: 'expression',
4929 FunctionType: 'function',
4930 FunctionsListType: 'functionsList',
4931 GlobalType: 'global',
4933 ImportantType: 'important',
4934 IncludeType: 'include',
4935 InterpolationType: 'interpolation',
4936 InterpolatedVariableType: 'interpolatedVariable',
4937 KeyframesSelectorType: 'keyframesSelector',
4940 NamePrefixType: 'namePrefix',
4941 NamespacePrefixType: 'namespacePrefix',
4942 NamespaceSeparatorType: 'namespaceSeparator',
4943 NumberType: 'number',
4944 OperatorType: 'operator',
4945 OptionalType: 'optional',
4946 ParenthesesType: 'parentheses',
4947 ParentSelectorType: 'parentSelector',
4948 ParentSelectorExtensionType: 'parentSelectorExtension',
4949 PercentageType: 'percentage',
4950 PlaceholderType: 'placeholder',
4951 ProgidType: 'progid',
4952 PropertyType: 'property',
4953 PropertyDelimType: 'propertyDelimiter',
4954 PseudocType: 'pseudoClass',
4955 PseudoeType: 'pseudoElement',
4957 RulesetType: 'ruleset',
4959 SelectorType: 'selector',
4961 StringType: 'string',
4962 StylesheetType: 'stylesheet',
4963 TypeSelectorType: 'typeSelector',
4964 UnicodeRangeType: 'unicodeRange',
4965 UniversalSelectorType: 'universalSelector',
4967 UrangeType: 'urange',
4969 VariableType: 'variable',
4970 VariablesListType: 'variablesList',
4976 /***/ (function(module, exports, __webpack_require__) {
4980 module.exports = function (css, tabSize) {
4981 var TokenType = __webpack_require__(13);
4984 var urlMode = false;
4993 ' ': TokenType.Space,
4994 '\n': TokenType.Newline,
4995 '\r': TokenType.Newline,
4996 '\t': TokenType.Tab,
4997 '!': TokenType.ExclamationMark,
4998 '"': TokenType.QuotationMark,
4999 '#': TokenType.NumberSign,
5000 '$': TokenType.DollarSign,
5001 '%': TokenType.PercentSign,
5002 '&': TokenType.Ampersand,
5003 '\'': TokenType.Apostrophe,
5004 '(': TokenType.LeftParenthesis,
5005 ')': TokenType.RightParenthesis,
5006 '*': TokenType.Asterisk,
5007 '+': TokenType.PlusSign,
5008 ',': TokenType.Comma,
5009 '-': TokenType.HyphenMinus,
5010 '.': TokenType.FullStop,
5011 '/': TokenType.Solidus,
5012 ':': TokenType.Colon,
5013 ';': TokenType.Semicolon,
5014 '<': TokenType.LessThanSign,
5015 '=': TokenType.EqualsSign,
5016 '>': TokenType.GreaterThanSign,
5017 '?': TokenType.QuestionMark,
5018 '@': TokenType.CommercialAt,
5019 '[': TokenType.LeftSquareBracket,
5020 ']': TokenType.RightSquareBracket,
5021 '^': TokenType.CircumflexAccent,
5022 '_': TokenType.LowLine,
5023 '{': TokenType.LeftCurlyBracket,
5024 '|': TokenType.VerticalLine,
5025 '}': TokenType.RightCurlyBracket,
5026 '~': TokenType.Tilde
5030 * Add a token to the token list
5031 * @param {string} type
5032 * @param {string} value
5034 function pushToken(type, value, column) {
5045 * Check if a character is a decimal digit
5046 * @param {string} c Character
5047 * @returns {boolean}
5049 function isDecimalDigit(c) {
5050 return '0123456789'.indexOf(c) >= 0;
5055 * @param {string} css Unparsed part of CSS string
5057 function parseSpaces(css) {
5060 // Read the string until we meet a non-space character:
5061 for (; pos < cssLength; pos++) {
5062 if (css.charAt(pos) !== ' ') break;
5065 // Add a substring containing only spaces to tokens:
5066 pushToken(TokenType.Space, css.substring(start, pos--), col);
5071 * Parse a string within quotes
5072 * @param {string} css Unparsed part of CSS string
5073 * @param {string} q Quote (either `'` or `"`)
5075 function parseString(css, q) {
5078 // Read the string until we meet a matching quote:
5079 for (pos++; pos < cssLength; pos++) {
5080 // Skip escaped quotes:
5081 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) === q) break;
5084 // Add the string (including quotes) to tokens:
5085 pushToken(q === '"' ? TokenType.StringDQ : TokenType.StringSQ, css.substring(start, pos + 1), col);
5091 * @param {string} css Unparsed part of CSS string
5093 function parseDecimalNumber(css) {
5096 // Read the string until we meet a character that's not a digit:
5097 for (; pos < cssLength; pos++) {
5098 if (!isDecimalDigit(css.charAt(pos))) break;
5101 // Add the number to tokens:
5102 pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);
5108 * @param {string} css Unparsed part of CSS string
5110 function parseIdentifier(css) {
5113 // Skip all opening slashes:
5114 while (css.charAt(pos) === '/') {
5116 } // Read the string until we meet a punctuation mark:
5117 for (; pos < cssLength; pos++) {
5119 if (css.charAt(pos) === '\\') pos++;else if (Punctuation[css.charAt(pos)]) break;
5122 var ident = css.substring(start, pos--);
5124 // Enter url mode if parsed substring is `url`:
5125 urlMode = urlMode || ident === 'url';
5127 // Add identifier to tokens:
5128 pushToken(TokenType.Identifier, ident, col);
5133 * Parse a multiline comment
5134 * @param {string} css Unparsed part of CSS string
5136 function parseMLComment(css) {
5139 // Read the string until we meet `*/`.
5140 // Since we already know first 2 characters (`/*`), start reading
5142 for (pos = pos + 2; pos < cssLength; pos++) {
5143 if (css.charAt(pos) === '*' && css.charAt(pos + 1) === '/') {
5149 // Add full comment (including `/*` and `*/`) to the list of tokens:
5150 var comment = css.substring(start, pos + 1);
5151 pushToken(TokenType.CommentML, comment, col);
5153 var newlines = comment.split('\n');
5154 if (newlines.length > 1) {
5155 ln += newlines.length - 1;
5156 col = newlines[newlines.length - 1].length;
5162 function parseSLComment(css) {
5165 // Read the string until we meet line break.
5166 // Since we already know first 2 characters (`//`), start reading
5168 for (pos += 2; pos < cssLength; pos++) {
5169 if (css.charAt(pos) === '\n' || css.charAt(pos) === '\r') {
5174 // Add comment (including `//` and line break) to the list of tokens:
5175 pushToken(TokenType.CommentSL, css.substring(start, pos--), col);
5180 * Convert a CSS string to a list of tokens
5181 * @param {string} css CSS string
5182 * @returns {Array} List of tokens
5185 function getTokens(css) {
5186 var c; // Current character
5187 var cn; // Next character
5189 cssLength = css.length;
5191 // Parse string, character by character:
5192 for (pos = 0; pos < cssLength; col++, pos++) {
5193 c = css.charAt(pos);
5194 cn = css.charAt(pos + 1);
5196 // If we meet `/*`, it's a start of a multiline comment.
5197 // Parse following characters as a multiline comment:
5198 if (c === '/' && cn === '*') {
5199 parseMLComment(css);
5202 // If we meet `//` and it is not a part of url:
5203 else if (!urlMode && c === '/' && cn === '/') {
5204 // If we're currently inside a block, treat `//` as a start
5205 // of identifier. Else treat `//` as a start of a single-line
5207 if (blockMode > 0) parseIdentifier(css);else parseSLComment(css);
5210 // If current character is a double or single quote, it's a start
5212 else if (c === '"' || c === "'") {
5213 parseString(css, c);
5216 // If current character is a space:
5217 else if (c === ' ') {
5221 // If current character is a punctuation mark:
5222 else if (Punctuation[c]) {
5223 // Add it to the list of tokens:
5224 pushToken(Punctuation[c], c, col);
5225 if (c === '\n' || c === '\r') {
5228 } // Go to next line
5229 else if (c === ')') urlMode = false; // Exit url mode
5230 else if (c === '{') blockMode++; // Enter a block
5231 else if (c === '}') blockMode--; // Exit a block
5232 else if (c === '\t' && tabSize > 1) col += tabSize - 1;
5235 // If current character is a decimal digit:
5236 else if (isDecimalDigit(c)) {
5237 parseDecimalNumber(css);
5240 // If current character is anything else:
5242 parseIdentifier(css);
5249 return getTokens(css);
5254 /***/ (function(module, exports, __webpack_require__) {
5258 exports.__esModule = true;
5260 mark: __webpack_require__(18),
5261 parse: __webpack_require__(19),
5262 stringify: __webpack_require__(4),
5263 tokenizer: __webpack_require__(20)
5265 module.exports = exports['default'];
5269 /***/ (function(module, exports, __webpack_require__) {
5273 var TokenType = __webpack_require__(13);
5275 module.exports = function () {
5277 * Mark whitespaces and comments
5279 function markSC(tokens) {
5280 var tokensLength = tokens.length;
5281 var ws = -1; // Flag for whitespaces
5282 var sc = -1; // Flag for whitespaces and comments
5283 var t = void 0; // Current token
5285 // For every token in the token list, mark spaces and line breaks
5286 // as spaces (set both `ws` and `sc` flags). Mark multiline comments
5288 // If there are several spaces or tabs or line breaks or multiline
5289 // comments in a row, group them: take the last one's index number
5290 // and save it to the first token in the group as a reference:
5291 // e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
5292 // for a group of whitespaces and comments.
5293 for (var i = 0; i < tokensLength; i++) {
5296 case TokenType.Space:
5298 case TokenType.Newline:
5302 if (ws === -1) ws = i;
5303 if (sc === -1) sc = i;
5306 case TokenType.CommentML:
5307 case TokenType.CommentSL:
5309 tokens[ws].ws_last = i - 1;
5318 tokens[ws].ws_last = i - 1;
5323 tokens[sc].sc_last = i - 1;
5329 if (ws !== -1) tokens[ws].ws_last = i - 1;
5330 if (sc !== -1) tokens[sc].sc_last = i - 1;
5336 function markBrackets(tokens) {
5337 var tokensLength = tokens.length;
5338 var ps = []; // Parentheses
5339 var sbs = []; // Square brackets
5340 var cbs = []; // Curly brackets
5341 var t = void 0; // Current token
5343 // For every token in the token list, if we meet an opening (left)
5344 // bracket, push its index number to a corresponding array.
5345 // If we then meet a closing (right) bracket, look at the corresponding
5346 // array. If there are any elements (records about previously met
5347 // left brackets), take a token of the last left bracket (take
5348 // the last index number from the array and find a token with
5349 // this index number) and save right bracket's index as a reference:
5350 for (var i = 0; i < tokensLength; i++) {
5353 case TokenType.LeftParenthesis:
5356 case TokenType.RightParenthesis:
5359 tokens[t.left].right = i;
5362 case TokenType.LeftSquareBracket:
5365 case TokenType.RightSquareBracket:
5368 tokens[t.left].right = i;
5371 case TokenType.LeftCurlyBracket:
5374 case TokenType.RightCurlyBracket:
5377 tokens[t.left].right = i;
5384 return function (tokens) {
5385 markBrackets(tokens);
5392 /***/ (function(module, exports, __webpack_require__) {
5396 var Node = __webpack_require__(1);
5397 var NodeType = __webpack_require__(15);
5398 var TokenType = __webpack_require__(13);
5400 var tokens = void 0;
5401 var tokensLength = void 0;
5405 'arguments': function _arguments() {
5406 return checkArguments(pos) && getArguments();
5408 'atkeyword': function atkeyword() {
5409 return checkAtkeyword(pos) && getAtkeyword();
5411 'atrule': function atrule() {
5412 return checkAtrule(pos) && getAtrule();
5414 'attributeSelector': function attributeSelector() {
5415 return checkAttributeSelector(pos) && getAttributeSelector();
5417 'block': function block() {
5418 return checkBlock(pos) && getBlock();
5420 'brackets': function brackets() {
5421 return checkBrackets(pos) && getBrackets();
5423 'class': function _class() {
5424 return checkClass(pos) && getClass();
5426 'combinator': function combinator() {
5427 return checkCombinator(pos) && getCombinator();
5429 'commentML': function commentML() {
5430 return checkCommentML(pos) && getCommentML();
5432 'commentSL': function commentSL() {
5433 return checkCommentSL(pos) && getCommentSL();
5435 'condition': function condition() {
5436 return checkCondition(pos) && getCondition();
5438 'declaration': function declaration() {
5439 return checkDeclaration(pos) && getDeclaration();
5441 'declDelim': function declDelim() {
5442 return checkDeclDelim(pos) && getDeclDelim();
5444 'delim': function delim() {
5445 return checkDelim(pos) && getDelim();
5447 'dimension': function dimension() {
5448 return checkDimension(pos) && getDimension();
5450 'escapedString': function escapedString() {
5451 return checkEscapedString(pos) && getEscapedString();
5453 'expression': function expression() {
5454 return checkExpression(pos) && getExpression();
5456 'extend': function extend() {
5457 return checkExtend(pos) && getExtend();
5459 'function': function _function() {
5460 return checkFunction(pos) && getFunction();
5462 'ident': function ident() {
5463 return checkIdent(pos) && getIdent();
5465 'important': function important() {
5466 return checkImportant(pos) && getImportant();
5468 'include': function include() {
5469 return checkInclude(pos) && getInclude();
5471 'interpolatedVariable': function interpolatedVariable() {
5472 return checkInterpolatedVariable(pos) && getInterpolatedVariable();
5474 'mixin': function mixin() {
5475 return checkMixin(pos) && getMixin();
5477 'namespace': function namespace() {
5478 return checkNamespace(pos) && getNamespace();
5480 'number': function number() {
5481 return checkNumber(pos) && getNumber();
5483 'operator': function operator() {
5484 return checkOperator(pos) && getOperator();
5486 'parentheses': function parentheses() {
5487 return checkParentheses(pos) && getParentheses();
5489 'parentselector': function parentselector() {
5490 return checkParentSelector(pos) && getParentSelector();
5492 'percentage': function percentage() {
5493 return checkPercentage(pos) && getPercentage();
5495 'progid': function progid() {
5496 return checkProgid(pos) && getProgid();
5498 'property': function property() {
5499 return checkProperty(pos) && getProperty();
5501 'propertyDelim': function propertyDelim() {
5502 return checkPropertyDelim(pos) && getPropertyDelim();
5504 'pseudoc': function pseudoc() {
5505 return checkPseudoc(pos) && getPseudoc();
5507 'pseudoe': function pseudoe() {
5508 return checkPseudoe(pos) && getPseudoe();
5510 'ruleset': function ruleset() {
5511 return checkRuleset(pos) && getRuleset();
5514 return checkS(pos) && getS();
5516 'selector': function selector() {
5517 return checkSelector(pos) && getSelector();
5519 'shash': function shash() {
5520 return checkShash(pos) && getShash();
5522 'string': function string() {
5523 return checkString(pos) && getString();
5525 'stylesheet': function stylesheet() {
5526 return checkStylesheet(pos) && getStylesheet();
5528 'unary': function unary() {
5529 return checkUnary(pos) && getUnary();
5531 'unicodeRange': function unicodeRange() {
5532 return checkUnicodeRange(pos) && getUnicodeRange();
5534 'universalSelector': function universalSelector() {
5535 return checkUniversalSelector(pos) && getUniversalSelector();
5537 'urange': function urange() {
5538 return checkUrange(pos) && getUrange();
5540 'uri': function uri() {
5541 return checkUri(pos) && getUri();
5543 'value': function value() {
5544 return checkValue(pos) && getValue();
5546 'variable': function variable() {
5547 return checkVariable(pos) && getVariable();
5549 'variableslist': function variableslist() {
5550 return checkVariablesList(pos) && getVariablesList();
5552 'vhash': function vhash() {
5553 return checkVhash(pos) && getVhash();
5558 * Stop parsing and display error
5559 * @param {Number=} i Token's index number
5561 function throwError(i) {
5562 var ln = tokens[i].ln;
5564 throw { line: ln, syntax: 'less' };
5568 * @param {Object} exclude
5569 * @param {Number} i Token's index number
5572 function checkExcluding(exclude, i) {
5575 while (i < tokensLength) {
5576 if (exclude[tokens[i++].type]) break;
5579 return i - start - 2;
5583 * @param {Number} start
5584 * @param {Number} finish
5587 function joinValues(start, finish) {
5590 for (var i = start; i < finish + 1; i++) {
5591 s += tokens[i].value;
5598 * @param {Number} start
5599 * @param {Number} num
5602 function joinValues2(start, num) {
5603 if (start + num - 1 >= tokensLength) return;
5607 for (var i = 0; i < num; i++) {
5608 s += tokens[start + i].value;
5614 function getLastPosition(content, line, column, colOffset) {
5615 return typeof content === 'string' ? getLastPositionForString(content, line, column, colOffset) : getLastPositionForArray(content, line, column, colOffset);
5618 function getLastPositionForString(content, line, column, colOffset) {
5622 position = [line, column];
5623 if (colOffset) position[1] += colOffset - 1;
5627 var lastLinebreak = content.lastIndexOf('\n');
5628 var endsWithLinebreak = lastLinebreak === content.length - 1;
5629 var splitContent = content.split('\n');
5630 var linebreaksCount = splitContent.length - 1;
5631 var prevLinebreak = linebreaksCount === 0 || linebreaksCount === 1 ? -1 : content.length - splitContent[linebreaksCount - 1].length - 2;
5634 var offset = endsWithLinebreak ? linebreaksCount - 1 : linebreaksCount;
5635 position[0] = line + offset;
5638 if (endsWithLinebreak) {
5639 offset = prevLinebreak !== -1 ? content.length - prevLinebreak : content.length - 1;
5641 offset = linebreaksCount !== 0 ? content.length - lastLinebreak - column - 1 : content.length - 1;
5643 position[1] = column + offset;
5645 if (!colOffset) return position;
5647 if (endsWithLinebreak) {
5649 position[1] = colOffset;
5651 position[1] += colOffset;
5657 function getLastPositionForArray(content, line, column, colOffset) {
5658 var position = void 0;
5660 if (content.length === 0) {
5661 position = [line, column];
5663 var c = content[content.length - 1];
5664 if (c.hasOwnProperty('end')) {
5665 position = [c.end.line, c.end.column];
5667 position = getLastPosition(c.content, line, column);
5671 if (!colOffset) return position;
5673 if (tokens[pos - 1] && tokens[pos - 1].type !== 'Newline') {
5674 position[1] += colOffset;
5683 function newNode(type, content, line, column, end) {
5684 if (!end) end = getLastPosition(content, line, column);
5701 * @param {Number} i Token's index number
5704 function checkAny(i) {
5707 if (l = checkBrackets(i)) tokens[i].any_child = 1;else if (l = checkParentheses(i)) tokens[i].any_child = 2;else if (l = checkString(i)) tokens[i].any_child = 3;else if (l = checkVariablesList(i)) tokens[i].any_child = 4;else if (l = checkVariable(i)) tokens[i].any_child = 5;else if (l = checkPercentage(i)) tokens[i].any_child = 6;else if (l = checkDimension(i)) tokens[i].any_child = 7;else if (l = checkUnicodeRange(i)) tokens[i].any_child = 15;else if (l = checkNumber(i)) tokens[i].any_child = 8;else if (l = checkUri(i)) tokens[i].any_child = 9;else if (l = checkExpression(i)) tokens[i].any_child = 10;else if (l = checkFunction(i)) tokens[i].any_child = 11;else if (l = checkIdent(i)) tokens[i].any_child = 12;else if (l = checkClass(i)) tokens[i].any_child = 13;else if (l = checkUnary(i)) tokens[i].any_child = 14;
5716 var childType = tokens[pos].any_child;
5718 if (childType === 1) return getBrackets();
5719 if (childType === 2) return getParentheses();
5720 if (childType === 3) return getString();
5721 if (childType === 4) return getVariablesList();
5722 if (childType === 5) return getVariable();
5723 if (childType === 6) return getPercentage();
5724 if (childType === 7) return getDimension();
5725 if (childType === 15) return getUnicodeRange();
5726 if (childType === 8) return getNumber();
5727 if (childType === 9) return getUri();
5728 if (childType === 10) return getExpression();
5729 if (childType === 11) return getFunction();
5730 if (childType === 12) return getIdent();
5731 if (childType === 13) return getClass();
5732 if (childType === 14) return getUnary();
5736 * Check if token is part of mixin's arguments.
5737 * @param {Number} i Token's index number
5740 function checkArguments(i) {
5744 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
5749 while (i < tokens[start].right) {
5750 if (l = checkArgument(i)) i += l;else return 0;
5753 return tokens[start].right - start + 1;
5759 function getArguments() {
5760 var type = NodeType.ArgumentsType;
5761 var token = tokens[pos];
5762 var line = token.ln;
5763 var column = token.col;
5770 while (pos < tokensLength && tokens[pos].type !== TokenType.RightParenthesis) {
5771 if (checkDeclaration(pos)) content.push(getDeclaration());else if (checkArgument(pos)) {
5772 body = getArgument();
5773 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
5774 } else if (checkClass(pos)) content.push(getClass());else throwError(pos);
5777 var end = getLastPosition(content, line, column, 1);
5782 return newNode(type, content, line, column, end);
5786 * Check if token is valid to be part of arguments list.
5787 * @param {Number} i Token's index number
5790 function checkArgument(i) {
5793 if (l = checkEscapedString(i)) tokens[i].argument_child = 1;else if (l = checkDeclaration(i)) tokens[i].argument_child = 2;else if (l = checkVariablesList(i)) tokens[i].argument_child = 3;else if (l = checkVariable(i)) tokens[i].argument_child = 4;else if (l = checkSC(i)) tokens[i].argument_child = 5;else if (l = checkUnary(i)) tokens[i].argument_child = 6;else if (l = checkOperator(i)) tokens[i].argument_child = 7;else if (l = checkDelim(i)) tokens[i].argument_child = 8;else if (l = checkDeclDelim(i)) tokens[i].argument_child = 9;else if (l = checkString(i)) tokens[i].argument_child = 10;else if (l = checkPercentage(i)) tokens[i].argument_child = 11;else if (l = checkDimension(i)) tokens[i].argument_child = 12;else if (l = checkNumber(i)) tokens[i].argument_child = 13;else if (l = checkUri(i)) tokens[i].argument_child = 14;else if (l = checkFunction(i)) tokens[i].argument_child = 15;else if (l = checkIdent(i)) tokens[i].argument_child = 16;else if (l = checkVhash(i)) tokens[i].argument_child = 17;else if (l = checkBlock(i)) tokens[i].argument_child = 18;else if (l = checkParentheses(i)) tokens[i].argument_child = 19;
5799 * @returns {Array} Node that is part of arguments list.
5801 function getArgument() {
5802 var childType = tokens[pos].argument_child;
5804 if (childType === 1) return getEscapedString();
5805 if (childType === 2) return getDeclaration();
5806 if (childType === 3) return getVariablesList();
5807 if (childType === 4) return getVariable();
5808 if (childType === 5) return getSC();
5809 if (childType === 6) return getUnary();
5810 if (childType === 7) return getOperator();
5811 if (childType === 8) return getDelim();
5812 if (childType === 9) return getDeclDelim();
5813 if (childType === 10) return getString();
5814 if (childType === 11) return getPercentage();
5815 if (childType === 12) return getDimension();
5816 if (childType === 13) return getNumber();
5817 if (childType === 14) return getUri();
5818 if (childType === 15) return getFunction();
5819 if (childType === 16) return getIdent();
5820 if (childType === 17) return getVhash();
5821 if (childType === 18) return getBlock();
5822 if (childType === 19) return getParentheses();
5826 * Check if token is part of an @-word (e.g. `@import`, `@include`)
5827 * @param {Number} i Token's index number
5830 function checkAtkeyword(i) {
5833 // Check that token is `@`:
5834 if (i >= tokensLength || tokens[i++].type !== TokenType.CommercialAt) return 0;
5836 return (l = checkIdent(i)) ? l + 1 : 0;
5840 * Get node with @-word
5841 * @returns {Array} `['atkeyword', ['ident', x]]` where `x` is
5842 * an identifier without
5843 * `@` (e.g. `import`, `include`)
5845 function getAtkeyword() {
5846 var type = NodeType.AtkeywordType;
5847 var token = tokens[pos];
5848 var line = token.ln;
5849 var column = token.col;
5854 var content = [getIdent()];
5856 return newNode(type, content, line, column);
5860 * Check if token is a part of an @-rule
5861 * @param {Number} i Token's index number
5862 * @returns {Number} Length of @-rule
5864 function checkAtrule(i) {
5867 if (i >= tokensLength) return 0;
5869 // If token already has a record of being part of an @-rule,
5870 // return the @-rule's length:
5871 if (tokens[i].atrule_l !== undefined) return tokens[i].atrule_l;
5873 // If token is part of an @-rule, save the rule's type to token.
5874 if (l = checkKeyframesRule(i)) tokens[i].atrule_type = 4;
5875 // @-rule with ruleset:
5876 else if (l = checkAtruler(i)) tokens[i].atrule_type = 1;
5878 else if (l = checkAtruleb(i)) tokens[i].atrule_type = 2;
5879 // Single-line @-rule:
5880 else if (l = checkAtrules(i)) tokens[i].atrule_type = 3;else return 0;
5882 // If token is part of an @-rule, save the rule's length to token:
5883 tokens[i].atrule_l = l;
5889 * Get node with @-rule
5892 function getAtrule() {
5893 var childType = tokens[pos].atrule_type;
5895 if (childType === 1) return getAtruler(); // @-rule with ruleset
5896 if (childType === 2) return getAtruleb(); // Block @-rule
5897 if (childType === 3) return getAtrules(); // Single-line @-rule
5898 if (childType === 4) return getKeyframesRule();
5902 * Check if token is part of a block @-rule
5903 * @param {Number} i Token's index number
5904 * @returns {Number} Length of the @-rule
5906 function checkAtruleb(i) {
5910 if (i >= tokensLength) return 0;
5912 if (l = checkAtkeyword(i)) i += l;else return 0;
5914 if (l = checkTsets(i)) i += l;
5916 if (l = checkBlock(i)) i += l;else return 0;
5922 * Get node with a block @-rule
5923 * @returns {Array} `['atruleb', ['atkeyword', x], y, ['block', z]]`
5925 function getAtruleb() {
5926 var type = NodeType.AtruleType;
5927 var token = tokens[pos];
5928 var line = token.ln;
5929 var column = token.col;
5930 var content = [].concat(getAtkeyword(), getTsets(), getBlock());
5932 return newNode(type, content, line, column);
5936 * Check if token is part of an @-rule with ruleset
5937 * @param {Number} i Token's index number
5938 * @returns {Number} Length of the @-rule
5940 function checkAtruler(i) {
5944 if (i >= tokensLength) return 0;
5946 if (l = checkAtkeyword(i)) i += l;else return 0;
5948 if (l = checkTsets(i)) i += l;
5950 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
5952 if (l = checkAtrulers(i)) i += l;
5954 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
5960 * Get node with an @-rule with ruleset
5961 * @returns {Array} ['atruler', ['atkeyword', x], y, z]
5963 function getAtruler() {
5964 var type = NodeType.AtruleType;
5965 var token = tokens[pos];
5966 var line = token.ln;
5967 var column = token.col;
5968 var content = [].concat(getAtkeyword(), getTsets(), getAtrulers());
5970 return newNode(type, content, line, column);
5974 * @param {Number} i Token's index number
5977 function checkAtrulers(i) {
5981 if (i >= tokensLength) return 0;
5983 if (l = checkSC(i)) i += l;
5985 while (i < tokensLength) {
5986 if (l = checkSC(i)) tokens[i].atrulers_child = 1;else if (l = checkAtrule(i)) tokens[i].atrulers_child = 2;else if (l = checkRuleset(i)) tokens[i].atrulers_child = 3;else break;
5990 if (i < tokensLength) tokens[i].atrulers_end = 1;
5992 if (l = checkSC(i)) i += l;
5998 * @returns {Array} `['atrulers', x]`
6000 function getAtrulers() {
6001 var type = NodeType.BlockType;
6002 var token = tokens[pos];
6003 var line = token.ln;
6004 var column = token.col;
6010 content = content.concat(getSC());
6012 while (pos < tokensLength && !tokens[pos].atrulers_end) {
6013 var childType = tokens[pos].atrulers_child;
6014 if (childType === 1) content = content.concat(getSC());else if (childType === 2) content.push(getAtrule());else if (childType === 3) content.push(getRuleset());else break;
6017 content = content.concat(getSC());
6019 var end = getLastPosition(content, line, column, 1);
6024 return newNode(type, content, line, column, end);
6028 * @param {Number} i Token's index number
6031 function checkAtrules(i) {
6035 if (i >= tokensLength) return 0;
6037 if (l = checkAtkeyword(i)) i += l;else return 0;
6039 if (l = checkTsets(i)) i += l;
6045 * @returns {Array} `['atrules', ['atkeyword', x], y]`
6047 function getAtrules() {
6048 var type = NodeType.AtruleType;
6049 var token = tokens[pos];
6050 var line = token.ln;
6051 var column = token.col;
6052 var content = [].concat(getAtkeyword(), getTsets());
6054 return newNode(type, content, line, column);
6058 * Check if token is part of a block (e.g. `{...}`).
6059 * @param {Number} i Token's index number
6060 * @returns {Number} Length of the block
6062 function checkBlock(i) {
6063 return i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket ? tokens[i].right - i + 1 : 0;
6067 * Get node with a block
6068 * @returns {Array} `['block', x]`
6070 function getBlock() {
6071 var type = NodeType.BlockType;
6072 var token = tokens[pos];
6073 var line = token.ln;
6074 var column = token.col;
6075 var end = tokens[pos].right;
6082 if (checkBlockdecl(pos)) content = content.concat(getBlockdecl());else throwError(pos);
6085 var end_ = getLastPosition(content, line, column, 1);
6088 return newNode(type, content, line, column, end_);
6092 * Check if token is part of a declaration (property-value pair)
6093 * @param {Number} i Token's index number
6094 * @returns {Number} Length of the declaration
6096 function checkBlockdecl(i) {
6099 if (i >= tokensLength) return 0;
6101 if (l = checkBlockdecl1(i)) tokens[i].bd_type = 1;else if (l = checkBlockdecl2(i)) tokens[i].bd_type = 2;else if (l = checkBlockdecl3(i)) tokens[i].bd_type = 3;else if (l = checkBlockdecl4(i)) tokens[i].bd_type = 4;else return 0;
6109 function getBlockdecl() {
6110 var childType = tokens[pos].bd_type;
6112 if (childType === 1) return getBlockdecl1();
6113 if (childType === 2) return getBlockdecl2();
6114 if (childType === 3) return getBlockdecl3();
6115 if (childType === 4) return getBlockdecl4();
6119 * @param {Number} i Token's index number
6122 function checkBlockdecl1(i) {
6126 if (l = checkSC(i)) i += l;
6128 if (l = checkCondition(i)) tokens[i].bd_kind = 1;else if (l = checkExtend(i)) tokens[i].bd_kind = 6;else if (l = checkRuleset(i)) tokens[i].bd_kind = 2;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 3;else if (l = checkAtrule(i)) tokens[i].bd_kind = 4;else if (l = checkInclude(i)) tokens[i].bd_kind = 5;else return 0;
6132 if (i < tokensLength && (l = checkDeclDelim(i))) i += l;else return 0;
6134 if (l = checkSC(i)) i += l;else return 0;
6142 function getBlockdecl1() {
6144 var content = void 0;
6146 switch (tokens[pos].bd_kind) {
6148 content = getCondition();
6151 content = getRuleset();
6154 content = getDeclaration();
6157 content = getAtrule();
6160 content = getInclude();
6163 content = getExtend();
6167 return sc.concat(content, getDeclDelim(), getSC());
6171 * @param {Number} i Token's index number
6174 function checkBlockdecl2(i) {
6178 if (l = checkSC(i)) i += l;
6180 if (l = checkCondition(i)) tokens[i].bd_kind = 1;else if (l = checkExtend(i)) tokens[i].bd_kind = 3;else if (l = checkRuleset(i)) tokens[i].bd_kind = 6;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 4;else if (l = checkAtrule(i)) tokens[i].bd_kind = 5;else if (l = checkInclude(i)) tokens[i].bd_kind = 2;else return 0;
6184 if (l = checkSC(i)) i += l;
6192 function getBlockdecl2() {
6194 var content = void 0;
6196 switch (tokens[pos].bd_kind) {
6198 content = getCondition();
6201 content = getInclude();
6204 content = getExtend();
6207 content = getDeclaration();
6210 content = getAtrule();
6213 content = getRuleset();
6217 return sc.concat(content, getSC());
6221 * @param {Number} i Token's index number
6224 function checkBlockdecl3(i) {
6228 if (l = checkSC(i)) i += l;
6230 if (l = checkDeclDelim(i)) i += l;else return 0;
6232 if (l = checkSC(i)) i += l;
6238 * @returns {Array} `[s0, ['declDelim'], s1]` where `s0` and `s1` are
6239 * are optional whitespaces.
6241 function getBlockdecl3() {
6242 return [].concat(getSC(), getDeclDelim(), getSC());
6246 * @param {Number} i Token's index number
6249 function checkBlockdecl4(i) {
6256 function getBlockdecl4() {
6261 * Check if token is part of text inside square brackets, e.g. `[1]`
6262 * @param {Number} i Token's index number
6265 function checkBrackets(i) {
6266 if (i >= tokensLength) return 0;
6271 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
6273 if (i < tokens[start].right) {
6274 var l = checkTsets(i);
6275 if (l) i += l;else return 0;
6285 * Get node with text inside square brackets, e.g. `[1]`
6288 function getBrackets() {
6289 var type = NodeType.BracketsType;
6290 var token = tokens[pos];
6291 var line = token.ln;
6292 var column = token.col;
6293 var right = token.right;
6300 content = getTsets();
6303 var end = getLastPosition(content, line, column, 1);
6308 return newNode(type, content, line, column, end);
6312 * Check if token is part of a class selector (e.g. `.abc`)
6313 * @param {Number} i Token's index number
6314 * @returns {Number} Length of the class selector
6316 function checkClass(i) {
6319 if (i >= tokensLength) return 0;
6321 if (tokens[i].class_l) return tokens[i].class_l;
6323 if (tokens[i++].type === TokenType.FullStop) {
6324 if (l = checkInterpolatedVariable(i)) tokens[i].class_child = 1;else if (l = checkIdent(i)) tokens[i].class_child = 2;else return 0;
6326 tokens[i].class_l = l + 1;
6334 * Get node with a class selector
6335 * @returns {Array} `['class', ['ident', x]]` where x is a class's
6336 * identifier (without `.`, e.g. `abc`).
6338 function getClass() {
6339 var type = NodeType.ClassType;
6340 var token = tokens[pos];
6341 var line = token.ln;
6342 var column = token.col;
6348 var childType = tokens[pos].class_child;
6349 if (childType === 1) content.push(getInterpolatedVariable());else content.push(getIdent());
6351 return newNode(type, content, line, column);
6354 function checkCombinator(i) {
6355 if (i >= tokensLength) return 0;
6358 if (l = checkCombinator1(i)) tokens[i].combinatorType = 1;else if (l = checkCombinator2(i)) tokens[i].combinatorType = 2;else if (l = checkCombinator3(i)) tokens[i].combinatorType = 3;else if (l = checkCombinator4(i)) tokens[i].combinatorType = 4;
6363 function getCombinator() {
6364 var type = tokens[pos].combinatorType;
6365 if (type === 1) return getCombinator1();
6366 if (type === 2) return getCombinator2();
6367 if (type === 3) return getCombinator3();
6368 if (type === 4) return getCombinator4();
6377 function checkCombinator1(i) {
6378 if (i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign) return 3;
6386 function getCombinator1() {
6387 var type = NodeType.CombinatorType;
6388 var token = tokens[pos];
6389 var line = token.ln;
6390 var column = token.col;
6391 var content = '>>>';
6396 return newNode(type, content, line, column);
6406 function checkCombinator2(i) {
6407 if (i + 1 >= tokensLength) return 0;
6409 if (tokens[i].type === TokenType.VerticalLine && tokens[i + 1].type === TokenType.VerticalLine) return 2;
6411 if (tokens[i].type === TokenType.GreaterThanSign && tokens[i + 1].type === TokenType.GreaterThanSign) return 2;
6419 function getCombinator2() {
6420 var type = NodeType.CombinatorType;
6421 var token = tokens[pos];
6422 var line = token.ln;
6423 var column = token.col;
6424 var content = '' + token.value + tokens[pos + 1].value;
6429 return newNode(type, content, line, column);
6440 function checkCombinator3(i) {
6441 var type = tokens[i].type;
6442 if (type === TokenType.PlusSign || type === TokenType.GreaterThanSign || type === TokenType.Tilde) return 1;else return 0;
6448 function getCombinator3() {
6449 var type = NodeType.CombinatorType;
6450 var token = tokens[pos];
6451 var line = token.ln;
6452 var column = token.col;
6453 var content = token.value;
6458 return newNode(type, content, line, column);
6464 function checkCombinator4(i) {
6467 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
6470 if (l = checkIdent(i)) i += l;else return 0;
6472 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
6480 function getCombinator4() {
6481 var type = NodeType.CombinatorType;
6482 var token = tokens[pos];
6483 var line = token.ln;
6484 var column = token.col;
6489 var ident = getIdent();
6494 var content = '/' + ident.content + '/';
6496 return newNode(type, content, line, column);
6500 * Check if token is a multiline comment.
6501 * @param {Number} i Token's index number
6502 * @returns {Number} `1` if token is a multiline comment, otherwise `0`
6504 function checkCommentML(i) {
6505 return i < tokensLength && tokens[i].type === TokenType.CommentML ? 1 : 0;
6509 * Get node with a multiline comment
6510 * @returns {Array} `['commentML', x]` where `x`
6511 * is the comment's text (without `/*` and `* /`).
6513 function getCommentML() {
6514 var type = NodeType.CommentMLType;
6515 var token = tokens[pos];
6516 var line = token.ln;
6517 var column = token.col;
6518 var content = tokens[pos].value.substring(2);
6519 var l = content.length;
6521 if (content.charAt(l - 2) === '*' && content.charAt(l - 1) === '/') content = content.substring(0, l - 2);
6523 var end = getLastPosition(content, line, column, 2);
6524 if (end[0] === line) end[1] += 2;
6527 return newNode(type, content, line, column, end);
6531 * Check if token is part of a single-line comment.
6532 * @param {Number} i Token's index number
6533 * @returns {Number} `1` if token is a single-line comment, otherwise `0`
6535 function checkCommentSL(i) {
6536 return i < tokensLength && tokens[i].type === TokenType.CommentSL ? 1 : 0;
6540 * Get node with a single-line comment.
6543 function getCommentSL() {
6544 var type = NodeType.CommentSLType;
6545 var token = tokens[pos];
6546 var line = token.ln;
6547 var column = token.col;
6548 var content = tokens[pos++].value.substring(2);
6549 var end = getLastPosition(content, line, column + 2);
6551 return newNode(type, content, line, column, end);
6555 * Check if token is part of a condition.
6556 * @param {Number} i Token's index number
6557 * @return {Number} Length of the condition
6559 function checkCondition(i) {
6563 if (i >= tokensLength) return 0;
6565 if ((l = checkIdent(i)) && tokens[i].value === 'when') i += l;else return 0;
6567 while (i < tokensLength) {
6568 if (l = checkBlock(i)) {
6569 tokens[i].condition_child = 0;
6571 } else if (l = checkFunction(i)) tokens[i].condition_child = 1;else if (l = checkBrackets(i)) tokens[i].condition_child = 2;else if (l = checkParentheses(i)) tokens[i].condition_child = 3;else if (l = checkVariable(i)) tokens[i].condition_child = 4;else if (l = checkIdent(i)) tokens[i].condition_child = 5;else if (l = checkNumber(i)) tokens[i].condition_child = 6;else if (l = checkDelim(i)) tokens[i].condition_child = 7;else if (l = checkOperator(i)) tokens[i].condition_child = 8;else if (l = checkCombinator(i)) tokens[i].condition_child = 9;else if (l = checkSC(i)) tokens[i].condition_child = 10;else if (l = checkString(i)) tokens[i].condition_child = 11;else return 0;
6580 * Get node with a condition.
6581 * @returns {Array} `['condition', x]`
6583 function getCondition() {
6584 var type = NodeType.ConditionType;
6585 var token = tokens[pos];
6586 var line = token.ln;
6587 var column = token.col;
6590 content.push(getIdent());
6592 while (pos < tokensLength) {
6593 var childType = tokens[pos].condition_child;
6595 if (childType === 0) break;else if (childType === 1) content.push(getFunction());else if (childType === 2) content.push(getBrackets());else if (childType === 3) content.push(getParentheses());else if (childType === 4) content.push(getVariable());else if (childType === 5) content.push(getIdent());else if (childType === 6) content.push(getNumber());else if (childType === 7) content.push(getDelim());else if (childType === 8) content.push(getOperator());else if (childType === 9) content.push(getCombinator());else if (childType === 10) content = content.concat(getSC());else if (childType === 11) content.push(getString());
6598 return newNode(type, content, line, column);
6602 * Check if token is part of a declaration (property-value pair)
6603 * @param {Number} i Token's index number
6604 * @returns {Number} Length of the declaration
6606 function checkDeclaration(i) {
6610 if (i >= tokensLength) return 0;
6612 if (l = checkProperty(i)) i += l;else return 0;
6614 if (l = checkSC(i)) i += l;
6616 if (l = checkPropertyDelim(i)) i++;else return 0;
6618 if (l = checkSC(i)) i += l;
6620 if (l = checkValue(i)) i += l;else return 0;
6626 * Get node with a declaration
6627 * @returns {Array} `['declaration', ['property', x], ['propertyDelim'],
6630 function getDeclaration() {
6631 var type = NodeType.DeclarationType;
6632 var token = tokens[pos];
6633 var line = token.ln;
6634 var column = token.col;
6635 var content = [].concat(getProperty(), getSC(), getPropertyDelim(), getSC(), getValue());
6637 return newNode(type, content, line, column);
6641 * Check if token is a semicolon
6642 * @param {Number} i Token's index number
6643 * @returns {Number} `1` if token is a semicolon, otherwise `0`
6645 function checkDeclDelim(i) {
6646 return i < tokensLength && tokens[i].type === TokenType.Semicolon ? 1 : 0;
6650 * Get node with a semicolon
6651 * @returns {Array} `['declDelim']`
6653 function getDeclDelim() {
6654 var type = NodeType.DeclDelimType;
6655 var token = tokens[pos];
6656 var line = token.ln;
6657 var column = token.col;
6662 return newNode(type, content, line, column);
6666 * Check if token is a comma
6667 * @param {Number} i Token's index number
6668 * @returns {Number} `1` if token is a comma, otherwise `0`
6670 function checkDelim(i) {
6671 return i < tokensLength && tokens[i].type === TokenType.Comma ? 1 : 0;
6675 * Get node with a comma
6676 * @returns {Array} `['delim']`
6678 function getDelim() {
6679 var type = NodeType.DelimType;
6680 var token = tokens[pos];
6681 var line = token.ln;
6682 var column = token.col;
6687 return newNode(type, content, line, column);
6691 * Check if token is part of a number with dimension unit (e.g. `10px`)
6692 * @param {Number} i Token's index number
6695 function checkDimension(i) {
6696 var ln = checkNumber(i);
6699 if (i >= tokensLength || !ln || i + ln >= tokensLength) return 0;
6701 return (li = checkUnit(i + ln)) ? ln + li : 0;
6705 * Get node of a number with dimension unit
6708 function getDimension() {
6709 var type = NodeType.DimensionType;
6710 var token = tokens[pos];
6711 var line = token.ln;
6712 var column = token.col;
6713 var content = [getNumber(), getUnit()];
6715 return newNode(type, content, line, column);
6719 * Check if token is part of an escaped string (e.g. `~"ms:something"`).
6720 * @param {Number} i Token's index number
6721 * @returns {Number} Length of the string (including `~` and quotes)
6723 function checkEscapedString(i) {
6727 if (i >= tokensLength) return 0;
6729 if (tokens[i].type === TokenType.Tilde && (l = checkString(i + 1))) return i + l - start;else return 0;
6733 * Get node with an escaped string
6734 * @returns {Array} `['escapedString', ['string', x]]` where `x` is a string
6735 * without `~` but with quotes
6737 function getEscapedString() {
6738 var type = NodeType.EscapedStringType;
6739 var token = tokens[pos];
6740 var line = token.ln;
6741 var column = token.col;
6745 var content = tokens[pos].value;
6746 var end = getLastPosition(content, line, column + 1);
6750 return newNode(type, content, line, column, end);
6754 * @param {Number} i Token's index number
6757 function checkExpression(i) {
6760 if (i >= tokensLength || tokens[i++].value !== 'expression' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) {
6764 return tokens[i].right - start + 1;
6770 function getExpression() {
6771 var type = NodeType.ExpressionType;
6772 var token = tokens[pos];
6773 var line = token.ln;
6774 var column = token.col;
6778 var content = joinValues(pos + 1, tokens[pos].right - 1);
6779 var end = getLastPosition(content, line, column, 1);
6781 if (end[0] === line) end[1] += 11;
6782 pos = tokens[pos].right + 1;
6784 return newNode(type, content, line, column, end);
6787 function checkExtend(i) {
6788 if (i >= tokensLength) return 0;
6792 if (l = checkExtend1(i)) tokens[i].extendType = 1;else if (l = checkExtend2(i)) tokens[i].extendType = 2;else return 0;
6797 function getExtend() {
6798 var childType = tokens[pos].extendType;
6800 if (childType === 1) return getExtend1();
6801 if (childType === 2) return getExtend2();
6805 * (1) `selector:extend(selector) {...}`
6807 function checkExtend1(i) {
6811 if (i >= tokensLength) return 0;
6813 if (l = checkExtendSelector(i)) i += l;else return 0;
6815 if (tokens[i + 1] && tokens[i + 1].value === 'extend' && (l = checkPseudoc(i))) i += l;else return 0;
6817 if (l = checkSC(i)) i += l;
6819 if (l = checkBlock(i)) i += l;else return 0;
6824 function getExtend1() {
6825 var type = NodeType.ExtendType;
6826 var token = tokens[pos];
6827 var line = token.ln;
6828 var column = token.col;
6829 var content = [].concat(getExtendSelector(), getPseudoc(), getSC(), getBlock());
6831 return newNode(type, content, line, column);
6835 * (1) `selector:extend(selector)`
6837 function checkExtend2(i) {
6841 if (i >= tokensLength) return 0;
6843 if (l = checkExtendSelector(i)) i += l;else return 0;
6845 if (tokens[i + 1] && tokens[i + 1].value === 'extend' && (l = checkPseudoc(i))) i += l;else return 0;
6850 function getExtend2() {
6851 var type = NodeType.ExtendType;
6852 var token = tokens[pos];
6853 var line = token.ln;
6854 var column = token.col;
6855 var content = [].concat(getExtendSelector(), getPseudoc());
6857 return newNode(type, content, line, column);
6860 function checkExtendSelector(i) {
6863 if (l = checkParentSelectorWithExtension(i)) tokens[i].extend_type = 1;else if (l = checkIdent(i)) tokens[i].extend_type = 2;else if (l = checkClass(i)) tokens[i].extend_type = 3;else if (l = checkShash(i)) tokens[i].extend_type = 4;
6868 function getExtendSelector() {
6869 var childType = tokens[pos].extend_type;
6871 if (childType === 1) return getParentSelectorWithExtension();
6872 if (childType === 2) return [getIdent()];
6873 if (childType === 3) return [getClass()];
6874 if (childType === 4) return [getShash()];
6878 * @param {Number} i Token's index number
6881 function checkFunction(i) {
6885 if (i >= tokensLength) return 0;
6887 if (l = checkIdent(i)) i += l;else return 0;
6889 return i < tokensLength && tokens[i].type === TokenType.LeftParenthesis ? tokens[i].right - start + 1 : 0;
6895 function getFunction() {
6896 var type = NodeType.FunctionType;
6897 var token = tokens[pos];
6898 var line = token.ln;
6899 var column = token.col;
6900 var content = [].concat(getIdent(), getArguments());
6902 return newNode(type, content, line, column);
6906 * Check if token is part of an identifier
6907 * @param {Number} i Token's index number
6908 * @returns {Number} Length of the identifier
6910 function checkIdent(i) {
6913 if (i >= tokensLength) return 0;
6915 if (tokens[i].type === TokenType.HyphenMinus) i++;
6917 if (tokens[i].type === TokenType.LowLine || tokens[i].type === TokenType.Identifier) i++;else return 0;
6919 for (; i < tokensLength; i++) {
6920 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
6923 tokens[start].ident_last = i - 1;
6929 * Get node with an identifier
6930 * @returns {Array} `['ident', x]` where `x` is identifier's name
6932 function getIdent() {
6933 var type = NodeType.IdentType;
6934 var token = tokens[pos];
6935 var line = token.ln;
6936 var column = token.col;
6937 var content = joinValues(pos, tokens[pos].ident_last);
6939 pos = tokens[pos].ident_last + 1;
6941 return newNode(type, content, line, column);
6945 * @param {number} i Token's index number
6946 * @returns {number} Length of the identifier
6948 function checkPartialIdent(i) {
6951 if (i >= tokensLength) return 0;
6953 for (; i < tokensLength; i++) {
6954 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
6957 tokens[start].ident_last = i - 1;
6963 * Check if token is part of `!important` word
6964 * @param {Number} i Token's index number
6967 function checkImportant(i) {
6971 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
6973 if (l = checkSC(i)) i += l;
6975 if (tokens[i].value === 'important') {
6976 tokens[start].importantEnd = i;
6977 return i - start + 1;
6984 * Get node with `!important` word
6985 * @returns {Array} `['important', sc]` where `sc` is optional whitespace
6987 function getImportant() {
6988 var token = tokens[pos];
6989 var line = token.ln;
6990 var column = token.col;
6991 var content = joinValues(pos, token.importantEnd);
6993 pos = token.importantEnd + 1;
6995 return newNode(NodeType.ImportantType, content, line, column);
6999 * Check if token is part of an include (`@include` or `@extend` directive).
7000 * @param {Number} i Token's index number
7003 function checkInclude(i) {
7006 if (i >= tokensLength) return 0;
7008 if (l = checkInclude1(i)) tokens[i].include_type = 1;else if (l = checkInclude2(i)) tokens[i].include_type = 2;
7014 * Get node with included mixin
7015 * @returns {Array} `['include', x]`
7017 function getInclude() {
7018 var type = tokens[pos].include_type;
7020 if (type === 1) return getInclude1();
7021 if (type === 2) return getInclude2();
7025 * @param {Number} i Token's index number
7028 function checkInclude1(i) {
7032 if (l = checkClass(i) || checkShash(i)) i += l;else return 0;
7034 while (i < tokensLength) {
7035 if (l = checkClass(i) || checkShash(i) || checkSC(i)) i += l;else if (tokens[i].type === TokenType.GreaterThanSign) i++;else break;
7038 if (l = checkArguments(i)) i += l;else return 0;
7040 if (i < tokensLength && (l = checkSC(i))) i += l;
7042 if (i < tokensLength && (l = checkImportant(i))) i += l;
7048 * @returns {Array} `['include', x]`
7050 function getInclude1() {
7051 var type = NodeType.IncludeType;
7052 var token = tokens[pos];
7053 var line = token.ln;
7054 var column = token.col;
7057 content.push(checkClass(pos) ? getClass() : getShash());
7059 while (pos < tokensLength) {
7060 if (checkClass(pos)) content.push(getClass());else if (checkShash(pos)) content.push(getShash());else if (checkSC(pos)) content = content.concat(getSC());else if (checkOperator(pos)) content.push(getOperator());else break;
7063 content.push(getArguments());
7065 content = content.concat(getSC());
7067 if (checkImportant(pos)) content.push(getImportant());
7069 return newNode(type, content, line, column);
7073 * @param {Number} i Token's index number
7076 function checkInclude2(i) {
7080 if (l = checkClass(i) || checkShash(i)) i += l;else return 0;
7082 while (i < tokensLength) {
7083 if (l = checkClass(i) || checkShash(i) || checkSC(i)) i += l;else if (tokens[i].type === TokenType.GreaterThanSign) i++;else break;
7090 * @returns {Array} `['include', x]`
7092 function getInclude2() {
7093 var type = NodeType.IncludeType;
7094 var token = tokens[pos];
7095 var line = token.ln;
7096 var column = token.col;
7099 content.push(checkClass(pos) ? getClass() : getShash());
7101 while (pos < tokensLength) {
7102 if (checkClass(pos)) content.push(getClass());else if (checkShash(pos)) content.push(getShash());else if (checkSC(pos)) content = content.concat(getSC());else if (checkOperator(pos)) content.push(getOperator());else break;
7105 return newNode(type, content, line, column);
7109 * Check if token is part of LESS interpolated variable
7110 * @param {Number} i Token's index number
7113 function checkInterpolatedVariable(i) {
7117 if (i >= tokensLength) return 0;
7119 if (tokens[i].type !== TokenType.CommercialAt || !tokens[i + 1] || tokens[i + 1].type !== TokenType.LeftCurlyBracket) {
7125 if (l = checkIdent(i)) i += l;else return 0;
7127 return tokens[i].type === TokenType.RightCurlyBracket ? i - start + 1 : 0;
7131 * Get node with LESS interpolated variable
7132 * @returns {Array} `['interpolatedVariable', x]`
7134 function getInterpolatedVariable() {
7135 var type = NodeType.InterpolatedVariableType;
7136 var token = tokens[pos];
7137 var line = token.ln;
7138 var column = token.col;
7144 content.push(getIdent());
7146 var end = getLastPosition(content, line, column, 1);
7151 return newNode(type, content, line, column, end);
7154 function checkKeyframesBlock(i) {
7158 if (i >= tokensLength) return 0;
7160 if (l = checkKeyframesSelector(i)) i += l;else return 0;
7162 if (l = checkSC(i)) i += l;
7164 if (l = checkBlock(i)) i += l;else return 0;
7169 function getKeyframesBlock() {
7170 var type = NodeType.RulesetType;
7171 var token = tokens[pos];
7172 var line = token.ln;
7173 var column = token.col;
7174 var content = [].concat(getKeyframesSelector(), getSC(), getBlock());
7176 return newNode(type, content, line, column);
7179 function checkKeyframesBlocks(i) {
7183 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
7185 if (l = checkSC(i)) i += l;
7187 if (l = checkKeyframesBlock(i)) i += l;else return 0;
7189 while (tokens[i].type !== TokenType.RightCurlyBracket) {
7190 if (l = checkSC(i)) i += l;else if (l = checkKeyframesBlock(i)) i += l;else break;
7193 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
7198 function getKeyframesBlocks() {
7199 var type = NodeType.BlockType;
7200 var token = tokens[pos];
7201 var line = token.ln;
7202 var column = token.col;
7203 var keyframesBlocksEnd = token.right;
7209 while (pos < keyframesBlocksEnd) {
7210 if (checkSC(pos)) content = content.concat(getSC());else if (checkKeyframesBlock(pos)) content.push(getKeyframesBlock());
7213 var end = getLastPosition(content, line, column, 1);
7218 return newNode(type, content, line, column, end);
7222 * Check if token is part of a @keyframes rule.
7223 * @param {Number} i Token's index number
7224 * @return {Number} Length of the @keyframes rule
7226 function checkKeyframesRule(i) {
7230 if (i >= tokensLength) return 0;
7232 if (l = checkAtkeyword(i)) i += l;else return 0;
7234 var atruleName = joinValues2(i - l, l);
7235 if (atruleName.toLowerCase().indexOf('keyframes') === -1) return 0;
7237 if (l = checkSC(i)) i += l;else return 0;
7239 if (l = checkIdent(i)) i += l;else return 0;
7241 if (l = checkSC(i)) i += l;
7243 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
7251 function getKeyframesRule() {
7252 var type = NodeType.AtruleType;
7253 var token = tokens[pos];
7254 var line = token.ln;
7255 var column = token.col;
7256 var content = [].concat(getAtkeyword(), getSC(), getIdent(), getSC(), getKeyframesBlocks());
7258 return newNode(type, content, line, column);
7261 function checkKeyframesSelector(i) {
7265 if (i >= tokensLength) return 0;
7267 if (l = checkIdent(i)) {
7268 // Valid selectors are only `from` and `to`.
7269 var selector = joinValues2(i, l);
7270 if (selector !== 'from' && selector !== 'to') return 0;
7273 tokens[start].keyframesSelectorType = 1;
7274 } else if (l = checkPercentage(i)) {
7276 tokens[start].keyframesSelectorType = 2;
7284 function getKeyframesSelector() {
7285 var keyframesSelectorType = NodeType.KeyframesSelectorType;
7286 var selectorType = NodeType.SelectorType;
7287 var token = tokens[pos];
7288 var line = token.ln;
7289 var column = token.col;
7292 if (token.keyframesSelectorType === 1) {
7293 content.push(getIdent());
7295 content.push(getPercentage());
7298 var keyframesSelector = newNode(keyframesSelectorType, content, line, column);
7300 return newNode(selectorType, [keyframesSelector], line, column);
7304 * Check if token is part of a LESS mixin
7305 * @param {Number} i Token's index number
7306 * @returns {Number} Length of the mixin
7308 function checkMixin(i) {
7311 if (i >= tokensLength) return 0;
7313 if (l = checkMixin1(i)) tokens[i].mixin_type = 1;else if (l = checkMixin2(i)) tokens[i].mixin_type = 2;else return 0;
7321 function getMixin() {
7322 var type = tokens[pos].mixin_type;
7324 if (type === 1) return getMixin1();
7325 if (type === 2) return getMixin2();
7328 function checkMixin1(i) {
7332 if (i >= tokensLength) return 0;
7334 if (l = checkClass(i) || checkShash(i)) i += l;else return 0;
7336 if (l = checkSC(i)) i += l;
7338 if (l = checkArguments(i)) i += l;
7340 if (l = checkSC(i)) i += l;
7342 if (l = checkBlock(i)) i += l;else return 0;
7348 * Get node with a mixin
7349 * @returns {Array} `['mixin', x]`
7351 function getMixin1() {
7352 var type = NodeType.MixinType;
7353 var token = tokens[pos];
7354 var line = token.ln;
7355 var column = token.col;
7358 content.push(checkClass(pos) ? getClass() : getShash());
7360 content = content.concat(getSC());
7362 if (checkArguments(pos)) content.push(getArguments());
7364 content = content.concat(getSC());
7366 if (checkBlock(pos)) content.push(getBlock());
7368 return newNode(type, content, line, column);
7372 * Check if token is part of a LESS mixin
7373 * @param {Number} i Token's index number
7374 * @returns {Number} Length of the mixin
7376 function checkMixin2(i) {
7380 if (i >= tokensLength) return 0;
7382 if (l = checkClass(i) || checkShash(i)) i += l;else return 0;
7384 if (l = checkSC(i)) i += l;
7386 if (l = checkArguments(i)) i += l;
7392 * Get node with a mixin
7393 * @returns {Array} `['mixin', x]`
7395 function getMixin2() {
7396 var type = NodeType.MixinType;
7397 var token = tokens[pos];
7398 var line = token.ln;
7399 var column = token.col;
7402 content.push(checkClass(pos) ? getClass() : getShash());
7404 content = content.concat(getSC());
7406 if (checkArguments(pos)) content.push(getArguments());
7408 return newNode(type, content, line, column);
7412 * Check if token is a namespace sign (`|`)
7413 * @param {Number} i Token's index number
7414 * @returns {Number} `1` if token is `|`, `0` if not
7416 function checkNamespace(i) {
7417 return i < tokensLength && tokens[i].type === TokenType.VerticalLine ? 1 : 0;
7421 * Get node with a namespace sign
7422 * @returns {Array} `['namespace']`
7424 function getNamespace() {
7425 var type = NodeType.NamespaceType;
7426 var token = tokens[pos];
7427 var line = token.ln;
7428 var column = token.col;
7433 return newNode(type, content, line, column);
7437 * @param {Number} i Token's index number
7440 function checkNmName2(i) {
7441 if (tokens[i].type === TokenType.Identifier) return 1;else if (tokens[i].type !== TokenType.DecimalNumber) return 0;
7445 return i < tokensLength && tokens[i].type === TokenType.Identifier ? 2 : 1;
7451 function getNmName2() {
7452 var s = tokens[pos].value;
7454 if (tokens[pos++].type === TokenType.DecimalNumber && pos < tokensLength && tokens[pos].type === TokenType.Identifier) s += tokens[pos++].value;
7460 * Check if token is part of a number
7461 * @param {Number} i Token's index number
7462 * @returns {Number} Length of number
7464 function checkNumber(i) {
7465 if (i >= tokensLength) return 0;
7467 if (tokens[i].number_l) return tokens[i].number_l;
7470 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && (!tokens[i + 1] || tokens[i + 1] && tokens[i + 1].type !== TokenType.FullStop)) {
7471 tokens[i].number_l = 1;
7476 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && (!tokens[i + 2] || tokens[i + 2].type !== TokenType.DecimalNumber)) {
7477 tokens[i].number_l = 2;
7482 if (i < tokensLength && tokens[i].type === TokenType.FullStop && tokens[i + 1].type === TokenType.DecimalNumber) {
7483 tokens[i].number_l = 2;
7488 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && tokens[i + 2] && tokens[i + 2].type === TokenType.DecimalNumber) {
7489 tokens[i].number_l = 3;
7497 * Get node with number
7498 * @returns {Array} `['number', x]` where `x` is a number converted
7501 function getNumber() {
7502 var type = NodeType.NumberType;
7503 var token = tokens[pos];
7504 var line = token.ln;
7505 var column = token.col;
7506 var l = tokens[pos].number_l;
7509 for (var j = 0; j < l; j++) {
7510 content += tokens[pos + j].value;
7515 return newNode(type, content, line, column);
7519 * Check if token is an operator (`/`, `,`, `:`, `=`, `>`, `<` or `*`)
7520 * @param {Number} i Token's index number
7521 * @returns {Number} `1` if token is an operator, otherwise `0`
7523 function checkOperator(i) {
7524 if (i >= tokensLength) return 0;
7526 switch (tokens[i].type) {
7527 case TokenType.Solidus:
7528 case TokenType.Comma:
7529 case TokenType.Colon:
7530 case TokenType.EqualsSign:
7531 case TokenType.LessThanSign:
7532 case TokenType.GreaterThanSign:
7533 case TokenType.Asterisk:
7541 * Get node with an operator
7542 * @returns {Array} `['operator', x]` where `x` is an operator converted
7545 function getOperator() {
7546 var type = NodeType.OperatorType;
7547 var token = tokens[pos];
7548 var line = token.ln;
7549 var column = token.col;
7550 var content = token.value;
7554 return newNode(type, content, line, column);
7558 * Check if token is part of text inside parentheses, e.g. `(1)`
7559 * @param {Number} i Token's index number
7562 function checkParentheses(i) {
7563 if (i >= tokensLength) return 0;
7566 var right = tokens[i].right;
7569 if (tokens[i].type === TokenType.LeftParenthesis) i++;else return 0;
7572 var l = checkTsets(i);
7573 if (l) i += l;else return 0;
7583 * Get node with text inside parentheses, e.g. `(1)`
7586 function getParentheses() {
7587 var type = NodeType.ParenthesesType;
7588 var token = tokens[pos];
7589 var line = token.ln;
7590 var column = token.col;
7591 var right = token.right;
7598 content = getTsets();
7601 var end = getLastPosition(content, line, column, 1);
7606 return newNode(type, content, line, column, end);
7610 * Check if token is a parent selector (`&`).
7611 * @param {Number} i Token's index number
7614 function checkParentSelector(i) {
7615 return i < tokensLength && tokens[i].type === TokenType.Ampersand ? 1 : 0;
7619 * Get node with a parent selector
7620 * @returns {Array} `['parentSelector']`
7622 function getParentSelector() {
7623 var type = NodeType.ParentSelectorType;
7624 var token = tokens[pos];
7625 var line = token.ln;
7626 var column = token.col;
7631 return newNode(type, content, line, column);
7634 function checkParentSelectorExtension(i) {
7638 if (i >= tokensLength) return 0;
7640 while (i < tokensLength) {
7641 if (l = checkNumber(i) || checkPartialIdent(i)) i += l;else break;
7647 function getParentSelectorExtension() {
7648 var type = NodeType.ParentSelectorExtensionType;
7649 var token = tokens[pos];
7650 var line = token.ln;
7651 var column = token.col;
7654 while (pos < tokensLength) {
7655 if (checkNumber(pos)) {
7656 content.push(getNumber());
7657 } else if (checkPartialIdent(pos)) {
7658 content.push(getIdent());
7662 return newNode(type, content, line, column);
7665 function checkParentSelectorWithExtension(i) {
7669 if (i >= tokensLength) return 0;
7671 if (l = checkParentSelector(i)) i += l;else return 0;
7673 if (l = checkParentSelectorExtension(i)) i += l;
7678 function getParentSelectorWithExtension() {
7679 var content = [getParentSelector()];
7681 if (checkParentSelectorExtension(pos)) content.push(getParentSelectorExtension());
7687 * Check if token is part of a number with percent sign (e.g. `10%`)
7688 * @param {Number} i Token's index number
7691 function checkPercentage(i) {
7695 if (i >= tokensLength) return 0;
7697 if (l = checkNumber(i)) i += l;else return 0;
7699 if (i >= tokensLength) return 0;
7702 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
7708 * Get node of number with percent sign
7709 * @returns {Array} `['percentage', ['number', x]]` where `x` is a number
7710 * (without percent sign) converted to string.
7712 function getPercentage() {
7713 var type = NodeType.PercentageType;
7714 var token = tokens[pos];
7715 var line = token.ln;
7716 var column = token.col;
7717 var content = [getNumber()];
7718 var end = getLastPosition(content, line, column, 1);
7723 return newNode(type, content, line, column, end);
7727 * @param {Number} i Token's index number
7730 function checkProgid(i) {
7734 if (i >= tokensLength) return 0;
7736 if (joinValues2(i, 6) === 'progid:DXImageTransform.Microsoft.') i += 6;else return 0;
7738 if (l = checkIdent(i)) i += l;else return 0;
7740 if (l = checkSC(i)) i += l;
7742 if (tokens[i].type === TokenType.LeftParenthesis) {
7743 tokens[start].progid_end = tokens[i].right;
7744 i = tokens[i].right + 1;
7753 function getProgid() {
7754 var type = NodeType.ProgidType;
7755 var token = tokens[pos];
7756 var line = token.ln;
7757 var column = token.col;
7758 var progid_end = token.progid_end;
7759 var content = joinValues(pos, progid_end);
7761 pos = progid_end + 1;
7763 return newNode(type, content, line, column);
7767 * Check if token is part of a property
7768 * @param {Number} i Token's index number
7769 * @returns {Number} Length of the property
7771 function checkProperty(i) {
7775 if (i >= tokensLength) return 0;
7777 if (l = checkVariable(i) || checkIdent(i)) i += l;else return 0;
7783 * Get node with a property
7784 * @returns {Array} `['property', x]`
7786 function getProperty() {
7787 var type = NodeType.PropertyType;
7788 var token = tokens[pos];
7789 var line = token.ln;
7790 var column = token.col;
7793 if (checkVariable(pos)) {
7794 content.push(getVariable());
7796 content.push(getIdent());
7799 return newNode(type, content, line, column);
7803 * Check if token is a colon
7804 * @param {Number} i Token's index number
7805 * @returns {Number} `1` if token is a colon, otherwise `0`
7807 function checkPropertyDelim(i) {
7808 return i < tokensLength && tokens[i].type === TokenType.Colon ? 1 : 0;
7812 * Get node with a colon
7813 * @returns {Array} `['propertyDelim']`
7815 function getPropertyDelim() {
7816 var type = NodeType.PropertyDelimType;
7817 var token = tokens[pos];
7818 var line = token.ln;
7819 var column = token.col;
7825 return newNode(type, content, line, column);
7829 * @param {Number} i Token's index number
7832 function checkPseudo(i) {
7833 return checkPseudoe(i) || checkPseudoc(i);
7839 function getPseudo() {
7840 if (checkPseudoe(pos)) return getPseudoe();
7841 if (checkPseudoc(pos)) return getPseudoc();
7845 * @param {Number} i Token's index number
7848 function checkPseudoe(i) {
7852 if (i >= tokensLength || tokens[i].type !== TokenType.Colon || i + 1 >= tokensLength || tokens[i + 1].type !== TokenType.Colon) return 0;
7854 if (l = checkPseudoElement1(i)) tokens[i].pseudoElementType = 1;else if (l = checkPseudoElement2(i)) tokens[i].pseudoElementType = 2;else return 0;
7862 function getPseudoe() {
7863 var childType = tokens[pos].pseudoElementType;
7864 if (childType === 1) return getPseudoElement1();
7865 if (childType === 2) return getPseudoElement2();
7869 * (1) `::slotted(selector)`
7870 * (2) `::slotted(selector, selector)`
7872 function checkPseudoElement1(i) {
7879 if (i >= tokensLength) return 0;
7881 if (l = checkIdent(i)) i += l;else return 0;
7883 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
7885 var right = tokens[i].right;
7890 if (l = checkSC(i)) i += l;
7892 if (l = checkSelectorsGroup(i)) i += l;else return 0;
7894 if (l = checkSC(i)) i += l;
7896 if (i !== right) return 0;
7905 * (1) `::slotted(selector)`
7906 * (2) `::slotted(selector, selector)`
7908 function getPseudoElement1() {
7909 var type = NodeType.PseudoeType;
7910 var token = tokens[pos];
7911 var line = token.ln;
7912 var column = token.col;
7918 content.push(getIdent());
7921 var _type = NodeType.ArgumentsType;
7922 var _token = tokens[pos];
7923 var _line = _token.ln;
7924 var _column = _token.col;
7929 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
7931 var end = getLastPosition(selectorContent, _line, _column, 1);
7932 var args = newNode(_type, selectorContent, _line, _column, end);
7939 return newNode(type, content, line, column);
7942 function checkPseudoElement2(i) {
7949 if (l = checkInterpolatedVariable(i) || checkIdent(i)) i += l;else return 0;
7957 function getPseudoElement2() {
7958 var type = NodeType.PseudoeType;
7959 var token = tokens[pos];
7960 var line = token.ln;
7961 var column = token.col;
7968 if (checkInterpolatedVariable(pos)) {
7969 content.push(getInterpolatedVariable());
7971 content.push(getIdent());
7974 return newNode(type, content, line, column);
7978 * @param {Number} i Token's index number
7981 function checkPseudoc(i) {
7984 if (i >= tokensLength || tokens[i].type !== TokenType.Colon) return 0;
7986 if (l = checkPseudoClass3(i)) tokens[i].pseudoClassType = 3;else if (l = checkPseudoClass4(i)) tokens[i].pseudoClassType = 4;else if (l = checkPseudoClass5(i)) tokens[i].pseudoClassType = 5;else if (l = checkPseudoClass1(i)) tokens[i].pseudoClassType = 1;else if (l = checkPseudoClass2(i)) tokens[i].pseudoClassType = 2;else if (l = checkPseudoClass6(i)) tokens[i].pseudoClassType = 6;else return 0;
7991 function getPseudoc() {
7992 var childType = tokens[pos].pseudoClassType;
7993 if (childType === 1) return getPseudoClass1();
7994 if (childType === 2) return getPseudoClass2();
7995 if (childType === 3) return getPseudoClass3();
7996 if (childType === 4) return getPseudoClass4();
7997 if (childType === 5) return getPseudoClass5();
7998 if (childType === 6) return getPseudoClass6();
8002 * (1) `:not(selector)`
8003 * (2) `:extend(selector, selector)`
8005 function checkPseudoClass1(i) {
8012 if (i >= tokensLength) return 0;
8014 if (l = checkIdent(i)) i += l;else return 0;
8016 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
8018 var right = tokens[i].right;
8023 if (l = checkSC(i)) i += l;
8025 if (l = checkSelectorsGroup(i)) i += l;else return 0;
8027 if (l = checkSC(i)) i += l;
8029 if (i !== right) return 0;
8040 function getPseudoClass1() {
8041 var type = NodeType.PseudocType;
8042 var token = tokens[pos];
8043 var line = token.ln;
8044 var column = token.col;
8050 content.push(getIdent());
8053 var _type2 = NodeType.ArgumentsType;
8054 var _token2 = tokens[pos];
8055 var _line2 = _token2.ln;
8056 var _column2 = _token2.col;
8061 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
8063 var end = getLastPosition(selectorContent, _line2, _column2, 1);
8064 var args = newNode(_type2, selectorContent, _line2, _column2, end);
8071 return newNode(type, content, line, column);
8075 * (1) `:nth-child(odd)`
8076 * (2) `:nth-child(even)`
8077 * (3) `:lang(de-DE)`
8079 function checkPseudoClass2(i) {
8086 if (i >= tokensLength) return 0;
8088 if (l = checkIdent(i)) i += l;else return 0;
8090 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
8092 var right = tokens[i].right;
8097 if (l = checkSC(i)) i += l;
8099 if (l = checkIdent(i)) i += l;else return 0;
8101 if (l = checkSC(i)) i += l;
8103 if (i !== right) return 0;
8111 function getPseudoClass2() {
8112 var type = NodeType.PseudocType;
8113 var token = tokens[pos];
8114 var line = token.ln;
8115 var column = token.col;
8121 content.push(getIdent());
8127 var l = tokens[pos].ln;
8128 var c = tokens[pos].col;
8129 var value = [].concat(getSC(), getIdent(), getSC());
8131 var end = getLastPosition(value, l, c, 1);
8132 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
8139 return newNode(type, content, line, column);
8143 * (-) `:nth-child(-3n + 2)`
8145 function checkPseudoClass3(i) {
8152 if (i >= tokensLength) return 0;
8154 if (l = checkIdent(i)) i += l;else return 0;
8156 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
8158 var right = tokens[i].right;
8163 if (l = checkSC(i)) i += l;
8165 if (l = checkUnary(i)) i += l;
8167 if (i >= tokensLength) return 0;
8168 if (tokens[i].type === TokenType.DecimalNumber) i++;
8170 if (i >= tokensLength) return 0;
8171 if (tokens[i].value === 'n') i++;else return 0;
8173 if (l = checkSC(i)) i += l;
8175 if (i >= tokensLength) return 0;
8176 if (tokens[i].value === '+' || tokens[i].value === '-') i++;else return 0;
8178 if (l = checkSC(i)) i += l;
8180 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
8182 if (l = checkSC(i)) i += l;
8184 if (i !== right) return 0;
8192 function getPseudoClass3() {
8193 var type = NodeType.PseudocType;
8194 var token = tokens[pos];
8195 var line = token.ln;
8196 var column = token.col;
8202 content.push(getIdent());
8204 var l = tokens[pos].ln;
8205 var c = tokens[pos].col;
8211 value = value.concat(getSC());
8213 if (checkUnary(pos)) value.push(getUnary());
8214 if (checkNumber(pos)) value.push(getNumber());
8217 var _l = tokens[pos].ln;
8218 var _c = tokens[pos].col;
8219 var _content = tokens[pos].value;
8220 var ident = newNode(NodeType.IdentType, _content, _l, _c);
8225 value = value.concat(getSC());
8227 if (checkUnary(pos)) value.push(getUnary());
8229 value = value.concat(getSC());
8231 if (checkNumber(pos)) value.push(getNumber());
8233 value = value.concat(getSC());
8235 var end = getLastPosition(value, l, c, 1);
8236 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
8242 return newNode(type, content, line, column);
8246 * (-) `:nth-child(-3n)`
8248 function checkPseudoClass4(i) {
8255 if (i >= tokensLength) return 0;
8257 if (l = checkIdent(i)) i += l;else return 0;
8259 if (i >= tokensLength) return 0;
8260 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
8262 var right = tokens[i].right;
8267 if (l = checkSC(i)) i += l;
8269 if (l = checkUnary(i)) i += l;
8270 if (tokens[i].type === TokenType.DecimalNumber) i++;
8272 if (tokens[i].value === 'n') i++;else return 0;
8274 if (l = checkSC(i)) i += l;
8276 if (i !== right) return 0;
8284 function getPseudoClass4() {
8285 var type = NodeType.PseudocType;
8286 var token = tokens[pos];
8287 var line = token.ln;
8288 var column = token.col;
8294 content.push(getIdent());
8296 var l = tokens[pos].ln;
8297 var c = tokens[pos].col;
8303 value = value.concat(getSC());
8305 if (checkUnary(pos)) value.push(getUnary());
8306 if (checkNumber(pos)) value.push(getNumber());
8307 if (checkIdent(pos)) value.push(getIdent());
8309 value = value.concat(getSC());
8311 var end = getLastPosition(value, l, c, 1);
8312 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
8318 return newNode(type, content, line, column);
8322 * (-) `:nth-child(+8)`
8324 function checkPseudoClass5(i) {
8331 if (i >= tokensLength) return 0;
8333 if (l = checkIdent(i)) i += l;else return 0;
8335 if (i >= tokensLength) return 0;
8336 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
8338 var right = tokens[i].right;
8343 if (l = checkSC(i)) i += l;
8345 if (l = checkUnary(i)) i += l;
8346 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
8348 if (l = checkSC(i)) i += l;
8350 if (i !== right) return 0;
8358 function getPseudoClass5() {
8359 var type = NodeType.PseudocType;
8360 var token = tokens[pos];
8361 var line = token.ln;
8362 var column = token.col;
8368 content.push(getIdent());
8370 var l = tokens[pos].ln;
8371 var c = tokens[pos].col;
8377 value = value.concat(getSC());
8379 if (checkUnary(pos)) value.push(getUnary());
8380 if (checkNumber(pos)) value.push(getNumber());
8382 value = value.concat(getSC());
8384 var end = getLastPosition(value, l, c, 1);
8385 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
8391 return newNode(type, content, line, column);
8397 function checkPseudoClass6(i) {
8404 if (i >= tokensLength) return 0;
8406 if (l = checkInterpolatedVariable(i)) i += l;else if (l = checkIdent(i)) i += l;else return 0;
8411 function getPseudoClass6() {
8412 var type = NodeType.PseudocType;
8413 var token = tokens[pos];
8414 var line = token.ln;
8415 var column = token.col;
8421 var ident = checkInterpolatedVariable(pos) ? getInterpolatedVariable() : getIdent();
8422 content.push(ident);
8424 return newNode(type, content, line, column);
8428 * @param {Number} i Token's index number
8431 function checkRuleset(i) {
8435 if (i >= tokensLength) return 0;
8437 if (l = checkSelectorsGroup(i)) i += l;else return 0;
8439 if (l = checkSC(i)) i += l;
8441 if (l = checkBlock(i)) i += l;else return 0;
8446 function getRuleset() {
8447 var type = NodeType.RulesetType;
8448 var token = tokens[pos];
8449 var line = token.ln;
8450 var column = token.col;
8451 var content = [].concat(getSelectorsGroup(), getSC(), getBlock());
8453 return newNode(type, content, line, column);
8457 * Check if token is marked as a space (if it's a space or a tab
8460 * @returns {Number} Number of spaces in a row starting with the given token.
8462 function checkS(i) {
8463 return i < tokensLength && tokens[i].ws ? tokens[i].ws_last - i + 1 : 0;
8467 * Get node with spaces
8468 * @returns {Array} `['s', x]` where `x` is a string containing spaces
8471 var type = NodeType.SType;
8472 var token = tokens[pos];
8473 var line = token.ln;
8474 var column = token.col;
8475 var content = joinValues(pos, tokens[pos].ws_last);
8477 pos = tokens[pos].ws_last + 1;
8479 return newNode(type, content, line, column);
8483 * Check if token is a space or a comment.
8484 * @param {Number} i Token's index number
8485 * @returns {Number} Number of similar (space or comment) tokens
8486 * in a row starting with the given token.
8488 function checkSC(i) {
8489 if (i >= tokensLength) return 0;
8494 while (i < tokensLength) {
8495 if (!(l = checkS(i)) && !(l = checkCommentML(i)) && !(l = checkCommentSL(i))) break;
8504 * Get node with spaces and comments
8505 * @returns {Array} Array containing nodes with spaces (if there are any)
8506 * and nodes with comments (if there are any):
8507 * `[['s', x]*, ['comment', y]*]` where `x` is a string of spaces
8508 * and `y` is a comment's text (without `/*` and `* /`).
8513 if (pos >= tokensLength) return sc;
8515 while (pos < tokensLength) {
8516 if (checkS(pos)) sc.push(getS());else if (checkCommentML(pos)) sc.push(getCommentML());else if (checkCommentSL(pos)) sc.push(getCommentSL());else break;
8523 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
8525 * @param {Number} i Token's index number
8528 function checkShash(i) {
8531 if (i >= tokensLength || tokens[i].type !== TokenType.NumberSign) return 0;
8533 if (l = checkInterpolatedVariable(i + 1) || checkIdent(i + 1)) return l + 1;else return 0;
8537 * Get node with a hexadecimal number (e.g. `#fff`) inside a simple
8539 * @returns {Array} `['shash', x]` where `x` is a hexadecimal number
8540 * converted to string (without `#`, e.g. `fff`)
8542 function getShash() {
8543 var type = NodeType.ShashType;
8544 var token = tokens[pos];
8545 var line = token.ln;
8546 var column = token.col;
8552 if (checkInterpolatedVariable(pos)) content.push(getInterpolatedVariable());else content.push(getIdent());
8554 return newNode(type, content, line, column);
8558 * Check if token is part of a string (text wrapped in quotes)
8559 * @param {Number} i Token's index number
8560 * @returns {Number} `1` if token is part of a string, `0` if not
8562 function checkString(i) {
8563 if (i >= tokensLength) {
8567 if (tokens[i].type === TokenType.StringSQ || tokens[i].type === TokenType.StringDQ) {
8576 * @returns {Array} `['string', x]` where `x` is a string (including
8579 function getString() {
8580 var type = NodeType.StringType;
8581 var token = tokens[pos];
8582 var line = token.ln;
8583 var column = token.col;
8584 var content = token.value;
8588 return newNode(type, content, line, column);
8592 * Validate stylesheet: it should consist of any number (0 or more) of
8593 * rulesets (sets of rules with selectors), @-rules, whitespaces or
8595 * @param {Number} i Token's index number
8598 function checkStylesheet(i) {
8602 // Check every token:
8603 while (i < tokensLength) {
8604 if (l = checkSC(i) || checkRuleset(i) || checkDeclaration(i) || checkDeclDelim(i) || checkAtrule(i) || checkMixin(i)) i += l;else throwError(i);
8611 * @returns {Array} `['stylesheet', x]` where `x` is all stylesheet's
8614 function getStylesheet() {
8615 var type = NodeType.StylesheetType;
8616 var token = tokens[pos];
8617 var line = token.ln;
8618 var column = token.col;
8621 while (pos < tokensLength) {
8622 if (checkSC(pos)) content = content.concat(getSC());else if (checkRuleset(pos)) content.push(getRuleset());else if (checkDeclaration(pos)) content.push(getDeclaration());else if (checkDeclDelim(pos)) content.push(getDeclDelim());else if (checkAtrule(pos)) content.push(getAtrule());else if (checkMixin(pos)) content.push(getMixin());else throwError(pos);
8625 return newNode(type, content, line, column);
8629 * @param {Number} i Token's index number
8632 function checkTset(i) {
8635 if (l = checkVhash(i)) tokens[i].tset_child = 1;else if (l = checkAny(i)) tokens[i].tset_child = 2;else if (l = checkSC(i)) tokens[i].tset_child = 3;else if (l = checkOperator(i)) tokens[i].tset_child = 4;
8643 function getTset() {
8644 var childType = tokens[pos].tset_child;
8646 if (childType === 1) return getVhash();
8647 if (childType === 2) return getAny();
8648 if (childType === 3) return getSC();
8649 if (childType === 4) return getOperator();
8653 * @param {Number} i Token's index number
8656 function checkTsets(i) {
8660 if (i >= tokensLength) return 0;
8662 while (l = checkTset(i)) {
8672 function getTsets() {
8676 while (checkTset(pos)) {
8678 if (typeof t.content === 'string') content.push(t);else content = content.concat(t);
8685 * Check if token is an unary (arithmetical) sign (`+` or `-`)
8686 * @param {Number} i Token's index number
8687 * @returns {Number} `1` if token is an unary sign, `0` if not
8689 function checkUnary(i) {
8690 if (i >= tokensLength) return 0;
8692 if (tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.PlusSign) {
8700 * Get node with an unary (arithmetical) sign (`+` or `-`)
8701 * @returns {Array} `['unary', x]` where `x` is an unary sign
8702 * converted to string.
8704 function getUnary() {
8705 var type = NodeType.OperatorType;
8706 var token = tokens[pos];
8707 var line = token.ln;
8708 var column = token.col;
8709 var content = token.value;
8713 return newNode(type, content, line, column);
8717 * Check if token is a unicode range (single or multiple <urange> nodes)
8718 * @param {number} i Token's index
8719 * @return {number} Unicode range node's length
8721 function checkUnicodeRange(i) {
8725 if (i >= tokensLength) return 0;
8727 if (l = checkUrange(i)) i += l;else return 0;
8729 while (i < tokensLength) {
8730 var spaceBefore = checkSC(i);
8731 var comma = checkDelim(i + spaceBefore);
8734 var spaceAfter = checkSC(i + spaceBefore + comma);
8735 if (l = checkUrange(i + spaceBefore + comma + spaceAfter)) {
8736 i += spaceBefore + comma + spaceAfter + l;
8744 * Get a unicode range node
8747 function getUnicodeRange() {
8748 var type = NodeType.UnicodeRangeType;
8749 var token = tokens[pos];
8750 var line = token.ln;
8751 var column = token.col;
8754 while (pos < tokensLength) {
8755 if (checkSC(pos)) content = content.concat(getSC());else if (checkDelim(pos)) content.push(getDelim());else if (checkUrange(pos)) content.push(getUrange());else break;
8758 return newNode(type, content, line, column);
8762 * Check if token is unit
8763 * @param {Number} i Token's index number
8766 function checkUnit(i) {
8767 var units = ['em', 'ex', 'ch', 'rem', 'vh', 'vw', 'vmin', 'vmax', 'px', 'mm', 'q', 'cm', 'in', 'pt', 'pc', 'deg', 'grad', 'rad', 'turn', 's', 'ms', 'Hz', 'kHz', 'dpi', 'dpcm', 'dppx'];
8769 return units.indexOf(tokens[i].value) !== -1 ? 1 : 0;
8773 * Get unit node of type ident
8774 * @return {Node} An ident node containing the unit value
8776 function getUnit() {
8777 var type = NodeType.IdentType;
8778 var token = tokens[pos];
8779 var line = token.ln;
8780 var column = token.col;
8781 var content = token.value;
8785 return newNode(type, content, line, column);
8789 * Check if token is a u-range (part of a unicode-range)
8793 * @param {number} i Token's index
8794 * @return {number} Urange node's length
8796 function checkUrange(i) {
8800 if (i >= tokensLength) return 0;
8802 // Check for unicode prefix (u+ or U+)
8803 if (tokens[i].value === 'U' || tokens[i].value === 'u') i += 1;else return 0;
8805 if (i >= tokensLength) return 0;
8807 if (tokens[i].value === '+') i += 1;else return 0;
8809 while (i < tokensLength) {
8810 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = _checkUnicodeWildcard(i)) i += l;else break;
8813 tokens[start].urangeEnd = i - 1;
8819 * Get a u-range node (part of a unicode-range)
8822 function getUrange() {
8824 var type = NodeType.UrangeType;
8825 var token = tokens[pos];
8826 var line = token.ln;
8827 var column = token.col;
8830 content = joinValues(startPos, tokens[startPos].urangeEnd);
8831 pos = tokens[startPos].urangeEnd + 1;
8833 return newNode(type, content, line, column);
8837 * Check for unicode wildcard characters `?`
8838 * @param {number} i Token's index
8839 * @return {number} Wildcard length
8841 function _checkUnicodeWildcard(i) {
8844 if (i >= tokensLength) return 0;
8846 while (i < tokensLength) {
8847 if (tokens[i].type === TokenType.QuestionMark) i += 1;else break;
8854 * Check if token is part of URI (e.g. `url('/css/styles.css')`)
8855 * @param {Number} i Token's index number
8856 * @returns {Number} Length of URI
8858 function checkUri(i) {
8861 if (i >= tokensLength || tokens[i++].value !== 'url' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
8863 return tokens[i].right - start + 1;
8868 * @returns {Array} `['uri', x]` where `x` is URI's nodes (without `url`
8869 * and braces, e.g. `['string', ''/css/styles.css'']`).
8873 var uriExcluding = {};
8881 uriExcluding[TokenType.Space] = 1;
8882 uriExcluding[TokenType.Tab] = 1;
8883 uriExcluding[TokenType.Newline] = 1;
8884 uriExcluding[TokenType.LeftParenthesis] = 1;
8885 uriExcluding[TokenType.RightParenthesis] = 1;
8887 if (checkUri1(pos)) {
8888 uri = [].concat(getSC()).concat([getString()]).concat(getSC());
8891 l = checkExcluding(uriExcluding, pos);
8892 token = tokens[pos];
8893 raw = newNode(NodeType.RawType, joinValues(pos, pos + l), token.ln, token.col);
8899 uri = uri.concat(getSC());
8902 token = tokens[startPos];
8903 var line = token.ln;
8904 var column = token.col;
8905 var end = getLastPosition(uri, line, column, 1);
8908 return newNode(NodeType.UriType, uri, line, column, end);
8912 * @param {Number} i Token's index number
8915 function checkUri1(i) {
8919 if (i >= tokensLength) return 0;
8921 if (l = checkSC(i)) i += l;
8923 if (tokens[i].type !== TokenType.StringDQ && tokens[i].type !== TokenType.StringSQ) {
8929 if (l = checkSC(i)) i += l;
8935 * Check if token is part of a value
8936 * @param {Number} i Token's index number
8937 * @returns {Number} Length of the value
8939 function checkValue(i) {
8945 while (i < tokensLength) {
8949 if (l = _checkValue(_i)) i += l + s;
8950 if (!l || checkBlock(_i)) break;
8953 tokens[start].value_end = i;
8961 function getValue() {
8962 var type = NodeType.ValueType;
8963 var token = tokens[pos];
8964 var line = token.ln;
8965 var column = token.col;
8966 var end = tokens[pos].value_end;
8975 if (!_checkValue(_pos)) break;
8977 if (s) content = content.concat(getSC());
8978 content.push(_getValue());
8981 return newNode(type, content, line, column);
8985 * @param {Number} i Token's index number
8988 function _checkValue(i) {
8991 if (l = checkEscapedString(i)) tokens[i].value_child = 1;else if (l = checkInterpolatedVariable(i)) tokens[i].value_child = 2;else if (l = checkVariable(i)) tokens[i].value_child = 3;else if (l = checkVhash(i)) tokens[i].value_child = 4;else if (l = checkBlock(i)) tokens[i].value_child = 5;else if (l = checkProgid(i)) tokens[i].value_child = 6;else if (l = checkAny(i)) tokens[i].value_child = 7;else if (l = checkAtkeyword(i)) tokens[i].value_child = 8;else if (l = checkOperator(i)) tokens[i].value_child = 9;else if (l = checkImportant(i)) tokens[i].value_child = 10;
8999 function _getValue() {
9000 var childType = tokens[pos].value_child;
9001 if (childType === 1) return getEscapedString();
9002 if (childType === 2) return getInterpolatedVariable();
9003 if (childType === 3) return getVariable();
9004 if (childType === 4) return getVhash();
9005 if (childType === 5) return getBlock();
9006 if (childType === 6) return getProgid();
9007 if (childType === 7) return getAny();
9008 if (childType === 8) return getAtkeyword();
9009 if (childType === 9) return getOperator();
9010 if (childType === 10) return getImportant();
9014 * Check if token is part of LESS variable
9015 * @param {Number} i Token's index number
9016 * @returns {Number} Length of the variable
9018 function checkVariable(i) {
9021 if (i >= tokensLength || tokens[i].type !== TokenType.CommercialAt) return 0;
9023 if (tokens[i - 1] && tokens[i - 1].type === TokenType.CommercialAt && tokens[i - 2] && tokens[i - 2].type === TokenType.CommercialAt) return 0;
9025 return (l = checkVariable(i + 1) || checkIdent(i + 1)) ? l + 1 : 0;
9029 * Get node with a variable
9030 * @returns {Array} `['variable', ['ident', x]]` where `x` is
9033 function getVariable() {
9034 var type = NodeType.VariableType;
9035 var token = tokens[pos];
9036 var line = token.ln;
9037 var column = token.col;
9043 if (checkVariable(pos)) content.push(getVariable());else content.push(getIdent());
9045 return newNode(type, content, line, column);
9049 * Check if token is part of a variables list (e.g. `@rest...`).
9050 * @param {Number} i Token's index number
9053 function checkVariablesList(i) {
9054 var d = 0; // Number of dots
9057 if (i >= tokensLength) return 0;
9059 if (l = checkVariable(i)) i += l;else return 0;
9061 while (tokens[i] && tokens[i].type === TokenType.FullStop) {
9066 return d === 3 ? l + d : 0;
9070 * Get node with a variables list
9071 * @returns {Array} `['variableslist', ['variable', ['ident', x]]]` where
9072 * `x` is a variable name.
9074 function getVariablesList() {
9075 var type = NodeType.VariablesListType;
9076 var token = tokens[pos];
9077 var line = token.ln;
9078 var column = token.col;
9079 var content = [getVariable()];
9080 var end = getLastPosition(content, line, column, 3);
9085 return newNode(type, content, line, column, end);
9089 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
9091 * @param {Number} i Token's index number
9094 function checkVhash(i) {
9098 if (i >= tokensLength) return 0;
9101 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
9103 if (l = checkNmName2(i)) i += l;else return 0;
9109 * Get node with a hexadecimal number (e.g. `#fff`) inside some value
9110 * @returns {Array} `['vhash', x]` where `x` is a hexadecimal number
9111 * converted to string (without `#`, e.g. `'fff'`).
9113 function getVhash() {
9114 var type = NodeType.VhashType;
9115 var token = tokens[pos];
9116 var line = token.ln;
9117 var column = token.col;
9122 var content = getNmName2();
9123 var end = getLastPosition(content, line, column + 1);
9124 return newNode(type, content, line, column, end);
9127 function checkSelectorsGroup(i) {
9128 if (i >= tokensLength) return 0;
9133 if (l = checkSelector(i)) i += l;else return 0;
9135 while (i < tokensLength) {
9136 var spaceBefore = checkSC(i);
9137 var comma = checkDelim(i + spaceBefore);
9140 var spaceAfter = checkSC(i + spaceBefore + comma);
9141 if (l = checkSelector(i + spaceBefore + comma + spaceAfter)) {
9142 i += spaceBefore + comma + spaceAfter + l;
9146 tokens[start].selectorsGroupEnd = i;
9150 function getSelectorsGroup() {
9151 var selectorsGroup = [];
9152 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
9154 selectorsGroup.push(getSelector());
9156 while (pos < selectorsGroupEnd) {
9157 selectorsGroup = selectorsGroup.concat(getSC(), getDelim(), getSC(), getSelector());
9160 return selectorsGroup;
9163 function checkSelector(i) {
9166 if (l = checkSelector1(i)) tokens[i].selectorType = 1;else if (l = checkSelector2(i)) tokens[i].selectorType = 2;
9171 function getSelector() {
9172 var selectorType = tokens[pos].selectorType;
9173 if (selectorType === 1) return getSelector1();else return getSelector2();
9177 * Checks for selector which starts with a compound selector.
9179 function checkSelector1(i) {
9180 if (i >= tokensLength) return 0;
9185 if (l = checkCompoundSelector(i)) i += l;else return 0;
9187 while (i < tokensLength) {
9188 var space = checkSC(i);
9189 var comma = checkCombinator(i + space);
9190 if (!space && !comma) break;
9197 if (l = checkCompoundSelector(i + space)) i += space + l;else break;
9200 tokens[start].selectorEnd = i;
9204 function getSelector1() {
9205 var type = NodeType.SelectorType;
9206 var token = tokens[pos];
9207 var line = token.ln;
9208 var column = token.col;
9209 var selectorEnd = token.selectorEnd;
9210 var content = getCompoundSelector();
9212 while (pos < selectorEnd) {
9213 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
9216 return newNode(type, content, line, column);
9220 * Checks for a selector that starts with a combinator.
9222 function checkSelector2(i) {
9223 if (i >= tokensLength) return 0;
9228 if (l = checkCombinator(i)) i += l;else return 0;
9230 while (i < tokensLength) {
9231 var spaceBefore = checkSC(i);
9232 if (l = checkCompoundSelector(i + spaceBefore)) i += spaceBefore + l;else break;
9234 var spaceAfter = checkSC(i);
9235 var comma = checkCombinator(i + spaceAfter);
9236 if (!spaceAfter && !comma) break;
9238 i += spaceAfter + comma;
9242 tokens[start].selectorEnd = i;
9246 function getSelector2() {
9247 var type = NodeType.SelectorType;
9248 var token = tokens[pos];
9249 var line = token.ln;
9250 var column = token.col;
9251 var selectorEnd = token.selectorEnd;
9252 var content = [getCombinator()];
9254 while (pos < selectorEnd) {
9255 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
9258 return newNode(type, content, line, column);
9261 function checkCompoundSelector(i) {
9264 if (l = checkCompoundSelector1(i)) {
9265 tokens[i].compoundSelectorType = 1;
9266 } else if (l = checkCompoundSelector2(i)) {
9267 tokens[i].compoundSelectorType = 2;
9273 function getCompoundSelector() {
9274 var type = tokens[pos].compoundSelectorType;
9275 if (type === 1) return getCompoundSelector1();
9276 if (type === 2) return getCompoundSelector2();
9279 function checkCompoundSelector1(i) {
9280 if (i >= tokensLength) return 0;
9285 if (l = checkUniversalSelector(i) || checkTypeSelector(i) || checkParentSelectorWithExtension(i)) i += l;else return 0;
9287 while (i < tokensLength) {
9288 var _l2 = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i);
9289 if (_l2) i += _l2;else break;
9292 tokens[start].compoundSelectorEnd = i;
9297 function getCompoundSelector1() {
9299 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
9301 if (checkUniversalSelector(pos)) sequence.push(getUniversalSelector());else if (checkTypeSelector(pos)) sequence.push(getTypeSelector());else if (checkParentSelectorWithExtension(pos)) sequence = sequence.concat(getParentSelectorWithExtension());
9303 while (pos < compoundSelectorEnd) {
9304 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());
9310 function checkCompoundSelector2(i) {
9311 if (i >= tokensLength) return 0;
9315 while (i < tokensLength) {
9316 var l = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i);
9317 if (l) i += l;else break;
9320 tokens[start].compoundSelectorEnd = i;
9325 function getCompoundSelector2() {
9327 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
9329 while (pos < compoundSelectorEnd) {
9330 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());
9336 function checkUniversalSelector(i) {
9337 if (i >= tokensLength) return 0;
9342 if (l = checkNamePrefix(i)) i += l;
9344 if (tokens[i].type === TokenType.Asterisk) i++;else return 0;
9349 function getUniversalSelector() {
9350 var type = NodeType.UniversalSelectorType;
9351 var token = tokens[pos];
9352 var line = token.ln;
9353 var column = token.col;
9357 if (checkNamePrefix(pos)) {
9358 content.push(getNamePrefix());
9359 end = getLastPosition(content, line, column, 1);
9364 return newNode(type, content, line, column, end);
9367 function checkTypeSelector(i) {
9368 if (i >= tokensLength) return 0;
9373 if (l = checkNamePrefix(i)) i += l;
9375 if (l = checkIdent(i)) i += l;else return 0;
9380 function getTypeSelector() {
9381 var type = NodeType.TypeSelectorType;
9382 var token = tokens[pos];
9383 var line = token.ln;
9384 var column = token.col;
9387 if (checkNamePrefix(pos)) content.push(getNamePrefix());
9389 content.push(getIdent());
9391 return newNode(type, content, line, column);
9394 function checkAttributeSelector(i) {
9396 if (l = checkAttributeSelector1(i)) tokens[i].attributeSelectorType = 1;else if (l = checkAttributeSelector2(i)) tokens[i].attributeSelectorType = 2;
9401 function getAttributeSelector() {
9402 var type = tokens[pos].attributeSelectorType;
9403 if (type === 1) return getAttributeSelector1();else return getAttributeSelector2();
9407 * (1) `[panda=nani]`
9408 * (2) `[panda='nani']`
9409 * (3) `[panda='nani' i]`
9412 function checkAttributeSelector1(i) {
9415 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
9418 if (l = checkSC(i)) i += l;
9420 if (l = checkAttributeName(i)) i += l;else return 0;
9422 if (l = checkSC(i)) i += l;
9424 if (l = checkAttributeMatch(i)) i += l;else return 0;
9426 if (l = checkSC(i)) i += l;
9428 if (l = checkAttributeValue(i)) i += l;else return 0;
9430 if (l = checkSC(i)) i += l;
9432 if (l = checkAttributeFlags(i)) {
9434 if (l = checkSC(i)) i += l;
9437 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
9442 function getAttributeSelector1() {
9443 var type = NodeType.AttributeSelectorType;
9444 var token = tokens[pos];
9445 var line = token.ln;
9446 var column = token.col;
9452 content = content.concat(getSC(), getAttributeName(), getSC(), getAttributeMatch(), getSC(), getAttributeValue(), getSC());
9454 if (checkAttributeFlags(pos)) {
9455 content.push(getAttributeFlags());
9456 content = content.concat(getSC());
9462 var end = getLastPosition(content, line, column, 1);
9463 return newNode(type, content, line, column, end);
9469 function checkAttributeSelector2(i) {
9472 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
9475 if (l = checkSC(i)) i += l;
9477 if (l = checkAttributeName(i)) i += l;else return 0;
9479 if (l = checkSC(i)) i += l;
9481 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
9486 function getAttributeSelector2() {
9487 var type = NodeType.AttributeSelectorType;
9488 var token = tokens[pos];
9489 var line = token.ln;
9490 var column = token.col;
9496 content = content.concat(getSC(), getAttributeName(), getSC());
9501 var end = getLastPosition(content, line, column, 1);
9502 return newNode(type, content, line, column, end);
9505 function checkAttributeName(i) {
9509 if (l = checkNamePrefix(i)) i += l;
9511 if (l = checkIdent(i)) i += l;else return 0;
9516 function getAttributeName() {
9517 var type = NodeType.AttributeNameType;
9518 var token = tokens[pos];
9519 var line = token.ln;
9520 var column = token.col;
9523 if (checkNamePrefix(pos)) content.push(getNamePrefix());
9524 content.push(getIdent());
9526 return newNode(type, content, line, column);
9529 function checkAttributeMatch(i) {
9531 if (l = checkAttributeMatch1(i)) tokens[i].attributeMatchType = 1;else if (l = checkAttributeMatch2(i)) tokens[i].attributeMatchType = 2;
9536 function getAttributeMatch() {
9537 var type = tokens[pos].attributeMatchType;
9538 if (type === 1) return getAttributeMatch1();else return getAttributeMatch2();
9541 function checkAttributeMatch1(i) {
9544 var type = tokens[i].type;
9545 if (type === TokenType.Tilde || type === TokenType.VerticalLine || type === TokenType.CircumflexAccent || type === TokenType.DollarSign || type === TokenType.Asterisk) i++;else return 0;
9547 if (tokens[i].type === TokenType.EqualsSign) i++;else return 0;
9552 function getAttributeMatch1() {
9553 var type = NodeType.AttributeMatchType;
9554 var token = tokens[pos];
9555 var line = token.ln;
9556 var column = token.col;
9557 var content = tokens[pos].value + tokens[pos + 1].value;
9560 return newNode(type, content, line, column);
9563 function checkAttributeMatch2(i) {
9564 if (tokens[i].type === TokenType.EqualsSign) return 1;else return 0;
9567 function getAttributeMatch2() {
9568 var type = NodeType.AttributeMatchType;
9569 var token = tokens[pos];
9570 var line = token.ln;
9571 var column = token.col;
9575 return newNode(type, content, line, column);
9578 function checkAttributeValue(i) {
9579 return checkString(i) || checkIdent(i);
9582 function getAttributeValue() {
9583 var type = NodeType.AttributeValueType;
9584 var token = tokens[pos];
9585 var line = token.ln;
9586 var column = token.col;
9589 if (checkString(pos)) content.push(getString());else content.push(getIdent());
9591 return newNode(type, content, line, column);
9594 function checkAttributeFlags(i) {
9595 return checkIdent(i);
9598 function getAttributeFlags() {
9599 var type = NodeType.AttributeFlagsType;
9600 var token = tokens[pos];
9601 var line = token.ln;
9602 var column = token.col;
9603 var content = [getIdent()];
9605 return newNode(type, content, line, column);
9608 function checkNamePrefix(i) {
9609 if (i >= tokensLength) return 0;
9612 if (l = checkNamePrefix1(i)) tokens[i].namePrefixType = 1;else if (l = checkNamePrefix2(i)) tokens[i].namePrefixType = 2;
9617 function getNamePrefix() {
9618 var type = tokens[pos].namePrefixType;
9619 if (type === 1) return getNamePrefix1();else return getNamePrefix2();
9624 * (2) `panda<comment>|`
9626 function checkNamePrefix1(i) {
9630 if (l = checkNamespacePrefix(i)) i += l;else return 0;
9632 if (l = checkCommentML(i)) i += l;
9634 if (l = checkNamespaceSeparator(i)) i += l;else return 0;
9639 function getNamePrefix1() {
9640 var type = NodeType.NamePrefixType;
9641 var token = tokens[pos];
9642 var line = token.ln;
9643 var column = token.col;
9646 content.push(getNamespacePrefix());
9648 if (checkCommentML(pos)) content.push(getCommentML());
9650 content.push(getNamespaceSeparator());
9652 return newNode(type, content, line, column);
9658 function checkNamePrefix2(i) {
9659 return checkNamespaceSeparator(i);
9662 function getNamePrefix2() {
9663 var type = NodeType.NamePrefixType;
9664 var token = tokens[pos];
9665 var line = token.ln;
9666 var column = token.col;
9667 var content = [getNamespaceSeparator()];
9669 return newNode(type, content, line, column);
9676 function checkNamespacePrefix(i) {
9677 if (i >= tokensLength) return 0;
9681 if (tokens[i].type === TokenType.Asterisk) return 1;else if (l = checkIdent(i)) return l;else return 0;
9684 function getNamespacePrefix() {
9685 var type = NodeType.NamespacePrefixType;
9686 var token = tokens[pos];
9687 var line = token.ln;
9688 var column = token.col;
9691 if (token.type === TokenType.Asterisk) {
9692 var asteriskNode = newNode(NodeType.IdentType, '*', line, column);
9693 content.push(asteriskNode);
9695 } else if (checkIdent(pos)) content.push(getIdent());
9697 return newNode(type, content, line, column);
9703 function checkNamespaceSeparator(i) {
9704 if (i >= tokensLength) return 0;
9706 if (tokens[i].type !== TokenType.VerticalLine) return 0;
9708 // Return false if `|=` - [attr|=value]
9709 if (tokens[i + 1] && tokens[i + 1].type === TokenType.EqualsSign) return 0;
9714 function getNamespaceSeparator() {
9715 var type = NodeType.NamespaceSeparatorType;
9716 var token = tokens[pos];
9717 var line = token.ln;
9718 var column = token.col;
9722 return newNode(type, content, line, column);
9725 module.exports = function (_tokens, context) {
9727 tokensLength = tokens.length;
9730 return contexts[context]();
9735 /***/ (function(module, exports, __webpack_require__) {
9739 module.exports = function (css, tabSize) {
9740 var TokenType = __webpack_require__(13);
9743 var urlMode = false;
9744 var c = void 0; // Current character
9745 var cn = void 0; // Next character
9752 ' ': TokenType.Space,
9753 '\n': TokenType.Newline,
9754 '\r': TokenType.Newline,
9755 '\t': TokenType.Tab,
9756 '!': TokenType.ExclamationMark,
9757 '"': TokenType.QuotationMark,
9758 '#': TokenType.NumberSign,
9759 '$': TokenType.DollarSign,
9760 '%': TokenType.PercentSign,
9761 '&': TokenType.Ampersand,
9762 '\'': TokenType.Apostrophe,
9763 '(': TokenType.LeftParenthesis,
9764 ')': TokenType.RightParenthesis,
9765 '*': TokenType.Asterisk,
9766 '+': TokenType.PlusSign,
9767 ',': TokenType.Comma,
9768 '-': TokenType.HyphenMinus,
9769 '.': TokenType.FullStop,
9770 '/': TokenType.Solidus,
9771 ':': TokenType.Colon,
9772 ';': TokenType.Semicolon,
9773 '<': TokenType.LessThanSign,
9774 '=': TokenType.EqualsSign,
9775 '>': TokenType.GreaterThanSign,
9776 '?': TokenType.QuestionMark,
9777 '@': TokenType.CommercialAt,
9778 '[': TokenType.LeftSquareBracket,
9779 ']': TokenType.RightSquareBracket,
9780 '^': TokenType.CircumflexAccent,
9781 '_': TokenType.LowLine,
9782 '{': TokenType.LeftCurlyBracket,
9783 '|': TokenType.VerticalLine,
9784 '}': TokenType.RightCurlyBracket,
9785 '~': TokenType.Tilde
9789 * Add a token to the token list
9790 * @param {string} type
9791 * @param {string} value
9793 function pushToken(type, value, column) {
9804 * Check if a character is a decimal digit
9805 * @param {string} c Character
9806 * @returns {boolean}
9808 function isDecimalDigit(c) {
9809 return '0123456789'.indexOf(c) >= 0;
9814 * @param {string} css Unparsed part of CSS string
9816 function parseSpaces(css) {
9819 // Read the string until we meet a non-space character:
9820 for (; pos < css.length; pos++) {
9821 if (css.charAt(pos) !== ' ') break;
9824 // Add a substring containing only spaces to tokens:
9825 pushToken(TokenType.Space, css.substring(start, pos--), col);
9830 * Parse a string within quotes
9831 * @param {string} css Unparsed part of CSS string
9832 * @param {string} q Quote (either `'` or `"`)
9834 function parseString(css, q) {
9837 // Read the string until we meet a matching quote:
9838 for (pos++; pos < css.length; pos++) {
9839 // Skip escaped quotes:
9840 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) === q) break;
9843 // Add the string (including quotes) to tokens:
9844 var type = q === '"' ? TokenType.StringDQ : TokenType.StringSQ;
9845 pushToken(type, css.substring(start, pos + 1), col);
9851 * @param {string} css Unparsed part of CSS string
9853 function parseDecimalNumber(css) {
9856 // Read the string until we meet a character that's not a digit:
9857 for (; pos < css.length; pos++) {
9858 if (!isDecimalDigit(css.charAt(pos))) break;
9861 // Add the number to tokens:
9862 pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);
9868 * @param {string} css Unparsed part of CSS string
9870 function parseIdentifier(css) {
9873 // Skip all opening slashes:
9874 while (css.charAt(pos) === '/') {
9876 } // Read the string until we meet a punctuation mark:
9877 for (; pos < css.length; pos++) {
9879 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) in Punctuation) break;
9882 var ident = css.substring(start, pos--);
9884 // Enter url mode if parsed substring is `url`:
9885 if (!urlMode && ident === 'url' && css.charAt(pos + 1) === '(') {
9889 // Add identifier to tokens:
9890 pushToken(TokenType.Identifier, ident, col);
9895 * Parse a multiline comment
9896 * @param {string} css Unparsed part of CSS string
9898 function parseMLComment(css) {
9901 // Read the string until we meet `*/`.
9902 // Since we already know first 2 characters (`/*`), start reading
9904 for (pos = pos + 2; pos < css.length; pos++) {
9905 if (css.charAt(pos) === '*' && css.charAt(pos + 1) === '/') {
9911 // Add full comment (including `/*` and `*/`) to the list of tokens:
9912 var comment = css.substring(start, pos + 1);
9913 pushToken(TokenType.CommentML, comment, col);
9915 var newlines = comment.split('\n');
9916 if (newlines.length > 1) {
9917 ln += newlines.length - 1;
9918 col = newlines[newlines.length - 1].length;
9925 * Parse a single line comment
9926 * @param {string} css Unparsed part of CSS string
9928 function parseSLComment(css) {
9931 // Read the string until we meet line break.
9932 // Since we already know first 2 characters (`//`), start reading
9934 for (pos += 2; pos < css.length; pos++) {
9935 if (css.charAt(pos) === '\n' || css.charAt(pos) === '\r') {
9940 // Add comment (including `//` and line break) to the list of tokens:
9941 pushToken(TokenType.CommentSL, css.substring(start, pos--), col);
9946 * Convert a CSS string to a list of tokens
9947 * @param {string} css CSS string
9948 * @returns {Array} List of tokens
9951 function getTokens(css) {
9952 // Parse string, character by character:
9953 for (pos = 0; pos < css.length; col++, pos++) {
9954 c = css.charAt(pos);
9955 cn = css.charAt(pos + 1);
9957 // If we meet `/*`, it's a start of a multiline comment.
9958 // Parse following characters as a multiline comment:
9959 if (c === '/' && cn === '*') {
9960 parseMLComment(css);
9963 // If we meet `//` and it is not a part of url:
9964 else if (!urlMode && c === '/' && cn === '/') {
9965 // If we're currently inside a block, treat `//` as a start
9966 // of identifier. Else treat `//` as a start of a single-line
9968 parseSLComment(css);
9971 // If current character is a double or single quote, it's a start
9973 else if (c === '"' || c === "'") {
9974 parseString(css, c);
9977 // If current character is a space:
9978 else if (c === ' ') {
9982 // If current character is a punctuation mark:
9983 else if (c in Punctuation) {
9984 // Add it to the list of tokens:
9985 pushToken(Punctuation[c], c, col);
9986 if (c === '\n' || c === '\r') {
9989 } // Go to next line
9990 if (c === ')') urlMode = false; // Exit url mode
9991 else if (c === '\t' && tabSize > 1) col += tabSize - 1;
9994 // If current character is a decimal digit:
9995 else if (isDecimalDigit(c)) {
9996 parseDecimalNumber(css);
9999 // If current character is anything else:
10001 parseIdentifier(css);
10008 return getTokens(css);
10013 /***/ (function(module, exports, __webpack_require__) {
10017 exports.__esModule = true;
10018 exports.default = {
10019 mark: __webpack_require__(22),
10020 parse: __webpack_require__(23),
10021 stringify: __webpack_require__(5),
10022 tokenizer: __webpack_require__(24)
10024 module.exports = exports['default'];
10028 /***/ (function(module, exports, __webpack_require__) {
10032 var TokenType = __webpack_require__(13);
10034 module.exports = function () {
10036 * Mark whitespaces and comments
10038 function markSC(tokens) {
10039 var tokensLength = tokens.length;
10040 var ws = -1; // Flag for whitespaces
10041 var sc = -1; // Flag for whitespaces and comments
10042 var t = void 0; // Current token
10044 // For every token in the token list, mark spaces and line breaks
10045 // as spaces (set both `ws` and `sc` flags). Mark multiline comments
10047 // If there are several spaces or tabs or line breaks or multiline
10048 // comments in a row, group them: take the last one's index number
10049 // and save it to the first token in the group as a reference:
10050 // e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
10051 // for a group of whitespaces and comments.
10052 for (var i = 0; i < tokensLength; i++) {
10055 case TokenType.Space:
10056 case TokenType.Tab:
10060 if (ws === -1) ws = i;
10061 if (sc === -1) sc = i;
10064 case TokenType.Newline:
10068 ws = ws === -1 ? i : ws;
10069 sc = sc === -1 ? i : ws;
10071 tokens[ws].ws_last = i - 1;
10072 tokens[sc].sc_last = i - 1;
10073 tokens[i].ws_last = i;
10074 tokens[i].sc_last = i;
10080 case TokenType.CommentML:
10081 case TokenType.CommentSL:
10083 tokens[ws].ws_last = i - 1;
10092 tokens[ws].ws_last = i - 1;
10097 tokens[sc].sc_last = i - 1;
10103 if (ws !== -1) tokens[ws].ws_last = i - 1;
10104 if (sc !== -1) tokens[sc].sc_last = i - 1;
10110 function markBrackets(tokens) {
10111 var tokensLength = tokens.length;
10112 var ps = []; // Parentheses
10113 var sbs = []; // Square brackets
10114 var cbs = []; // Curly brackets
10115 var t = void 0; // Current token
10117 // For every token in the token list, if we meet an opening (left)
10118 // bracket, push its index number to a corresponding array.
10119 // If we then meet a closing (right) bracket, look at the corresponding
10120 // array. If there are any elements (records about previously met
10121 // left brackets), take a token of the last left bracket (take
10122 // the last index number from the array and find a token with
10123 // this index number) and save right bracket's index as a reference:
10124 for (var i = 0; i < tokensLength; i++) {
10127 case TokenType.LeftParenthesis:
10130 case TokenType.RightParenthesis:
10133 tokens[t.left].right = i;
10136 case TokenType.LeftSquareBracket:
10139 case TokenType.RightSquareBracket:
10141 t.left = sbs.pop();
10142 tokens[t.left].right = i;
10145 case TokenType.LeftCurlyBracket:
10148 case TokenType.RightCurlyBracket:
10150 t.left = cbs.pop();
10151 tokens[t.left].right = i;
10158 function markBlocks(tokens) {
10160 var l = tokens.length;
10162 var whitespaceOnlyLines = [];
10164 for (i = 0; i < l; i++) {
10166 var currentLineIndent = 0;
10169 while (i < l && (tokens[i].type === TokenType.Space || tokens[i].type === TokenType.Tab)) {
10170 currentLineIndent += tokens[i].value.length;
10174 lines.push([lineStart, currentLineIndent]);
10177 while (i < l && tokens[i].type !== TokenType.Newline) {
10182 whitespaceOnlyLines.push(lines.length - 1);
10187 var blockStarts = [];
10189 for (i = 0; i < lines.length; i++) {
10190 var line = lines[i];
10191 var token = line[0];
10192 var indent = line[1];
10193 var lastLevel = levels[levels.length - 1];
10195 if (indent > lastLevel) {
10196 blockStarts.push(token);
10197 levels.push(indent);
10199 // Check if line is whitespace-only.
10203 if (whitespaceOnlyLines.indexOf(p) === -1) break;
10207 if (i === p && indent === lastLevel) continue;
10213 indent = lines[p][1];
10215 if (indent === lastLevel) {
10220 if (indent > lastLevel) {
10221 blockStarts.push(token);
10222 levels.push(lines[p][1]);
10228 var _lastLevel = levels.pop();
10229 if (indent < _lastLevel) {
10230 var start = blockStarts.pop();
10231 tokens[start].block_end = token - 1;
10233 levels.push(indent);
10240 blockStarts.forEach(function (start) {
10241 tokens[start].block_end = tokens.length - 1;
10245 return function (tokens) {
10246 markBrackets(tokens);
10248 markBlocks(tokens);
10254 /***/ (function(module, exports, __webpack_require__) {
10258 var Node = __webpack_require__(1);
10259 var NodeType = __webpack_require__(15);
10260 var TokenType = __webpack_require__(13);
10262 var tokens = void 0;
10263 var tokensLength = void 0;
10267 'arguments': function _arguments() {
10268 return checkArguments(pos) && getArguments();
10270 'atkeyword': function atkeyword() {
10271 return checkAtkeyword(pos) && getAtkeyword();
10273 'atrule': function atrule() {
10274 return checkAtrule(pos) && getAtrule();
10276 'attributeSelector': function attributeSelector() {
10277 return checkAttributeSelector(pos) && getAttributeSelector();
10279 'block': function block() {
10280 return checkBlock(pos) && getBlock();
10282 'brackets': function brackets() {
10283 return checkBrackets(pos) && getBrackets();
10285 'class': function _class() {
10286 return checkClass(pos) && getClass();
10288 'combinator': function combinator() {
10289 return checkCombinator(pos) && getCombinator();
10291 'commentML': function commentML() {
10292 return checkCommentML(pos) && getCommentML();
10294 'commentSL': function commentSL() {
10295 return checkCommentSL(pos) && getCommentSL();
10297 'condition': function condition() {
10298 return checkCondition(pos) && getCondition();
10300 'conditionalStatement': function conditionalStatement() {
10301 return checkConditionalStatement(pos) && getConditionalStatement();
10303 'declaration': function declaration() {
10304 return checkDeclaration(pos) && getDeclaration();
10306 'declDelim': function declDelim() {
10307 return checkDeclDelim(pos) && getDeclDelim();
10309 'default': function _default() {
10310 return checkDefault(pos) && getDefault();
10312 'delim': function delim() {
10313 return checkDelim(pos) && getDelim();
10315 'dimension': function dimension() {
10316 return checkDimension(pos) && getDimension();
10318 'expression': function expression() {
10319 return checkExpression(pos) && getExpression();
10321 'extend': function extend() {
10322 return checkExtend(pos) && getExtend();
10324 'function': function _function() {
10325 return checkFunction(pos) && getFunction();
10327 'global': function global() {
10328 return checkGlobal(pos) && getGlobal();
10330 'ident': function ident() {
10331 return checkIdent(pos) && getIdent();
10333 'important': function important() {
10334 return checkImportant(pos) && getImportant();
10336 'include': function include() {
10337 return checkInclude(pos) && getInclude();
10339 'interpolation': function interpolation() {
10340 return checkInterpolation(pos) && getInterpolation();
10342 'loop': function loop() {
10343 return checkLoop(pos) && getLoop();
10345 'mixin': function mixin() {
10346 return checkMixin(pos) && getMixin();
10348 'namespace': function namespace() {
10349 return checkNamespace(pos) && getNamespace();
10351 'number': function number() {
10352 return checkNumber(pos) && getNumber();
10354 'operator': function operator() {
10355 return checkOperator(pos) && getOperator();
10357 'optional': function optional() {
10358 return checkOptional(pos) && getOptional();
10360 'parentheses': function parentheses() {
10361 return checkParentheses(pos) && getParentheses();
10363 'parentselector': function parentselector() {
10364 return checkParentSelector(pos) && getParentSelector();
10366 'percentage': function percentage() {
10367 return checkPercentage(pos) && getPercentage();
10369 'placeholder': function placeholder() {
10370 return checkPlaceholder(pos) && getPlaceholder();
10372 'progid': function progid() {
10373 return checkProgid(pos) && getProgid();
10375 'property': function property() {
10376 return checkProperty(pos) && getProperty();
10378 'propertyDelim': function propertyDelim() {
10379 return checkPropertyDelim(pos) && getPropertyDelim();
10381 'pseudoc': function pseudoc() {
10382 return checkPseudoc(pos) && getPseudoc();
10384 'pseudoe': function pseudoe() {
10385 return checkPseudoe(pos) && getPseudoe();
10387 'ruleset': function ruleset() {
10388 return checkRuleset(pos) && getRuleset();
10390 's': function s() {
10391 return checkS(pos) && getS();
10393 'selector': function selector() {
10394 return checkSelector(pos) && getSelector();
10396 'shash': function shash() {
10397 return checkShash(pos) && getShash();
10399 'string': function string() {
10400 return checkString(pos) && getString();
10402 'stylesheet': function stylesheet() {
10403 return checkStylesheet(pos) && getStylesheet();
10405 'typeSelector': function typeSelector() {
10406 return checkTypeSelector(pos) && getTypeSelector();
10408 'unary': function unary() {
10409 return checkUnary(pos) && getUnary();
10411 'unicodeRange': function unicodeRange() {
10412 return checkUnicodeRange(pos) && getUnicodeRange();
10414 'universalSelector': function universalSelector() {
10415 return checkUniversalSelector(pos) && getUniversalSelector();
10417 'urange': function urange() {
10418 return checkUrange(pos) && getUrange();
10420 'uri': function uri() {
10421 return checkUri(pos) && getUri();
10423 'value': function value() {
10424 return checkValue(pos) && getValue();
10426 'variable': function variable() {
10427 return checkVariable(pos) && getVariable();
10429 'variableslist': function variableslist() {
10430 return checkVariablesList(pos) && getVariablesList();
10432 'vhash': function vhash() {
10433 return checkVhash(pos) && getVhash();
10438 * Stops parsing and display error.
10440 * @param {number=} i Token's index number
10442 function throwError(i) {
10443 var ln = tokens[i].ln;
10445 throw { line: ln, syntax: 'sass' };
10449 * @param {number} start
10450 * @param {number} finish
10453 function joinValues(start, finish) {
10456 for (var i = start; i < finish + 1; i++) {
10457 s += tokens[i].value;
10464 * @param {number} start
10465 * @param {number} num
10468 function joinValues2(start, num) {
10469 if (start + num - 1 >= tokensLength) return;
10473 for (var i = 0; i < num; i++) {
10474 s += tokens[start + i].value;
10481 * @param {string|!Array} content
10482 * @param {number} line
10483 * @param {number} column
10484 * @param {number} colOffset
10486 function getLastPosition(content, line, column, colOffset) {
10487 return typeof content === 'string' ? getLastPositionForString(content, line, column, colOffset) : getLastPositionForArray(content, line, column, colOffset);
10491 * @param {string} content
10492 * @param {number} line
10493 * @param {number} column
10494 * @param {number} colOffset
10496 function getLastPositionForString(content, line, column, colOffset) {
10500 position = [line, column];
10501 if (colOffset) position[1] += colOffset - 1;
10505 var lastLinebreak = content.lastIndexOf('\n');
10506 var endsWithLinebreak = lastLinebreak === content.length - 1;
10507 var splitContent = content.split('\n');
10508 var linebreaksCount = splitContent.length - 1;
10509 var prevLinebreak = linebreaksCount === 0 || linebreaksCount === 1 ? -1 : content.length - splitContent[linebreaksCount - 1].length - 2;
10512 var offset = endsWithLinebreak ? linebreaksCount - 1 : linebreaksCount;
10513 position[0] = line + offset;
10516 if (endsWithLinebreak) {
10517 offset = prevLinebreak !== -1 ? content.length - prevLinebreak : content.length - 1;
10519 offset = linebreaksCount !== 0 ? content.length - lastLinebreak - column - 1 : content.length - 1;
10521 position[1] = column + offset;
10523 if (!colOffset) return position;
10525 if (endsWithLinebreak) {
10527 position[1] = colOffset;
10529 position[1] += colOffset;
10536 * @param {!Array} content
10537 * @param {number} line
10538 * @param {number} column
10539 * @param {number} colOffset
10541 function getLastPositionForArray(content, line, column, colOffset) {
10542 var position = void 0;
10544 if (content.length === 0) {
10545 position = [line, column];
10547 var c = content[content.length - 1];
10548 if (c.hasOwnProperty('end')) {
10549 position = [c.end.line, c.end.column];
10551 position = getLastPosition(c.content, line, column);
10555 if (!colOffset) return position;
10557 if (tokens[pos - 1] && tokens[pos - 1].type !== 'Newline') {
10558 position[1] += colOffset;
10568 * @param {string} type
10569 * @param {string|!Array} content
10570 * @param {number} line
10571 * @param {number} column
10572 * @param {!Array} end
10574 function newNode(type, content, line, column, end) {
10575 if (!end) end = getLastPosition(content, line, column);
10592 * @param {number} i Token's index number
10595 function checkAny(i) {
10598 if (l = checkBrackets(i)) tokens[i].any_child = 1;else if (l = checkParentheses(i)) tokens[i].any_child = 2;else if (l = checkString(i)) tokens[i].any_child = 3;else if (l = checkVariablesList(i)) tokens[i].any_child = 4;else if (l = checkVariable(i)) tokens[i].any_child = 5;else if (l = checkPlaceholder(i)) tokens[i].any_child = 6;else if (l = checkPercentage(i)) tokens[i].any_child = 7;else if (l = checkDimension(i)) tokens[i].any_child = 8;else if (l = checkUnicodeRange(i)) tokens[i].any_child = 9;else if (l = checkNumber(i)) tokens[i].any_child = 10;else if (l = checkUri(i)) tokens[i].any_child = 11;else if (l = checkExpression(i)) tokens[i].any_child = 12;else if (l = checkFunctionsList(i)) tokens[i].any_child = 13;else if (l = checkFunction(i)) tokens[i].any_child = 14;else if (l = checkInterpolation(i)) tokens[i].any_child = 15;else if (l = checkIdent(i)) tokens[i].any_child = 16;else if (l = checkClass(i)) tokens[i].any_child = 17;else if (l = checkUnary(i)) tokens[i].any_child = 18;else if (l = checkParentSelector(i)) tokens[i].any_child = 19;else if (l = checkImportant(i)) tokens[i].any_child = 20;else if (l = checkGlobal(i)) tokens[i].any_child = 21;else if (l = checkDefault(i)) tokens[i].any_child = 22;else if (l = checkOptional(i)) tokens[i].any_child = 23;
10606 function getAny() {
10607 var childType = tokens[pos].any_child;
10609 if (childType === 1) return getBrackets();
10610 if (childType === 2) return getParentheses();
10611 if (childType === 3) return getString();
10612 if (childType === 4) return getVariablesList();
10613 if (childType === 5) return getVariable();
10614 if (childType === 6) return getPlaceholder();
10615 if (childType === 7) return getPercentage();
10616 if (childType === 8) return getDimension();
10617 if (childType === 9) return getUnicodeRange();
10618 if (childType === 10) return getNumber();
10619 if (childType === 11) return getUri();
10620 if (childType === 12) return getExpression();
10621 if (childType === 13) return getFunctionsList();
10622 if (childType === 14) return getFunction();
10623 if (childType === 15) return getInterpolation();
10624 if (childType === 16) return getIdent();
10625 if (childType === 17) return getClass();
10626 if (childType === 18) return getUnary();
10627 if (childType === 19) return getParentSelector();
10628 if (childType === 20) return getImportant();
10629 if (childType === 21) return getGlobal();
10630 if (childType === 22) return getDefault();
10631 if (childType === 23) return getOptional();
10635 * Checks if token is part of mixin's arguments.
10637 * @param {number} i Token's index number
10638 * @return {number} Length of arguments
10640 function checkArguments(i) {
10644 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
10649 while (i < tokens[start].right) {
10650 if (l = checkArgument(i)) i += l;else return 0;
10653 return tokens[start].right - start + 1;
10659 function getArguments() {
10660 var type = NodeType.ArgumentsType;
10661 var token = tokens[pos];
10662 var line = token.ln;
10663 var column = token.col;
10670 while (pos < tokensLength && tokens[pos].type !== TokenType.RightParenthesis) {
10671 if (checkSingleValueDeclaration(pos)) {
10672 content.push(getSingleValueDeclaration());
10673 } else if (checkArgument(pos)) {
10674 body = getArgument();
10675 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
10676 } else if (checkClass(pos)) content.push(getClass());else throwError(pos);
10679 var end = getLastPosition(content, line, column, 1);
10684 return newNode(type, content, line, column, end);
10688 * Checks if token is valid to be part of arguments list
10689 * @param {number} i Token's index number
10690 * @return {number} Length of argument
10692 function checkArgument(i) {
10695 if (l = checkBrackets(i)) tokens[i].argument_child = 1;else if (l = checkParentheses(i)) tokens[i].argument_child = 2;else if (l = checkSingleValueDeclaration(i)) tokens[i].argument_child = 3;else if (l = checkFunctionsList(i)) tokens[i].argument_child = 4;else if (l = checkFunction(i)) tokens[i].argument_child = 5;else if (l = checkVariablesList(i)) tokens[i].argument_child = 6;else if (l = checkVariable(i)) tokens[i].argument_child = 7;else if (l = checkSC(i)) tokens[i].argument_child = 8;else if (l = checkDelim(i)) tokens[i].argument_child = 9;else if (l = checkDeclDelim(i)) tokens[i].argument_child = 10;else if (l = checkString(i)) tokens[i].argument_child = 11;else if (l = checkPercentage(i)) tokens[i].argument_child = 12;else if (l = checkDimension(i)) tokens[i].argument_child = 13;else if (l = checkNumber(i)) tokens[i].argument_child = 14;else if (l = checkUri(i)) tokens[i].argument_child = 15;else if (l = checkInterpolation(i)) tokens[i].argument_child = 16;else if (l = checkIdent(i)) tokens[i].argument_child = 17;else if (l = checkVhash(i)) tokens[i].argument_child = 18;else if (l = checkCustomProperty(i)) tokens[i].argument_child = 19;else if (l = checkOperator(i)) tokens[i].argument_child = 20;else if (l = checkUnary(i)) tokens[i].argument_child = 21;else if (l = checkParentSelector(i)) tokens[i].argument_child = 22;else if (l = checkImportant(i)) tokens[i].argument_child = 23;else if (l = checkGlobal(i)) tokens[i].argument_child = 24;else if (l = checkDefault(i)) tokens[i].argument_child = 25;else if (l = checkOptional(i)) tokens[i].argument_child = 26;
10703 function getArgument() {
10704 var childType = tokens[pos].argument_child;
10706 if (childType === 1) return getBrackets();
10707 if (childType === 2) return getParentheses();
10708 if (childType === 3) return getSingleValueDeclaration();
10709 if (childType === 4) return getFunctionsList();
10710 if (childType === 5) return getFunction();
10711 if (childType === 6) return getVariablesList();
10712 if (childType === 7) return getVariable();
10713 if (childType === 8) return getSC();
10714 if (childType === 9) return getDelim();
10715 if (childType === 10) return getDeclDelim();
10716 if (childType === 11) return getString();
10717 if (childType === 12) return getPercentage();
10718 if (childType === 13) return getDimension();
10719 if (childType === 14) return getNumber();
10720 if (childType === 15) return getUri();
10721 if (childType === 16) return getInterpolation();
10722 if (childType === 17) return getIdent();
10723 if (childType === 18) return getVhash();
10724 if (childType === 19) return getCustomProperty();
10725 if (childType === 20) return getOperator();
10726 if (childType === 21) return getUnary();
10727 if (childType === 22) return getParentSelector();
10728 if (childType === 23) return getImportant();
10729 if (childType === 24) return getGlobal();
10730 if (childType === 25) return getDefault();
10731 if (childType === 26) return getOptional();
10735 * Checks if token is part of an @-word (e.g. `@import`, `@include`).
10737 * @param {number} i Token's index number
10740 function checkAtkeyword(i) {
10743 // Check that token is `@`:
10744 if (i >= tokensLength || tokens[i++].type !== TokenType.CommercialAt) return 0;
10746 return (l = checkIdentOrInterpolation(i)) ? l + 1 : 0;
10750 * Gets node with @-word.
10754 function getAtkeyword() {
10755 var type = NodeType.AtkeywordType;
10756 var token = tokens[pos];
10757 var line = token.ln;
10758 var column = token.col;
10763 var content = getIdentOrInterpolation();
10765 return newNode(type, content, line, column);
10769 * Checks if token is a part of an @-rule.
10771 * @param {number} i Token's index number
10772 * @return {number} Length of @-rule
10774 function checkAtrule(i) {
10777 if (i >= tokensLength) return 0;
10779 // If token already has a record of being part of an @-rule,
10780 // return the @-rule's length:
10781 if (tokens[i].atrule_l !== undefined) return tokens[i].atrule_l;
10783 // If token is part of an @-rule, save the rule's type to token.
10785 if (l = checkKeyframesRule(i)) tokens[i].atrule_type = 4;
10786 // @-rule with ruleset:
10787 else if (l = checkAtruler(i)) tokens[i].atrule_type = 1;
10789 else if (l = checkAtruleb(i)) tokens[i].atrule_type = 2;
10790 // Single-line @-rule:
10791 else if (l = checkAtrules(i)) tokens[i].atrule_type = 3;else return 0;
10793 // If token is part of an @-rule, save the rule's length to token:
10794 tokens[i].atrule_l = l;
10800 * Gets node with @-rule.
10804 function getAtrule() {
10805 var childType = tokens[pos].atrule_type;
10807 if (childType === 1) return getAtruler(); // @-rule with ruleset
10808 if (childType === 2) return getAtruleb(); // Block @-rule
10809 if (childType === 3) return getAtrules(); // Single-line @-rule
10810 if (childType === 4) return getKeyframesRule();
10814 * Checks if token is part of a block @-rule.
10816 * @param {number} i Token's index number
10817 * @return {number} Length of the @-rule
10819 function checkAtruleb(i) {
10823 if (i >= tokensLength) return 0;
10825 if (l = checkAtkeyword(i)) i += l;else return 0;
10827 if (l = checkTsets(i)) i += l;
10829 if (l = checkBlock(i)) i += l;else return 0;
10835 * Gets node with a block @-rule.
10839 function getAtruleb() {
10840 var type = NodeType.AtruleType;
10841 var token = tokens[pos];
10842 var line = token.ln;
10843 var column = token.col;
10844 var content = [].concat(getAtkeyword(), getTsets(), getBlock());
10846 return newNode(type, content, line, column);
10850 * Checks if token is part of an @-rule with ruleset.
10852 * @param {number} i Token's index number
10853 * @return {number} Length of the @-rule
10855 function checkAtruler(i) {
10859 if (i >= tokensLength) return 0;
10861 if (l = checkAtkeyword(i)) i += l;else return 0;
10863 if (l = checkTsets(i)) i += l;
10865 if (l = checkAtrulers(i)) i += l;else return 0;
10871 * Gets node with an @-rule with ruleset.
10875 function getAtruler() {
10876 var type = NodeType.AtruleType;
10877 var token = tokens[pos];
10878 var line = token.ln;
10879 var column = token.col;
10880 var content = [].concat(getAtkeyword(), getTsets(), getAtrulers());
10882 return newNode(type, content, line, column);
10886 * @param {number} i Token's index number
10889 function checkAtrulers(i) {
10893 if (i >= tokensLength) return 0;
10895 var blockEnd = tokens[i].block_end;
10896 if (!blockEnd) return 0;
10898 while (i < blockEnd) {
10899 if (l = checkSC(i)) tokens[i].atrulers_child = 1;else if (l = checkAtrule(i)) tokens[i].atrulers_child = 2;else if (l = checkRuleset(i)) tokens[i].atrulers_child = 3;else return 0;
10903 if (i < tokensLength) tokens[i].atrulers_end = 1;
10911 function getAtrulers() {
10912 var type = NodeType.BlockType;
10913 var token = tokens[pos];
10914 var line = token.ln;
10915 var column = token.col;
10916 var content = getSC();
10918 while (pos < tokensLength && !tokens[pos].atrulers_end) {
10919 var childType = tokens[pos].atrulers_child;
10920 if (childType === 1) content = content.concat(getSC());else if (childType === 2) content.push(getAtrule());else if (childType === 3) content.push(getRuleset());else break;
10923 var end = getLastPosition(content, line, column);
10925 return newNode(type, content, line, column, end);
10929 * @param {number} i Token's index number
10932 function checkAtrules(i) {
10936 if (i >= tokensLength) return 0;
10938 if (l = checkAtkeyword(i)) i += l;else return 0;
10940 if (l = checkTsets(i)) i += l;
10948 function getAtrules() {
10949 var type = NodeType.AtruleType;
10950 var token = tokens[pos];
10951 var line = token.ln;
10952 var column = token.col;
10953 var content = [].concat(getAtkeyword(), getTsets());
10955 return newNode(type, content, line, column);
10959 * Checks if token is part of a block (e.g. `{...}`).
10961 * @param {number} i Token's index number
10962 * @return {number} Length of the block
10964 function checkBlock(i) {
10965 return i < tokensLength && tokens[i].block_end ? tokens[i].block_end - i + 1 : 0;
10969 * Gets node with a block.
10973 function getBlock() {
10974 var type = NodeType.BlockType;
10975 var token = tokens[pos];
10976 var line = token.ln;
10977 var column = token.col;
10978 var end = tokens[pos].block_end;
10981 while (pos < end) {
10982 if (checkBlockdecl(pos)) content = content.concat(getBlockdecl());else throwError(pos);
10985 return newNode(type, content, line, column);
10989 * Checks if token is part of a declaration (property-value pair).
10991 * @param {number} i Token's index number
10992 * @return {number} Length of the declaration
10994 function checkBlockdecl(i) {
10997 if (i >= tokensLength) return 0;
10999 if (l = checkBlockdecl7(i)) tokens[i].bd_type = 7;else if (l = checkBlockdecl5(i)) tokens[i].bd_type = 5;else if (l = checkBlockdecl6(i)) tokens[i].bd_type = 6;else if (l = checkBlockdecl1(i)) tokens[i].bd_type = 1;else if (l = checkBlockdecl2(i)) tokens[i].bd_type = 2;else if (l = checkBlockdecl3(i)) tokens[i].bd_type = 3;else if (l = checkBlockdecl4(i)) tokens[i].bd_type = 4;else return 0;
11007 function getBlockdecl() {
11008 var childType = tokens[pos].bd_type;
11010 if (childType === 1) return getBlockdecl1();
11011 if (childType === 2) return getBlockdecl2();
11012 if (childType === 3) return getBlockdecl3();
11013 if (childType === 4) return getBlockdecl4();
11014 if (childType === 5) return getBlockdecl5();
11015 if (childType === 6) return getBlockdecl6();
11016 if (childType === 7) return getBlockdecl7();
11020 * @param {number} i Token's index number
11023 function checkBlockdecl1(i) {
11027 if (l = checkInclude(i)) tokens[i].bd_kind = 2;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 5;else if (l = checkAtrule(i)) tokens[i].bd_kind = 6;else return 0;
11031 if (tokens[start].bd_kind === 2 && [2, 4, 6, 8].indexOf(tokens[start].include_type) === -1) return 0;
11033 if (tokens[start].bd_kind === 6 && tokens[start].atrule_type === 3) return 0;
11035 while (i < tokensLength) {
11036 if (l = checkDeclDelim(i)) return i + l - start;
11038 if (l = checkS(i)) i += l;else if (l = checkCommentSL(i)) i += l;else break;
11047 function getBlockdecl1() {
11051 switch (tokens[pos].bd_kind) {
11053 content.push(getInclude());
11056 content.push(getDeclaration());
11059 content.push(getAtrule());
11063 while (pos < tokensLength) {
11065 if (checkDeclDelim(pos)) {
11066 _content.push(getDeclDelim());
11067 content = content.concat(_content);
11071 if (checkS(pos)) _content.push(getS());else if (checkCommentSL(pos)) _content.push(getCommentSL());else {
11081 * @param {number} i Token's index number
11084 function checkBlockdecl2(i) {
11088 if (l = checkConditionalStatement(i)) tokens[i].bd_kind = 1;else if (l = checkInclude(i)) tokens[i].bd_kind = 2;else if (l = checkExtend(i)) tokens[i].bd_kind = 4;else if (l = checkMixin(i)) tokens[i].bd_kind = 8;else if (l = checkLoop(i)) tokens[i].bd_kind = 3;else if (l = checkRuleset(i)) tokens[i].bd_kind = 7;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 5;else if (l = checkAtrule(i)) tokens[i].bd_kind = 6;else return 0;
11092 while (i < tokensLength) {
11093 if (l = checkS(i)) i += l;else if (l = checkCommentSL(i)) i += l;else break;
11102 function getBlockdecl2() {
11105 switch (tokens[pos].bd_kind) {
11107 content.push(getConditionalStatement());
11110 content.push(getInclude());
11113 content.push(getLoop());
11116 content.push(getExtend());
11119 content.push(getDeclaration());
11122 content.push(getAtrule());
11125 content.push(getRuleset());
11128 content.push(getMixin());
11132 while (pos < tokensLength) {
11133 if (checkS(pos)) content.push(getS());else if (checkCommentSL(pos)) content.push(getCommentSL());else break;
11140 * @param {number} i Token's index number
11143 function checkBlockdecl3(i) {
11147 if (l = checkConditionalStatement(i)) tokens[i].bd_kind = 1;else if (l = checkInclude(i)) tokens[i].bd_kind = 2;else if (l = checkExtend(i)) tokens[i].bd_kind = 4;else if (l = checkLoop(i)) tokens[i].bd_kind = 3;else if (l = checkRuleset(i)) tokens[i].bd_kind = 7;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 5;else if (l = checkAtrule(i)) tokens[i].bd_kind = 6;else return 0;
11157 function getBlockdecl3() {
11158 var content = void 0;
11160 switch (tokens[pos].bd_kind) {
11162 content = getConditionalStatement();
11165 content = getInclude();
11168 content = getLoop();
11171 content = getExtend();
11174 content = getDeclaration();
11177 content = getAtrule();
11180 content = getRuleset();
11188 * @param {number} i Token's index number
11191 function checkBlockdecl4(i) {
11198 function getBlockdecl4() {
11203 * @param {number} i Token's index number
11206 function checkBlockdecl5(i) {
11210 if (l = checkInclude(i)) i += l;else if (l = checkRuleset(i)) i += l;else return 0;
11212 while (i < tokensLength) {
11213 if (l = checkS(i)) i += l;else if (l = checkCommentSL(i)) i += l;else break;
11222 function getBlockdecl5() {
11225 if (checkInclude(pos)) content.push(getInclude());else content.push(getRuleset());
11227 while (pos < tokensLength) {
11228 if (checkS(pos)) content.push(getS());else if (checkCommentSL(pos)) content.push(getCommentSL());else break;
11235 * @param {number} i Token's index number
11238 function checkBlockdecl6(i) {
11242 if (l = checkInclude(i)) i += l;else if (l = checkRuleset(i)) i += l;else return 0;
11250 function getBlockdecl6() {
11251 var content = void 0;
11253 if (checkInclude(pos)) content = getInclude();else content = getRuleset();
11259 * @param {number} i Token's index number
11262 function checkBlockdecl7(i) {
11266 if (l = checkInclude(i)) i += l;else return 0;
11268 if ([2, 4, 6, 8].indexOf(tokens[start].include_type) === -1) return 0;
11270 while (i < tokensLength) {
11271 if (l = checkDeclDelim(i)) return i + l - start;
11273 if (l = checkS(i)) i += l;else if (l = checkCommentSL(i)) i += l;else break;
11282 function getBlockdecl7() {
11286 content.push(getInclude());
11288 while (pos < tokensLength) {
11290 if (checkDeclDelim(pos)) {
11291 _content.push(getDeclDelim());
11292 content = content.concat(_content);
11296 if (checkS(pos)) _content.push(getS());else if (checkCommentSL(pos)) _content.push(getCommentSL());else {
11306 * Checks if token is part of text inside square brackets, e.g. `[1]`.
11308 * @param {number} i Token's index number
11311 function checkBrackets(i) {
11312 if (i >= tokensLength) return 0;
11317 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
11319 if (i < tokens[start].right) {
11320 var l = checkTsets(i);
11321 if (l) i += l;else return 0;
11331 * Gets node with text inside square brackets, e.g. `[1]`.
11335 function getBrackets() {
11336 var type = NodeType.BracketsType;
11337 var token = tokens[pos];
11338 var line = token.ln;
11339 var column = token.col;
11340 var right = token.right;
11347 content = getTsets();
11350 var end = getLastPosition(content, line, column, 1);
11355 return newNode(type, content, line, column, end);
11359 * Checks if token is part of a class selector (e.g. `.abc`).
11361 * @param {number} i Token's index number
11362 * @return {number} Length of the class selector
11364 function checkClass(i) {
11368 if (i >= tokensLength) return 0;
11370 if (tokens[i].class_l) return tokens[i].class_l;
11373 if (tokens[i].type === TokenType.FullStop) i++;else return 0;
11375 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
11377 while (i < tokensLength) {
11378 if (l = checkIdentOrInterpolation(i)) {
11379 tokens[start].class_l = l + 1;
11384 tokens[start].classEnd = i;
11390 * Gets node with a class selector.
11394 function getClass() {
11395 var type = NodeType.ClassType;
11396 var token = tokens[pos];
11397 var line = token.ln;
11398 var column = token.col;
11399 var end = token.classEnd;
11405 while (pos < end) {
11406 if (checkIdentOrInterpolation(pos)) {
11407 content = content.concat(getIdentOrInterpolation());
11411 return newNode(type, content, line, column);
11415 * @param {number} i
11418 function checkCombinator(i) {
11419 if (i >= tokensLength) return 0;
11422 if (l = checkCombinator1(i)) tokens[i].combinatorType = 1;else if (l = checkCombinator2(i)) tokens[i].combinatorType = 2;else if (l = checkCombinator3(i)) tokens[i].combinatorType = 3;else if (l = checkCombinator4(i)) tokens[i].combinatorType = 4;
11430 function getCombinator() {
11431 var type = tokens[pos].combinatorType;
11432 if (type === 1) return getCombinator1();
11433 if (type === 2) return getCombinator2();
11434 if (type === 3) return getCombinator3();
11435 if (type === 4) return getCombinator4();
11441 * @param {Number} i
11444 function checkCombinator1(i) {
11445 if (i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign) return 3;
11453 function getCombinator1() {
11454 var type = NodeType.CombinatorType;
11455 var token = tokens[pos];
11456 var line = token.ln;
11457 var column = token.col;
11458 var content = '>>>';
11463 return newNode(type, content, line, column);
11470 * @param {number} i
11473 function checkCombinator2(i) {
11474 if (i + 1 >= tokensLength) return 0;
11476 if (tokens[i].type === TokenType.VerticalLine && tokens[i + 1].type === TokenType.VerticalLine) return 2;
11478 if (tokens[i].type === TokenType.GreaterThanSign && tokens[i + 1].type === TokenType.GreaterThanSign) return 2;
11486 function getCombinator2() {
11487 var type = NodeType.CombinatorType;
11488 var token = tokens[pos];
11489 var line = token.ln;
11490 var column = token.col;
11491 var content = '' + token.value + tokens[pos + 1].value;
11496 return newNode(type, content, line, column);
11504 * @param {number} i
11507 function checkCombinator3(i) {
11508 var type = tokens[i].type;
11509 if (type === TokenType.PlusSign || type === TokenType.GreaterThanSign || type === TokenType.Tilde) return 1;else return 0;
11515 function getCombinator3() {
11516 var type = NodeType.CombinatorType;
11517 var token = tokens[pos];
11518 var line = token.ln;
11519 var column = token.col;
11520 var content = token.value;
11525 return newNode(type, content, line, column);
11531 function checkCombinator4(i) {
11534 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
11537 if (l = checkIdent(i)) i += l;else return 0;
11539 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
11547 function getCombinator4() {
11548 var type = NodeType.CombinatorType;
11549 var token = tokens[pos];
11550 var line = token.ln;
11551 var column = token.col;
11556 var ident = getIdent();
11561 var content = '/' + ident.content + '/';
11563 return newNode(type, content, line, column);
11567 * Check if token is a multiline comment.
11568 * @param {number} i Token's index number
11569 * @return {number} `1` if token is a multiline comment, otherwise `0`
11571 function checkCommentML(i) {
11572 return i < tokensLength && tokens[i].type === TokenType.CommentML ? 1 : 0;
11576 * Get node with a multiline comment
11577 * @return {Array} `['commentML', x]` where `x`
11578 * is the comment's text (without `/*` and `* /`).
11580 function getCommentML() {
11581 var type = NodeType.CommentMLType;
11582 var token = tokens[pos];
11583 var line = token.ln;
11584 var column = token.col;
11585 var content = tokens[pos].value.substring(2);
11587 var end = getLastPosition(content, line, column + 2);
11589 if (content.endsWith('*/')) {
11590 content = content.substring(0, content.length - 2);
11595 return newNode(type, content, line, column, end);
11599 * Check if token is part of a single-line comment.
11600 * @param {number} i Token's index number
11601 * @return {number} `1` if token is a single-line comment, otherwise `0`
11603 function checkCommentSL(i) {
11604 return i < tokensLength && tokens[i].type === TokenType.CommentSL ? 1 : 0;
11608 * Get node with a single-line comment.
11609 * @return {Array} `['commentSL', x]` where `x` is comment's message
11612 function getCommentSL() {
11613 var type = NodeType.CommentSLType;
11614 var token = tokens[pos];
11615 var line = token.ln;
11616 var column = token.col;
11617 var content = tokens[pos++].value.substring(2);
11618 var end = !content ? [line, column + 1] : getLastPosition(content, line, column + 2);
11620 return newNode(type, content, line, column, end);
11624 * Check if token is part of a condition
11625 * (e.g. `@if ...`, `@else if ...` or `@else ...`).
11626 * @param {number} i Token's index number
11627 * @return {number} Length of the condition
11629 function checkCondition(i) {
11635 if (i >= tokensLength) return 0;
11637 if (l = checkAtkeyword(i)) i += l;else return 0;
11639 if (['if', 'else'].indexOf(tokens[start + 1].value) < 0) return 0;
11641 while (i < tokensLength) {
11642 if (l = checkBlock(i)) break;
11647 if (l = _checkCondition(_i)) i += l + s;else break;
11653 function _checkCondition(i) {
11654 return checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkOperator(i) || checkCombinator(i) || checkString(i);
11658 * Get node with a condition.
11659 * @return {Array} `['condition', x]`
11661 function getCondition() {
11662 var type = NodeType.ConditionType;
11663 var token = tokens[pos];
11664 var line = token.ln;
11665 var column = token.col;
11670 content.push(getAtkeyword());
11672 while (pos < tokensLength) {
11673 if (checkBlock(pos)) break;
11678 if (!_checkCondition(_pos)) break;
11680 if (s) content = content.concat(getSC());
11681 content.push(_getCondition());
11684 return newNode(type, content, line, column);
11687 function _getCondition() {
11688 if (checkVariable(pos)) return getVariable();
11689 if (checkNumber(pos)) return getNumber();
11690 if (checkInterpolation(pos)) return getInterpolation();
11691 if (checkIdent(pos)) return getIdent();
11692 if (checkOperator(pos)) return getOperator();
11693 if (checkCombinator(pos)) return getCombinator();
11694 if (checkString(pos)) return getString();
11698 * Check if token is part of a conditional statement
11699 * (e.g. `@if ... {} @else if ... {} @else ... {}`).
11700 * @param {number} i Token's index number
11701 * @return {number} Length of the condition
11703 function checkConditionalStatement(i) {
11707 if (i >= tokensLength) return 0;
11709 if (l = checkCondition(i)) i += l;else return 0;
11711 if (l = checkSC(i)) i += l;
11713 if (l = checkBlock(i)) i += l;else return 0;
11719 * Get node with a condition.
11720 * @return {Array} `['condition', x]`
11722 function getConditionalStatement() {
11723 var type = NodeType.ConditionalStatementType;
11724 var token = tokens[pos];
11725 var line = token.ln;
11726 var column = token.col;
11727 var content = [].concat(getCondition(), getSC(), getBlock());
11729 return newNode(type, content, line, column);
11733 * Check if token is part of a declaration (property-value pair)
11734 * @param {number} i Token's index number
11735 * @return {number} Length of the declaration
11737 function checkDeclaration(i) {
11738 return checkDeclaration1(i) || checkDeclaration2(i);
11742 * Get node with a declaration
11743 * @return {Array} `['declaration', ['property', x], ['propertyDelim'],
11746 function getDeclaration() {
11747 return checkDeclaration1(pos) ? getDeclaration1() : getDeclaration2();
11751 * Check if token is part of a declaration (property-value pair)
11752 * @param {number} i Token's index number
11753 * @return {number} Length of the declaration
11755 function checkDeclaration1(i) {
11759 if (i >= tokensLength) return 0;
11761 if (l = checkProperty(i)) i += l;else return 0;
11763 if (l = checkSC(i)) i += l;
11765 if (l = checkPropertyDelim(i)) i++;else return 0;
11767 if (l = checkValue(i)) return i + l - start;
11769 if (l = checkS(i)) i += l;
11771 if (l = checkValue(i)) i += l;else return 0;
11777 * Get node with a declaration
11778 * @return {Array} `['declaration', ['property', x], ['propertyDelim'],
11781 function getDeclaration1() {
11782 var type = NodeType.DeclarationType;
11783 var token = tokens[pos];
11784 var line = token.ln;
11785 var column = token.col;
11788 content.push(getProperty());
11789 if (checkS(pos)) content.push(getS());
11790 content.push(getPropertyDelim());
11791 if (checkS(pos)) content.push(getS());
11792 content.push(getValue());
11794 return newNode(type, content, line, column);
11798 * Check if token is part of a declaration (property-value pair)
11799 * @param {number} i Token's index number
11800 * @return {number} Length of the declaration
11802 function checkDeclaration2(i) {
11806 if (i >= tokensLength) return 0;
11808 if (l = checkPropertyDelim(i)) i++;else return 0;
11810 if (l = checkProperty(i)) i += l;else return 0;
11812 if (l = checkValue(i)) return i + l - start;
11814 if (l = checkSC(i)) i += l;
11816 if (l = checkValue(i)) i += l;else return 0;
11822 * Get node with a declaration
11823 * @return {Array} `['declaration', ['propertyDelim'], ['property', x],
11826 function getDeclaration2() {
11827 var type = NodeType.DeclarationType;
11828 var token = tokens[pos];
11829 var line = token.ln;
11830 var column = token.col;
11831 var content = [].concat(getPropertyDelim(), getProperty(), getSC(), getValue());
11833 return newNode(type, content, line, column);
11837 * @param {number} i Token's index number
11838 * @returns {number} Length of the declaration
11840 function checkSingleValueDeclaration(i) {
11844 if (i >= tokensLength) return 0;
11846 if (l = checkProperty(i)) i += l;else return 0;
11848 if (l = checkSC(i)) i += l;
11850 if (l = checkPropertyDelim(i)) i++;else return 0;
11852 if (l = checkSC(i)) i += l;
11854 if (l = checkSingleValue(i)) i += l;else return 0;
11860 * Get node with a declaration
11861 * @returns {Array} `['declaration', ['property', x], ['propertyDelim'],
11864 function getSingleValueDeclaration() {
11865 var type = NodeType.DeclarationType;
11866 var token = tokens[pos];
11867 var line = token.ln;
11868 var column = token.col;
11869 var content = [].concat(getProperty(), getSC(), getPropertyDelim(), getSC(), getSingleValue());
11871 return newNode(type, content, line, column);
11875 * Check if token is a semicolon
11876 * @param {number} i Token's index number
11877 * @return {number} `1` if token is a semicolon, otherwise `0`
11879 function checkDeclDelim(i) {
11880 if (i >= tokensLength) return 0;
11882 return tokens[i].type === TokenType.Newline || tokens[i].type === TokenType.Semicolon ? 1 : 0;
11886 * Get node with a semicolon
11887 * @return {Array} `['declDelim']`
11889 function getDeclDelim() {
11890 var type = NodeType.DeclDelimType;
11891 var token = tokens[pos];
11892 var line = token.ln;
11893 var column = token.col;
11894 var content = '\n';
11898 return newNode(type, content, line, column);
11902 * Check if token if part of `!default` word.
11903 * @param {number} i Token's index number
11904 * @return {number} Length of the `!default` word
11906 function checkDefault(i) {
11910 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
11912 if (l = checkSC(i)) i += l;
11914 if (tokens[i].value === 'default') {
11915 tokens[start].defaultEnd = i;
11916 return i - start + 1;
11923 * Get node with a `!default` word
11924 * @return {Array} `['default', sc]` where `sc` is optional whitespace
11926 function getDefault() {
11927 var type = NodeType.DefaultType;
11928 var token = tokens[pos];
11929 var line = token.ln;
11930 var column = token.col;
11931 var content = joinValues(pos, token.defaultEnd);
11933 pos = token.defaultEnd + 1;
11935 return newNode(type, content, line, column);
11939 * Check if token is a comma
11940 * @param {number} i Token's index number
11941 * @return {number} `1` if token is a comma, otherwise `0`
11943 function checkDelim(i) {
11944 return i < tokensLength && tokens[i].type === TokenType.Comma ? 1 : 0;
11948 * Get node with a comma
11949 * @return {Array} `['delim']`
11951 function getDelim() {
11952 var type = NodeType.DelimType;
11953 var token = tokens[pos];
11954 var line = token.ln;
11955 var column = token.col;
11960 return newNode(type, content, line, column);
11964 * Check if token is part of a number with dimension unit (e.g. `10px`)
11965 * @param {Number} i Token's index number
11968 function checkDimension(i) {
11969 var ln = checkNumber(i);
11972 if (i >= tokensLength || !ln || i + ln >= tokensLength) return 0;
11974 return (li = checkUnit(i + ln)) ? ln + li : 0;
11978 * Get node of a number with dimension unit
11981 function getDimension() {
11982 var type = NodeType.DimensionType;
11983 var token = tokens[pos];
11984 var line = token.ln;
11985 var column = token.col;
11986 var content = [getNumber(), getUnit()];
11988 return newNode(type, content, line, column);
11992 * @param {number} i Token's index number
11995 function checkExpression(i) {
11998 if (i >= tokensLength || tokens[i++].value !== 'expression' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) {
12002 return tokens[i].right - start + 1;
12008 function getExpression() {
12009 var type = NodeType.ExpressionType;
12010 var token = tokens[pos];
12011 var line = token.ln;
12012 var column = token.col;
12016 var content = joinValues(pos + 1, tokens[pos].right - 1);
12017 var end = getLastPosition(content, line, column, 1);
12019 if (end[0] === line) end[1] += 11;
12020 pos = tokens[pos].right + 1;
12022 return newNode(type, content, line, column, end);
12025 function checkExtend(i) {
12026 if (i >= tokensLength) return 0;
12030 if (l = checkExtend1(i)) tokens[i].extend_child = 1;else if (l = checkExtend2(i)) tokens[i].extend_child = 2;
12035 function getExtend() {
12036 var childType = tokens[pos].extend_child;
12038 if (childType === 1) return getExtend1();
12039 if (childType === 2) return getExtend2();
12043 * Checks if token is part of an extend with `!optional` flag.
12044 * @param {number} i
12046 function checkExtend1(i) {
12050 if (i >= tokensLength) return 0;
12052 if (l = checkAtkeyword(i)) i += l;else return 0;
12054 if (tokens[start + 1].value !== 'extend') return 0;
12056 if (l = checkSC(i)) i += l;else return 0;
12058 if (l = checkSelectorsGroup(i)) i += l;else return 0;
12060 if (l = checkSC(i)) i += l;else return 0;
12062 if (l = checkOptional(i)) i += l;else return 0;
12067 function getExtend1() {
12068 var type = NodeType.ExtendType;
12069 var token = tokens[pos];
12070 var line = token.ln;
12071 var column = token.col;
12072 var content = [].concat(getAtkeyword(), getSC(), getSelectorsGroup(), getSC(), getOptional());
12074 return newNode(type, content, line, column);
12078 * Checks if token is part of an extend without `!optional` flag.
12079 * @param {number} i
12081 function checkExtend2(i) {
12085 if (i >= tokensLength) return 0;
12087 if (l = checkAtkeyword(i)) i += l;else return 0;
12089 if (tokens[start + 1].value !== 'extend') return 0;
12091 if (l = checkSC(i)) i += l;else return 0;
12093 if (l = checkSelectorsGroup(i)) i += l;else return 0;
12098 function getExtend2() {
12099 var type = NodeType.ExtendType;
12100 var token = tokens[pos];
12101 var line = token.ln;
12102 var column = token.col;
12103 var content = [].concat(getAtkeyword(), getSC(), getSelectorsGroup());
12105 return newNode(type, content, line, column);
12109 * @param {number} i Token's index number
12112 function checkFunction(i) {
12116 if (i >= tokensLength) return 0;
12118 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12120 return i < tokensLength && tokens[i].type === TokenType.LeftParenthesis ? tokens[i].right - start + 1 : 0;
12126 function getFunction() {
12127 var type = NodeType.FunctionType;
12128 var token = tokens[pos];
12129 var line = token.ln;
12130 var column = token.col;
12131 var content = [].concat(getIdentOrInterpolation(), getArguments());
12133 return newNode(type, content, line, column);
12137 * Check if token is part of a functions list (e.g. `function(value)...`).
12138 * @param {Number} i Token's index number
12139 * @returns {Number}
12141 function checkFunctionsList(i) {
12142 var d = 0; // Number of dots
12145 if (i >= tokensLength) return 0;
12147 if (l = checkFunction(i)) i += l;else return 0;
12149 while (i < tokensLength && tokens[i].type === TokenType.FullStop) {
12154 return d === 3 ? l + d : 0;
12158 * Get node with a functions list
12161 function getFunctionsList() {
12162 var type = NodeType.FunctionsListType;
12163 var token = tokens[pos];
12164 var line = token.ln;
12165 var column = token.col;
12166 var content = [getFunction()];
12167 var end = getLastPosition(content, line, column, 3);
12172 return newNode(type, content, line, column, end);
12176 * Check if token is part of `!global` word
12177 * @param {number} i Token's index number
12180 function checkGlobal(i) {
12184 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
12186 if (l = checkSC(i)) i += l;
12188 if (tokens[i].value === 'global') {
12189 tokens[start].globalEnd = i;
12190 return i - start + 1;
12197 * Get node with `!global` word
12199 function getGlobal() {
12200 var type = NodeType.GlobalType;
12201 var token = tokens[pos];
12202 var line = token.ln;
12203 var column = token.col;
12204 var content = joinValues(pos, token.globalEnd);
12206 pos = token.globalEnd + 1;
12208 return newNode(type, content, line, column);
12212 * Check if token is part of an identifier
12213 * @param {number} i Token's index number
12214 * @return {number} Length of the identifier
12216 function checkIdent(i) {
12219 if (i >= tokensLength) return 0;
12221 // Check if token is part of a negative number
12222 if (tokens[i].type === TokenType.HyphenMinus && tokens[i + 1].type === TokenType.DecimalNumber) return 0;
12224 if (tokens[i].type === TokenType.HyphenMinus) i++;
12226 if (checkInterpolation(i)) {
12227 tokens[start].ident_last = i - 1;
12231 if (tokens[i].type === TokenType.LowLine || tokens[i].type === TokenType.Identifier) i++;else return 0;
12233 for (; i < tokensLength; i++) {
12234 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
12237 tokens[start].ident_last = i - 1;
12243 * Get node with an identifier
12244 * @return {Array} `['ident', x]` where `x` is identifier's name
12246 function getIdent() {
12247 var type = NodeType.IdentType;
12248 var token = tokens[pos];
12249 var line = token.ln;
12250 var column = token.col;
12251 var content = joinValues(pos, tokens[pos].ident_last);
12253 pos = tokens[pos].ident_last + 1;
12255 return newNode(type, content, line, column);
12259 * @param {number} i Token's index number
12260 * @returns {number} Length of the identifier
12262 function checkPartialIdent(i) {
12265 if (i >= tokensLength) return 0;
12267 for (; i < tokensLength; i++) {
12268 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
12271 tokens[start].ident_last = i - 1;
12277 * @param {number} i Token's index number
12278 * @returns {number} Length of the identifier
12280 function checkIdentOrInterpolation(i) {
12283 var prevIsInterpolation = false;
12285 while (i < tokensLength) {
12286 if (l = checkInterpolation(i)) {
12287 tokens[i].ii_type = 1;
12289 prevIsInterpolation = true;
12290 } else if (l = checkIdent(i)) {
12291 tokens[i].ii_type = 2;
12293 prevIsInterpolation = false;
12294 } else if (prevIsInterpolation && (l = checkPartialIdent(i))) {
12295 tokens[i].ii_type = 3;
12297 prevIsInterpolation = false;
12304 function getIdentOrInterpolation() {
12307 while (pos < tokensLength) {
12308 var tokenType = tokens[pos].ii_type;
12310 if (tokenType === 1) {
12311 content.push(getInterpolation());
12312 } else if (tokenType === 2 || tokenType === 3) {
12313 content.push(getIdent());
12321 * Check if token is part of `!important` word
12322 * @param {number} i Token's index number
12325 function checkImportant(i) {
12329 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
12331 if (l = checkSC(i)) i += l;
12333 if (tokens[i].value === 'important') {
12334 tokens[start].importantEnd = i;
12335 return i - start + 1;
12342 * Get node with `!important` word
12343 * @return {Array} `['important', sc]` where `sc` is optional whitespace
12345 function getImportant() {
12346 var type = NodeType.ImportantType;
12347 var token = tokens[pos];
12348 var line = token.ln;
12349 var column = token.col;
12350 var content = joinValues(pos, token.importantEnd);
12352 pos = token.importantEnd + 1;
12354 return newNode(type, content, line, column);
12358 * Check if token is part of an included mixin (`@include` or `@extend`
12360 * @param {number} i Token's index number
12361 * @return {number} Length of the included mixin
12363 function checkInclude(i) {
12366 if (i >= tokensLength) return 0;
12368 if (l = checkIncludeWithKeyframes1(i)) tokens[i].include_type = 9;else if (l = checkInclude1(i)) tokens[i].include_type = 1;else if (l = checkInclude2(i)) tokens[i].include_type = 2;else if (l = checkInclude3(i)) tokens[i].include_type = 3;else if (l = checkInclude4(i)) tokens[i].include_type = 4;else if (l = checkIncludeWithKeyframes2(i)) tokens[i].include_type = 10;else if (l = checkInclude5(i)) tokens[i].include_type = 5;else if (l = checkInclude6(i)) tokens[i].include_type = 6;else if (l = checkInclude7(i)) tokens[i].include_type = 7;else if (l = checkInclude8(i)) tokens[i].include_type = 8;
12374 * Get node with included mixin
12375 * @return {Array} `['include', x]`
12377 function getInclude() {
12378 var type = tokens[pos].include_type;
12380 if (type === 1) return getInclude1();
12381 if (type === 2) return getInclude2();
12382 if (type === 3) return getInclude3();
12383 if (type === 4) return getInclude4();
12384 if (type === 5) return getInclude5();
12385 if (type === 6) return getInclude6();
12386 if (type === 7) return getInclude7();
12387 if (type === 8) return getInclude8();
12388 if (type === 9) return getIncludeWithKeyframes1();
12389 if (type === 10) return getIncludeWithKeyframes2();
12393 * Check if token is part of an included mixin like `@include nani(foo) {...}`
12394 * @param {number} i Token's index number
12395 * @return {number} Length of the include
12397 function checkInclude1(i) {
12401 if (l = checkAtkeyword(i)) i += l;else return 0;
12403 if (tokens[start + 1].value !== 'include') return 0;
12405 if (l = checkSC(i)) i += l;else return 0;
12407 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12409 if (l = checkSC(i)) i += l;
12411 if (l = checkArguments(i)) i += l;else return 0;
12413 if (l = checkSC(i)) i += l;
12415 if (l = checkBlock(i)) i += l;else return 0;
12421 * Get node with included mixin like `@include nani(foo) {...}`
12422 * @return {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
12423 * ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
12424 * `extend`, `y` is mixin's identifier (selector), `z` are arguments
12425 * passed to the mixin, `q` is block passed to the mixin and `sc`
12426 * are optional whitespaces
12428 function getInclude1() {
12429 var type = NodeType.IncludeType;
12430 var token = tokens[pos];
12431 var line = token.ln;
12432 var column = token.col;
12433 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getBlock());
12435 return newNode(type, content, line, column);
12439 * Check if token is part of an included mixin like `@include nani(foo)`
12440 * @param {number} i Token's index number
12441 * @return {number} Length of the include
12443 function checkInclude2(i) {
12447 if (l = checkAtkeyword(i)) i += l;else return 0;
12449 if (tokens[start + 1].value !== 'include') return 0;
12451 if (l = checkSC(i)) i += l;else return 0;
12453 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12455 if (l = checkSC(i)) i += l;
12457 if (l = checkArguments(i)) i += l;else return 0;
12463 * Get node with included mixin like `@include nani(foo)`
12464 * @return {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
12465 * ['arguments', z], sc]` where `x` is `include` or `extend`, `y` is
12466 * mixin's identifier (selector), `z` are arguments passed to the
12467 * mixin and `sc` are optional whitespaces
12469 function getInclude2() {
12470 var type = NodeType.IncludeType;
12471 var token = tokens[pos];
12472 var line = token.ln;
12473 var column = token.col;
12474 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments());
12476 return newNode(type, content, line, column);
12480 * Check if token is part of an included mixin with a content block passed
12481 * as an argument (e.g. `@include nani {...}`)
12482 * @param {number} i Token's index number
12483 * @return {number} Length of the mixin
12485 function checkInclude3(i) {
12489 if (l = checkAtkeyword(i)) i += l;else return 0;
12491 if (tokens[start + 1].value !== 'include') return 0;
12493 if (l = checkSC(i)) i += l;else return 0;
12495 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12497 if (l = checkSC(i)) i += l;
12499 if (l = checkBlock(i)) i += l;else return 0;
12505 * Get node with an included mixin with a content block passed
12506 * as an argument (e.g. `@include nani {...}`)
12507 * @return {Array} `['include', x]`
12509 function getInclude3() {
12510 var type = NodeType.IncludeType;
12511 var token = tokens[pos];
12512 var line = token.ln;
12513 var column = token.col;
12514 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getBlock());
12516 return newNode(type, content, line, column);
12520 * @param {number} i Token's index number
12523 function checkInclude4(i) {
12527 if (l = checkAtkeyword(i)) i += l;else return 0;
12529 if (tokens[start + 1].value !== 'include') return 0;
12531 if (l = checkSC(i)) i += l;else return 0;
12533 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12539 * @return {Array} `['include', x]`
12541 function getInclude4() {
12542 var type = NodeType.IncludeType;
12543 var token = tokens[pos];
12544 var line = token.ln;
12545 var column = token.col;
12546 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation());
12548 return newNode(type, content, line, column);
12552 * Check if token is part of an included mixin like `+nani(foo) {...}`
12553 * @param {number} i Token's index number
12554 * @return {number} Length of the include
12556 function checkInclude5(i) {
12560 if (tokens[i].type === TokenType.PlusSign) i++;else return 0;
12562 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12564 if (l = checkSC(i)) i += l;
12566 if (l = checkArguments(i)) i += l;else return 0;
12568 if (l = checkSC(i)) i += l;
12570 if (l = checkBlock(i)) i += l;else return 0;
12576 * Get node with included mixin like `+nani(foo) {...}`
12577 * @return {Array} `['include', ['operator', '+'], ['selector', x], sc,
12578 * ['arguments', y], sc, ['block', z], sc` where `x` is
12579 * mixin's identifier (selector), `y` are arguments passed to the
12580 * mixin, `z` is block passed to mixin and `sc` are optional whitespaces
12582 function getInclude5() {
12583 var type = NodeType.IncludeType;
12584 var token = tokens[pos];
12585 var line = token.ln;
12586 var column = token.col;
12587 var content = [].concat(getOperator(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getBlock());
12589 return newNode(type, content, line, column);
12593 * Check if token is part of an included mixin like `+nani(foo)`
12594 * @param {number} i Token's index number
12595 * @return {number} Length of the include
12597 function checkInclude6(i) {
12601 if (tokens[i].type === TokenType.PlusSign) i++;else return 0;
12603 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12605 if (l = checkSC(i)) i += l;
12607 if (l = checkArguments(i)) i += l;else return 0;
12613 * Get node with included mixin like `+nani(foo)`
12614 * @return {Array} `['include', ['operator', '+'], ['selector', y], sc,
12615 * ['arguments', z], sc]` where `y` is
12616 * mixin's identifier (selector), `z` are arguments passed to the
12617 * mixin and `sc` are optional whitespaces
12619 function getInclude6() {
12620 var type = NodeType.IncludeType;
12621 var token = tokens[pos];
12622 var line = token.ln;
12623 var column = token.col;
12624 var content = [].concat(getOperator(), getIdentOrInterpolation(), getSC(), getArguments());
12626 return newNode(type, content, line, column);
12630 * Check if token is part of an included mixin with a content block passed
12631 * as an argument (e.g. `+nani {...}`)
12632 * @param {number} i Token's index number
12633 * @return {number} Length of the mixin
12635 function checkInclude7(i) {
12639 if (tokens[i].type === TokenType.PlusSign) i++;else return 0;
12641 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12643 if (l = checkSC(i)) i += l;
12645 if (l = checkBlock(i)) i += l;else return 0;
12651 * Get node with an included mixin with a content block passed
12652 * as an argument (e.g. `+nani {...}`)
12653 * @return {Array} `['include', x]`
12655 function getInclude7() {
12656 var type = NodeType.IncludeType;
12657 var token = tokens[pos];
12658 var line = token.ln;
12659 var column = token.col;
12660 var content = [].concat(getOperator(), getIdentOrInterpolation(), getSC(), getBlock());
12662 return newNode(type, content, line, column);
12666 * @param {number} i Token's index number
12669 function checkInclude8(i) {
12673 if (tokens[i].type === TokenType.PlusSign) i++;else return 0;
12675 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12681 * @return {Array} `['include', x]`
12683 function getInclude8() {
12684 var type = NodeType.IncludeType;
12685 var token = tokens[pos];
12686 var line = token.ln;
12687 var column = token.col;
12688 var content = [].concat(getOperator(), getIdentOrInterpolation());
12690 return newNode(type, content, line, column);
12694 * Get node with included mixin with keyfames selector like
12695 * `@include nani(foo) { 0% {}}`
12696 * @param {number} i Token's index number
12697 * @returns {number} Length of the include
12699 function checkIncludeWithKeyframes1(i) {
12703 if (l = checkAtkeyword(i)) i += l;else return 0;
12705 if (tokens[start + 1].value !== 'include') return 0;
12707 if (l = checkSC(i)) i += l;else return 0;
12709 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12711 if (l = checkSC(i)) i += l;
12713 if (l = checkArguments(i)) i += l;else return 0;
12715 if (l = checkSC(i)) i += l;
12717 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
12723 * Get node with included mixin with keyfames selector like
12724 * `@include nani(foo) { 0% {}}`
12727 function getIncludeWithKeyframes1() {
12728 var type = NodeType.IncludeType;
12729 var token = tokens[pos];
12730 var line = token.ln;
12731 var column = token.col;
12732 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getKeyframesBlocks());
12734 return newNode(type, content, line, column);
12738 * Get node with included mixin with keyfames selector like
12739 * `+nani(foo) { 0% {}}`
12740 * @param {number} i Token's index number
12741 * @returns {number} Length of the include
12743 function checkIncludeWithKeyframes2(i) {
12747 if (tokens[i].type === TokenType.PlusSign) i++;else return 0;
12749 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
12751 if (l = checkSC(i)) i += l;
12753 if (l = checkArguments(i)) i += l;else return 0;
12755 if (l = checkSC(i)) i += l;
12757 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
12763 * Get node with included mixin with keyfames selector like
12764 * `+nani(foo) { 0% {}}`
12767 function getIncludeWithKeyframes2() {
12768 var type = NodeType.IncludeType;
12769 var token = tokens[pos];
12770 var line = token.ln;
12771 var column = token.col;
12772 var content = [].concat(getOperator(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getKeyframesBlocks());
12774 return newNode(type, content, line, column);
12778 * Check if token is part of an interpolated variable (e.g. `#{$nani}`).
12779 * @param {number} i Token's index number
12782 function checkInterpolation(i) {
12786 if (i >= tokensLength) return 0;
12788 if (tokens[i].type !== TokenType.NumberSign || !tokens[i + 1] || tokens[i + 1].type !== TokenType.LeftCurlyBracket) return 0;
12792 while (tokens[i].type !== TokenType.RightCurlyBracket) {
12793 if (l = checkArgument(i)) i += l;else return 0;
12796 return tokens[i].type === TokenType.RightCurlyBracket ? i - start + 1 : 0;
12800 * Get node with an interpolated variable
12801 * @return {Array} `['interpolation', x]`
12803 function getInterpolation() {
12804 var type = NodeType.InterpolationType;
12805 var token = tokens[pos];
12806 var line = token.ln;
12807 var column = token.col;
12813 while (pos < tokensLength && tokens[pos].type !== TokenType.RightCurlyBracket) {
12814 var body = getArgument();
12815 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
12818 var end = getLastPosition(content, line, column, 1);
12823 return newNode(type, content, line, column, end);
12827 * Check a single keyframe block - `5% {}`
12828 * @param {number} i
12831 function checkKeyframesBlock(i) {
12835 if (i >= tokensLength) return 0;
12837 if (l = checkKeyframesSelectorsGroup(i)) i += l;else return 0;
12839 if (l = checkSC(i)) i += l;
12841 if (l = checkBlock(i)) i += l;else return 0;
12847 * Get a single keyframe block - `5% {}`
12850 function getKeyframesBlock() {
12851 var type = NodeType.RulesetType;
12852 var token = tokens[pos];
12853 var line = token.ln;
12854 var column = token.col;
12855 var content = [].concat(getKeyframesSelectorsGroup(), getSC(), getBlock());
12857 return newNode(type, content, line, column);
12861 * Check all keyframe blocks - `5% {} 100% {}`
12862 * @param {number} i
12865 function checkKeyframesBlocks(i) {
12866 if (i >= tokensLength) return 0;
12868 var blockEnd = tokens[i].block_end;
12872 if (!blockEnd) return 0;
12874 if (l = checkSC(i)) i += l;
12876 if (l = checkKeyframesBlock(i)) i += l;
12878 while (i < blockEnd) {
12879 if (l = checkSC(i)) i += l;else if (l = checkKeyframesBlock(i)) i += l;else if (l = checkAtrule(i)) i += l;else break;
12882 if (i !== blockEnd + 1) return 0;
12884 return blockEnd + 1 - start;
12888 * Get all keyframe blocks - `5% {} 100% {}`
12891 function getKeyframesBlocks() {
12892 var type = NodeType.BlockType;
12893 var token = tokens[pos];
12894 var line = token.ln;
12895 var column = token.col;
12896 var keyframesBlocksEnd = token.block_end;
12899 while (pos < keyframesBlocksEnd) {
12900 if (checkSC(pos)) content = content.concat(getSC());else if (checkKeyframesBlock(pos)) content.push(getKeyframesBlock());else if (checkAtrule(pos)) content.push(getAtrule()); // @content
12904 return newNode(type, content, line, column);
12908 * Check if token is part of a @keyframes rule.
12909 * @param {number} i Token's index number
12910 * @return {number} Length of the @keyframes rule
12912 function checkKeyframesRule(i) {
12916 if (i >= tokensLength) return 0;
12918 if (l = checkAtkeyword(i)) i += l;else return 0;
12920 var atruleName = joinValues2(i - l, l);
12921 if (atruleName.toLowerCase().indexOf('keyframes') === -1) return 0;
12923 if (l = checkSC(i)) i += l;else return 0;
12925 if (l = checkIdentOrInterpolation(i) || checkPseudoc(i)) i += l;else return 0;
12927 if (l = checkSC(i)) i += l;
12929 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
12937 function getKeyframesRule() {
12938 var type = NodeType.AtruleType;
12939 var token = tokens[pos];
12940 var line = token.ln;
12941 var column = token.col;
12942 var content = [].concat(getAtkeyword(), getSC());
12944 if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());else if (checkPseudoc(pos)) {
12945 content = content.concat(getPseudoc());
12948 content = content.concat(getSC(), getKeyframesBlocks());
12950 return newNode(type, content, line, column);
12954 * Check a single keyframe selector - `5%`, `from` etc
12955 * @param {Number} i
12958 function checkKeyframesSelector(i) {
12962 if (i >= tokensLength) return 0;
12964 if (l = checkIdent(i)) {
12965 // Valid selectors are only `from` and `to`.
12966 var selector = joinValues2(i, l);
12967 if (selector !== 'from' && selector !== 'to') return 0;
12970 tokens[start].keyframesSelectorType = 1;
12971 } else if (l = checkPercentage(i)) {
12973 tokens[start].keyframesSelectorType = 2;
12974 } else if (l = checkInterpolation(i)) {
12976 tokens[start].keyframesSelectorType = 3;
12985 * Get a single keyframe selector
12988 function getKeyframesSelector() {
12989 var keyframesSelectorType = NodeType.KeyframesSelectorType;
12990 var selectorType = NodeType.SelectorType;
12991 var token = tokens[pos];
12992 var line = token.ln;
12993 var column = token.col;
12996 if (token.keyframesSelectorType === 1) {
12997 content.push(getIdent());
12998 } else if (token.keyframesSelectorType === 2) {
12999 content.push(getPercentage());
13000 } else if (token.keyframesSelectorType === 3) {
13001 content.push(getInterpolation());
13004 var keyframesSelector = newNode(keyframesSelectorType, content, line, column);
13006 return newNode(selectorType, [keyframesSelector], line, column);
13010 * Check the keyframe's selector groups
13011 * @param {number} i
13014 function checkKeyframesSelectorsGroup(i) {
13018 if (l = checkKeyframesSelector(i)) i += l;else return 0;
13020 // Check for trailing space
13021 if (l = checkSC(i) && tokens[i].type !== TokenType.Newline) i += l;
13023 while (i < tokensLength) {
13026 var tempLength = void 0;
13028 if (tempLength = checkDelim(tempIndex)) tempIndex += tempLength;else break;
13030 // Check for maxmimum space usage - 'space', '\n', 'space'
13031 if (tempLength = checkSC(tempIndex)) tempIndex += tempLength;
13032 if (tempLength = checkSC(tempIndex)) tempIndex += tempLength;
13033 if (tempLength = checkSC(tempIndex)) tempIndex += tempLength;
13035 if (tempLength = checkKeyframesSelector(tempIndex)) tempIndex += tempLength;else break;
13037 // Check for trailing space
13038 if (tempLength = checkSC(tempIndex) && tokens[tempIndex].type !== TokenType.Newline) {
13039 tempIndex += tempLength;
13042 i += tempIndex - tempStart;
13045 tokens[start].selectorsGroupEnd = i;
13051 * Get the keyframe's selector groups
13052 * @return {Array} An array of keyframe selectors
13054 function getKeyframesSelectorsGroup() {
13055 var selectorsGroup = [];
13056 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
13058 selectorsGroup.push(getKeyframesSelector());
13060 if (checkSC(pos) && tokens[pos].type !== TokenType.Newline) {
13061 selectorsGroup = selectorsGroup.concat(getSC());
13064 while (pos < selectorsGroupEnd) {
13065 selectorsGroup = selectorsGroup.concat(getDelim(), getSC(), getSC(), getSC(), getKeyframesSelector());
13067 if (checkSC(pos) && tokens[pos].type !== TokenType.Newline) {
13068 selectorsGroup = selectorsGroup.concat(getSC());
13072 return selectorsGroup;
13076 * Check if token is part of a loop.
13077 * @param {number} i Token's index number
13078 * @return {number} Length of the loop
13080 function checkLoop(i) {
13084 if (i >= tokensLength) return 0;
13086 if (l = checkAtkeyword(i)) i += l;else return 0;
13088 if (['for', 'each', 'while'].indexOf(tokens[start + 1].value) < 0) return 0;
13090 while (i < tokensLength) {
13091 if (l = checkBlock(i)) {
13094 } else if (l = checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkSC(i) || checkOperator(i) || checkCombinator(i) || checkString(i)) i += l;else return 0;
13101 * Get node with a loop.
13102 * @return {Array} `['loop', x]`
13104 function getLoop() {
13105 var type = NodeType.LoopType;
13106 var token = tokens[pos];
13107 var line = token.ln;
13108 var column = token.col;
13111 content.push(getAtkeyword());
13113 while (pos < tokensLength) {
13114 if (checkBlock(pos)) {
13115 content.push(getBlock());
13117 } else if (checkVariable(pos)) content.push(getVariable());else if (checkNumber(pos)) content.push(getNumber());else if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkIdent(pos)) content.push(getIdent());else if (checkOperator(pos)) content.push(getOperator());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkSC(pos)) content = content.concat(getSC());else if (checkString(pos)) content.push(getString());
13120 return newNode(type, content, line, column);
13124 * Check if token is part of a mixin
13125 * @param {number} i Token's index number
13126 * @return {number} Length of the mixin
13128 function checkMixin(i) {
13129 return checkMixin1(i) || checkMixin2(i);
13133 * Get node with a mixin
13134 * @return {Array} `['mixin', x]`
13136 function getMixin() {
13137 return checkMixin1(pos) ? getMixin1() : getMixin2();
13141 * Check if token is part of a mixin
13142 * @param {number} i Token's index number
13143 * @return {number} Length of the mixin
13145 function checkMixin1(i) {
13149 if (i >= tokensLength) return 0;
13151 if ((l = checkAtkeyword(i)) && tokens[i + 1].value === 'mixin') i += l;else return 0;
13153 if (l = checkSC(i)) i += l;
13155 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
13157 if (l = checkSC(i)) i += l;
13159 if (l = checkBlock(i)) i += l;else {
13160 if (l = checkArguments(i)) i += l;
13162 if (l = checkSC(i)) i += l;
13164 if (l = checkBlock(i)) i += l;else return 0;
13171 * Get node with a mixin
13172 * @return {Array} `['mixin', x]`
13174 function getMixin1() {
13175 var type = NodeType.MixinType;
13176 var token = tokens[pos];
13177 var line = token.ln;
13178 var column = token.col;
13179 var content = [].concat(getAtkeyword(), getSC());
13181 if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());
13183 content = content.concat(getSC());
13185 if (checkBlock(pos)) content.push(getBlock());else {
13186 if (checkArguments(pos)) content.push(getArguments());
13188 content = content.concat(getSC());
13190 content.push(getBlock());
13193 return newNode(type, content, line, column);
13197 * Check if token is part of a mixin
13198 * @param {number} i Token's index number
13199 * @return {number} Length of the mixin
13201 function checkMixin2(i) {
13205 if (i >= tokensLength) return 0;
13207 if (tokens[i].type === TokenType.EqualsSign) i++;else return 0;
13209 if (l = checkSC(i)) i += l;
13211 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
13213 if (l = checkSC(i)) i += l;
13215 if (l = checkBlock(i)) i += l;else {
13216 if (l = checkArguments(i)) i += l;
13218 if (l = checkSC(i)) i += l;
13220 if (l = checkBlock(i)) i += l;else return 0;
13227 * Get node with a mixin
13228 * @return {Array} `['mixin', x]`
13230 function getMixin2() {
13231 var type = NodeType.MixinType;
13232 var token = tokens[pos];
13233 var line = token.ln;
13234 var column = token.col;
13235 var content = [].concat(getOperator(), getSC());
13237 if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());
13239 content = content.concat(getSC());
13241 if (checkBlock(pos)) content.push(getBlock());else {
13242 if (checkArguments(pos)) content.push(getArguments());
13244 content = content.concat(getSC());
13246 content.push(getBlock());
13249 return newNode(type, content, line, column);
13253 * Check if token is a namespace sign (`|`)
13254 * @param {number} i Token's index number
13255 * @return {number} `1` if token is `|`, `0` if not
13257 function checkNamespace(i) {
13258 return i < tokensLength && tokens[i].type === TokenType.VerticalLine ? 1 : 0;
13262 * Get node with a namespace sign
13263 * @return {Array} `['namespace']`
13265 function getNamespace() {
13266 var type = NodeType.NamespaceType;
13267 var token = tokens[pos];
13268 var line = token.ln;
13269 var column = token.col;
13274 return newNode(type, content, line, column);
13278 * @param {number} i Token's index number
13281 function checkNmName2(i) {
13282 if (tokens[i].type === TokenType.Identifier) return 1;else if (tokens[i].type !== TokenType.DecimalNumber) return 0;
13286 return i < tokensLength && tokens[i].type === TokenType.Identifier ? 2 : 1;
13292 function getNmName2() {
13293 var s = tokens[pos].value;
13295 if (tokens[pos++].type === TokenType.DecimalNumber && pos < tokensLength && tokens[pos].type === TokenType.Identifier) s += tokens[pos++].value;
13301 * Check if token is part of a number
13302 * @param {number} i Token's index number
13303 * @return {number} Length of number
13305 function checkNumber(i) {
13306 if (i >= tokensLength) return 0;
13308 if (tokens[i].number_l) return tokens[i].number_l;
13311 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && (!tokens[i + 1] || tokens[i + 1] && tokens[i + 1].type !== TokenType.FullStop)) {
13312 tokens[i].number_l = 1;
13317 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && (!tokens[i + 2] || tokens[i + 2].type !== TokenType.DecimalNumber)) {
13318 tokens[i].number_l = 2;
13323 if (i < tokensLength && tokens[i].type === TokenType.FullStop && tokens[i + 1].type === TokenType.DecimalNumber) {
13324 tokens[i].number_l = 2;
13329 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && tokens[i + 2] && tokens[i + 2].type === TokenType.DecimalNumber) {
13330 tokens[i].number_l = 3;
13338 * Get node with number
13339 * @return {Array} `['number', x]` where `x` is a number converted
13342 function getNumber() {
13343 var type = NodeType.NumberType;
13344 var token = tokens[pos];
13345 var line = token.ln;
13346 var column = token.col;
13347 var l = tokens[pos].number_l;
13350 for (var j = 0; j < l; j++) {
13351 content += tokens[pos + j].value;
13356 return newNode(type, content, line, column);
13360 * Check if token is an operator (`/`, `%`, `,`, `:` or `=`).
13361 * @param {number} i Token's index number
13362 * @return {number} `1` if token is an operator, otherwise `0`
13364 function checkOperator(i) {
13365 if (i >= tokensLength) return 0;
13367 switch (tokens[i].type) {
13368 case TokenType.Solidus:
13369 case TokenType.PercentSign:
13370 case TokenType.Comma:
13371 case TokenType.Colon:
13372 case TokenType.EqualsSign:
13373 case TokenType.EqualitySign:
13374 case TokenType.InequalitySign:
13375 case TokenType.LessThanSign:
13376 case TokenType.GreaterThanSign:
13377 case TokenType.Asterisk:
13385 * Get node with an operator
13386 * @return {Array} `['operator', x]` where `x` is an operator converted
13389 function getOperator() {
13390 var type = NodeType.OperatorType;
13391 var token = tokens[pos];
13392 var line = token.ln;
13393 var column = token.col;
13394 var content = token.value;
13398 return newNode(type, content, line, column);
13402 * Check if token is part of `!optional` word
13403 * @param {number} i Token's index number
13406 function checkOptional(i) {
13410 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
13412 if (l = checkSC(i)) i += l;
13414 if (tokens[i].value === 'optional') {
13415 tokens[start].optionalEnd = i;
13416 return i - start + 1;
13423 * Get node with `!optional` word
13425 function getOptional() {
13426 var type = NodeType.OptionalType;
13427 var token = tokens[pos];
13428 var line = token.ln;
13429 var column = token.col;
13430 var content = joinValues(pos, token.optionalEnd);
13432 pos = token.optionalEnd + 1;
13434 return newNode(type, content, line, column);
13438 * Check if token is part of text inside parentheses, e.g. `(1)`
13439 * @param {number} i Token's index number
13442 function checkParentheses(i) {
13443 if (i >= tokensLength) return 0;
13446 var right = tokens[i].right;
13450 if (tokens[i].type === TokenType.LeftParenthesis) i++;else return 0;
13453 if (l = checkTsets(i)) i += l;else return 0;
13463 * Get node with text inside parentheses, e.g. `(1)`
13466 function getParentheses() {
13467 var type = NodeType.ParenthesesType;
13468 var token = tokens[pos];
13469 var line = token.ln;
13470 var column = token.col;
13471 var right = token.right;
13478 content = getTsets();
13481 var end = getLastPosition(content, line, column, 1);
13486 return newNode(type, content, line, column, end);
13490 * Check if token is a parent selector, e.g. `&`
13491 * @param {number} i Token's index number
13494 function checkParentSelector(i) {
13495 return i < tokensLength && tokens[i].type === TokenType.Ampersand ? 1 : 0;
13499 * Get node with a parent selector
13502 function getParentSelector() {
13503 var type = NodeType.ParentSelectorType;
13504 var token = tokens[pos];
13505 var line = token.ln;
13506 var column = token.col;
13511 return newNode(type, content, line, column);
13515 * Check if token is a parent selector extension, e.g. `&--foo-bar`
13516 * @param {number} i Token's index number
13517 * @returns {number} Length of the parent selector extension
13519 function checkParentSelectorExtension(i) {
13523 if (i >= tokensLength) return 0;
13525 while (i < tokensLength) {
13526 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else break;
13533 * Get parent selector extension node
13536 function getParentSelectorExtension() {
13537 var type = NodeType.ParentSelectorExtensionType;
13538 var token = tokens[pos];
13539 var line = token.ln;
13540 var column = token.col;
13543 while (pos < tokensLength) {
13544 if (checkIdentOrInterpolation(pos)) {
13545 content = content.concat(getIdentOrInterpolation());
13546 } else if (checkPartialIdent(pos)) {
13547 content.push(getIdent());
13551 return newNode(type, content, line, column);
13555 * Check if token is a parent selector with an extension or not
13556 * @param {number} i Token's index number
13557 * @return {number} Length of the parent selector and extension if applicable
13559 function checkParentSelectorWithExtension(i) {
13563 if (i >= tokensLength) return 0;
13565 if (l = checkParentSelector(i)) i += l;else return 0;
13567 if (l = checkParentSelectorExtension(i)) i += l;
13573 * Get parent selector node and extension node if applicable
13576 function getParentSelectorWithExtension() {
13577 var content = [getParentSelector()];
13579 if (checkParentSelectorExtension(pos)) content.push(getParentSelectorExtension());
13585 * Check if token is part of a number or an interpolation with a percent sign
13587 * @param {number} i Token's index number
13590 function checkPercentage(i) {
13594 if (i >= tokensLength) return 0;
13596 if (l = checkNumberOrInterpolation(i)) i += l;else return 0;
13598 if (i >= tokensLength) return 0;
13601 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
13607 * Get a percentage node that contains either a number or an interpolation
13608 * @return {Object} The percentage node
13610 function getPercentage() {
13611 var type = NodeType.PercentageType;
13612 var token = tokens[pos];
13613 var line = token.ln;
13614 var column = token.col;
13615 var content = getNumberOrInterpolation();
13616 var end = getLastPosition(content, line, column, 1);
13621 return newNode(type, content, line, column, end);
13625 * Check if token is a number or an interpolation
13626 * @param {number} i Token's index number
13629 function checkNumberOrInterpolation(i) {
13633 while (i < tokensLength) {
13634 if (l = checkInterpolation(i) || checkNumber(i)) i += l;else break;
13641 * Get a number and/or interpolation node
13642 * @return {Array} An array containing a single or multiple nodes
13644 function getNumberOrInterpolation() {
13647 while (pos < tokensLength) {
13648 if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkNumber(pos)) content.push(getNumber());else break;
13655 * Check if token is part of a placeholder selector (e.g. `%abc`).
13656 * @param {number} i Token's index number
13657 * @return {number} Length of the selector
13659 function checkPlaceholder(i) {
13663 if (i >= tokensLength) return 0;
13665 if (tokens[start].placeholder_l) return tokens[start].placeholder_l;
13668 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
13670 if (l = checkIdentOrInterpolation(i)) {
13672 tokens[start].placeholder_l = i - start;
13679 * Get node with a placeholder selector
13680 * @return {Array} `['placeholder', ['ident', x]]` where x is a placeholder's
13681 * identifier (without `%`, e.g. `abc`).
13683 function getPlaceholder() {
13684 var type = NodeType.PlaceholderType;
13685 var token = tokens[pos];
13686 var line = token.ln;
13687 var column = token.col;
13693 content = content.concat(getIdentOrInterpolation());
13695 return newNode(type, content, line, column);
13699 * @param {number} i Token's index number
13702 function checkProgid(i) {
13706 if (i >= tokensLength) return 0;
13708 if (joinValues2(i, 6) === 'progid:DXImageTransform.Microsoft.') i += 6;else return 0;
13710 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
13712 if (l = checkSC(i)) i += l;
13714 if (tokens[i].type === TokenType.LeftParenthesis) {
13715 tokens[start].progid_end = tokens[i].right;
13716 i = tokens[i].right + 1;
13725 function getProgid() {
13726 var type = NodeType.ProgidType;
13727 var token = tokens[pos];
13728 var line = token.ln;
13729 var column = token.col;
13730 var progid_end = token.progid_end;
13731 var content = joinValues(pos, progid_end);
13733 pos = progid_end + 1;
13735 return newNode(type, content, line, column);
13739 * Check if token is part of a property
13740 * @param {Number} i Token's index number
13741 * @return {Number} Length of the property
13743 function checkProperty(i) {
13747 if (l = checkProperty1(i)) tokens[start].propertyType = 1;else if (l = checkProperty2(i)) tokens[start].propertyType = 2;else if (l = checkProperty3(i)) tokens[start].propertyType = 3;
13753 * Get node with a property
13756 function getProperty() {
13757 var type = tokens[pos].propertyType;
13759 if (type === 1) return getProperty1();
13760 if (type === 2) return getProperty2();
13761 if (type === 3) return getProperty3();
13765 * Check if token is part of a property
13768 * @param {Number} i Token's index number
13769 * @returns {Number} Length of the property
13771 function checkProperty1(i) {
13775 if (i >= tokensLength) return 0;
13777 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
13783 * Get node with a property
13786 function getProperty1() {
13787 var type = NodeType.PropertyType;
13788 var token = tokens[pos];
13789 var line = token.ln;
13790 var column = token.col;
13791 var content = getIdentOrInterpolation();
13793 return newNode(type, content, line, column);
13797 * Check if token is part of a custom property
13799 * @param {Number} i Token's index number
13800 * @return {Number} Length of the property
13802 function checkProperty2(i) {
13803 return checkCustomProperty(i);
13807 * Get node with a custom property
13810 function getProperty2() {
13811 return getCustomProperty();
13815 * Check if token is part of a property
13817 * @param {Number} i Token's index number
13818 * @returns {Number} Length of the property
13820 function checkProperty3(i) {
13824 if (i >= tokensLength) return 0;
13826 if (l = checkVariable(i)) i += l;else return 0;
13832 * Get node with a property
13833 * @returns {Array} `['property', x]`
13835 function getProperty3() {
13836 var type = NodeType.PropertyType;
13837 var token = tokens[pos];
13838 var line = token.ln;
13839 var column = token.col;
13840 var content = [getVariable()];
13842 return newNode(type, content, line, column);
13846 * Check if token is part of a custom property
13847 * @param {Number} i Token's index number
13848 * @return {Number} Length of the property
13850 function checkCustomProperty(i) {
13854 if (i >= tokensLength) return 0;
13856 if (tokens[i].type !== TokenType.HyphenMinus || tokens[i + 1] && tokens[i + 1].type !== TokenType.HyphenMinus) return 0;
13861 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
13867 * Get node with a custom property
13870 function getCustomProperty() {
13871 var type = NodeType.CustomPropertyType;
13872 var token = tokens[pos];
13873 var line = token.ln;
13874 var column = token.col;
13879 var content = getIdentOrInterpolation();
13881 return newNode(type, content, line, column);
13885 * Check if token is a colon
13886 * @param {number} i Token's index number
13887 * @return {number} `1` if token is a colon, otherwise `0`
13889 function checkPropertyDelim(i) {
13890 return i < tokensLength && tokens[i].type === TokenType.Colon ? 1 : 0;
13894 * Get node with a colon
13895 * @return {Array} `['propertyDelim']`
13897 function getPropertyDelim() {
13898 var type = NodeType.PropertyDelimType;
13899 var token = tokens[pos];
13900 var line = token.ln;
13901 var column = token.col;
13907 return newNode(type, content, line, column);
13911 * @param {number} i Token's index number
13914 function checkPseudo(i) {
13915 return checkPseudoe(i) || checkPseudoc(i);
13921 function getPseudo() {
13922 if (checkPseudoe(pos)) return getPseudoe();
13923 if (checkPseudoc(pos)) return getPseudoc();
13927 * @param {Number} i Token's index number
13930 function checkPseudoe(i) {
13934 if (i >= tokensLength || tokens[i].type !== TokenType.Colon || i + 1 >= tokensLength || tokens[i + 1].type !== TokenType.Colon) return 0;
13936 if (l = checkPseudoElement1(i)) tokens[i].pseudoElementType = 1;else if (l = checkPseudoElement2(i)) tokens[i].pseudoElementType = 2;else return 0;
13944 function getPseudoe() {
13945 var childType = tokens[pos].pseudoElementType;
13946 if (childType === 1) return getPseudoElement1();
13947 if (childType === 2) return getPseudoElement2();
13951 * (1) `::slotted(selector)`
13952 * (2) `::slotted(selector, selector)`
13954 function checkPseudoElement1(i) {
13961 if (i >= tokensLength) return 0;
13963 if (l = checkIdent(i)) i += l;else return 0;
13965 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
13967 var right = tokens[i].right;
13972 if (l = checkSC(i)) i += l;
13974 if (l = checkSelectorsGroup(i)) i += l;else return 0;
13976 if (l = checkSC(i)) i += l;
13978 if (i !== right) return 0;
13987 * (1) `::slotted(selector)`
13988 * (2) `::slotted(selector, selector)`
13990 function getPseudoElement1() {
13991 var type = NodeType.PseudoeType;
13992 var token = tokens[pos];
13993 var line = token.ln;
13994 var column = token.col;
14000 content.push(getIdent());
14003 var _type = NodeType.ArgumentsType;
14004 var _token = tokens[pos];
14005 var _line = _token.ln;
14006 var _column = _token.col;
14011 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
14013 var end = getLastPosition(selectorContent, _line, _column, 1);
14014 var args = newNode(_type, selectorContent, _line, _column, end);
14015 content.push(args);
14021 return newNode(type, content, line, column);
14024 function checkPseudoElement2(i) {
14031 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14039 function getPseudoElement2() {
14040 var type = NodeType.PseudoeType;
14041 var token = tokens[pos];
14042 var line = token.ln;
14043 var column = token.col;
14048 var content = getIdentOrInterpolation();
14050 return newNode(type, content, line, column);
14054 * @param {number} i Token's index number
14057 function checkPseudoc(i) {
14060 if (i >= tokensLength || tokens[i].type !== TokenType.Colon) return 0;
14062 if (l = checkPseudoClass3(i)) tokens[i].pseudoClassType = 3;else if (l = checkPseudoClass4(i)) tokens[i].pseudoClassType = 4;else if (l = checkPseudoClass5(i)) tokens[i].pseudoClassType = 5;else if (l = checkPseudoClass1(i)) tokens[i].pseudoClassType = 1;else if (l = checkPseudoClass2(i)) tokens[i].pseudoClassType = 2;else if (l = checkPseudoClass6(i)) tokens[i].pseudoClassType = 6;else return 0;
14070 function getPseudoc() {
14071 var childType = tokens[pos].pseudoClassType;
14072 if (childType === 1) return getPseudoClass1();
14073 if (childType === 2) return getPseudoClass2();
14074 if (childType === 3) return getPseudoClass3();
14075 if (childType === 4) return getPseudoClass4();
14076 if (childType === 5) return getPseudoClass5();
14077 if (childType === 6) return getPseudoClass6();
14081 * (-) `:not(panda)`
14083 function checkPseudoClass1(i) {
14090 if (i >= tokensLength) return 0;
14092 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14094 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
14096 var right = tokens[i].right;
14101 if (l = checkSC(i)) i += l;
14103 if (l = checkSelectorsGroup(i)) i += l;else return 0;
14105 if (l = checkSC(i)) i += l;
14107 if (i !== right) return 0;
14116 * (-) `:not(panda)`
14118 function getPseudoClass1() {
14119 var type = NodeType.PseudocType;
14120 var token = tokens[pos];
14121 var line = token.ln;
14122 var column = token.col;
14128 content = content.concat(getIdentOrInterpolation());
14131 var _type2 = NodeType.ArgumentsType;
14132 var _token2 = tokens[pos];
14133 var _line2 = _token2.ln;
14134 var _column2 = _token2.col;
14139 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
14141 var end = getLastPosition(selectorContent, _line2, _column2, 1);
14142 var args = newNode(_type2, selectorContent, _line2, _column2, end);
14143 content.push(args);
14149 return newNode(type, content, line, column);
14153 * (1) `:nth-child(odd)`
14154 * (2) `:nth-child(even)`
14155 * (3) `:lang(de-DE)`
14157 function checkPseudoClass2(i) {
14164 if (i >= tokensLength) return 0;
14166 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14168 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
14170 var right = tokens[i].right;
14175 if (l = checkSC(i)) i += l;
14177 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14179 if (l = checkSC(i)) i += l;
14181 if (i !== right) return 0;
14189 function getPseudoClass2() {
14190 var type = NodeType.PseudocType;
14191 var token = tokens[pos];
14192 var line = token.ln;
14193 var column = token.col;
14199 content = content.concat(getIdentOrInterpolation());
14201 var l = tokens[pos].ln;
14202 var c = tokens[pos].col;
14207 var value = [].concat(getSC(), getIdentOrInterpolation(), getSC());
14209 var end = getLastPosition(value, l, c, 1);
14210 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
14211 content.push(args);
14216 return newNode(type, content, line, column);
14220 * (-) `:nth-child(-3n + 2)`
14222 function checkPseudoClass3(i) {
14229 if (i >= tokensLength) return 0;
14231 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14233 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
14235 var right = tokens[i].right;
14240 if (l = checkSC(i)) i += l;
14242 if (l = checkUnary(i)) i += l;
14244 if (l = checkNumberOrInterpolation(i)) i += l;
14246 if (i >= tokensLength) return 0;
14248 if (tokens[i].value === 'n') i++;
14250 if (l = checkSC(i)) i += l;
14252 if (i >= tokensLength) return 0;
14254 if (tokens[i].type === TokenType.PlusSign || tokens[i].type === TokenType.HyphenMinus) i++;else return 0;
14256 if (l = checkSC(i)) i += l;
14258 if (l = checkNumberOrInterpolation(i)) i += l;else return 0;
14260 if (l = checkSC(i)) i += l;
14262 if (i !== right) return 0;
14270 function getPseudoClass3() {
14271 var type = NodeType.PseudocType;
14272 var token = tokens[pos];
14273 var line = token.ln;
14274 var column = token.col;
14280 content = content.concat(getIdentOrInterpolation());
14282 var l = tokens[pos].ln;
14283 var c = tokens[pos].col;
14289 value = value.concat(getSC());
14291 if (checkUnary(pos)) value.push(getUnary());
14292 if (checkNumberOrInterpolation(pos)) value = value.concat(getNumberOrInterpolation());
14295 var _token3 = tokens[pos];
14297 if (_token3.value === 'n') {
14298 var _l = _token3.ln;
14299 var _c = _token3.col;
14300 var _content2 = _token3.value;
14301 var ident = newNode(NodeType.IdentType, _content2, _l, _c);
14307 value = value.concat(getSC());
14309 if (checkUnary(pos)) value.push(getUnary());
14311 value = value.concat(getSC());
14313 if (checkNumberOrInterpolation(pos)) value = value.concat(getNumberOrInterpolation());
14315 value = value.concat(getSC());
14317 var end = getLastPosition(value, l, c, 1);
14318 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
14319 content.push(args);
14324 return newNode(type, content, line, column);
14328 * (-) `:nth-child(-3n)`
14330 function checkPseudoClass4(i) {
14337 if (i >= tokensLength) return 0;
14339 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14341 if (i >= tokensLength) return 0;
14342 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
14344 var right = tokens[i].right;
14349 if (l = checkSC(i)) i += l;
14351 if (l = checkUnary(i)) i += l;
14353 if (l = checkInterpolation(i)) i += l;
14355 if (tokens[i].type === TokenType.DecimalNumber) i++;
14357 if (tokens[i].value === 'n') i++;else return 0;
14359 if (l = checkSC(i)) i += l;
14361 if (i !== right) return 0;
14369 function getPseudoClass4() {
14370 var type = NodeType.PseudocType;
14371 var token = tokens[pos];
14372 var line = token.ln;
14373 var column = token.col;
14379 content = content.concat(getIdentOrInterpolation());
14381 var l = tokens[pos].ln;
14382 var c = tokens[pos].col;
14388 value = value.concat(getSC());
14390 if (checkUnary(pos)) value.push(getUnary());
14391 if (checkInterpolation(pos)) value.push(getInterpolation());
14392 if (checkNumber(pos)) value.push(getNumber());
14393 if (checkIdent(pos)) value.push(getIdent());
14395 value = value.concat(getSC());
14397 var end = getLastPosition(value, l, c, 1);
14398 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
14399 content.push(args);
14404 return newNode(type, content, line, column);
14408 * (-) `:nth-child(+8)`
14410 function checkPseudoClass5(i) {
14417 if (i >= tokensLength) return 0;
14419 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14421 if (i >= tokensLength) return 0;
14422 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
14424 var right = tokens[i].right;
14429 if (l = checkSC(i)) i += l;
14431 if (l = checkUnary(i)) i += l;
14432 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
14434 if (l = checkSC(i)) i += l;
14436 if (i !== right) return 0;
14444 function getPseudoClass5() {
14445 var type = NodeType.PseudocType;
14446 var token = tokens[pos];
14447 var line = token.ln;
14448 var column = token.col;
14454 content = content.concat(getIdentOrInterpolation());
14456 var l = tokens[pos].ln;
14457 var c = tokens[pos].col;
14463 value = value.concat(getSC());
14465 if (checkUnary(pos)) value.push(getUnary());
14466 if (checkNumber(pos)) value.push(getNumber());
14468 value = value.concat(getSC());
14470 var end = getLastPosition(value, l, c, 1);
14471 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
14472 content.push(args);
14477 return newNode(type, content, line, column);
14483 function checkPseudoClass6(i) {
14490 if (i >= tokensLength) return 0;
14492 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
14497 function getPseudoClass6() {
14498 var type = NodeType.PseudocType;
14499 var token = tokens[pos];
14500 var line = token.ln;
14501 var column = token.col;
14506 var content = getIdentOrInterpolation();
14508 return newNode(type, content, line, column);
14512 * @param {number} i Token's index number
14515 function checkRuleset(i) {
14519 if (i >= tokensLength) return 0;
14521 if (l = checkSelectorsGroup(i)) i += l;else return 0;
14523 if (l = checkSC(i)) i += l;
14525 if (l = checkBlock(i)) {
14527 } else if (l = checkSC(i)) {
14529 if (l = checkBlock(i)) i += l;else return 0;
14535 function getRuleset() {
14536 var type = NodeType.RulesetType;
14537 var token = tokens[pos];
14538 var line = token.ln;
14539 var column = token.col;
14540 var content = [].concat(getSelectorsGroup(), getSC());
14542 if (checkBlock(pos)) {
14543 content.push(getBlock());
14545 content = content.concat(getSC(), getBlock());
14548 return newNode(type, content, line, column);
14552 * Check if token is marked as a space (if it's a space or a tab
14553 * or a line break).
14554 * @param {number} i
14555 * @return {number} Number of spaces in a row starting with the given token.
14557 function checkS(i) {
14558 return i < tokensLength && tokens[i].ws ? tokens[i].ws_last - i + 1 : 0;
14562 * Get node with spaces
14563 * @return {Array} `['s', x]` where `x` is a string containing spaces
14566 var type = NodeType.SType;
14567 var token = tokens[pos];
14568 var line = token.ln;
14569 var column = token.col;
14570 var content = joinValues(pos, tokens[pos].ws_last);
14572 pos = tokens[pos].ws_last + 1;
14574 return newNode(type, content, line, column);
14578 * Check if token is a space, newline, or a comment.
14579 * @param {number} i Token's index number
14580 * @return {number} Number of similar (space, newline, or comment) tokens
14581 * in a row starting with the given token.
14583 function checkMultilineSC(i) {
14584 if (!tokens[i]) return 0;
14589 while (i < tokensLength) {
14590 if (!(l = checkS(i)) && !(l = checkCommentML(i)) && !(l = checkCommentSL(i))) break;
14600 * Get node with spaces newlines and comments
14603 function getMultilineSC() {
14606 if (pos >= tokensLength) return sc;
14608 while (pos < tokensLength) {
14609 if (checkS(pos)) sc.push(getS());else if (checkCommentML(pos)) sc.push(getCommentML());else if (checkCommentSL(pos)) sc.push(getCommentSL());else break;
14616 * Check if token is a space or a comment.
14617 * @param {number} i Token's index number
14618 * @return {number} Number of similar (space or comment) tokens
14619 * in a row starting with the given token.
14621 function checkSC(i) {
14622 if (i >= tokensLength) return 0;
14626 var ln = tokens[i].ln;
14628 while (i < tokensLength) {
14629 if (tokens[i].ln !== ln) break;
14631 if (l = checkS(i)) tokens[i].sc_child = 1;else if (l = checkCommentML(i)) tokens[i].sc_child = 2;else if (l = checkCommentSL(i)) tokens[i].sc_child = 3;else break;
14636 if (tokens[i] && tokens[i].type === TokenType.Newline) break;
14643 * Get node with spaces and comments
14644 * @return {Array} Array containing nodes with spaces (if there are any)
14645 * and nodes with comments (if there are any):
14646 * `[['s', x]*, ['comment', y]*]` where `x` is a string of spaces
14647 * and `y` is a comment's text (without `/*` and `* /`).
14652 if (pos >= tokensLength) return sc;
14654 var ln = tokens[pos].ln;
14656 while (pos < tokensLength) {
14657 if (tokens[pos].ln !== ln) break;else if (checkS(pos)) sc.push(getS());else if (checkCommentML(pos)) sc.push(getCommentML());else if (checkCommentSL(pos)) sc.push(getCommentSL());else break;
14659 if (tokens[pos] && tokens[pos].type === TokenType.Newline) break;
14666 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside a simple
14668 * @param {number} i Token's index number
14671 function checkShash(i) {
14675 if (i >= tokensLength) return 0;
14677 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
14679 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else return 0;
14681 while (i < tokensLength) {
14682 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else break;
14685 tokens[start].shashEnd = i;
14691 * Get node with a hexadecimal number (e.g. `#fff`) inside a simple selector
14694 function getShash() {
14695 var type = NodeType.ShashType;
14696 var token = tokens[pos];
14697 var line = token.ln;
14698 var column = token.col;
14699 var end = token.shashEnd;
14705 while (pos < end) {
14706 if (checkIdentOrInterpolation(pos)) {
14707 content = content.concat(getIdentOrInterpolation());
14708 } else if (checkPartialIdent(pos)) {
14709 content.push(getIdent());
14713 return newNode(type, content, line, column);
14717 * Check if token is part of a string (text wrapped in quotes)
14718 * @param {number} i Token's index number
14719 * @return {number} `1` if token is part of a string, `0` if not
14721 function checkString(i) {
14722 if (i >= tokensLength) return 0;
14724 if (tokens[i].type === TokenType.StringSQ || tokens[i].type === TokenType.StringDQ) {
14732 * Get string's node
14733 * @return {Array} `['string', x]` where `x` is a string (including
14736 function getString() {
14737 var type = NodeType.StringType;
14738 var token = tokens[pos];
14739 var line = token.ln;
14740 var column = token.col;
14741 var content = token.value;
14745 return newNode(type, content, line, column);
14749 * Validate stylesheet: it should consist of any number (0 or more) of
14750 * rulesets (sets of rules with selectors), @-rules, whitespaces or
14752 * @param {number} i Token's index number
14755 function checkStylesheet(i) {
14759 while (i < tokensLength) {
14760 if (l = checkSC(i) || checkDeclaration(i) || checkDeclDelim(i) || checkInclude(i) || checkExtend(i) || checkMixin(i) || checkLoop(i) || checkConditionalStatement(i) || checkAtrule(i) || checkRuleset(i)) i += l;else throwError(i);
14767 * @return {Array} `['stylesheet', x]` where `x` is all stylesheet's
14770 function getStylesheet() {
14771 var type = NodeType.StylesheetType;
14772 var token = tokens[pos];
14773 var line = token.ln;
14774 var column = token.col;
14777 var wasDeclaration = false;
14779 while (pos < tokensLength) {
14780 if (wasDeclaration && checkDeclDelim(pos)) node = getDeclDelim();else if (checkSC(pos)) node = getSC();else if (checkRuleset(pos)) node = getRuleset();else if (checkInclude(pos)) node = getInclude();else if (checkExtend(pos)) node = getExtend();else if (checkMixin(pos)) node = getMixin();else if (checkLoop(pos)) node = getLoop();else if (checkConditionalStatement(pos)) node = getConditionalStatement();else if (checkAtrule(pos)) node = getAtrule();else if (checkDeclaration(pos)) node = getDeclaration();else throwError(pos);
14782 wasDeclaration = node.type === NodeType.DeclarationType;
14783 if (Array.isArray(node)) content = content.concat(node);else content.push(node);
14786 return newNode(type, content, line, column);
14790 * @param {Number} i Token's index number
14793 function checkTset(i) {
14794 return checkVhash(i) || checkOperator(i) || checkAny(i) || checkSC(i);
14800 function getTset() {
14801 if (checkVhash(pos)) return getVhash();else if (checkOperator(pos)) return getOperator();else if (checkAny(pos)) return getAny();else if (checkSC(pos)) return getSC();
14805 * @param {number} i Token's index number
14808 function checkTsets(i) {
14812 if (i >= tokensLength) return 0;
14814 while (tokens[i - 1].type !== TokenType.Newline && (l = checkTset(i))) {
14824 function getTsets() {
14828 while (tokens[pos - 1].type !== TokenType.Newline && (t = getTset())) {
14829 if (typeof t.content === 'string') content.push(t);else content = content.concat(t);
14836 * Check if token is an unary (arithmetical) sign (`+` or `-`)
14837 * @param {number} i Token's index number
14838 * @return {number} `1` if token is an unary sign, `0` if not
14840 function checkUnary(i) {
14841 if (i >= tokensLength) return 0;
14843 if (tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.PlusSign) {
14851 * Get node with an unary (arithmetical) sign (`+` or `-`)
14852 * @return {Array} `['unary', x]` where `x` is an unary sign
14853 * converted to string.
14855 function getUnary() {
14856 var type = NodeType.OperatorType;
14857 var token = tokens[pos];
14858 var line = token.ln;
14859 var column = token.col;
14860 var content = token.value;
14864 return newNode(type, content, line, column);
14868 * Check if token is a unicode range (single or multiple <urange> nodes)
14869 * @param {number} i Token's index
14870 * @return {number} Unicode range node's length
14872 function checkUnicodeRange(i) {
14876 if (i >= tokensLength) return 0;
14878 if (l = checkUrange(i)) i += l;else return 0;
14880 while (i < tokensLength) {
14881 var spaceBefore = checkSC(i);
14882 var comma = checkDelim(i + spaceBefore);
14885 var spaceAfter = checkSC(i + spaceBefore + comma);
14886 if (l = checkUrange(i + spaceBefore + comma + spaceAfter)) {
14887 i += spaceBefore + comma + spaceAfter + l;
14895 * Get a unicode range node
14898 function getUnicodeRange() {
14899 var type = NodeType.UnicodeRangeType;
14900 var token = tokens[pos];
14901 var line = token.ln;
14902 var column = token.col;
14905 while (pos < tokensLength) {
14906 if (checkSC(pos)) content = content.concat(getSC());else if (checkDelim(pos)) content.push(getDelim());else if (checkUrange(pos)) content.push(getUrange());else break;
14909 return newNode(type, content, line, column);
14913 * Check if token is unit
14914 * @param {Number} i Token's index number
14917 function checkUnit(i) {
14918 var units = ['em', 'ex', 'ch', 'rem', 'vh', 'vw', 'vmin', 'vmax', 'px', 'mm', 'q', 'cm', 'in', 'pt', 'pc', 'deg', 'grad', 'rad', 'turn', 's', 'ms', 'Hz', 'kHz', 'dpi', 'dpcm', 'dppx'];
14920 return units.indexOf(tokens[i].value) !== -1 ? 1 : 0;
14924 * Get unit node of type ident
14925 * @return {Node} An ident node containing the unit value
14927 function getUnit() {
14928 var type = NodeType.IdentType;
14929 var token = tokens[pos];
14930 var line = token.ln;
14931 var column = token.col;
14932 var content = token.value;
14936 return newNode(type, content, line, column);
14940 * Check if token is a u-range (part of a unicode-range)
14944 * @param {number} i Token's index
14945 * @return {number} Urange node's length
14947 function checkUrange(i) {
14951 if (i >= tokensLength) return 0;
14953 // Check for unicode prefix (u+ or U+)
14954 if (tokens[i].value === 'U' || tokens[i].value === 'u') i += 1;else return 0;
14956 if (i >= tokensLength) return 0;
14958 if (tokens[i].value === '+') i += 1;else return 0;
14960 while (i < tokensLength) {
14961 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = _checkUnicodeWildcard(i)) i += l;else break;
14964 tokens[start].urangeEnd = i - 1;
14970 * Get a u-range node (part of a unicode-range)
14973 function getUrange() {
14974 var startPos = pos;
14975 var type = NodeType.UrangeType;
14976 var token = tokens[pos];
14977 var line = token.ln;
14978 var column = token.col;
14981 content = joinValues(startPos, tokens[startPos].urangeEnd);
14982 pos = tokens[startPos].urangeEnd + 1;
14984 return newNode(type, content, line, column);
14988 * Check for unicode wildcard characters `?`
14989 * @param {number} i Token's index
14990 * @return {number} Wildcard length
14992 function _checkUnicodeWildcard(i) {
14995 if (i >= tokensLength) return 0;
14997 while (i < tokensLength) {
14998 if (tokens[i].type === TokenType.QuestionMark) i += 1;else break;
15005 * Check if token is part of URI, e.g. `url('/css/styles.css')`
15006 * @param {number} i Token's index number
15007 * @returns {number} Length of URI
15009 function checkUri(i) {
15013 if (i >= tokensLength || tokens[i].value !== 'url') return 0;
15018 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
15020 // Store the opening parenthesis token as we will reference it's `right`
15021 // property to determine when the parentheses close
15022 var leftParenthesis = tokens[i];
15027 // Determine the type of URI
15028 while (i < leftParenthesis.right) {
15029 if (l = checkUri1(i)) {
15031 tokens[start].uriType = 1; // Raw based URI (without quotes)
15032 } else if (l = checkUri2(i)) {
15034 tokens[start].uriType = 2; // Non-raw based URI (with quotes)
15045 * Get specific type of URI node
15046 * @return {Node} Specific type of URI node
15048 function getUri() {
15049 var startPos = pos;
15050 var type = NodeType.UriType;
15051 var token = tokens[startPos];
15052 var line = token.ln;
15053 var column = token.col;
15057 var uriType = tokens[startPos].uriType;
15059 // Skip `url` and `(`.
15062 if (uriType === 1) content = content.concat(getUri1());else if (uriType === 2) content = content.concat(getUri2());else end = getLastPosition(content, line, column, 4);
15064 if (!end) end = getLastPosition(content, line, column, 1);
15069 return newNode(type, content, line, column, end);
15073 * Check if token type is valid URI character
15074 * @param {number} i Token's index number
15075 * @return {number} Length of raw node
15077 function checkUriRawCharacters(i) {
15081 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else {
15082 switch (tokens[i].type) {
15083 case TokenType.ExclamationMark:
15084 case TokenType.NumberSign:
15085 case TokenType.DollarSign:
15086 case TokenType.PercentSign:
15087 case TokenType.Ampersand:
15088 case TokenType.Asterisk:
15089 case TokenType.PlusSign:
15090 case TokenType.Comma:
15091 case TokenType.HyphenMinus:
15092 case TokenType.FullStop:
15093 case TokenType.Solidus:
15094 case TokenType.Colon:
15095 case TokenType.Semicolon:
15096 case TokenType.LessThanSign:
15097 case TokenType.EqualsSign:
15098 case TokenType.GreaterThanSign:
15099 case TokenType.QuotationMark:
15100 case TokenType.CommercialAt:
15101 case TokenType.LeftSquareBracket:
15102 case TokenType.RightSquareBracket:
15103 case TokenType.CircumflexAccent:
15104 case TokenType.LowLine:
15105 case TokenType.LeftCurlyBracket:
15106 case TokenType.VerticalLine:
15107 case TokenType.RightCurlyBracket:
15108 case TokenType.Tilde:
15121 * Check if content of URI can be contained within a raw node
15122 * @param {number} i Token's index number
15123 * @return {number} Length of raw node
15125 function checkUriRaw(i) {
15129 while (i < tokensLength) {
15130 if (checkInterpolation(i) || checkVariable(i)) break;else if (l = checkUriRawCharacters(i)) i += l;else break;
15133 tokens[start].uri_raw_end = i;
15142 function getUriRaw() {
15143 var startPos = pos;
15144 var type = NodeType.RawType;
15145 var token = tokens[startPos];
15146 var line = token.ln;
15147 var column = token.col;
15151 while (pos < tokens[startPos].uri_raw_end) {
15152 if (checkInterpolation(pos) || checkVariable(pos)) break;else if (l = checkUriRawCharacters(pos)) pos += l;else break;
15155 content = joinValues(startPos, pos - 1);
15157 return newNode(type, content, line, column);
15161 * Check for a raw (without quotes) URI
15162 * (1) http://foo.com/bar.png
15163 * (2) http://foo.com/#{$bar}.png
15164 * (3) #{$foo}/bar.png
15166 * @param {number} i Token's index number
15167 * @return {number} Length of URI node
15169 function checkUri1(i) {
15173 if (l = checkSC(i)) i += l;
15175 while (i < tokensLength) {
15176 if (l = checkInterpolation(i) || checkUriRaw(i)) i += l;else break;
15179 if (l = checkSC(i)) i += l;
15181 // Check that we are at the end of the uri
15182 if (i < tokens[start - 1].right) return 0;
15184 tokens[start].uri_end = i;
15190 * Get a raw (without quotes) URI
15194 function getUri1() {
15195 var startPos = pos;
15198 if (checkSC(pos)) content = content.concat(getSC());
15200 while (pos < tokens[startPos].uri_end) {
15201 if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkUriRaw(pos)) content.push(getUriRaw());else break;
15204 if (checkSC(pos)) content = content.concat(getSC());
15210 * Check for a non-raw (with quotes) URI
15211 * (1) 'http://foo.com/bar.png'
15212 * (2) 'http://foo.com/'#{$bar}.png
15213 * (3) #{$foo}'/bar.png'
15214 * @param {number} i Token's index number
15215 * @return {number} Length of URI node
15217 function checkUri2(i) {
15221 while (i < tokensLength) {
15222 if (l = checkSC(i)) i += l;else if (l = checkString(i)) i += l;else if (l = checkFunction(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = checkIdentOrInterpolation(i)) i += l;else if (l = checkVariable(i)) i += l;else break;
15225 // Check that we are at the end of the uri
15226 if (i < tokens[start - 1].right) return 0;
15228 tokens[start].uri_end = i;
15234 * Get a non-raw (with quotes) URI node
15237 function getUri2() {
15238 var startPos = pos;
15241 while (pos < tokens[startPos].uri_end) {
15242 if (checkSC(pos)) content = content.concat(getSC());else if (checkUnary(pos)) content.push(getUnary());else if (_checkValue(pos)) content.push(_getValue());else break;
15249 * Check if token is part of a value
15250 * @param {number} i Token's index number
15251 * @return {number} Length of the value
15253 function checkValue(i) {
15259 while (i < tokensLength) {
15260 if (checkDeclDelim(i)) break;
15262 if (l = checkBlock(i)) {
15270 if (l = _checkValue(_i)) i += l + s;
15271 if (!l || checkBlock(i - l)) break;
15280 function getValue() {
15281 var type = NodeType.ValueType;
15282 var token = tokens[pos];
15283 var line = token.ln;
15284 var column = token.col;
15289 while (pos < tokensLength) {
15290 if (checkDeclDelim(pos)) break;
15295 if (checkDeclDelim(_pos)) break;
15297 if (checkBlock(pos)) {
15298 content.push(getBlock());
15302 if (!_checkValue(_pos)) break;
15304 if (s) content.push(getS());
15305 content.push(_getValue());
15307 if (checkBlock(_pos)) break;
15310 return newNode(type, content, line, column);
15314 * @param {number} i Token's index number
15317 function _checkValue(i) {
15320 if (l = checkInterpolation(i)) tokens[i].value_child = 1;else if (l = checkVariable(i)) tokens[i].value_child = 2;else if (l = checkVhash(i)) tokens[i].value_child = 3;else if (l = checkBlock(i)) tokens[i].value_child = 4;else if (l = checkAtkeyword(i)) tokens[i].value_child = 5;else if (l = checkOperator(i)) tokens[i].value_child = 6;else if (l = checkImportant(i)) tokens[i].value_child = 7;else if (l = checkGlobal(i)) tokens[i].value_child = 8;else if (l = checkDefault(i)) tokens[i].value_child = 9;else if (l = checkProgid(i)) tokens[i].value_child = 10;else if (l = checkAny(i)) tokens[i].value_child = 11;else if (l = checkParentSelector(i)) tokens[i].value_child = 12;
15328 function _getValue() {
15329 var childType = tokens[pos].value_child;
15330 if (childType === 1) return getInterpolation();
15331 if (childType === 2) return getVariable();
15332 if (childType === 3) return getVhash();
15333 if (childType === 4) return getBlock();
15334 if (childType === 5) return getAtkeyword();
15335 if (childType === 6) return getOperator();
15336 if (childType === 7) return getImportant();
15337 if (childType === 8) return getGlobal();
15338 if (childType === 9) return getDefault();
15339 if (childType === 10) return getProgid();
15340 if (childType === 11) return getAny();
15341 if (childType === 12) return getParentSelector();
15345 * @param {number} i Token's index number
15346 * @returns {number} Length of the value
15348 function checkSingleValue(i) {
15354 while (i < tokensLength) {
15355 if (checkDeclDelim(i) || checkDelim(i)) break;
15357 if (l = checkBlock(i)) {
15365 if (l = _checkValue(_i)) i += l + s;
15366 if (!l || checkBlock(i - l)) break;
15375 function getSingleValue() {
15376 var type = NodeType.ValueType;
15377 var token = tokens[pos];
15378 var line = token.ln;
15379 var column = token.col;
15384 while (pos < tokensLength) {
15385 if (checkDeclDelim(pos) || checkDelim(pos)) break;
15390 if (checkDeclDelim(_pos) || checkDelim(_pos)) break;
15392 if (checkBlock(pos)) {
15393 content.push(getBlock());
15397 if (!_checkValue(_pos)) break;
15399 if (s) content.push(getS());
15400 content.push(_getValue());
15402 if (checkBlock(_pos)) break;
15405 return newNode(type, content, line, column);
15409 * Check if token is part of a variable
15410 * @param {number} i Token's index number
15411 * @return {number} Length of the variable
15413 function checkVariable(i) {
15417 if (i >= tokensLength) return 0;
15420 if (tokens[i].type === TokenType.DollarSign) i++;else return 0;
15422 if (l = checkIdent(i)) i += l;else return 0;
15428 * Get node with a variable
15429 * @return {Array} `['variable', ['ident', x]]` where `x` is
15432 function getVariable() {
15433 var type = NodeType.VariableType;
15434 var token = tokens[pos];
15435 var line = token.ln;
15436 var column = token.col;
15441 var content = [getIdent()];
15443 return newNode(type, content, line, column);
15447 * Check if token is part of a variables list (e.g. `$values...`).
15448 * @param {number} i Token's index number
15451 function checkVariablesList(i) {
15452 var d = 0; // Number of dots
15455 if (i >= tokensLength) return 0;
15457 if (l = checkVariable(i)) i += l;else return 0;
15459 while (i < tokensLength && tokens[i].type === TokenType.FullStop) {
15464 return d === 3 ? l + d : 0;
15468 * Get node with a variables list
15469 * @return {Array} `['variableslist', ['variable', ['ident', x]]]` where
15470 * `x` is a variable name.
15472 function getVariablesList() {
15473 var type = NodeType.VariablesListType;
15474 var token = tokens[pos];
15475 var line = token.ln;
15476 var column = token.col;
15477 var content = [getVariable()];
15478 var end = getLastPosition(content, line, column, 3);
15483 return newNode(type, content, line, column, end);
15487 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
15489 * @param {number} i Token's index number
15492 function checkVhash(i) {
15496 if (i >= tokensLength) return 0;
15499 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
15501 if (l = checkNmName2(i)) i += l;else return 0;
15507 * Get node with a hexadecimal number (e.g. `#fff`) inside some value
15508 * @return {Array} `['vhash', x]` where `x` is a hexadecimal number
15509 * converted to string (without `#`, e.g. `'fff'`).
15511 function getVhash() {
15512 var type = NodeType.VhashType;
15513 var token = tokens[pos];
15514 var line = token.ln;
15515 var column = token.col;
15520 var content = getNmName2();
15521 var end = getLastPosition(content, line, column + 1);
15522 return newNode(type, content, line, column, end);
15525 function checkSelectorsGroup(i) {
15526 if (i >= tokensLength) return 0;
15531 if (l = checkSelector(i)) i += l;else return 0;
15533 while (i < tokensLength) {
15534 var spaceBefore = checkSC(i);
15535 var comma = checkDelim(i + spaceBefore);
15538 var spaceAfter = checkMultilineSC(i + spaceBefore + comma);
15539 var spaceEnd = spaceAfter ? checkMultilineSC(i + spaceBefore + comma + spaceAfter) : 0;
15541 if (l = checkSelector(i + spaceBefore + comma + spaceAfter + spaceEnd)) i += spaceBefore + comma + spaceAfter + spaceEnd + l;else break;
15544 tokens[start].selectorsGroupEnd = i;
15548 function getSelectorsGroup() {
15549 var selectorsGroup = [];
15550 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
15552 selectorsGroup.push(getSelector());
15554 while (pos < selectorsGroupEnd) {
15555 selectorsGroup = selectorsGroup.concat(getMultilineSC(), getDelim(), getMultilineSC(), getSelector());
15558 return selectorsGroup;
15561 function checkSelector(i) {
15564 if (l = checkSelector1(i)) tokens[i].selectorType = 1;else if (l = checkSelector2(i)) tokens[i].selectorType = 2;
15569 function getSelector() {
15570 var selectorType = tokens[pos].selectorType;
15571 if (selectorType === 1) return getSelector1();else return getSelector2();
15575 * Checks for selector which starts with a compound selector.
15577 function checkSelector1(i) {
15578 if (i >= tokensLength) return 0;
15583 if (l = checkCompoundSelector(i)) i += l;else return 0;
15585 while (i < tokensLength) {
15586 var space = checkSC(i);
15587 var comma = checkCombinator(i + space);
15588 if (!space && !comma) break;
15591 i += space + comma;
15592 space = checkSC(i);
15595 if (l = checkCompoundSelector(i + space)) i += space + l;else break;
15598 tokens[start].selectorEnd = i;
15602 function getSelector1() {
15603 var type = NodeType.SelectorType;
15604 var token = tokens[pos];
15605 var line = token.ln;
15606 var column = token.col;
15607 var selectorEnd = token.selectorEnd;
15608 var content = getCompoundSelector();
15610 while (pos < selectorEnd) {
15611 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
15614 return newNode(type, content, line, column);
15618 * Checks for a selector that starts with a combinator.
15620 function checkSelector2(i) {
15621 if (i >= tokensLength) return 0;
15626 if (l = checkCombinator(i)) i += l;else return 0;
15628 while (i < tokensLength) {
15629 var spaceBefore = checkSC(i);
15630 if (l = checkCompoundSelector(i + spaceBefore)) i += spaceBefore + l;else break;
15632 var spaceAfter = checkSC(i);
15633 var comma = checkCombinator(i + spaceAfter);
15634 if (!spaceAfter && !comma) break;
15636 i += spaceAfter + comma;
15640 tokens[start].selectorEnd = i;
15644 function getSelector2() {
15645 var type = NodeType.SelectorType;
15646 var token = tokens[pos];
15647 var line = token.ln;
15648 var column = token.col;
15649 var selectorEnd = token.selectorEnd;
15650 var content = [getCombinator()];
15652 while (pos < selectorEnd) {
15653 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
15656 return newNode(type, content, line, column);
15659 function checkCompoundSelector(i) {
15662 if (l = checkCompoundSelector1(i)) {
15663 tokens[i].compoundSelectorType = 1;
15664 } else if (l = checkCompoundSelector2(i)) {
15665 tokens[i].compoundSelectorType = 2;
15671 function getCompoundSelector() {
15672 var type = tokens[pos].compoundSelectorType;
15673 if (type === 1) return getCompoundSelector1();
15674 if (type === 2) return getCompoundSelector2();
15678 * Check for compound selectors that start with either a type selector,
15679 * placeholder or parent selector with extension
15681 * (2) `foo[attr=val]`
15682 * (3) `foo:first-of-type`
15684 * @param {number} i Token's index
15685 * @return {number} Compound selector's length
15687 function checkCompoundSelector1(i) {
15688 if (i >= tokensLength) return 0;
15693 if (l = checkUniversalSelector(i) || checkTypeSelector(i) || checkPlaceholder(i) || checkParentSelectorWithExtension(i)) i += l;else return 0;
15695 while (i < tokensLength) {
15696 var _l2 = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i) || checkInterpolation(i);
15698 if (_l2) i += _l2;else break;
15701 tokens[start].compoundSelectorEnd = i;
15707 * @return {Array} An array of nodes that make up the compound selector
15709 function getCompoundSelector1() {
15711 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
15713 if (checkUniversalSelector(pos)) sequence.push(getUniversalSelector());else if (checkTypeSelector(pos)) sequence.push(getTypeSelector());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkParentSelectorWithExtension(pos)) sequence = sequence.concat(getParentSelectorWithExtension());
15715 while (pos < compoundSelectorEnd) {
15716 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkInterpolation(pos)) sequence.push(getInterpolation());else break;
15723 * Check for all other compound selectors
15725 * (2) `.foo[attr=val]`
15726 * (3) `.foo:first-of-type`
15728 * (5) `.foo#{$bar}`
15729 * @param {number} i Token's index
15730 * @return {number} Compound selector's length
15732 function checkCompoundSelector2(i) {
15733 if (i >= tokensLength) return 0;
15737 while (i < tokensLength) {
15738 var l = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i) || checkInterpolation(i);
15740 if (l) i += l;else break;
15743 tokens[start].compoundSelectorEnd = i;
15749 * @return {Array} An array of nodes that make up the compound selector
15751 function getCompoundSelector2() {
15753 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
15755 while (pos < compoundSelectorEnd) {
15756 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkInterpolation(pos)) sequence.push(getInterpolation());else break;
15762 function checkUniversalSelector(i) {
15763 if (i >= tokensLength) return 0;
15768 if (l = checkNamePrefix(i)) i += l;
15770 if (tokens[i].type === TokenType.Asterisk) i++;else return 0;
15775 function getUniversalSelector() {
15776 var type = NodeType.UniversalSelectorType;
15777 var token = tokens[pos];
15778 var line = token.ln;
15779 var column = token.col;
15783 if (checkNamePrefix(pos)) {
15784 content.push(getNamePrefix());
15785 end = getLastPosition(content, line, column, 1);
15790 return newNode(type, content, line, column, end);
15794 * Check if token is part of a type selector
15795 * @param {number} i Token's index
15796 * @return {number} Type selector's length
15798 function checkTypeSelector(i) {
15799 if (i >= tokensLength) return 0;
15804 if (l = checkNamePrefix(i)) i += l;
15806 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
15812 * Get type selector node
15815 function getTypeSelector() {
15816 var type = NodeType.TypeSelectorType;
15817 var token = tokens[pos];
15818 var line = token.ln;
15819 var column = token.col;
15822 if (checkNamePrefix(pos)) content.push(getNamePrefix());
15824 content = content.concat(getIdentOrInterpolation());
15826 return newNode(type, content, line, column);
15829 function checkAttributeSelector(i) {
15831 if (l = checkAttributeSelector1(i)) tokens[i].attributeSelectorType = 1;else if (l = checkAttributeSelector2(i)) tokens[i].attributeSelectorType = 2;
15836 function getAttributeSelector() {
15837 var type = tokens[pos].attributeSelectorType;
15838 if (type === 1) return getAttributeSelector1();else return getAttributeSelector2();
15842 * (1) `[panda=nani]`
15843 * (2) `[panda='nani']`
15844 * (3) `[panda='nani' i]`
15847 function checkAttributeSelector1(i) {
15850 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
15853 if (l = checkSC(i)) i += l;
15855 if (l = checkAttributeName(i)) i += l;else return 0;
15857 if (l = checkSC(i)) i += l;
15859 if (l = checkAttributeMatch(i)) i += l;else return 0;
15861 if (l = checkSC(i)) i += l;
15863 if (l = checkAttributeValue(i)) i += l;else return 0;
15865 if (l = checkSC(i)) i += l;
15867 if (l = checkAttributeFlags(i)) {
15869 if (l = checkSC(i)) i += l;
15872 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
15877 function getAttributeSelector1() {
15878 var type = NodeType.AttributeSelectorType;
15879 var token = tokens[pos];
15880 var line = token.ln;
15881 var column = token.col;
15887 content = content.concat(getSC(), getAttributeName(), getSC(), getAttributeMatch(), getSC(), getAttributeValue(), getSC());
15889 if (checkAttributeFlags(pos)) {
15890 content.push(getAttributeFlags());
15891 content = content.concat(getSC());
15897 var end = getLastPosition(content, line, column, 1);
15898 return newNode(type, content, line, column, end);
15904 function checkAttributeSelector2(i) {
15907 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
15910 if (l = checkSC(i)) i += l;
15912 if (l = checkAttributeName(i)) i += l;else return 0;
15914 if (l = checkSC(i)) i += l;
15916 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
15921 function getAttributeSelector2() {
15922 var type = NodeType.AttributeSelectorType;
15923 var token = tokens[pos];
15924 var line = token.ln;
15925 var column = token.col;
15931 content = content.concat(getSC(), getAttributeName(), getSC());
15936 var end = getLastPosition(content, line, column, 1);
15937 return newNode(type, content, line, column, end);
15940 function checkAttributeName(i) {
15944 if (l = checkNamePrefix(i)) i += l;
15946 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
15951 function getAttributeName() {
15952 var type = NodeType.AttributeNameType;
15953 var token = tokens[pos];
15954 var line = token.ln;
15955 var column = token.col;
15958 if (checkNamePrefix(pos)) content.push(getNamePrefix());
15959 content = content.concat(getIdentOrInterpolation());
15961 return newNode(type, content, line, column);
15964 function checkAttributeMatch(i) {
15966 if (l = checkAttributeMatch1(i)) tokens[i].attributeMatchType = 1;else if (l = checkAttributeMatch2(i)) tokens[i].attributeMatchType = 2;
15971 function getAttributeMatch() {
15972 var type = tokens[pos].attributeMatchType;
15973 if (type === 1) return getAttributeMatch1();else return getAttributeMatch2();
15976 function checkAttributeMatch1(i) {
15979 var type = tokens[i].type;
15980 if (type === TokenType.Tilde || type === TokenType.VerticalLine || type === TokenType.CircumflexAccent || type === TokenType.DollarSign || type === TokenType.Asterisk) i++;else return 0;
15982 if (tokens[i].type === TokenType.EqualsSign) i++;else return 0;
15987 function getAttributeMatch1() {
15988 var type = NodeType.AttributeMatchType;
15989 var token = tokens[pos];
15990 var line = token.ln;
15991 var column = token.col;
15992 var content = tokens[pos].value + tokens[pos + 1].value;
15995 return newNode(type, content, line, column);
15998 function checkAttributeMatch2(i) {
15999 if (tokens[i].type === TokenType.EqualsSign) return 1;else return 0;
16002 function getAttributeMatch2() {
16003 var type = NodeType.AttributeMatchType;
16004 var token = tokens[pos];
16005 var line = token.ln;
16006 var column = token.col;
16010 return newNode(type, content, line, column);
16013 function checkAttributeValue(i) {
16014 return checkString(i) || checkIdentOrInterpolation(i);
16017 function getAttributeValue() {
16018 var type = NodeType.AttributeValueType;
16019 var token = tokens[pos];
16020 var line = token.ln;
16021 var column = token.col;
16024 if (checkString(pos)) content.push(getString());else content = content.concat(getIdentOrInterpolation());
16026 return newNode(type, content, line, column);
16029 function checkAttributeFlags(i) {
16030 return checkIdentOrInterpolation(i);
16033 function getAttributeFlags() {
16034 var type = NodeType.AttributeFlagsType;
16035 var token = tokens[pos];
16036 var line = token.ln;
16037 var column = token.col;
16038 var content = getIdentOrInterpolation();
16040 return newNode(type, content, line, column);
16043 function checkNamePrefix(i) {
16044 if (i >= tokensLength) return 0;
16047 if (l = checkNamePrefix1(i)) tokens[i].namePrefixType = 1;else if (l = checkNamePrefix2(i)) tokens[i].namePrefixType = 2;
16052 function getNamePrefix() {
16053 var type = tokens[pos].namePrefixType;
16054 if (type === 1) return getNamePrefix1();else return getNamePrefix2();
16059 * (2) `panda<comment>|`
16061 function checkNamePrefix1(i) {
16065 if (l = checkNamespacePrefix(i)) i += l;else return 0;
16067 if (l = checkCommentML(i)) i += l;
16069 if (l = checkNamespaceSeparator(i)) i += l;else return 0;
16074 function getNamePrefix1() {
16075 var type = NodeType.NamePrefixType;
16076 var token = tokens[pos];
16077 var line = token.ln;
16078 var column = token.col;
16081 content.push(getNamespacePrefix());
16083 if (checkCommentML(pos)) content.push(getCommentML());
16085 content.push(getNamespaceSeparator());
16087 return newNode(type, content, line, column);
16093 function checkNamePrefix2(i) {
16094 return checkNamespaceSeparator(i);
16097 function getNamePrefix2() {
16098 var type = NodeType.NamePrefixType;
16099 var token = tokens[pos];
16100 var line = token.ln;
16101 var column = token.col;
16102 var content = [getNamespaceSeparator()];
16104 return newNode(type, content, line, column);
16111 function checkNamespacePrefix(i) {
16112 if (i >= tokensLength) return 0;
16116 if (tokens[i].type === TokenType.Asterisk) return 1;else if (l = checkIdentOrInterpolation(i)) return l;else return 0;
16119 function getNamespacePrefix() {
16120 var type = NodeType.NamespacePrefixType;
16121 var token = tokens[pos];
16122 var line = token.ln;
16123 var column = token.col;
16126 if (token.type === TokenType.Asterisk) {
16127 var asteriskNode = newNode(NodeType.IdentType, '*', line, column);
16128 content.push(asteriskNode);
16130 } else if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());
16132 return newNode(type, content, line, column);
16138 function checkNamespaceSeparator(i) {
16139 if (i >= tokensLength) return 0;
16141 if (tokens[i].type !== TokenType.VerticalLine) return 0;
16143 // Return false if `|=` - [attr|=value]
16144 if (tokens[i + 1] && tokens[i + 1].type === TokenType.EqualsSign) return 0;
16149 function getNamespaceSeparator() {
16150 var type = NodeType.NamespaceSeparatorType;
16151 var token = tokens[pos];
16152 var line = token.ln;
16153 var column = token.col;
16157 return newNode(type, content, line, column);
16160 module.exports = function (_tokens, context) {
16162 tokensLength = tokens.length;
16165 return contexts[context]();
16170 /***/ (function(module, exports, __webpack_require__) {
16174 module.exports = function (css, tabSize) {
16175 var TokenType = __webpack_require__(13);
16178 var urlMode = false;
16179 var c = void 0; // Current character
16180 var cn = void 0; // Next character
16186 var Punctuation = {
16187 ' ': TokenType.Space,
16188 '\n': TokenType.Newline,
16189 '\r': TokenType.Newline,
16190 '\t': TokenType.Tab,
16191 '!': TokenType.ExclamationMark,
16192 '"': TokenType.QuotationMark,
16193 '#': TokenType.NumberSign,
16194 '$': TokenType.DollarSign,
16195 '%': TokenType.PercentSign,
16196 '&': TokenType.Ampersand,
16197 '\'': TokenType.Apostrophe,
16198 '(': TokenType.LeftParenthesis,
16199 ')': TokenType.RightParenthesis,
16200 '*': TokenType.Asterisk,
16201 '+': TokenType.PlusSign,
16202 ',': TokenType.Comma,
16203 '-': TokenType.HyphenMinus,
16204 '.': TokenType.FullStop,
16205 '/': TokenType.Solidus,
16206 ':': TokenType.Colon,
16207 ';': TokenType.Semicolon,
16208 '<': TokenType.LessThanSign,
16209 '=': TokenType.EqualsSign,
16210 '==': TokenType.EqualitySign,
16211 '!=': TokenType.InequalitySign,
16212 '>': TokenType.GreaterThanSign,
16213 '?': TokenType.QuestionMark,
16214 '@': TokenType.CommercialAt,
16215 '[': TokenType.LeftSquareBracket,
16216 ']': TokenType.RightSquareBracket,
16217 '^': TokenType.CircumflexAccent,
16218 '_': TokenType.LowLine,
16219 '{': TokenType.LeftCurlyBracket,
16220 '|': TokenType.VerticalLine,
16221 '}': TokenType.RightCurlyBracket,
16222 '~': TokenType.Tilde,
16223 '`': TokenType.Backtick
16227 * Add a token to the token list
16228 * @param {string} type
16229 * @param {string} value
16231 function pushToken(type, value, column) {
16242 * Check if a character is a decimal digit
16243 * @param {string} c Character
16244 * @returns {boolean}
16246 function isDecimalDigit(c) {
16247 return '0123456789'.indexOf(c) >= 0;
16252 * @param {string} css Unparsed part of CSS string
16254 function parseSpaces(css) {
16257 // Read the string until we meet a non-space character:
16258 for (; pos < css.length; pos++) {
16259 if (css.charAt(pos) !== ' ') break;
16262 // Add a substring containing only spaces to tokens:
16263 pushToken(TokenType.Space, css.substring(start, pos--), col);
16264 col += pos - start;
16268 * Parse a string within quotes
16269 * @param {string} css Unparsed part of CSS string
16270 * @param {string} q Quote (either `'` or `"`)
16272 function parseString(css, q) {
16275 // Read the string until we meet a matching quote:
16276 for (pos++; pos < css.length; pos++) {
16277 // Skip escaped quotes:
16278 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) === q) break;
16281 // Add the string (including quotes) to tokens:
16282 var type = q === '"' ? TokenType.StringDQ : TokenType.StringSQ;
16283 pushToken(type, css.substring(start, pos + 1), col);
16284 col += pos - start;
16289 * @param {string} css Unparsed part of CSS string
16291 function parseDecimalNumber(css) {
16294 // Read the string until we meet a character that's not a digit:
16295 for (; pos < css.length; pos++) {
16296 if (!isDecimalDigit(css.charAt(pos))) break;
16299 // Add the number to tokens:
16300 pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);
16301 col += pos - start;
16306 * @param {string} css Unparsed part of CSS string
16308 function parseIdentifier(css) {
16311 // Skip all opening slashes:
16312 while (css.charAt(pos) === '/') {
16314 } // Read the string until we meet a punctuation mark:
16315 for (; pos < css.length; pos++) {
16317 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) in Punctuation) break;
16320 var ident = css.substring(start, pos--);
16322 // Enter url mode if parsed substring is `url`:
16323 if (!urlMode && ident === 'url' && css.charAt(pos + 1) === '(') {
16327 // Add identifier to tokens:
16328 pushToken(TokenType.Identifier, ident, col);
16329 col += pos - start;
16333 * Parse equality sign
16335 function parseEquality() {
16336 pushToken(TokenType.EqualitySign, '==', col);
16342 * Parse inequality sign
16344 function parseInequality() {
16345 pushToken(TokenType.InequalitySign, '!=', col);
16351 * Parse a multiline comment
16352 * @param {string} css Unparsed part of CSS string
16354 function parseMLComment(css) {
16358 // Get current indent level:
16360 for (var _pos = pos - 1; _pos > -1; _pos--) {
16361 // TODO: Can be tabs:
16362 if (css.charAt(_pos) === ' ') il++;else break;
16365 for (pos += 2; pos < css.length; pos++) {
16366 var ch = css.charAt(pos);
16368 var _pos2 = void 0;
16369 // Get new line's indent level:
16371 for (_pos2 = pos + 1; _pos2 < css.length; _pos2++) {
16372 if (css.charAt(_pos2) === ' ') _il++;else break;
16377 pos += _pos2 - pos;
16382 } else if (ch === '*' && css.charAt(pos + 1) === '/') {
16388 // If CRLF is used, we need to adjust pos
16389 if (css.charAt(pos) === '\r') pos--;
16391 // Add full comment (including `/*`) to the list of tokens:
16392 var comment = css.substring(start, pos + 1);
16393 pushToken(TokenType.CommentML, comment, col_);
16395 var newlines = comment.split('\n');
16396 if (newlines.length > 1) {
16397 ln += newlines.length - 1;
16398 col = newlines[newlines.length - 1].length;
16400 col += pos - start;
16405 * Parse a single line comment
16406 * @param {string} css Unparsed part of CSS string
16408 function parseSLComment(css) {
16413 // Check if comment is the only token on the line, and if so,
16414 // get current indent level:
16416 var onlyToken = false;
16417 for (_pos = pos - 1; _pos > -1; _pos--) {
16418 // TODO: Can be tabs:
16419 if (css.charAt(_pos) === ' ') il++;else if (css.charAt(_pos) === '\n') {
16424 if (_pos === -1) onlyToken = true;
16426 // Read the string until we meet comment end.
16427 // Since we already know first 2 characters (`//`), start reading
16430 for (pos += 2; pos < css.length; pos++) {
16431 if (css.charAt(pos) === '\n' || css.charAt(pos) === '\r') {
16436 for (pos += 2; pos < css.length; pos++) {
16437 var ch = css.charAt(pos);
16439 // Get new line's indent level:
16441 for (_pos = pos + 1; _pos < css.length; _pos++) {
16442 if (css.charAt(_pos) === ' ') _il++;else break;
16455 // If CRLF is used, we need to adjust pos
16456 if (css.charAt(pos - 1) === '\r') pos--;
16458 // Add comment (including `//` and line break) to the list of tokens:
16459 var comment = css.substring(start, pos--);
16460 pushToken(TokenType.CommentSL, comment, col_);
16462 var newlines = comment.split('\n');
16463 if (newlines.length > 1) {
16464 ln += newlines.length - 1;
16465 col = newlines[newlines.length - 1].length;
16467 col += pos - start;
16472 * Convert a CSS string to a list of tokens
16473 * @param {string} css CSS string
16474 * @returns {Array} List of tokens
16477 function getTokens(css) {
16478 // Parse string, character by character:
16479 for (pos = 0; pos < css.length; col++, pos++) {
16480 c = css.charAt(pos);
16481 cn = css.charAt(pos + 1);
16483 // If we meet `/*`, it's a start of a multiline comment.
16484 // Parse following characters as a multiline comment:
16485 if (c === '/' && cn === '*') {
16486 parseMLComment(css);
16489 // If we meet `//` and it is not a part of url:
16490 else if (!urlMode && c === '/' && cn === '/') {
16491 // If we're currently inside a block, treat `//` as a start
16492 // of identifier. Else treat `//` as a start of a single-line
16494 parseSLComment(css);
16497 // If current character is a double or single quote, it's a start
16499 else if (c === '"' || c === "'") {
16500 parseString(css, c);
16503 // If current character is a space:
16504 else if (c === ' ') {
16508 // If current character is `=`, it must be combined with next `=`
16509 else if (c === '=' && cn === '=') {
16510 parseEquality(css);
16513 // If we meet `!=`, this must be inequality
16514 else if (c === '!' && cn === '=') {
16515 parseInequality(css);
16518 // If current character is a punctuation mark:
16519 else if (c in Punctuation) {
16520 // Check for CRLF here or just LF
16521 if (c === '\r' && cn === '\n' || c === '\n') {
16522 // If \r we know the next character is \n due to statement above
16523 // so we push a CRLF token type to the token list and importantly
16524 // skip the next character so as not to double count newlines or
16527 pushToken(TokenType.Newline, '\r\n', col);
16528 pos++; // If CRLF skip the next character and push crlf token
16529 } else if (c === '\n') {
16530 // If just a LF newline and not part of CRLF newline we can just
16531 // push punctuation as usual
16532 pushToken(Punctuation[c], c, col);
16535 ln++; // Go to next line
16536 col = 0; // Reset the column count
16537 } else if (c !== '\r' && c !== '\n') {
16538 // Handle all other punctuation and add to list of tokens
16539 pushToken(Punctuation[c], c, col);
16540 } // Go to next line
16541 if (c === ')') urlMode = false; // Exit url mode
16542 else if (c === '\t' && tabSize > 1) col += tabSize - 1;
16545 // If current character is a decimal digit:
16546 else if (isDecimalDigit(c)) {
16547 parseDecimalNumber(css);
16550 // If current character is anything else:
16552 parseIdentifier(css);
16559 return getTokens(css);
16564 /***/ (function(module, exports, __webpack_require__) {
16568 exports.__esModule = true;
16569 exports.default = {
16570 mark: __webpack_require__(26),
16571 parse: __webpack_require__(27),
16572 stringify: __webpack_require__(6),
16573 tokenizer: __webpack_require__(28)
16575 module.exports = exports['default'];
16579 /***/ (function(module, exports, __webpack_require__) {
16583 var TokenType = __webpack_require__(13);
16585 module.exports = function () {
16587 * Mark whitespaces and comments
16589 function markSC(tokens) {
16590 var tokensLength = tokens.length;
16591 var ws = -1; // Flag for whitespaces
16592 var sc = -1; // Flag for whitespaces and comments
16593 var t = void 0; // Current token
16595 // For every token in the token list, mark spaces and line breaks
16596 // as spaces (set both `ws` and `sc` flags). Mark multiline comments
16598 // If there are several spaces or tabs or line breaks or multiline
16599 // comments in a row, group them: take the last one's index number
16600 // and save it to the first token in the group as a reference:
16601 // e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
16602 // for a group of whitespaces and comments.
16603 for (var i = 0; i < tokensLength; i++) {
16606 case TokenType.Space:
16607 case TokenType.Tab:
16608 case TokenType.Newline:
16612 if (ws === -1) ws = i;
16613 if (sc === -1) sc = i;
16616 case TokenType.CommentML:
16617 case TokenType.CommentSL:
16619 tokens[ws].ws_last = i - 1;
16628 tokens[ws].ws_last = i - 1;
16633 tokens[sc].sc_last = i - 1;
16639 if (ws !== -1) tokens[ws].ws_last = i - 1;
16640 if (sc !== -1) tokens[sc].sc_last = i - 1;
16646 function markBrackets(tokens) {
16647 var tokensLength = tokens.length;
16648 var ps = []; // Parentheses
16649 var sbs = []; // Square brackets
16650 var cbs = []; // Curly brackets
16651 var t = void 0; // Current token
16653 // For every token in the token list, if we meet an opening (left)
16654 // bracket, push its index number to a corresponding array.
16655 // If we then meet a closing (right) bracket, look at the corresponding
16656 // array. If there are any elements (records about previously met
16657 // left brackets), take a token of the last left bracket (take
16658 // the last index number from the array and find a token with
16659 // this index number) and save right bracket's index as a reference:
16660 for (var i = 0; i < tokensLength; i++) {
16663 case TokenType.LeftParenthesis:
16666 case TokenType.RightParenthesis:
16669 tokens[t.left].right = i;
16672 case TokenType.LeftSquareBracket:
16675 case TokenType.RightSquareBracket:
16677 t.left = sbs.pop();
16678 tokens[t.left].right = i;
16681 case TokenType.LeftCurlyBracket:
16684 case TokenType.RightCurlyBracket:
16686 t.left = cbs.pop();
16687 tokens[t.left].right = i;
16694 return function (tokens) {
16695 markBrackets(tokens);
16702 /***/ (function(module, exports, __webpack_require__) {
16706 var Node = __webpack_require__(1);
16707 var NodeType = __webpack_require__(15);
16708 var TokenType = __webpack_require__(13);
16710 var tokens = void 0;
16711 var tokensLength = void 0;
16715 'arguments': function _arguments() {
16716 return checkArguments(pos) && getArguments();
16718 'atkeyword': function atkeyword() {
16719 return checkAtkeyword(pos) && getAtkeyword();
16721 'atrule': function atrule() {
16722 return checkAtrule(pos) && getAtrule();
16724 'attributeSelector': function attributeSelector() {
16725 return checkAttributeSelector(pos) && getAttributeSelector();
16727 'block': function block() {
16728 return checkBlock(pos) && getBlock();
16730 'brackets': function brackets() {
16731 return checkBrackets(pos) && getBrackets();
16733 'class': function _class() {
16734 return checkClass(pos) && getClass();
16736 'combinator': function combinator() {
16737 return checkCombinator(pos) && getCombinator();
16739 'commentML': function commentML() {
16740 return checkCommentML(pos) && getCommentML();
16742 'commentSL': function commentSL() {
16743 return checkCommentSL(pos) && getCommentSL();
16745 'condition': function condition() {
16746 return checkCondition(pos) && getCondition();
16748 'conditionalStatement': function conditionalStatement() {
16749 return checkConditionalStatement(pos) && getConditionalStatement();
16751 'declaration': function declaration() {
16752 return checkDeclaration(pos) && getDeclaration();
16754 'declDelim': function declDelim() {
16755 return checkDeclDelim(pos) && getDeclDelim();
16757 'default': function _default() {
16758 return checkDefault(pos) && getDefault();
16760 'delim': function delim() {
16761 return checkDelim(pos) && getDelim();
16763 'dimension': function dimension() {
16764 return checkDimension(pos) && getDimension();
16766 'expression': function expression() {
16767 return checkExpression(pos) && getExpression();
16769 'extend': function extend() {
16770 return checkExtend(pos) && getExtend();
16772 'function': function _function() {
16773 return checkFunction(pos) && getFunction();
16775 'global': function global() {
16776 return checkGlobal(pos) && getGlobal();
16778 'ident': function ident() {
16779 return checkIdent(pos) && getIdent();
16781 'important': function important() {
16782 return checkImportant(pos) && getImportant();
16784 'include': function include() {
16785 return checkInclude(pos) && getInclude();
16787 'interpolation': function interpolation() {
16788 return checkInterpolation(pos) && getInterpolation();
16790 'loop': function loop() {
16791 return checkLoop(pos) && getLoop();
16793 'mixin': function mixin() {
16794 return checkMixin(pos) && getMixin();
16796 'namespace': function namespace() {
16797 return checkNamespace(pos) && getNamespace();
16799 'number': function number() {
16800 return checkNumber(pos) && getNumber();
16802 'operator': function operator() {
16803 return checkOperator(pos) && getOperator();
16805 'optional': function optional() {
16806 return checkOptional(pos) && getOptional();
16808 'parentheses': function parentheses() {
16809 return checkParentheses(pos) && getParentheses();
16811 'parentselector': function parentselector() {
16812 return checkParentSelector(pos) && getParentSelector();
16814 'percentage': function percentage() {
16815 return checkPercentage(pos) && getPercentage();
16817 'placeholder': function placeholder() {
16818 return checkPlaceholder(pos) && getPlaceholder();
16820 'progid': function progid() {
16821 return checkProgid(pos) && getProgid();
16823 'property': function property() {
16824 return checkProperty(pos) && getProperty();
16826 'propertyDelim': function propertyDelim() {
16827 return checkPropertyDelim(pos) && getPropertyDelim();
16829 'pseudoc': function pseudoc() {
16830 return checkPseudoc(pos) && getPseudoc();
16832 'pseudoe': function pseudoe() {
16833 return checkPseudoe(pos) && getPseudoe();
16835 'ruleset': function ruleset() {
16836 return checkRuleset(pos) && getRuleset();
16838 's': function s() {
16839 return checkS(pos) && getS();
16841 'selector': function selector() {
16842 return checkSelector(pos) && getSelector();
16844 'shash': function shash() {
16845 return checkShash(pos) && getShash();
16847 'string': function string() {
16848 return checkString(pos) && getString();
16850 'stylesheet': function stylesheet() {
16851 return checkStylesheet(pos) && getStylesheet();
16853 'typeSelector': function typeSelector() {
16854 return checkTypeSelector(pos) && getTypeSelector();
16856 'unary': function unary() {
16857 return checkUnary(pos) && getUnary();
16859 'unicodeRange': function unicodeRange() {
16860 return checkUnicodeRange(pos) && getUnicodeRange();
16862 'universalSelector': function universalSelector() {
16863 return checkUniversalSelector(pos) && getUniversalSelector();
16865 'urange': function urange() {
16866 return checkUrange(pos) && getUrange();
16868 'uri': function uri() {
16869 return checkUri(pos) && getUri();
16871 'value': function value() {
16872 return checkValue(pos) && getValue();
16874 'variable': function variable() {
16875 return checkVariable(pos) && getVariable();
16877 'variableslist': function variableslist() {
16878 return checkVariablesList(pos) && getVariablesList();
16880 'vhash': function vhash() {
16881 return checkVhash(pos) && getVhash();
16886 * Stop parsing and display error
16887 * @param {Number=} i Token's index number
16889 function throwError(i) {
16890 var ln = tokens[i].ln;
16892 throw { line: ln, syntax: 'scss' };
16896 * @param {Number} start
16897 * @param {Number} finish
16898 * @returns {String}
16900 function joinValues(start, finish) {
16903 for (var i = start; i < finish + 1; i++) {
16904 s += tokens[i].value;
16911 * @param {Number} start
16912 * @param {Number} num
16913 * @returns {String}
16915 function joinValues2(start, num) {
16916 if (start + num - 1 >= tokensLength) return;
16920 for (var i = 0; i < num; i++) {
16921 s += tokens[start + i].value;
16927 function getLastPosition(content, line, column, colOffset) {
16928 return typeof content === 'string' ? getLastPositionForString(content, line, column, colOffset) : getLastPositionForArray(content, line, column, colOffset);
16931 function getLastPositionForString(content, line, column, colOffset) {
16935 position = [line, column];
16936 if (colOffset) position[1] += colOffset - 1;
16940 var lastLinebreak = content.lastIndexOf('\n');
16941 var endsWithLinebreak = lastLinebreak === content.length - 1;
16942 var splitContent = content.split('\n');
16943 var linebreaksCount = splitContent.length - 1;
16944 var prevLinebreak = linebreaksCount === 0 || linebreaksCount === 1 ? -1 : content.length - splitContent[linebreaksCount - 1].length - 2;
16947 var offset = endsWithLinebreak ? linebreaksCount - 1 : linebreaksCount;
16948 position[0] = line + offset;
16951 if (endsWithLinebreak) {
16952 offset = prevLinebreak !== -1 ? content.length - prevLinebreak : content.length - 1;
16954 offset = linebreaksCount !== 0 ? content.length - lastLinebreak - column - 1 : content.length - 1;
16956 position[1] = column + offset;
16958 if (!colOffset) return position;
16960 if (endsWithLinebreak) {
16962 position[1] = colOffset;
16964 position[1] += colOffset;
16970 function getLastPositionForArray(content, line, column, colOffset) {
16971 var position = void 0;
16973 if (content.length === 0) {
16974 position = [line, column];
16976 var c = content[content.length - 1];
16977 if (c.hasOwnProperty('end')) {
16978 position = [c.end.line, c.end.column];
16980 position = getLastPosition(c.content, line, column);
16984 if (!colOffset) return position;
16986 if (tokens[pos - 1] && tokens[pos - 1].type !== 'Newline') {
16987 position[1] += colOffset;
16996 function newNode(type, content, line, column, end) {
16997 if (!end) end = getLastPosition(content, line, column);
17014 * @param {Number} i Token's index number
17015 * @returns {Number}
17017 function checkAny(i) {
17020 if (l = checkBrackets(i)) tokens[i].any_child = 1;else if (l = checkParentheses(i)) tokens[i].any_child = 2;else if (l = checkString(i)) tokens[i].any_child = 3;else if (l = checkVariablesList(i)) tokens[i].any_child = 4;else if (l = checkVariable(i)) tokens[i].any_child = 5;else if (l = checkPlaceholder(i)) tokens[i].any_child = 6;else if (l = checkPercentage(i)) tokens[i].any_child = 7;else if (l = checkDimension(i)) tokens[i].any_child = 8;else if (l = checkUnicodeRange(i)) tokens[i].any_child = 9;else if (l = checkNumber(i)) tokens[i].any_child = 10;else if (l = checkUri(i)) tokens[i].any_child = 11;else if (l = checkExpression(i)) tokens[i].any_child = 12;else if (l = checkFunctionsList(i)) tokens[i].any_child = 13;else if (l = checkFunction(i)) tokens[i].any_child = 14;else if (l = checkInterpolation(i)) tokens[i].any_child = 15;else if (l = checkIdent(i)) tokens[i].any_child = 16;else if (l = checkClass(i)) tokens[i].any_child = 17;else if (l = checkUnary(i)) tokens[i].any_child = 18;else if (l = checkParentSelector(i)) tokens[i].any_child = 19;else if (l = checkImportant(i)) tokens[i].any_child = 20;else if (l = checkGlobal(i)) tokens[i].any_child = 21;else if (l = checkDefault(i)) tokens[i].any_child = 22;else if (l = checkOptional(i)) tokens[i].any_child = 23;
17028 function getAny() {
17029 var childType = tokens[pos].any_child;
17031 if (childType === 1) return getBrackets();
17032 if (childType === 2) return getParentheses();
17033 if (childType === 3) return getString();
17034 if (childType === 4) return getVariablesList();
17035 if (childType === 5) return getVariable();
17036 if (childType === 6) return getPlaceholder();
17037 if (childType === 7) return getPercentage();
17038 if (childType === 8) return getDimension();
17039 if (childType === 9) return getUnicodeRange();
17040 if (childType === 10) return getNumber();
17041 if (childType === 11) return getUri();
17042 if (childType === 12) return getExpression();
17043 if (childType === 13) return getFunctionsList();
17044 if (childType === 14) return getFunction();
17045 if (childType === 15) return getInterpolation();
17046 if (childType === 16) return getIdent();
17047 if (childType === 17) return getClass();
17048 if (childType === 18) return getUnary();
17049 if (childType === 19) return getParentSelector();
17050 if (childType === 20) return getImportant();
17051 if (childType === 21) return getGlobal();
17052 if (childType === 22) return getDefault();
17053 if (childType === 23) return getOptional();
17057 * Check if token is part of mixin's arguments.
17058 * @param {Number} i Token's index number
17059 * @returns {Number} Length of arguments
17061 function checkArguments(i) {
17065 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
17070 while (i < tokens[start].right) {
17071 if (l = checkArgument(i)) i += l;else return 0;
17074 return tokens[start].right - start + 1;
17080 function getArguments() {
17081 var type = NodeType.ArgumentsType;
17082 var token = tokens[pos];
17083 var line = token.ln;
17084 var column = token.col;
17091 while (pos < tokensLength && tokens[pos].type !== TokenType.RightParenthesis) {
17092 if (checkSingleValueDeclaration(pos)) {
17093 content.push(getSingleValueDeclaration());
17094 } else if (checkArgument(pos)) {
17095 body = getArgument();
17096 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
17097 } else if (checkClass(pos)) content.push(getClass());else throwError(pos);
17100 var end = getLastPosition(content, line, column, 1);
17105 return newNode(type, content, line, column, end);
17109 * Check if token is valid to be part of arguments list
17110 * @param {Number} i Token's index number
17111 * @returns {Number} Length of argument
17113 function checkArgument(i) {
17116 if (l = checkBrackets(i)) tokens[i].argument_child = 1;else if (l = checkParentheses(i)) tokens[i].argument_child = 2;else if (l = checkSingleValueDeclaration(i)) tokens[i].argument_child = 3;else if (l = checkFunctionsList(i)) tokens[i].argument_child = 4;else if (l = checkFunction(i)) tokens[i].argument_child = 5;else if (l = checkVariablesList(i)) tokens[i].argument_child = 6;else if (l = checkVariable(i)) tokens[i].argument_child = 7;else if (l = checkSC(i)) tokens[i].argument_child = 8;else if (l = checkDelim(i)) tokens[i].argument_child = 9;else if (l = checkDeclDelim(i)) tokens[i].argument_child = 10;else if (l = checkString(i)) tokens[i].argument_child = 11;else if (l = checkPercentage(i)) tokens[i].argument_child = 12;else if (l = checkDimension(i)) tokens[i].argument_child = 13;else if (l = checkNumber(i)) tokens[i].argument_child = 14;else if (l = checkUri(i)) tokens[i].argument_child = 15;else if (l = checkInterpolation(i)) tokens[i].argument_child = 16;else if (l = checkIdent(i)) tokens[i].argument_child = 17;else if (l = checkVhash(i)) tokens[i].argument_child = 18;else if (l = checkCustomProperty(i)) tokens[i].argument_child = 19;else if (l = checkOperator(i)) tokens[i].argument_child = 20;else if (l = checkUnary(i)) tokens[i].argument_child = 21;else if (l = checkParentSelector(i)) tokens[i].argument_child = 22;else if (l = checkImportant(i)) tokens[i].argument_child = 23;else if (l = checkGlobal(i)) tokens[i].argument_child = 24;else if (l = checkDefault(i)) tokens[i].argument_child = 25;else if (l = checkOptional(i)) tokens[i].argument_child = 26;
17122 * @returns {Array} Node that is part of arguments list
17124 function getArgument() {
17125 var childType = tokens[pos].argument_child;
17127 if (childType === 1) return getBrackets();
17128 if (childType === 2) return getParentheses();
17129 if (childType === 3) return getSingleValueDeclaration();
17130 if (childType === 4) return getFunctionsList();
17131 if (childType === 5) return getFunction();
17132 if (childType === 6) return getVariablesList();
17133 if (childType === 7) return getVariable();
17134 if (childType === 8) return getSC();
17135 if (childType === 9) return getDelim();
17136 if (childType === 10) return getDeclDelim();
17137 if (childType === 11) return getString();
17138 if (childType === 12) return getPercentage();
17139 if (childType === 13) return getDimension();
17140 if (childType === 14) return getNumber();
17141 if (childType === 15) return getUri();
17142 if (childType === 16) return getInterpolation();
17143 if (childType === 17) return getIdent();
17144 if (childType === 18) return getVhash();
17145 if (childType === 19) return getCustomProperty();
17146 if (childType === 20) return getOperator();
17147 if (childType === 21) return getUnary();
17148 if (childType === 22) return getParentSelector();
17149 if (childType === 23) return getImportant();
17150 if (childType === 24) return getGlobal();
17151 if (childType === 25) return getDefault();
17152 if (childType === 26) return getOptional();
17156 * Check if token is part of an @-word (e.g. `@import`, `@include`)
17157 * @param {Number} i Token's index number
17158 * @returns {Number}
17160 function checkAtkeyword(i) {
17163 // Check that token is `@`:
17164 if (i >= tokensLength || tokens[i++].type !== TokenType.CommercialAt) return 0;
17166 return (l = checkIdentOrInterpolation(i)) ? l + 1 : 0;
17170 * Get node with @-word
17173 function getAtkeyword() {
17174 var type = NodeType.AtkeywordType;
17175 var token = tokens[pos];
17176 var line = token.ln;
17177 var column = token.col;
17182 var content = getIdentOrInterpolation();
17184 return newNode(type, content, line, column);
17188 * Check if token is a part of an @-rule
17189 * @param {Number} i Token's index number
17190 * @returns {Number} Length of @-rule
17192 function checkAtrule(i) {
17195 if (i >= tokensLength) return 0;
17197 // If token already has a record of being part of an @-rule,
17198 // return the @-rule's length:
17199 if (tokens[i].atrule_l !== undefined) return tokens[i].atrule_l;
17201 // If token is part of an @-rule, save the rule's type to token.
17203 if (l = checkKeyframesRule(i)) tokens[i].atrule_type = 4;
17204 // @-rule with ruleset:
17205 else if (l = checkAtruler(i)) tokens[i].atrule_type = 1;
17207 else if (l = checkAtruleb(i)) tokens[i].atrule_type = 2;
17208 // Single-line @-rule:
17209 else if (l = checkAtrules(i)) tokens[i].atrule_type = 3;else return 0;
17211 // If token is part of an @-rule, save the rule's length to token:
17212 tokens[i].atrule_l = l;
17218 * Get node with @-rule
17221 function getAtrule() {
17222 var childType = tokens[pos].atrule_type;
17224 if (childType === 1) return getAtruler(); // @-rule with ruleset
17225 if (childType === 2) return getAtruleb(); // Block @-rule
17226 if (childType === 3) return getAtrules(); // Single-line @-rule
17227 if (childType === 4) return getKeyframesRule();
17231 * Check if token is part of a block @-rule
17232 * @param {Number} i Token's index number
17233 * @returns {Number} Length of the @-rule
17235 function checkAtruleb(i) {
17239 if (i >= tokensLength) return 0;
17241 if (l = checkAtkeyword(i)) i += l;else return 0;
17243 if (l = checkTsets(i)) i += l;
17245 if (l = checkBlock(i)) i += l;else return 0;
17251 * Get node with a block @-rule
17252 * @returns {Array} `['atruleb', ['atkeyword', x], y, ['block', z]]`
17254 function getAtruleb() {
17255 var type = NodeType.AtruleType;
17256 var token = tokens[pos];
17257 var line = token.ln;
17258 var column = token.col;
17259 var content = [].concat(getAtkeyword(), getTsets(), getBlock());
17261 return newNode(type, content, line, column);
17265 * Check if token is part of an @-rule with ruleset
17266 * @param {Number} i Token's index number
17267 * @returns {Number} Length of the @-rule
17269 function checkAtruler(i) {
17273 if (i >= tokensLength) return 0;
17275 if (l = checkAtkeyword(i)) i += l;else return 0;
17277 if (l = checkTsets(i)) i += l;
17279 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
17281 if (l = checkAtrulers(i)) i += l;
17283 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
17289 * Get node with an @-rule with ruleset
17290 * @returns {Array} ['atruler', ['atkeyword', x], y, z]
17292 function getAtruler() {
17293 var type = NodeType.AtruleType;
17294 var token = tokens[pos];
17295 var line = token.ln;
17296 var column = token.col;
17297 var content = [].concat(getAtkeyword(), getTsets(), getAtrulers());
17299 return newNode(type, content, line, column);
17303 * @param {Number} i Token's index number
17304 * @returns {Number}
17306 function checkAtrulers(i) {
17310 if (i >= tokensLength) return 0;
17312 if (l = checkSC(i)) i += l;
17314 while (i < tokensLength) {
17315 if (l = checkSC(i)) tokens[i].atrulers_child = 1;else if (l = checkAtrule(i)) tokens[i].atrulers_child = 2;else if (l = checkRuleset(i)) tokens[i].atrulers_child = 3;else break;
17319 if (i < tokensLength) tokens[i].atrulers_end = 1;
17321 if (l = checkSC(i)) i += l;
17327 * @returns {Array} `['atrulers', x]`
17329 function getAtrulers() {
17330 var type = NodeType.BlockType;
17331 var token = tokens[pos];
17332 var line = token.ln;
17333 var column = token.col;
17339 content = content.concat(getSC());
17341 while (pos < tokensLength && !tokens[pos].atrulers_end) {
17342 var childType = tokens[pos].atrulers_child;
17343 if (childType === 1) content = content.concat(getSC());else if (childType === 2) content.push(getAtrule());else if (childType === 3) content.push(getRuleset());else break;
17346 content = content.concat(getSC());
17348 var end = getLastPosition(content, line, column, 1);
17353 return newNode(type, content, line, column, end);
17357 * @param {Number} i Token's index number
17358 * @returns {Number}
17360 function checkAtrules(i) {
17364 if (i >= tokensLength) return 0;
17366 if (l = checkAtkeyword(i)) i += l;else return 0;
17368 if (l = checkTsets(i)) i += l;
17374 * @returns {Array} `['atrules', ['atkeyword', x], y]`
17376 function getAtrules() {
17377 var type = NodeType.AtruleType;
17378 var token = tokens[pos];
17379 var line = token.ln;
17380 var column = token.col;
17381 var content = [].concat(getAtkeyword(), getTsets());
17383 return newNode(type, content, line, column);
17387 * Check if token is part of a block (e.g. `{...}`).
17388 * @param {Number} i Token's index number
17389 * @returns {Number} Length of the block
17391 function checkBlock(i) {
17392 return i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket ? tokens[i].right - i + 1 : 0;
17396 * Get node with a block
17397 * @returns {Array} `['block', x]`
17399 function getBlock() {
17400 var type = NodeType.BlockType;
17401 var token = tokens[pos];
17402 var line = token.ln;
17403 var column = token.col;
17404 var end = tokens[pos].right;
17410 while (pos < end) {
17411 if (checkBlockdecl(pos)) content = content.concat(getBlockdecl());else throwError(pos);
17414 var end_ = getLastPosition(content, line, column, 1);
17417 return newNode(type, content, line, column, end_);
17421 * Check if token is part of a declaration (property-value pair)
17422 * @param {Number} i Token's index number
17423 * @returns {Number} Length of the declaration
17425 function checkBlockdecl(i) {
17428 if (i >= tokensLength) return 0;
17430 if (l = checkBlockdecl1(i)) tokens[i].bd_type = 1;else if (l = checkBlockdecl2(i)) tokens[i].bd_type = 2;else if (l = checkBlockdecl3(i)) tokens[i].bd_type = 3;else if (l = checkBlockdecl4(i)) tokens[i].bd_type = 4;else return 0;
17438 function getBlockdecl() {
17439 var childType = tokens[pos].bd_type;
17441 if (childType === 1) return getBlockdecl1();
17442 if (childType === 2) return getBlockdecl2();
17443 if (childType === 3) return getBlockdecl3();
17444 if (childType === 4) return getBlockdecl4();
17448 * @param {Number} i Token's index number
17449 * @returns {Number}
17451 function checkBlockdecl1(i) {
17455 if (l = checkSC(i)) i += l;
17457 if (l = checkConditionalStatement(i)) tokens[i].bd_kind = 1;else if (l = checkInclude(i)) tokens[i].bd_kind = 2;else if (l = checkExtend(i)) tokens[i].bd_kind = 4;else if (l = checkLoop(i)) tokens[i].bd_kind = 3;else if (l = checkAtrule(i)) tokens[i].bd_kind = 6;else if (l = checkRuleset(i)) tokens[i].bd_kind = 7;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 5;else return 0;
17461 if (i < tokensLength && (l = checkDeclDelim(i))) i += l;else return 0;
17463 if (l = checkSC(i)) i += l;
17471 function getBlockdecl1() {
17473 var content = void 0;
17475 switch (tokens[pos].bd_kind) {
17477 content = getConditionalStatement();
17480 content = getInclude();
17483 content = getLoop();
17486 content = getExtend();
17489 content = getDeclaration();
17492 content = getAtrule();
17495 content = getRuleset();
17499 return sc.concat(content, getSC(), getDeclDelim(), getSC());
17503 * @param {Number} i Token's index number
17504 * @returns {Number}
17506 function checkBlockdecl2(i) {
17510 if (l = checkSC(i)) i += l;
17512 if (l = checkConditionalStatement(i)) tokens[i].bd_kind = 1;else if (l = checkInclude(i)) tokens[i].bd_kind = 2;else if (l = checkExtend(i)) tokens[i].bd_kind = 4;else if (l = checkMixin(i)) tokens[i].bd_kind = 8;else if (l = checkLoop(i)) tokens[i].bd_kind = 3;else if (l = checkAtrule(i)) tokens[i].bd_kind = 6;else if (l = checkRuleset(i)) tokens[i].bd_kind = 7;else if (l = checkDeclaration(i)) tokens[i].bd_kind = 5;else return 0;
17516 if (l = checkSC(i)) i += l;
17524 function getBlockdecl2() {
17526 var content = void 0;
17528 switch (tokens[pos].bd_kind) {
17530 content = getConditionalStatement();
17533 content = getInclude();
17536 content = getLoop();
17539 content = getExtend();
17542 content = getDeclaration();
17545 content = getAtrule();
17548 content = getRuleset();
17551 content = getMixin();
17555 return sc.concat(content, getSC());
17559 * @param {Number} i Token's index number
17560 * @returns {Number}
17562 function checkBlockdecl3(i) {
17566 if (l = checkSC(i)) i += l;
17568 if (l = checkDeclDelim(i)) i += l;else return 0;
17570 if (l = checkSC(i)) i += l;
17576 * @returns {Array} `[s0, ['declDelim'], s1]` where `s0` and `s1` are
17577 * are optional whitespaces.
17579 function getBlockdecl3() {
17580 return [].concat(getSC(), getDeclDelim(), getSC());
17584 * @param {Number} i Token's index number
17585 * @returns {Number}
17587 function checkBlockdecl4(i) {
17594 function getBlockdecl4() {
17599 * Check if token is part of text inside square brackets, e.g. `[1]`
17600 * @param {Number} i Token's index number
17601 * @returns {Number}
17603 function checkBrackets(i) {
17604 if (i >= tokensLength) return 0;
17609 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
17611 if (i < tokens[start].right) {
17612 var l = checkTsets(i);
17613 if (l) i += l;else return 0;
17623 * Get node with text inside parentheses or square brackets (e.g. `(1)`)
17626 function getBrackets() {
17627 var type = NodeType.BracketsType;
17628 var token = tokens[pos];
17629 var line = token.ln;
17630 var column = token.col;
17631 var right = token.right;
17638 content = getTsets();
17641 var end = getLastPosition(content, line, column, 1);
17646 return newNode(type, content, line, column, end);
17650 * Check if token is part of a class selector (e.g. `.abc`)
17651 * @param {Number} i Token's index number
17652 * @returns {Number} Length of the class selector
17654 function checkClass(i) {
17658 if (i >= tokensLength) return 0;
17660 if (tokens[i].class_l) return tokens[i].class_l;
17663 if (tokens[i].type === TokenType.FullStop) i++;else return 0;
17665 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
17667 while (i < tokensLength) {
17668 if (l = checkIdentOrInterpolation(i)) {
17669 tokens[start].class_l = l + 1;
17674 tokens[start].classEnd = i;
17680 * Get node with a class selector
17681 * @returns {Array} `['class', ['ident', x]]` where x is a class's
17682 * identifier (without `.`, e.g. `abc`).
17684 function getClass() {
17685 var type = NodeType.ClassType;
17686 var token = tokens[pos];
17687 var line = token.ln;
17688 var column = token.col;
17689 var end = token.classEnd;
17695 while (pos < end) {
17696 if (checkIdentOrInterpolation(pos)) {
17697 content = content.concat(getIdentOrInterpolation());
17701 return newNode(type, content, line, column);
17704 function checkCombinator(i) {
17705 if (i >= tokensLength) return 0;
17708 if (l = checkCombinator1(i)) tokens[i].combinatorType = 1;else if (l = checkCombinator2(i)) tokens[i].combinatorType = 2;else if (l = checkCombinator3(i)) tokens[i].combinatorType = 3;else if (l = checkCombinator4(i)) tokens[i].combinatorType = 4;
17713 function getCombinator() {
17714 var type = tokens[pos].combinatorType;
17715 if (type === 1) return getCombinator1();
17716 if (type === 2) return getCombinator2();
17717 if (type === 3) return getCombinator3();
17718 if (type === 4) return getCombinator4();
17724 * @param {Number} i
17727 function checkCombinator1(i) {
17728 if (i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign && i < tokensLength && tokens[i++].type === TokenType.GreaterThanSign) return 3;
17736 function getCombinator1() {
17737 var type = NodeType.CombinatorType;
17738 var token = tokens[pos];
17739 var line = token.ln;
17740 var column = token.col;
17741 var content = '>>>';
17746 return newNode(type, content, line, column);
17753 * @param {Number} i
17756 function checkCombinator2(i) {
17757 if (i + 1 >= tokensLength) return 0;
17759 if (tokens[i].type === TokenType.VerticalLine && tokens[i + 1].type === TokenType.VerticalLine) return 2;
17761 if (tokens[i].type === TokenType.GreaterThanSign && tokens[i + 1].type === TokenType.GreaterThanSign) return 2;
17769 function getCombinator2() {
17770 var type = NodeType.CombinatorType;
17771 var token = tokens[pos];
17772 var line = token.ln;
17773 var column = token.col;
17774 var content = '' + token.value + tokens[pos + 1].value;
17779 return newNode(type, content, line, column);
17787 * @param {Number} i
17790 function checkCombinator3(i) {
17791 var type = tokens[i].type;
17792 if (type === TokenType.PlusSign || type === TokenType.GreaterThanSign || type === TokenType.Tilde) return 1;else return 0;
17798 function getCombinator3() {
17799 var type = NodeType.CombinatorType;
17800 var token = tokens[pos];
17801 var line = token.ln;
17802 var column = token.col;
17803 var content = token.value;
17808 return newNode(type, content, line, column);
17814 function checkCombinator4(i) {
17817 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
17820 if (l = checkIdent(i)) i += l;else return 0;
17822 if (tokens[i].type === TokenType.Solidus) i++;else return 0;
17830 function getCombinator4() {
17831 var type = NodeType.CombinatorType;
17832 var token = tokens[pos];
17833 var line = token.ln;
17834 var column = token.col;
17839 var ident = getIdent();
17844 var content = '/' + ident.content + '/';
17846 return newNode(type, content, line, column);
17850 * Check if token is a multiline comment.
17851 * @param {Number} i Token's index number
17852 * @returns {Number} `1` if token is a multiline comment, otherwise `0`
17854 function checkCommentML(i) {
17855 return i < tokensLength && tokens[i].type === TokenType.CommentML ? 1 : 0;
17859 * Get node with a multiline comment
17860 * @returns {Array} `['commentML', x]` where `x`
17861 * is the comment's text (without `/*` and `* /`).
17863 function getCommentML() {
17864 var type = NodeType.CommentMLType;
17865 var token = tokens[pos];
17866 var line = token.ln;
17867 var column = token.col;
17868 var content = tokens[pos].value.substring(2);
17869 var l = content.length;
17871 if (content.charAt(l - 2) === '*' && content.charAt(l - 1) === '/') content = content.substring(0, l - 2);
17873 var end = getLastPosition(content, line, column, 2);
17874 if (end[0] === line) end[1] += 2;
17877 return newNode(type, content, line, column, end);
17881 * Check if token is part of a single-line comment.
17882 * @param {Number} i Token's index number
17883 * @returns {Number} `1` if token is a single-line comment, otherwise `0`
17885 function checkCommentSL(i) {
17886 return i < tokensLength && tokens[i].type === TokenType.CommentSL ? 1 : 0;
17890 * Get node with a single-line comment.
17891 * @returns {Array} `['commentSL', x]` where `x` is comment's message
17894 function getCommentSL() {
17895 var type = NodeType.CommentSLType;
17896 var token = tokens[pos];
17897 var line = token.ln;
17898 var column = token.col;
17899 var content = tokens[pos++].value.substring(2);
17900 var end = getLastPosition(content, line, column + 2);
17902 return newNode(type, content, line, column, end);
17906 * Check if token is part of a condition
17907 * (e.g. `@if ...`, `@else if ...` or `@else ...`).
17908 * @param {Number} i Token's index number
17909 * @returns {Number} Length of the condition
17911 function checkCondition(i) {
17917 if (i >= tokensLength) return 0;
17919 if (l = checkAtkeyword(i)) i += l;else return 0;
17921 if (['if', 'else'].indexOf(tokens[start + 1].value) < 0) return 0;
17923 while (i < tokensLength) {
17924 if (l = checkBlock(i)) break;
17929 if (l = _checkCondition(_i)) i += l + s;else break;
17935 function _checkCondition(i) {
17936 return checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkOperator(i) || checkCombinator(i) || checkString(i);
17940 * Get node with a condition.
17941 * @returns {Array} `['condition', x]`
17943 function getCondition() {
17944 var type = NodeType.ConditionType;
17945 var token = tokens[pos];
17946 var line = token.ln;
17947 var column = token.col;
17952 content.push(getAtkeyword());
17954 while (pos < tokensLength) {
17955 if (checkBlock(pos)) break;
17960 if (!_checkCondition(_pos)) break;
17962 if (s) content = content.concat(getSC());
17963 content.push(_getCondition());
17966 return newNode(type, content, line, column);
17969 function _getCondition() {
17970 if (checkVariable(pos)) return getVariable();
17971 if (checkNumber(pos)) return getNumber();
17972 if (checkInterpolation(pos)) return getInterpolation();
17973 if (checkIdent(pos)) return getIdent();
17974 if (checkOperator(pos)) return getOperator();
17975 if (checkCombinator(pos)) return getCombinator();
17976 if (checkString(pos)) return getString();
17980 * Check if token is part of a conditional statement
17981 * (e.g. `@if ... {} @else if ... {} @else ... {}`).
17982 * @param {Number} i Token's index number
17983 * @returns {Number} Length of the condition
17985 function checkConditionalStatement(i) {
17989 if (i >= tokensLength) return 0;
17991 if (l = checkCondition(i)) i += l;else return 0;
17993 if (l = checkSC(i)) i += l;
17995 if (l = checkBlock(i)) i += l;else return 0;
18001 * Get node with a condition.
18002 * @returns {Array} `['condition', x]`
18004 function getConditionalStatement() {
18005 var type = NodeType.ConditionalStatementType;
18006 var token = tokens[pos];
18007 var line = token.ln;
18008 var column = token.col;
18009 var content = [].concat(getCondition(), getSC(), getBlock());
18011 return newNode(type, content, line, column);
18015 * Check if token is part of a declaration (property-value pair)
18016 * @param {Number} i Token's index number
18017 * @returns {Number} Length of the declaration
18019 function checkDeclaration(i) {
18023 if (i >= tokensLength) return 0;
18025 if (l = checkProperty(i)) i += l;else return 0;
18027 if (l = checkSC(i)) i += l;
18029 if (l = checkPropertyDelim(i)) i++;else return 0;
18031 if (l = checkSC(i)) i += l;
18033 if (l = checkValue(i)) i += l;else return 0;
18039 * Get node with a declaration
18040 * @returns {Array} `['declaration', ['property', x], ['propertyDelim'],
18043 function getDeclaration() {
18044 var type = NodeType.DeclarationType;
18045 var token = tokens[pos];
18046 var line = token.ln;
18047 var column = token.col;
18048 var content = [].concat(getProperty(), getSC(), getPropertyDelim(), getSC(), getValue());
18050 return newNode(type, content, line, column);
18054 * @param {number} i Token's index number
18055 * @returns {number} Length of the declaration
18057 function checkSingleValueDeclaration(i) {
18061 if (i >= tokensLength) return 0;
18063 if (l = checkProperty(i)) i += l;else return 0;
18065 if (l = checkSC(i)) i += l;
18067 if (l = checkPropertyDelim(i)) i++;else return 0;
18069 if (l = checkSC(i)) i += l;
18071 if (l = checkSingleValue(i)) i += l;else return 0;
18077 * Get node with a declaration
18078 * @returns {Array} `['declaration', ['property', x], ['propertyDelim'],
18081 function getSingleValueDeclaration() {
18082 var type = NodeType.DeclarationType;
18083 var token = tokens[pos];
18084 var line = token.ln;
18085 var column = token.col;
18086 var content = [].concat(getProperty(), getSC(), getPropertyDelim(), getSC(), getSingleValue());
18088 return newNode(type, content, line, column);
18092 * Check if token is a semicolon
18093 * @param {Number} i Token's index number
18094 * @returns {Number} `1` if token is a semicolon, otherwise `0`
18096 function checkDeclDelim(i) {
18097 return i < tokensLength && tokens[i].type === TokenType.Semicolon ? 1 : 0;
18101 * Get node with a semicolon
18102 * @returns {Array} `['declDelim']`
18104 function getDeclDelim() {
18105 var type = NodeType.DeclDelimType;
18106 var token = tokens[pos];
18107 var line = token.ln;
18108 var column = token.col;
18113 return newNode(type, content, line, column);
18117 * Check if token if part of `!default` word.
18118 * @param {Number} i Token's index number
18119 * @returns {Number} Length of the `!default` word
18121 function checkDefault(i) {
18125 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
18127 if (l = checkSC(i)) i += l;
18129 if (tokens[i].value === 'default') {
18130 tokens[start].defaultEnd = i;
18131 return i - start + 1;
18138 * Get node with a `!default` word
18139 * @returns {Array} `['default', sc]` where `sc` is optional whitespace
18141 function getDefault() {
18142 var type = NodeType.DefaultType;
18143 var token = tokens[pos];
18144 var line = token.ln;
18145 var column = token.col;
18146 var content = joinValues(pos, token.defaultEnd);
18148 pos = token.defaultEnd + 1;
18150 return newNode(type, content, line, column);
18154 * Check if token is a comma
18155 * @param {Number} i Token's index number
18156 * @returns {Number} `1` if token is a comma, otherwise `0`
18158 function checkDelim(i) {
18159 return i < tokensLength && tokens[i].type === TokenType.Comma ? 1 : 0;
18163 * Get node with a comma
18164 * @returns {Array} `['delim']`
18166 function getDelim() {
18167 var type = NodeType.DelimType;
18168 var token = tokens[pos];
18169 var line = token.ln;
18170 var column = token.col;
18175 return newNode(type, content, line, column);
18179 * Check if token is part of a number with dimension unit (e.g. `10px`)
18180 * @param {Number} i Token's index number
18183 function checkDimension(i) {
18184 var ln = checkNumber(i);
18187 if (i >= tokensLength || !ln || i + ln >= tokensLength) return 0;
18189 return (li = checkUnit(i + ln)) ? ln + li : 0;
18193 * Get node of a number with dimension unit
18196 function getDimension() {
18197 var type = NodeType.DimensionType;
18198 var token = tokens[pos];
18199 var line = token.ln;
18200 var column = token.col;
18201 var content = [getNumber(), getUnit()];
18203 return newNode(type, content, line, column);
18207 * @param {Number} i Token's index number
18208 * @returns {Number}
18210 function checkExpression(i) {
18213 if (i >= tokensLength || tokens[i++].value !== 'expression' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) {
18217 return tokens[i].right - start + 1;
18223 function getExpression() {
18224 var type = NodeType.ExpressionType;
18225 var token = tokens[pos];
18226 var line = token.ln;
18227 var column = token.col;
18231 var content = joinValues(pos + 1, tokens[pos].right - 1);
18232 var end = getLastPosition(content, line, column, 1);
18234 if (end[0] === line) end[1] += 11;
18235 pos = tokens[pos].right + 1;
18237 return newNode(type, content, line, column, end);
18240 function checkExtend(i) {
18241 if (i >= tokensLength) return 0;
18245 if (l = checkExtend1(i)) tokens[i].extend_child = 1;else if (l = checkExtend2(i)) tokens[i].extend_child = 2;
18250 function getExtend() {
18251 var childType = tokens[pos].extend_child;
18253 if (childType === 1) return getExtend1();
18254 if (childType === 2) return getExtend2();
18258 * Checks if token is part of an extend with `!optional` flag.
18259 * @param {Number} i
18261 function checkExtend1(i) {
18265 if (i >= tokensLength) return 0;
18267 if (l = checkAtkeyword(i)) i += l;else return 0;
18269 if (tokens[start + 1].value !== 'extend') return 0;
18271 if (l = checkSC(i)) i += l;else return 0;
18273 if (l = checkSelectorsGroup(i)) i += l;else return 0;
18275 if (l = checkSC(i)) i += l;else return 0;
18277 if (l = checkOptional(i)) i += l;else return 0;
18282 function getExtend1() {
18283 var type = NodeType.ExtendType;
18284 var token = tokens[pos];
18285 var line = token.ln;
18286 var column = token.col;
18287 var content = [].concat(getAtkeyword(), getSC(), getSelectorsGroup(), getSC(), getOptional());
18289 return newNode(type, content, line, column);
18293 * Checks if token is part of an extend without `!optional` flag.
18294 * @param {Number} i
18296 function checkExtend2(i) {
18300 if (i >= tokensLength) return 0;
18302 if (l = checkAtkeyword(i)) i += l;else return 0;
18304 if (tokens[start + 1].value !== 'extend') return 0;
18306 if (l = checkSC(i)) i += l;else return 0;
18308 if (l = checkSelectorsGroup(i)) i += l;else return 0;
18313 function getExtend2() {
18314 var type = NodeType.ExtendType;
18315 var token = tokens[pos];
18316 var line = token.ln;
18317 var column = token.col;
18318 var content = [].concat(getAtkeyword(), getSC(), getSelectorsGroup());
18320 return newNode(type, content, line, column);
18324 * @param {Number} i Token's index number
18325 * @returns {Number}
18327 function checkFunction(i) {
18331 if (i >= tokensLength) return 0;
18333 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18335 return i < tokensLength && tokens[i].type === TokenType.LeftParenthesis ? tokens[i].right - start + 1 : 0;
18341 function getFunction() {
18342 var type = NodeType.FunctionType;
18343 var token = tokens[pos];
18344 var line = token.ln;
18345 var column = token.col;
18346 var content = [].concat(getIdentOrInterpolation(), getArguments());
18348 return newNode(type, content, line, column);
18352 * Check if token is part of a functions list (e.g. `function(value)...`).
18353 * @param {Number} i Token's index number
18354 * @returns {Number}
18356 function checkFunctionsList(i) {
18357 var d = 0; // Number of dots
18360 if (i >= tokensLength) return 0;
18362 if (l = checkFunction(i)) i += l;else return 0;
18364 while (i < tokensLength && tokens[i].type === TokenType.FullStop) {
18369 return d === 3 ? l + d : 0;
18373 * Get node with a functions list
18376 function getFunctionsList() {
18377 var type = NodeType.FunctionsListType;
18378 var token = tokens[pos];
18379 var line = token.ln;
18380 var column = token.col;
18381 var content = [getFunction()];
18382 var end = getLastPosition(content, line, column, 3);
18387 return newNode(type, content, line, column, end);
18391 * Check if token is part of `!global` word
18392 * @param {Number} i Token's index number
18393 * @returns {Number}
18395 function checkGlobal(i) {
18399 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
18401 if (l = checkSC(i)) i += l;
18403 if (tokens[i].value === 'global') {
18404 tokens[start].globalEnd = i;
18405 return i - start + 1;
18412 * Get node with `!global` word
18414 function getGlobal() {
18415 var type = NodeType.GlobalType;
18416 var token = tokens[pos];
18417 var line = token.ln;
18418 var column = token.col;
18419 var content = joinValues(pos, token.globalEnd);
18421 pos = token.globalEnd + 1;
18423 return newNode(type, content, line, column);
18427 * Check if token is part of an identifier
18428 * @param {Number} i Token's index number
18429 * @returns {Number} Length of the identifier
18431 function checkIdent(i) {
18434 if (i >= tokensLength) return 0;
18436 // Check if token is part of a negative number
18437 if (tokens[i].type === TokenType.HyphenMinus && tokens[i + 1].type === TokenType.DecimalNumber) return 0;
18439 if (tokens[i].type === TokenType.HyphenMinus) i++;
18441 if (checkInterpolation(i)) {
18442 tokens[start].ident_last = i - 1;
18446 if (tokens[i].type === TokenType.LowLine || tokens[i].type === TokenType.Identifier) i++;else return 0;
18448 for (; i < tokensLength; i++) {
18449 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
18452 tokens[start].ident_last = i - 1;
18458 * Get node with an identifier
18459 * @returns {Array} `['ident', x]` where `x` is identifier's name
18461 function getIdent() {
18462 var type = NodeType.IdentType;
18463 var token = tokens[pos];
18464 var line = token.ln;
18465 var column = token.col;
18466 var content = joinValues(pos, tokens[pos].ident_last);
18468 pos = tokens[pos].ident_last + 1;
18470 return newNode(type, content, line, column);
18474 * @param {number} i Token's index number
18475 * @returns {number} Length of the identifier
18477 function checkPartialIdent(i) {
18480 if (i >= tokensLength) return 0;
18482 for (; i < tokensLength; i++) {
18483 if (tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier && tokens[i].type !== TokenType.DecimalNumber) break;
18486 tokens[start].ident_last = i - 1;
18491 function checkIdentOrInterpolation(i) {
18494 var prevIsInterpolation = false;
18496 while (i < tokensLength) {
18497 if (l = checkInterpolation(i)) {
18498 tokens[i].ii_type = 1;
18500 prevIsInterpolation = true;
18501 } else if (l = checkIdent(i)) {
18502 tokens[i].ii_type = 2;
18504 prevIsInterpolation = false;
18505 } else if (prevIsInterpolation && (l = checkPartialIdent(i))) {
18506 tokens[i].ii_type = 3;
18508 prevIsInterpolation = false;
18515 function getIdentOrInterpolation() {
18518 while (pos < tokensLength) {
18519 var tokenType = tokens[pos].ii_type;
18521 if (tokenType === 1) {
18522 content.push(getInterpolation());
18523 } else if (tokenType === 2 || tokenType === 3) {
18524 content.push(getIdent());
18532 * Check if token is part of `!important` word
18533 * @param {Number} i Token's index number
18534 * @returns {Number}
18536 function checkImportant(i) {
18540 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
18542 if (l = checkSC(i)) i += l;
18544 if (tokens[i].value === 'important') {
18545 tokens[start].importantEnd = i;
18546 return i - start + 1;
18553 * Get node with `!important` word
18554 * @returns {Array} `['important', sc]` where `sc` is optional whitespace
18556 function getImportant() {
18557 var type = NodeType.ImportantType;
18558 var token = tokens[pos];
18559 var line = token.ln;
18560 var column = token.col;
18561 var content = joinValues(pos, token.importantEnd);
18563 pos = token.importantEnd + 1;
18565 return newNode(type, content, line, column);
18569 * Check if token is part of an included mixin (`@include` or `@extend`
18571 * @param {Number} i Token's index number
18572 * @returns {Number} Length of the included mixin
18574 function checkInclude(i) {
18577 if (i >= tokensLength) return 0;
18579 if (l = checkInclude1(i)) tokens[i].include_type = 1;else if (l = checkInclude2(i)) tokens[i].include_type = 2;else if (l = checkInclude3(i)) tokens[i].include_type = 3;else if (l = checkInclude4(i)) tokens[i].include_type = 4;else if (l = checkInclude5(i)) tokens[i].include_type = 5;
18585 * Get node with included mixin
18586 * @returns {Array} `['include', x]`
18588 function getInclude() {
18589 var type = tokens[pos].include_type;
18591 if (type === 1) return getInclude1();
18592 if (type === 2) return getInclude2();
18593 if (type === 3) return getInclude3();
18594 if (type === 4) return getInclude4();
18595 if (type === 5) return getInclude5();
18599 * Get node with included mixin with keyfames selector like
18600 * `@include nani(foo) { 0% {}}`
18601 * @param {Number} i Token's index number
18602 * @returns {Number} Length of the include
18604 function checkInclude1(i) {
18608 if (l = checkAtkeyword(i)) i += l;else return 0;
18610 if (tokens[start + 1].value !== 'include') return 0;
18612 if (l = checkSC(i)) i += l;else return 0;
18614 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18616 if (l = checkSC(i)) i += l;
18618 if (l = checkArguments(i)) i += l;else return 0;
18620 if (l = checkSC(i)) i += l;
18622 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
18628 * Get node with included mixin with keyfames selector like
18629 * `@include nani(foo) { 0% {}}`
18630 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
18631 * ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
18632 * `extend`, `y` is mixin's identifier (selector), `z` are arguments
18633 * passed to the mixin, `q` is block passed to the mixin containing a
18634 * ruleset > selector > keyframesSelector, and `sc` are optional
18637 function getInclude1() {
18638 var type = NodeType.IncludeType;
18639 var token = tokens[pos];
18640 var line = token.ln;
18641 var column = token.col;
18642 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getKeyframesBlocks());
18644 return newNode(type, content, line, column);
18648 * Check if token is part of an included mixin like `@include nani(foo) {...}`
18649 * @param {Number} i Token's index number
18650 * @returns {Number} Length of the include
18652 function checkInclude2(i) {
18656 if (l = checkAtkeyword(i)) i += l;else return 0;
18658 if (tokens[start + 1].value !== 'include') return 0;
18660 if (l = checkSC(i)) i += l;else return 0;
18662 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18664 if (l = checkSC(i)) i += l;
18666 if (l = checkArguments(i)) i += l;else return 0;
18668 if (l = checkSC(i)) i += l;
18670 if (l = checkBlock(i)) i += l;else return 0;
18676 * Get node with included mixin like `@include nani(foo) {...}`
18677 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
18678 * ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
18679 * `extend`, `y` is mixin's identifier (selector), `z` are arguments
18680 * passed to the mixin, `q` is block passed to the mixin and `sc`
18681 * are optional whitespaces
18683 function getInclude2() {
18684 var type = NodeType.IncludeType;
18685 var token = tokens[pos];
18686 var line = token.ln;
18687 var column = token.col;
18688 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments(), getSC(), getBlock());
18690 return newNode(type, content, line, column);
18694 * Check if token is part of an included mixin like `@include nani(foo)`
18695 * @param {Number} i Token's index number
18696 * @returns {Number} Length of the include
18698 function checkInclude3(i) {
18702 if (l = checkAtkeyword(i)) i += l;else return 0;
18704 if (tokens[start + 1].value !== 'include') return 0;
18706 if (l = checkSC(i)) i += l;else return 0;
18708 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18710 if (l = checkSC(i)) i += l;
18712 if (l = checkArguments(i)) i += l;else return 0;
18718 * Get node with included mixin like `@include nani(foo)`
18719 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
18720 * ['arguments', z], sc]` where `x` is `include` or `extend`, `y` is
18721 * mixin's identifier (selector), `z` are arguments passed to the
18722 * mixin and `sc` are optional whitespaces
18724 function getInclude3() {
18725 var type = NodeType.IncludeType;
18726 var token = tokens[pos];
18727 var line = token.ln;
18728 var column = token.col;
18729 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getArguments());
18731 return newNode(type, content, line, column);
18735 * Check if token is part of an included mixin with a content block passed
18736 * as an argument (e.g. `@include nani {...}`)
18737 * @param {Number} i Token's index number
18738 * @returns {Number} Length of the mixin
18740 function checkInclude4(i) {
18744 if (l = checkAtkeyword(i)) i += l;else return 0;
18746 if (tokens[start + 1].value !== 'include') return 0;
18748 if (l = checkSC(i)) i += l;else return 0;
18750 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18752 if (l = checkSC(i)) i += l;
18754 if (l = checkBlock(i)) i += l;else return 0;
18760 * Get node with an included mixin with a content block passed
18761 * as an argument (e.g. `@include nani {...}`)
18762 * @returns {Array} `['include', x]`
18764 function getInclude4() {
18765 var type = NodeType.IncludeType;
18766 var token = tokens[pos];
18767 var line = token.ln;
18768 var column = token.col;
18769 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation(), getSC(), getBlock());
18771 return newNode(type, content, line, column);
18775 * @param {Number} i Token's index number
18776 * @returns {Number}
18778 function checkInclude5(i) {
18782 if (l = checkAtkeyword(i)) i += l;else return 0;
18784 if (tokens[start + 1].value !== 'include') return 0;
18786 if (l = checkSC(i)) i += l;else return 0;
18788 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
18794 * @returns {Array} `['include', x]`
18796 function getInclude5() {
18797 var type = NodeType.IncludeType;
18798 var token = tokens[pos];
18799 var line = token.ln;
18800 var column = token.col;
18801 var content = [].concat(getAtkeyword(), getSC(), getIdentOrInterpolation());
18803 return newNode(type, content, line, column);
18807 * Check if token is part of an interpolated variable (e.g. `#{$nani}`).
18808 * @param {Number} i Token's index number
18809 * @returns {Number}
18811 function checkInterpolation(i) {
18815 if (i >= tokensLength) return 0;
18817 if (tokens[i].type !== TokenType.NumberSign || !tokens[i + 1] || tokens[i + 1].type !== TokenType.LeftCurlyBracket) return 0;
18821 while (tokens[i].type !== TokenType.RightCurlyBracket) {
18822 if (l = checkArgument(i)) i += l;else return 0;
18825 return tokens[i].type === TokenType.RightCurlyBracket ? i - start + 1 : 0;
18829 * Get node with an interpolated variable
18830 * @returns {Array} `['interpolation', x]`
18832 function getInterpolation() {
18833 var type = NodeType.InterpolationType;
18834 var token = tokens[pos];
18835 var line = token.ln;
18836 var column = token.col;
18842 while (pos < tokensLength && tokens[pos].type !== TokenType.RightCurlyBracket) {
18843 var body = getArgument();
18844 if (typeof body.content === 'string') content.push(body);else content = content.concat(body);
18847 var end = getLastPosition(content, line, column, 1);
18852 return newNode(type, content, line, column, end);
18856 * Check a single keyframe block - `5% {}`
18857 * @param {Number} i
18858 * @returns {Number}
18860 function checkKeyframesBlock(i) {
18864 if (i >= tokensLength) return 0;
18866 if (l = checkKeyframesSelectorsGroup(i)) i += l;else return 0;
18868 if (l = checkSC(i)) i += l;
18870 if (l = checkBlock(i)) i += l;else return 0;
18876 * Get a single keyframe block - `5% {}`
18879 function getKeyframesBlock() {
18880 var type = NodeType.RulesetType;
18881 var token = tokens[pos];
18882 var line = token.ln;
18883 var column = token.col;
18884 var content = [].concat(getKeyframesSelectorsGroup(), getSC(), getBlock());
18886 return newNode(type, content, line, column);
18890 * Check all keyframe blocks - `5% {} 100% {}`
18891 * @param {Number} i
18892 * @returns {Number}
18894 function checkKeyframesBlocks(i) {
18898 if (i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket) i++;else return 0;
18900 if (l = checkSC(i)) i += l;
18902 if (l = checkKeyframesBlock(i)) i += l;
18904 while (tokens[i].type !== TokenType.RightCurlyBracket) {
18905 if (l = checkSC(i)) i += l;else if (l = checkKeyframesBlock(i)) i += l;else if (l = checkAtrule(i)) {
18907 if (l = checkSC(i)) i += l;
18908 if (l = checkDeclDelim(i)) i += l;
18912 if (i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket) i++;else return 0;
18918 * Get all keyframe blocks - `5% {} 100% {}`
18921 function getKeyframesBlocks() {
18922 var type = NodeType.BlockType;
18923 var token = tokens[pos];
18924 var line = token.ln;
18925 var column = token.col;
18926 var keyframesBlocksEnd = token.right;
18932 while (pos < keyframesBlocksEnd) {
18933 if (checkSC(pos)) content = content.concat(getSC());else if (checkKeyframesBlock(pos)) content.push(getKeyframesBlock());else if (checkAtrule(pos)) {
18934 content.push(getAtrule()); // @content
18935 if (checkSC(pos)) content = content.concat(getSC());
18936 if (checkDeclDelim(pos)) content.push(getDeclDelim());
18940 var end = getLastPosition(content, line, column, 1);
18945 return newNode(type, content, line, column, end);
18949 * Check if token is part of a @keyframes rule.
18950 * @param {Number} i Token's index number
18951 * @return {Number} Length of the @keyframes rule
18953 function checkKeyframesRule(i) {
18957 if (i >= tokensLength) return 0;
18959 if (l = checkAtkeyword(i)) i += l;else return 0;
18961 var atruleName = joinValues2(i - l, l);
18962 if (atruleName.toLowerCase().indexOf('keyframes') === -1) return 0;
18964 if (l = checkSC(i)) i += l;else return 0;
18966 if (l = checkIdentOrInterpolation(i) || checkPseudoc(i)) i += l;else return 0;
18968 if (l = checkSC(i)) i += l;
18970 if (l = checkKeyframesBlocks(i)) i += l;else return 0;
18978 function getKeyframesRule() {
18979 var type = NodeType.AtruleType;
18980 var token = tokens[pos];
18981 var line = token.ln;
18982 var column = token.col;
18983 var content = [].concat(getAtkeyword(), getSC());
18985 if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());else if (checkPseudoc(pos)) {
18986 content = content.concat(getPseudoc());
18989 content = content.concat(getSC(), getKeyframesBlocks());
18991 return newNode(type, content, line, column);
18995 * Check a single keyframe selector - `5%`, `from` etc
18996 * @param {Number} i
18997 * @returns {Number}
18999 function checkKeyframesSelector(i) {
19003 if (i >= tokensLength) return 0;
19005 if (l = checkIdent(i)) {
19006 // Valid selectors are only `from` and `to`.
19007 var selector = joinValues2(i, l);
19008 if (selector !== 'from' && selector !== 'to') return 0;
19011 tokens[start].keyframesSelectorType = 1;
19012 } else if (l = checkPercentage(i)) {
19014 tokens[start].keyframesSelectorType = 2;
19015 } else if (l = checkInterpolation(i)) {
19017 tokens[start].keyframesSelectorType = 3;
19026 * Get a single keyframe selector
19029 function getKeyframesSelector() {
19030 var keyframesSelectorType = NodeType.KeyframesSelectorType;
19031 var selectorType = NodeType.SelectorType;
19032 var token = tokens[pos];
19033 var line = token.ln;
19034 var column = token.col;
19037 if (token.keyframesSelectorType === 1) {
19038 content.push(getIdent());
19039 } else if (token.keyframesSelectorType === 2) {
19040 content.push(getPercentage());
19041 } else if (token.keyframesSelectorType === 3) {
19042 content.push(getInterpolation());
19045 var keyframesSelector = newNode(keyframesSelectorType, content, line, column);
19047 return newNode(selectorType, [keyframesSelector], line, column);
19051 * Check the keyframe's selector groups
19052 * @param {Number} i
19053 * @returns {Number}
19055 function checkKeyframesSelectorsGroup(i) {
19059 if (l = checkKeyframesSelector(i)) i += l;else return 0;
19061 while (i < tokensLength) {
19062 var spaceBefore = checkSC(i);
19063 var comma = checkDelim(i + spaceBefore);
19066 var spaceAfter = checkSC(i + spaceBefore + comma);
19067 if (l = checkKeyframesSelector(i + spaceBefore + comma + spaceAfter)) {
19068 i += spaceBefore + comma + spaceAfter + l;
19072 tokens[start].selectorsGroupEnd = i;
19078 * Get the keyframe's selector groups
19079 * @returns {Array} An array of keyframe selectors
19081 function getKeyframesSelectorsGroup() {
19082 var selectorsGroup = [];
19083 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
19085 selectorsGroup.push(getKeyframesSelector());
19087 while (pos < selectorsGroupEnd) {
19088 selectorsGroup = selectorsGroup.concat(getSC(), getDelim(), getSC(), getKeyframesSelector());
19091 return selectorsGroup;
19095 * Check if token is part of a loop.
19096 * @param {Number} i Token's index number
19097 * @returns {Number} Length of the loop
19099 function checkLoop(i) {
19103 if (i >= tokensLength) return 0;
19105 if (l = checkAtkeyword(i)) i += l;else return 0;
19107 if (['for', 'each', 'while'].indexOf(tokens[start + 1].value) < 0) return 0;
19109 while (i < tokensLength) {
19110 if (l = checkBlock(i)) {
19113 } else if (l = checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkSC(i) || checkOperator(i) || checkCombinator(i) || checkString(i)) i += l;else return 0;
19120 * Get node with a loop.
19121 * @returns {Array} `['loop', x]`
19123 function getLoop() {
19124 var type = NodeType.LoopType;
19125 var token = tokens[pos];
19126 var line = token.ln;
19127 var column = token.col;
19130 content.push(getAtkeyword());
19132 while (pos < tokensLength) {
19133 if (checkBlock(pos)) {
19134 content.push(getBlock());
19136 } else if (checkVariable(pos)) content.push(getVariable());else if (checkNumber(pos)) content.push(getNumber());else if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkIdent(pos)) content.push(getIdent());else if (checkOperator(pos)) content.push(getOperator());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkSC(pos)) content = content.concat(getSC());else if (checkString(pos)) content.push(getString());
19139 return newNode(type, content, line, column);
19143 * Check if token is part of a mixin
19144 * @param {Number} i Token's index number
19145 * @returns {Number} Length of the mixin
19147 function checkMixin(i) {
19151 if (i >= tokensLength) return 0;
19153 if ((l = checkAtkeyword(i)) && tokens[i + 1].value === 'mixin') i += l;else return 0;
19155 if (l = checkSC(i)) i += l;
19157 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
19159 if (l = checkSC(i)) i += l;
19161 if (l = checkArguments(i)) i += l;
19163 if (l = checkSC(i)) i += l;
19165 if (l = checkBlock(i)) i += l;else return 0;
19171 * Get node with a mixin
19172 * @returns {Array} `['mixin', x]`
19174 function getMixin() {
19175 var type = NodeType.MixinType;
19176 var token = tokens[pos];
19177 var line = token.ln;
19178 var column = token.col;
19179 var content = [].concat(getAtkeyword(), getSC());
19181 if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());
19183 content = content.concat(getSC());
19185 if (checkArguments(pos)) content.push(getArguments());
19187 content = content.concat(getSC());
19189 if (checkBlock(pos)) content.push(getBlock());
19191 return newNode(type, content, line, column);
19195 * Check if token is a namespace sign (`|`)
19196 * @param {Number} i Token's index number
19197 * @returns {Number} `1` if token is `|`, `0` if not
19199 function checkNamespace(i) {
19200 return i < tokensLength && tokens[i].type === TokenType.VerticalLine ? 1 : 0;
19204 * Get node with a namespace sign
19205 * @returns {Array} `['namespace']`
19207 function getNamespace() {
19208 var type = NodeType.NamespaceType;
19209 var token = tokens[pos];
19210 var line = token.ln;
19211 var column = token.col;
19216 return newNode(type, content, line, column);
19220 * @param {Number} i Token's index number
19221 * @returns {Number}
19223 function checkNmName2(i) {
19224 if (tokens[i].type === TokenType.Identifier) return 1;else if (tokens[i].type !== TokenType.DecimalNumber) return 0;
19228 return i < tokensLength && tokens[i].type === TokenType.Identifier ? 2 : 1;
19232 * @returns {String}
19234 function getNmName2() {
19235 var s = tokens[pos].value;
19237 if (tokens[pos++].type === TokenType.DecimalNumber && pos < tokensLength && tokens[pos].type === TokenType.Identifier) s += tokens[pos++].value;
19243 * Check if token is part of a number
19244 * @param {Number} i Token's index number
19245 * @returns {Number} Length of number
19247 function checkNumber(i) {
19248 if (i >= tokensLength) return 0;
19250 if (tokens[i].number_l) return tokens[i].number_l;
19253 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && (!tokens[i + 1] || tokens[i + 1] && tokens[i + 1].type !== TokenType.FullStop)) {
19254 tokens[i].number_l = 1;
19259 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && (!tokens[i + 2] || tokens[i + 2].type !== TokenType.DecimalNumber)) {
19260 tokens[i].number_l = 2;
19265 if (i < tokensLength && tokens[i].type === TokenType.FullStop && tokens[i + 1].type === TokenType.DecimalNumber) {
19266 tokens[i].number_l = 2;
19271 if (i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && tokens[i + 2] && tokens[i + 2].type === TokenType.DecimalNumber) {
19272 tokens[i].number_l = 3;
19280 * Get node with number
19281 * @returns {Array} `['number', x]` where `x` is a number converted
19284 function getNumber() {
19285 var type = NodeType.NumberType;
19286 var token = tokens[pos];
19287 var line = token.ln;
19288 var column = token.col;
19289 var l = tokens[pos].number_l;
19292 for (var j = 0; j < l; j++) {
19293 content += tokens[pos + j].value;
19298 return newNode(type, content, line, column);
19302 * Check if token is an operator (`/`, `%`, `,`, `:` or `=`).
19303 * @param {Number} i Token's index number
19304 * @returns {Number} `1` if token is an operator, otherwise `0`
19306 function checkOperator(i) {
19307 if (i >= tokensLength) return 0;
19309 switch (tokens[i].type) {
19310 case TokenType.Solidus:
19311 case TokenType.PercentSign:
19312 case TokenType.Comma:
19313 case TokenType.Colon:
19314 case TokenType.EqualsSign:
19315 case TokenType.EqualitySign:
19316 case TokenType.InequalitySign:
19317 case TokenType.LessThanSign:
19318 case TokenType.GreaterThanSign:
19319 case TokenType.Asterisk:
19327 * Get node with an operator
19328 * @returns {Array} `['operator', x]` where `x` is an operator converted
19331 function getOperator() {
19332 var type = NodeType.OperatorType;
19333 var token = tokens[pos];
19334 var line = token.ln;
19335 var column = token.col;
19336 var content = token.value;
19340 return newNode(type, content, line, column);
19344 * Check if token is part of `!optional` word
19345 * @param {Number} i Token's index number
19346 * @returns {Number}
19348 function checkOptional(i) {
19352 if (i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark) return 0;
19354 if (l = checkSC(i)) i += l;
19356 if (tokens[i].value === 'optional') {
19357 tokens[start].optionalEnd = i;
19358 return i - start + 1;
19365 * Get node with `!optional` word
19367 function getOptional() {
19368 var type = NodeType.OptionalType;
19369 var token = tokens[pos];
19370 var line = token.ln;
19371 var column = token.col;
19372 var content = joinValues(pos, token.optionalEnd);
19374 pos = token.optionalEnd + 1;
19376 return newNode(type, content, line, column);
19380 * Check if token is part of text inside parentheses, e.g. `(1)`
19381 * @param {Number} i Token's index number
19384 function checkParentheses(i) {
19385 if (i >= tokensLength) return 0;
19388 var right = tokens[i].right;
19392 if (tokens[i].type === TokenType.LeftParenthesis) i++;else return 0;
19395 if (l = checkTsets(i)) i += l;else return 0;
19405 * Get node with text inside parentheses, e.g. `(1)`
19408 function getParentheses() {
19409 var type = NodeType.ParenthesesType;
19410 var token = tokens[pos];
19411 var line = token.ln;
19412 var column = token.col;
19413 var right = token.right;
19420 content = getTsets();
19423 var end = getLastPosition(content, line, column, 1);
19428 return newNode(type, content, line, column, end);
19432 * Check if token is a parent selector, e.g. `&`
19433 * @param {number} i Token's index number
19436 function checkParentSelector(i) {
19437 return i < tokensLength && tokens[i].type === TokenType.Ampersand ? 1 : 0;
19441 * Get node with a parent selector
19444 function getParentSelector() {
19445 var type = NodeType.ParentSelectorType;
19446 var token = tokens[pos];
19447 var line = token.ln;
19448 var column = token.col;
19453 return newNode(type, content, line, column);
19457 * Check if token is a parent selector extension, e.g. `&--foo-bar`
19458 * @param {number} i Token's index number
19459 * @returns {number} Length of the parent selector extension
19461 function checkParentSelectorExtension(i) {
19465 if (i >= tokensLength) return 0;
19467 while (i < tokensLength) {
19468 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else break;
19475 * Get parent selector extension node
19478 function getParentSelectorExtension() {
19479 var type = NodeType.ParentSelectorExtensionType;
19480 var token = tokens[pos];
19481 var line = token.ln;
19482 var column = token.col;
19485 while (pos < tokensLength) {
19486 if (checkIdentOrInterpolation(pos)) {
19487 content = content.concat(getIdentOrInterpolation());
19488 } else if (checkPartialIdent(pos)) {
19489 content.push(getIdent());
19493 return newNode(type, content, line, column);
19497 * Check if token is a parent selector with an extension or not
19498 * @param {number} i Token's index number
19499 * @return {number} Length of the parent selector and extension if applicable
19501 function checkParentSelectorWithExtension(i) {
19505 if (i >= tokensLength) return 0;
19507 if (l = checkParentSelector(i)) i += l;else return 0;
19509 if (l = checkParentSelectorExtension(i)) i += l;
19515 * Get parent selector node and extension node if applicable
19518 function getParentSelectorWithExtension() {
19519 var content = [getParentSelector()];
19521 if (checkParentSelectorExtension(pos)) content.push(getParentSelectorExtension());
19527 * Check if token is part of a number or an interpolation with a percent sign
19529 * @param {Number} i Token's index number
19530 * @returns {Number}
19532 function checkPercentage(i) {
19536 if (i >= tokensLength) return 0;
19538 if (l = checkNumberOrInterpolation(i)) i += l;else return 0;
19540 if (i >= tokensLength) return 0;
19543 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
19549 * Get a percentage node that contains either a number or an interpolation
19550 * @returns {Object} The percentage node
19552 function getPercentage() {
19553 var type = NodeType.PercentageType;
19554 var token = tokens[pos];
19555 var line = token.ln;
19556 var column = token.col;
19557 var content = getNumberOrInterpolation();
19558 var end = getLastPosition(content, line, column, 1);
19563 return newNode(type, content, line, column, end);
19567 * Check if token is a number or an interpolation
19568 * @param {Number} i Token's index number
19569 * @returns {Number}
19571 function checkNumberOrInterpolation(i) {
19575 while (i < tokensLength) {
19576 if (l = checkInterpolation(i) || checkNumber(i)) i += l;else break;
19583 * Get a number and/or interpolation node
19584 * @returns {Array} An array containing a single or multiple nodes
19586 function getNumberOrInterpolation() {
19589 while (pos < tokensLength) {
19590 if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkNumber(pos)) content.push(getNumber());else break;
19597 * Check if token is part of a placeholder selector (e.g. `%abc`).
19598 * @param {Number} i Token's index number
19599 * @returns {Number} Length of the selector
19601 function checkPlaceholder(i) {
19605 if (i >= tokensLength) return 0;
19607 if (tokens[start].placeholder_l) return tokens[start].placeholder_l;
19610 if (tokens[i].type === TokenType.PercentSign) i++;else return 0;
19612 if (l = checkIdentOrInterpolation(i)) {
19614 tokens[start].placeholder_l = i - start;
19621 * Get node with a placeholder selector
19622 * @returns {Array} `['placeholder', ['ident', x]]` where x is a placeholder's
19623 * identifier (without `%`, e.g. `abc`).
19625 function getPlaceholder() {
19626 var type = NodeType.PlaceholderType;
19627 var token = tokens[pos];
19628 var line = token.ln;
19629 var column = token.col;
19635 content = content.concat(getIdentOrInterpolation());
19637 return newNode(type, content, line, column);
19641 * @param {Number} i Token's index number
19642 * @returns {Number}
19644 function checkProgid(i) {
19648 if (i >= tokensLength) return 0;
19650 if (joinValues2(i, 6) === 'progid:DXImageTransform.Microsoft.') i += 6;else return 0;
19652 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
19654 if (l = checkSC(i)) i += l;
19656 if (tokens[i].type === TokenType.LeftParenthesis) {
19657 tokens[start].progid_end = tokens[i].right;
19658 i = tokens[i].right + 1;
19667 function getProgid() {
19668 var type = NodeType.ProgidType;
19669 var token = tokens[pos];
19670 var line = token.ln;
19671 var column = token.col;
19672 var progid_end = token.progid_end;
19673 var content = joinValues(pos, progid_end);
19675 pos = progid_end + 1;
19677 return newNode(type, content, line, column);
19681 * Check if token is part of a property
19682 * @param {Number} i Token's index number
19683 * @return {Number} Length of the property
19685 function checkProperty(i) {
19689 if (l = checkProperty1(i)) tokens[start].propertyType = 1;else if (l = checkProperty2(i)) tokens[start].propertyType = 2;else if (l = checkProperty3(i)) tokens[start].propertyType = 3;
19695 * Get node with a property
19698 function getProperty() {
19699 var type = tokens[pos].propertyType;
19701 if (type === 1) return getProperty1();
19702 if (type === 2) return getProperty2();
19703 if (type === 3) return getProperty3();
19707 * Check if token is part of a property
19710 * @param {Number} i Token's index number
19711 * @returns {Number} Length of the property
19713 function checkProperty1(i) {
19717 if (i >= tokensLength) return 0;
19719 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
19725 * Get node with a property
19728 function getProperty1() {
19729 var type = NodeType.PropertyType;
19730 var token = tokens[pos];
19731 var line = token.ln;
19732 var column = token.col;
19733 var content = getIdentOrInterpolation();
19735 return newNode(type, content, line, column);
19739 * Check if token is part of a custom property
19741 * @param {Number} i Token's index number
19742 * @return {Number} Length of the property
19744 function checkProperty2(i) {
19745 return checkCustomProperty(i);
19749 * Get node with a custom property
19752 function getProperty2() {
19753 return getCustomProperty();
19757 * Check if token is part of a property
19759 * @param {Number} i Token's index number
19760 * @returns {Number} Length of the property
19762 function checkProperty3(i) {
19766 if (i >= tokensLength) return 0;
19768 if (l = checkVariable(i)) i += l;else return 0;
19774 * Get node with a property
19775 * @returns {Array} `['property', x]`
19777 function getProperty3() {
19778 var type = NodeType.PropertyType;
19779 var token = tokens[pos];
19780 var line = token.ln;
19781 var column = token.col;
19782 var content = [getVariable()];
19784 return newNode(type, content, line, column);
19788 * Check if token is part of a custom property
19789 * @param {Number} i Token's index number
19790 * @return {Number} Length of the property
19792 function checkCustomProperty(i) {
19796 if (i >= tokensLength) return 0;
19798 if (tokens[i].type !== TokenType.HyphenMinus || tokens[i + 1] && tokens[i + 1].type !== TokenType.HyphenMinus) return 0;
19803 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
19809 * Get node with a custom property
19812 function getCustomProperty() {
19813 var type = NodeType.CustomPropertyType;
19814 var token = tokens[pos];
19815 var line = token.ln;
19816 var column = token.col;
19821 var content = getIdentOrInterpolation();
19823 return newNode(type, content, line, column);
19827 * Check if token is a colon
19828 * @param {Number} i Token's index number
19829 * @returns {Number} `1` if token is a colon, otherwise `0`
19831 function checkPropertyDelim(i) {
19832 return i < tokensLength && tokens[i].type === TokenType.Colon ? 1 : 0;
19836 * Get node with a colon
19837 * @returns {Array} `['propertyDelim']`
19839 function getPropertyDelim() {
19840 var type = NodeType.PropertyDelimType;
19841 var token = tokens[pos];
19842 var line = token.ln;
19843 var column = token.col;
19849 return newNode(type, content, line, column);
19853 * @param {Number} i Token's index number
19854 * @returns {Number}
19856 function checkPseudo(i) {
19857 return checkPseudoe(i) || checkPseudoc(i);
19863 function getPseudo() {
19864 if (checkPseudoe(pos)) return getPseudoe();
19865 if (checkPseudoc(pos)) return getPseudoc();
19869 * @param {Number} i Token's index number
19870 * @returns {Number}
19872 function checkPseudoe(i) {
19876 if (i >= tokensLength || tokens[i].type !== TokenType.Colon || i >= tokensLength || tokens[i + 1].type !== TokenType.Colon) return 0;
19878 if (l = checkPseudoElement1(i)) tokens[i].pseudoElementType = 1;else if (l = checkPseudoElement2(i)) tokens[i].pseudoElementType = 2;else return 0;
19886 function getPseudoe() {
19887 var childType = tokens[pos].pseudoElementType;
19888 if (childType === 1) return getPseudoElement1();
19889 if (childType === 2) return getPseudoElement2();
19893 * (1) `::slotted(selector)`
19894 * (2) `::slotted(selector, selector)`
19896 function checkPseudoElement1(i) {
19903 if (i >= tokensLength) return 0;
19905 if (l = checkIdent(i)) i += l;else return 0;
19907 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
19909 var right = tokens[i].right;
19914 if (l = checkSC(i)) i += l;
19916 if (l = checkSelectorsGroup(i)) i += l;else return 0;
19918 if (l = checkSC(i)) i += l;
19920 if (i !== right) return 0;
19929 * (1) `::slotted(selector)`
19930 * (2) `::slotted(selector, selector)`
19932 function getPseudoElement1() {
19933 var type = NodeType.PseudoeType;
19934 var token = tokens[pos];
19935 var line = token.ln;
19936 var column = token.col;
19942 content.push(getIdent());
19945 var _type = NodeType.ArgumentsType;
19946 var _token = tokens[pos];
19947 var _line = _token.ln;
19948 var _column = _token.col;
19953 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
19955 var end = getLastPosition(selectorContent, _line, _column, 1);
19956 var args = newNode(_type, selectorContent, _line, _column, end);
19957 content.push(args);
19963 return newNode(type, content, line, column);
19966 function checkPseudoElement2(i) {
19973 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
19981 function getPseudoElement2() {
19982 var type = NodeType.PseudoeType;
19983 var token = tokens[pos];
19984 var line = token.ln;
19985 var column = token.col;
19990 var content = getIdentOrInterpolation();
19992 return newNode(type, content, line, column);
19996 * @param {Number} i Token's index number
19997 * @returns {Number}
19999 function checkPseudoc(i) {
20002 if (i >= tokensLength || tokens[i].type !== TokenType.Colon) return 0;
20004 if (l = checkPseudoClass3(i)) tokens[i].pseudoClassType = 3;else if (l = checkPseudoClass4(i)) tokens[i].pseudoClassType = 4;else if (l = checkPseudoClass5(i)) tokens[i].pseudoClassType = 5;else if (l = checkPseudoClass1(i)) tokens[i].pseudoClassType = 1;else if (l = checkPseudoClass2(i)) tokens[i].pseudoClassType = 2;else if (l = checkPseudoClass6(i)) tokens[i].pseudoClassType = 6;else return 0;
20012 function getPseudoc() {
20013 var childType = tokens[pos].pseudoClassType;
20014 if (childType === 1) return getPseudoClass1();
20015 if (childType === 2) return getPseudoClass2();
20016 if (childType === 3) return getPseudoClass3();
20017 if (childType === 4) return getPseudoClass4();
20018 if (childType === 5) return getPseudoClass5();
20019 if (childType === 6) return getPseudoClass6();
20023 * (-) `:not(panda)`
20025 function checkPseudoClass1(i) {
20032 if (i >= tokensLength) return 0;
20034 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20036 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
20038 var right = tokens[i].right;
20043 if (l = checkSC(i)) i += l;
20045 if (l = checkSelectorsGroup(i)) i += l;else return 0;
20047 if (l = checkSC(i)) i += l;
20049 if (i !== right) return 0;
20058 * (-) `:not(panda)`
20060 function getPseudoClass1() {
20061 var type = NodeType.PseudocType;
20062 var token = tokens[pos];
20063 var line = token.ln;
20064 var column = token.col;
20070 content = content.concat(getIdentOrInterpolation());
20073 var _type2 = NodeType.ArgumentsType;
20074 var _token2 = tokens[pos];
20075 var _line2 = _token2.ln;
20076 var _column2 = _token2.col;
20081 var selectorContent = [].concat(getSC(), getSelectorsGroup(), getSC());
20083 var end = getLastPosition(selectorContent, _line2, _column2, 1);
20084 var args = newNode(_type2, selectorContent, _line2, _column2, end);
20085 content.push(args);
20091 return newNode(type, content, line, column);
20095 * (1) `:nth-child(odd)`
20096 * (2) `:nth-child(even)`
20097 * (3) `:lang(de-DE)`
20099 function checkPseudoClass2(i) {
20106 if (i >= tokensLength) return 0;
20108 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20110 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
20112 var right = tokens[i].right;
20117 if (l = checkSC(i)) i += l;
20119 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20121 if (l = checkSC(i)) i += l;
20123 if (i !== right) return 0;
20131 function getPseudoClass2() {
20132 var type = NodeType.PseudocType;
20133 var token = tokens[pos];
20134 var line = token.ln;
20135 var column = token.col;
20141 content = content.concat(getIdentOrInterpolation());
20143 var l = tokens[pos].ln;
20144 var c = tokens[pos].col;
20149 var value = [].concat(getSC(), getIdentOrInterpolation(), getSC());
20151 var end = getLastPosition(value, l, c, 1);
20152 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
20153 content.push(args);
20158 return newNode(type, content, line, column);
20162 * (-) `:nth-child(-3n + 2)`
20164 function checkPseudoClass3(i) {
20171 if (i >= tokensLength) return 0;
20173 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20175 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
20177 var right = tokens[i].right;
20182 if (l = checkSC(i)) i += l;
20184 if (l = checkUnary(i)) i += l;
20186 if (l = checkNumberOrInterpolation(i)) i += l;
20188 if (i >= tokensLength) return 0;
20190 if (tokens[i].value === 'n') i++;
20192 if (l = checkSC(i)) i += l;
20194 if (i >= tokensLength) return 0;
20196 if (tokens[i].type === TokenType.PlusSign || tokens[i].type === TokenType.HyphenMinus) i++;else return 0;
20198 if (l = checkSC(i)) i += l;
20200 if (l = checkNumberOrInterpolation(i)) i += l;else return 0;
20202 if (l = checkSC(i)) i += l;
20204 if (i !== right) return 0;
20212 function getPseudoClass3() {
20213 var type = NodeType.PseudocType;
20214 var token = tokens[pos];
20215 var line = token.ln;
20216 var column = token.col;
20222 content = content.concat(getIdentOrInterpolation());
20224 var l = tokens[pos].ln;
20225 var c = tokens[pos].col;
20231 value = value.concat(getSC());
20233 if (checkUnary(pos)) value.push(getUnary());
20234 if (checkNumberOrInterpolation(pos)) value = value.concat(getNumberOrInterpolation());
20237 var _token3 = tokens[pos];
20239 if (_token3.value === 'n') {
20240 var _l = _token3.ln;
20241 var _c = _token3.col;
20242 var _content = _token3.value;
20243 var ident = newNode(NodeType.IdentType, _content, _l, _c);
20249 value = value.concat(getSC());
20251 if (checkUnary(pos)) value.push(getUnary());
20253 value = value.concat(getSC());
20255 if (checkNumberOrInterpolation(pos)) value = value.concat(getNumberOrInterpolation());
20257 value = value.concat(getSC());
20259 var end = getLastPosition(value, l, c, 1);
20260 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
20261 content.push(args);
20266 return newNode(type, content, line, column);
20270 * (-) `:nth-child(-3n)`
20272 function checkPseudoClass4(i) {
20279 if (i >= tokensLength) return 0;
20281 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20283 if (i >= tokensLength) return 0;
20284 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
20286 var right = tokens[i].right;
20291 if (l = checkSC(i)) i += l;
20293 if (l = checkUnary(i)) i += l;
20295 if (l = checkInterpolation(i)) i += l;
20297 if (tokens[i].type === TokenType.DecimalNumber) i++;
20299 if (tokens[i].value === 'n') i++;else return 0;
20301 if (l = checkSC(i)) i += l;
20303 if (i !== right) return 0;
20311 function getPseudoClass4() {
20312 var type = NodeType.PseudocType;
20313 var token = tokens[pos];
20314 var line = token.ln;
20315 var column = token.col;
20321 content = content.concat(getIdentOrInterpolation());
20323 var l = tokens[pos].ln;
20324 var c = tokens[pos].col;
20330 value = value.concat(getSC());
20332 if (checkUnary(pos)) value.push(getUnary());
20333 if (checkInterpolation(pos)) value.push(getInterpolation());
20334 if (checkNumber(pos)) value.push(getNumber());
20335 if (checkIdent(pos)) value.push(getIdent());
20337 value = value.concat(getSC());
20339 var end = getLastPosition(value, l, c, 1);
20340 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
20341 content.push(args);
20346 return newNode(type, content, line, column);
20350 * (-) `:nth-child(+8)`
20352 function checkPseudoClass5(i) {
20359 if (i >= tokensLength) return 0;
20361 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20363 if (i >= tokensLength) return 0;
20364 if (tokens[i].type !== TokenType.LeftParenthesis) return 0;
20366 var right = tokens[i].right;
20371 if (l = checkSC(i)) i += l;
20373 if (l = checkUnary(i)) i += l;
20374 if (tokens[i].type === TokenType.DecimalNumber) i++;else return 0;
20376 if (l = checkSC(i)) i += l;
20378 if (i !== right) return 0;
20386 function getPseudoClass5() {
20387 var type = NodeType.PseudocType;
20388 var token = tokens[pos];
20389 var line = token.ln;
20390 var column = token.col;
20396 content = content.concat(getIdentOrInterpolation());
20398 var l = tokens[pos].ln;
20399 var c = tokens[pos].col;
20405 value = value.concat(getSC());
20407 if (checkUnary(pos)) value.push(getUnary());
20408 if (checkNumber(pos)) value.push(getNumber());
20410 value = value.concat(getSC());
20412 var end = getLastPosition(value, l, c, 1);
20413 var args = newNode(NodeType.ArgumentsType, value, l, c, end);
20414 content.push(args);
20419 return newNode(type, content, line, column);
20425 function checkPseudoClass6(i) {
20432 if (i >= tokensLength) return 0;
20434 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
20439 function getPseudoClass6() {
20440 var type = NodeType.PseudocType;
20441 var token = tokens[pos];
20442 var line = token.ln;
20443 var column = token.col;
20448 var content = getIdentOrInterpolation();
20450 return newNode(type, content, line, column);
20454 * @param {Number} i Token's index number
20455 * @returns {Number}
20457 function checkRuleset(i) {
20461 if (i >= tokensLength) return 0;
20463 if (l = checkSelectorsGroup(i)) i += l;else return 0;
20465 if (l = checkSC(i)) i += l;
20467 if (l = checkBlock(i)) i += l;else return 0;
20472 function getRuleset() {
20473 var type = NodeType.RulesetType;
20474 var token = tokens[pos];
20475 var line = token.ln;
20476 var column = token.col;
20477 var content = [].concat(getSelectorsGroup(), getSC(), getBlock());
20479 return newNode(type, content, line, column);
20483 * Check if token is marked as a space (if it's a space or a tab
20484 * or a line break).
20485 * @param {Number} i
20486 * @returns {Number} Number of spaces in a row starting with the given token.
20488 function checkS(i) {
20489 return i < tokensLength && tokens[i].ws ? tokens[i].ws_last - i + 1 : 0;
20493 * Get node with spaces
20494 * @returns {Array} `['s', x]` where `x` is a string containing spaces
20497 var type = NodeType.SType;
20498 var token = tokens[pos];
20499 var line = token.ln;
20500 var column = token.col;
20501 var content = joinValues(pos, tokens[pos].ws_last);
20503 pos = tokens[pos].ws_last + 1;
20505 return newNode(type, content, line, column);
20509 * Check if token is a space or a comment.
20510 * @param {Number} i Token's index number
20511 * @returns {Number} Number of similar (space or comment) tokens
20512 * in a row starting with the given token.
20514 function checkSC(i) {
20515 if (i >= tokensLength) return 0;
20520 while (i < tokensLength) {
20521 if (l = checkS(i)) tokens[i].sc_child = 1;else if (l = checkCommentML(i)) tokens[i].sc_child = 2;else if (l = checkCommentSL(i)) tokens[i].sc_child = 3;else break;
20531 * Get node with spaces and comments
20532 * @returns {Array} Array containing nodes with spaces (if there are any)
20533 * and nodes with comments (if there are any):
20534 * `[['s', x]*, ['comment', y]*]` where `x` is a string of spaces
20535 * and `y` is a comment's text (without `/*` and `* /`).
20540 if (pos >= tokensLength) return sc;
20542 while (pos < tokensLength) {
20543 var childType = tokens[pos].sc_child;
20545 if (childType === 1) sc.push(getS());else if (childType === 2) sc.push(getCommentML());else if (childType === 3) sc.push(getCommentSL());else break;
20552 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside a simple
20554 * @param {number} i Token's index number
20557 function checkShash(i) {
20561 if (i >= tokensLength) return 0;
20563 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
20565 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else return 0;
20567 while (i < tokensLength) {
20568 if (l = checkIdentOrInterpolation(i) || checkPartialIdent(i)) i += l;else break;
20571 tokens[start].shashEnd = i;
20577 * Get node with a hexadecimal number (e.g. `#fff`) inside a simple selector
20580 function getShash() {
20581 var type = NodeType.ShashType;
20582 var token = tokens[pos];
20583 var line = token.ln;
20584 var column = token.col;
20585 var end = token.shashEnd;
20591 while (pos < end) {
20592 if (checkIdentOrInterpolation(pos)) {
20593 content = content.concat(getIdentOrInterpolation());
20594 } else if (checkPartialIdent(pos)) {
20595 content.push(getIdent());
20599 return newNode(type, content, line, column);
20603 * Check if token is part of a string (text wrapped in quotes)
20604 * @param {Number} i Token's index number
20605 * @returns {Number} `1` if token is part of a string, `0` if not
20607 function checkString(i) {
20608 if (i >= tokensLength) return 0;
20610 if (tokens[i].type === TokenType.StringSQ || tokens[i].type === TokenType.StringDQ) {
20618 * Get string's node
20619 * @returns {Array} `['string', x]` where `x` is a string (including
20622 function getString() {
20623 var type = NodeType.StringType;
20624 var token = tokens[pos];
20625 var line = token.ln;
20626 var column = token.col;
20627 var content = token.value;
20631 return newNode(type, content, line, column);
20635 * Validate stylesheet: it should consist of any number (0 or more) of
20636 * rulesets (sets of rules with selectors), @-rules, whitespaces or
20638 * @param {Number} i Token's index number
20639 * @returns {Number}
20641 function checkStylesheet(i) {
20645 while (i < tokensLength) {
20646 if (l = checkSC(i)) tokens[i].stylesheet_child = 1;else if (l = checkRuleset(i)) tokens[i].stylesheet_child = 2;else if (l = checkInclude(i)) tokens[i].stylesheet_child = 3;else if (l = checkExtend(i)) tokens[i].stylesheet_child = 4;else if (l = checkMixin(i)) tokens[i].stylesheet_child = 5;else if (l = checkLoop(i)) tokens[i].stylesheet_child = 6;else if (l = checkConditionalStatement(i)) tokens[i].stylesheet_child = 7;else if (l = checkAtrule(i)) tokens[i].stylesheet_child = 8;else if (l = checkDeclaration(i)) tokens[i].stylesheet_child = 9;else if (l = checkDeclDelim(i)) tokens[i].stylesheet_child = 10;else throwError(i);
20655 * @returns {Array} `['stylesheet', x]` where `x` is all stylesheet's
20658 function getStylesheet() {
20659 var type = NodeType.StylesheetType;
20660 var token = tokens[pos];
20661 var line = token.ln;
20662 var column = token.col;
20665 while (pos < tokensLength) {
20666 var childType = tokens[pos].stylesheet_child;
20668 if (childType === 1) content = content.concat(getSC());
20669 if (childType === 2) content.push(getRuleset());
20670 if (childType === 3) content.push(getInclude());
20671 if (childType === 4) content.push(getExtend());
20672 if (childType === 5) content.push(getMixin());
20673 if (childType === 6) content.push(getLoop());
20674 if (childType === 7) content.push(getConditionalStatement());
20675 if (childType === 8) content.push(getAtrule());
20676 if (childType === 9) content.push(getDeclaration());
20677 if (childType === 10) content.push(getDeclDelim());
20680 return newNode(type, content, line, column);
20684 * @param {Number} i Token's index number
20685 * @returns {Number}
20687 function checkTset(i) {
20690 if (l = checkVhash(i)) tokens[i].tset_child = 1;else if (l = checkOperator(i)) tokens[i].tset_child = 2;else if (l = checkAny(i)) tokens[i].tset_child = 3;else if (l = checkSC(i)) tokens[i].tset_child = 4;
20698 function getTset() {
20699 var childType = tokens[pos].tset_child;
20701 if (childType === 1) return getVhash();
20702 if (childType === 2) return getOperator();
20703 if (childType === 3) return getAny();
20704 if (childType === 4) return getSC();
20708 * @param {Number} i Token's index number
20709 * @returns {Number}
20711 function checkTsets(i) {
20715 if (i >= tokensLength) return 0;
20717 while (l = checkTset(i)) {
20721 tokens[start].tsets_end = i;
20728 function getTsets() {
20732 if (pos >= tokensLength) return content;
20734 var end = tokens[pos].tsets_end;
20735 while (pos < end) {
20737 if (typeof t.content === 'string') content.push(t);else content = content.concat(t);
20744 * Check if token is an unary (arithmetical) sign (`+` or `-`)
20745 * @param {Number} i Token's index number
20746 * @returns {Number} `1` if token is an unary sign, `0` if not
20748 function checkUnary(i) {
20749 if (i >= tokensLength) return 0;
20751 if (tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.PlusSign) {
20759 * Get node with an unary (arithmetical) sign (`+` or `-`)
20760 * @returns {Array} `['unary', x]` where `x` is an unary sign
20761 * converted to string.
20763 function getUnary() {
20764 var type = NodeType.OperatorType;
20765 var token = tokens[pos];
20766 var line = token.ln;
20767 var column = token.col;
20768 var content = token.value;
20772 return newNode(type, content, line, column);
20776 * Check if token is a unicode range (single or multiple <urange> nodes)
20777 * @param {number} i Token's index
20778 * @return {number} Unicode range node's length
20780 function checkUnicodeRange(i) {
20784 if (i >= tokensLength) return 0;
20786 if (l = checkUrange(i)) i += l;else return 0;
20788 while (i < tokensLength) {
20789 var spaceBefore = checkSC(i);
20790 var comma = checkDelim(i + spaceBefore);
20793 var spaceAfter = checkSC(i + spaceBefore + comma);
20794 if (l = checkUrange(i + spaceBefore + comma + spaceAfter)) {
20795 i += spaceBefore + comma + spaceAfter + l;
20803 * Get a unicode range node
20806 function getUnicodeRange() {
20807 var type = NodeType.UnicodeRangeType;
20808 var token = tokens[pos];
20809 var line = token.ln;
20810 var column = token.col;
20813 while (pos < tokensLength) {
20814 if (checkSC(pos)) content = content.concat(getSC());else if (checkDelim(pos)) content.push(getDelim());else if (checkUrange(pos)) content.push(getUrange());else break;
20817 return newNode(type, content, line, column);
20821 * Check if token is unit
20822 * @param {Number} i Token's index number
20825 function checkUnit(i) {
20826 var units = ['em', 'ex', 'ch', 'rem', 'vh', 'vw', 'vmin', 'vmax', 'px', 'mm', 'q', 'cm', 'in', 'pt', 'pc', 'deg', 'grad', 'rad', 'turn', 's', 'ms', 'Hz', 'kHz', 'dpi', 'dpcm', 'dppx'];
20828 return units.indexOf(tokens[i].value) !== -1 ? 1 : 0;
20832 * Get unit node of type ident
20833 * @return {Node} An ident node containing the unit value
20835 function getUnit() {
20836 var type = NodeType.IdentType;
20837 var token = tokens[pos];
20838 var line = token.ln;
20839 var column = token.col;
20840 var content = token.value;
20844 return newNode(type, content, line, column);
20848 * Check if token is a u-range (part of a unicode-range)
20852 * @param {number} i Token's index
20853 * @return {number} Urange node's length
20855 function checkUrange(i) {
20859 if (i >= tokensLength) return 0;
20861 // Check for unicode prefix (u+ or U+)
20862 if (tokens[i].value === 'U' || tokens[i].value === 'u') i += 1;else return 0;
20864 if (i >= tokensLength) return 0;
20866 if (tokens[i].value === '+') i += 1;else return 0;
20868 while (i < tokensLength) {
20869 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = _checkUnicodeWildcard(i)) i += l;else break;
20872 tokens[start].urangeEnd = i - 1;
20878 * Get a u-range node (part of a unicode-range)
20881 function getUrange() {
20882 var startPos = pos;
20883 var type = NodeType.UrangeType;
20884 var token = tokens[pos];
20885 var line = token.ln;
20886 var column = token.col;
20889 content = joinValues(startPos, tokens[startPos].urangeEnd);
20890 pos = tokens[startPos].urangeEnd + 1;
20892 return newNode(type, content, line, column);
20896 * Check for unicode wildcard characters `?`
20897 * @param {number} i Token's index
20898 * @return {number} Wildcard length
20900 function _checkUnicodeWildcard(i) {
20903 if (i >= tokensLength) return 0;
20905 while (i < tokensLength) {
20906 if (tokens[i].type === TokenType.QuestionMark) i += 1;else break;
20913 * Check if token is part of URI, e.g. `url('/css/styles.css')`
20914 * @param {number} i Token's index number
20915 * @returns {number} Length of URI
20917 function checkUri(i) {
20921 if (i >= tokensLength || tokens[i].value !== 'url') return 0;
20926 if (i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis) return 0;
20928 // Store the opening parenthesis token as we will reference it's `right`
20929 // property to determine when the parentheses close
20930 var leftParenthesis = tokens[i];
20935 // Determine the type of URI
20936 while (i < leftParenthesis.right) {
20937 if (l = checkUri1(i)) {
20939 tokens[start].uriType = 1; // Raw based URI (without quotes)
20940 } else if (l = checkUri2(i)) {
20942 tokens[start].uriType = 2; // Non-raw based URI (with quotes)
20953 * Get specific type of URI node
20954 * @return {Node} Specific type of URI node
20956 function getUri() {
20957 var startPos = pos;
20958 var type = NodeType.UriType;
20959 var token = tokens[startPos];
20960 var line = token.ln;
20961 var column = token.col;
20965 var uriType = tokens[startPos].uriType;
20967 // Skip `url` and `(`.
20970 if (uriType === 1) content = content.concat(getUri1());else if (uriType === 2) content = content.concat(getUri2());else end = getLastPosition(content, line, column, 4);
20972 if (!end) end = getLastPosition(content, line, column, 1);
20977 return newNode(type, content, line, column, end);
20981 * Check if token type is valid URI character
20982 * @param {number} i Token's index number
20983 * @return {number} Length of raw node
20985 function checkUriRawCharacters(i) {
20989 if (l = checkIdent(i)) i += l;else if (l = checkNumber(i)) i += l;else {
20990 switch (tokens[i].type) {
20991 case TokenType.ExclamationMark:
20992 case TokenType.NumberSign:
20993 case TokenType.DollarSign:
20994 case TokenType.PercentSign:
20995 case TokenType.Ampersand:
20996 case TokenType.Asterisk:
20997 case TokenType.PlusSign:
20998 case TokenType.Comma:
20999 case TokenType.HyphenMinus:
21000 case TokenType.FullStop:
21001 case TokenType.Solidus:
21002 case TokenType.Colon:
21003 case TokenType.Semicolon:
21004 case TokenType.LessThanSign:
21005 case TokenType.EqualsSign:
21006 case TokenType.GreaterThanSign:
21007 case TokenType.QuotationMark:
21008 case TokenType.CommercialAt:
21009 case TokenType.LeftSquareBracket:
21010 case TokenType.RightSquareBracket:
21011 case TokenType.CircumflexAccent:
21012 case TokenType.LowLine:
21013 case TokenType.LeftCurlyBracket:
21014 case TokenType.VerticalLine:
21015 case TokenType.RightCurlyBracket:
21016 case TokenType.Tilde:
21029 * Check if content of URI can be contained within a raw node
21030 * @param {number} i Token's index number
21031 * @return {number} Length of raw node
21033 function checkUriRaw(i) {
21037 while (i < tokensLength) {
21038 if (checkInterpolation(i) || checkVariable(i)) break;else if (l = checkUriRawCharacters(i)) i += l;else break;
21041 tokens[start].uri_raw_end = i;
21050 function getUriRaw() {
21051 var startPos = pos;
21052 var type = NodeType.RawType;
21053 var token = tokens[startPos];
21054 var line = token.ln;
21055 var column = token.col;
21059 while (pos < tokens[startPos].uri_raw_end) {
21060 if (checkInterpolation(pos) || checkVariable(pos)) break;else if (l = checkUriRawCharacters(pos)) pos += l;else break;
21063 content = joinValues(startPos, pos - 1);
21065 return newNode(type, content, line, column);
21069 * Check for a raw (without quotes) URI
21070 * (1) http://foo.com/bar.png
21071 * (2) http://foo.com/#{$bar}.png
21072 * (3) #{$foo}/bar.png
21074 * @param {number} i Token's index number
21075 * @return {number} Length of URI node
21077 function checkUri1(i) {
21081 if (l = checkSC(i)) i += l;
21083 while (i < tokensLength) {
21084 if (l = checkInterpolation(i) || checkUriRaw(i)) i += l;else break;
21087 if (l = checkSC(i)) i += l;
21089 // Check that we are at the end of the uri
21090 if (i < tokens[start - 1].right) return 0;
21092 tokens[start].uri_end = i;
21098 * Get a raw (without quotes) URI
21102 function getUri1() {
21103 var startPos = pos;
21106 if (checkSC(pos)) content = content.concat(getSC());
21108 while (pos < tokens[startPos].uri_end) {
21109 if (checkInterpolation(pos)) content.push(getInterpolation());else if (checkUriRaw(pos)) content.push(getUriRaw());else break;
21112 if (checkSC(pos)) content = content.concat(getSC());
21118 * Check for a non-raw (with quotes) URI
21119 * (1) 'http://foo.com/bar.png'
21120 * (2) 'http://foo.com/'#{$bar}.png
21121 * (3) #{$foo}'/bar.png'
21122 * @param {number} i Token's index number
21123 * @return {number} Length of URI node
21125 function checkUri2(i) {
21129 while (i < tokensLength) {
21130 if (l = checkSC(i)) i += l;else if (l = checkString(i)) i += l;else if (l = checkFunction(i)) i += l;else if (l = checkUnary(i)) i += l;else if (l = checkIdentOrInterpolation(i)) i += l;else if (l = checkVariable(i)) i += l;else break;
21133 // Check that we are at the end of the uri
21134 if (i < tokens[start - 1].right) return 0;
21136 tokens[start].uri_end = i;
21142 * Get a non-raw (with quotes) URI node
21145 function getUri2() {
21146 var startPos = pos;
21149 while (pos < tokens[startPos].uri_end) {
21150 if (checkSC(pos)) content = content.concat(getSC());else if (checkUnary(pos)) content.push(getUnary());else if (_checkValue(pos)) content.push(_getValue());else break;
21157 * Check if token is part of a value
21158 * @param {Number} i Token's index number
21159 * @returns {Number} Length of the value
21161 function checkValue(i) {
21167 while (i < tokensLength) {
21168 if (checkDeclDelim(i)) break;
21173 if (l = _checkValue(_i)) i += l + s;
21174 if (!l || checkBlock(i - l)) break;
21177 tokens[start].value_end = i;
21185 function getValue() {
21186 var type = NodeType.ValueType;
21187 var token = tokens[pos];
21188 var line = token.ln;
21189 var column = token.col;
21190 var end = tokens[pos].value_end;
21195 while (pos < end) {
21199 if (checkDeclDelim(_pos)) break;
21201 if (!_checkValue(_pos)) break;
21203 if (s) content = content.concat(getSC());
21204 content.push(_getValue());
21206 if (checkBlock(_pos)) break;
21209 return newNode(type, content, line, column);
21213 * @param {Number} i Token's index number
21214 * @returns {Number}
21216 function _checkValue(i) {
21219 if (l = checkInterpolation(i)) tokens[i].value_child = 1;else if (l = checkVariable(i)) tokens[i].value_child = 2;else if (l = checkVhash(i)) tokens[i].value_child = 3;else if (l = checkBlock(i)) tokens[i].value_child = 4;else if (l = checkAtkeyword(i)) tokens[i].value_child = 5;else if (l = checkOperator(i)) tokens[i].value_child = 6;else if (l = checkImportant(i)) tokens[i].value_child = 7;else if (l = checkGlobal(i)) tokens[i].value_child = 8;else if (l = checkDefault(i)) tokens[i].value_child = 9;else if (l = checkProgid(i)) tokens[i].value_child = 10;else if (l = checkAny(i)) tokens[i].value_child = 11;else if (l = checkParentSelector(i)) tokens[i].value_child = 12;
21227 function _getValue() {
21228 var childType = tokens[pos].value_child;
21229 if (childType === 1) return getInterpolation();
21230 if (childType === 2) return getVariable();
21231 if (childType === 3) return getVhash();
21232 if (childType === 4) return getBlock();
21233 if (childType === 5) return getAtkeyword();
21234 if (childType === 6) return getOperator();
21235 if (childType === 7) return getImportant();
21236 if (childType === 8) return getGlobal();
21237 if (childType === 9) return getDefault();
21238 if (childType === 10) return getProgid();
21239 if (childType === 11) return getAny();
21240 if (childType === 12) return getParentSelector();
21244 * @param {number} i Token's index number
21245 * @returns {number} Length of the value
21247 function checkSingleValue(i) {
21253 while (i < tokensLength) {
21254 if (checkDeclDelim(i) || checkDelim(i)) break;
21259 if (l = _checkValue(_i)) i += l + s;
21260 if (!l || checkBlock(i - l)) break;
21269 function getSingleValue() {
21270 var type = NodeType.ValueType;
21271 var token = tokens[pos];
21272 var line = token.ln;
21273 var column = token.col;
21278 while (pos < tokensLength) {
21282 if (checkDeclDelim(_pos) || checkDelim(_pos)) break;
21284 if (!_checkValue(_pos)) break;
21286 if (s) content = content.concat(getSC());
21287 content.push(_getValue());
21289 if (checkBlock(_pos)) break;
21292 return newNode(type, content, line, column);
21296 * Check if token is part of a variable
21297 * @param {Number} i Token's index number
21298 * @returns {Number} Length of the variable
21300 function checkVariable(i) {
21304 if (i >= tokensLength) return 0;
21307 if (tokens[i].type === TokenType.DollarSign) i++;else return 0;
21309 if (l = checkIdent(i)) i += l;else return 0;
21315 * Get node with a variable
21316 * @returns {Array} `['variable', ['ident', x]]` where `x` is
21319 function getVariable() {
21320 var type = NodeType.VariableType;
21321 var token = tokens[pos];
21322 var line = token.ln;
21323 var column = token.col;
21328 var content = [getIdent()];
21330 return newNode(type, content, line, column);
21334 * Check if token is part of a variables list (e.g. `$values...`).
21335 * @param {Number} i Token's index number
21336 * @returns {Number}
21338 function checkVariablesList(i) {
21339 var d = 0; // Number of dots
21342 if (i >= tokensLength) return 0;
21344 if (l = checkVariable(i)) i += l;else return 0;
21346 while (i < tokensLength && tokens[i].type === TokenType.FullStop) {
21351 return d === 3 ? l + d : 0;
21355 * Get node with a variables list
21356 * @returns {Array} `['variableslist', ['variable', ['ident', x]]]` where
21357 * `x` is a variable name.
21359 function getVariablesList() {
21360 var type = NodeType.VariablesListType;
21361 var token = tokens[pos];
21362 var line = token.ln;
21363 var column = token.col;
21364 var content = [getVariable()];
21365 var end = getLastPosition(content, line, column, 3);
21370 return newNode(type, content, line, column, end);
21374 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
21376 * @param {Number} i Token's index number
21377 * @returns {Number}
21379 function checkVhash(i) {
21383 if (i >= tokensLength) return 0;
21386 if (tokens[i].type === TokenType.NumberSign) i++;else return 0;
21388 if (l = checkNmName2(i)) i += l;else return 0;
21394 * Get node with a hexadecimal number (e.g. `#fff`) inside some value
21395 * @returns {Array} `['vhash', x]` where `x` is a hexadecimal number
21396 * converted to string (without `#`, e.g. `'fff'`).
21398 function getVhash() {
21399 var type = NodeType.VhashType;
21400 var token = tokens[pos];
21401 var line = token.ln;
21402 var column = token.col;
21407 var content = getNmName2();
21408 var end = getLastPosition(content, line, column + 1);
21409 return newNode(type, content, line, column, end);
21412 function checkSelectorsGroup(i) {
21413 if (i >= tokensLength) return 0;
21417 var selectorCounter = 0;
21418 var delimCounter = 0;
21420 if (l = checkSelector(i)) {
21425 while (i < tokensLength) {
21428 var tempLength = void 0;
21430 var spaceBefore = checkSC(tempIndex);
21432 if (tempLength = checkDelim(tempIndex + spaceBefore)) {
21433 tempIndex += spaceBefore + tempLength;
21436 if (tempLength = checkSC(tempIndex)) tempIndex += tempLength;
21437 if (tempLength = checkSelector(tempIndex)) {
21438 tempIndex += tempLength;
21443 i += tempIndex - tempStart;
21446 tokens[start].selectorsGroupEnd = i;
21447 tokens[start].selectorsGroupSelectorCount = selectorCounter;
21448 tokens[start].selectorsGroupDelimCount = delimCounter;
21453 function getSelectorsGroup() {
21454 var selectorsGroup = [];
21455 var selectorCounter = 0;
21456 var delimCounter = 0;
21458 var selectorsGroupEnd = tokens[pos].selectorsGroupEnd;
21459 var selectorCount = tokens[pos].selectorsGroupSelectorCount;
21460 var delimCount = tokens[pos].selectorsGroupDelimCount;
21462 selectorsGroup.push(getSelector());
21465 while (pos < selectorsGroupEnd) {
21466 if (delimCounter < delimCount) {
21467 selectorsGroup = selectorsGroup.concat(getSC());
21468 selectorsGroup = selectorsGroup.concat(getDelim());
21471 selectorsGroup = selectorsGroup.concat(getSC());
21473 if (selectorCounter < selectorCount) {
21474 selectorsGroup = selectorsGroup.concat(getSelector());
21480 return selectorsGroup;
21483 function checkSelector(i) {
21486 if (l = checkSelector1(i)) tokens[i].selectorType = 1;else if (l = checkSelector2(i)) tokens[i].selectorType = 2;
21491 function getSelector() {
21492 var selectorType = tokens[pos].selectorType;
21493 if (selectorType === 1) return getSelector1();else return getSelector2();
21497 * Checks for selector which starts with a compound selector.
21499 function checkSelector1(i) {
21500 if (i >= tokensLength) return 0;
21505 if (l = checkCompoundSelector(i)) i += l;else return 0;
21507 while (i < tokensLength) {
21508 var space = checkSC(i);
21509 var comma = checkCombinator(i + space);
21510 if (!space && !comma) break;
21513 i += space + comma;
21514 space = checkSC(i);
21517 if (l = checkCompoundSelector(i + space)) i += space + l;else break;
21520 tokens[start].selectorEnd = i;
21524 function getSelector1() {
21525 var type = NodeType.SelectorType;
21526 var token = tokens[pos];
21527 var line = token.ln;
21528 var column = token.col;
21529 var selectorEnd = token.selectorEnd;
21530 var content = getCompoundSelector();
21532 while (pos < selectorEnd) {
21533 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
21536 return newNode(type, content, line, column);
21540 * Checks for a selector that starts with a combinator.
21542 function checkSelector2(i) {
21543 if (i >= tokensLength) return 0;
21548 if (l = checkCombinator(i)) i += l;else return 0;
21550 while (i < tokensLength) {
21551 var spaceBefore = checkSC(i);
21552 if (l = checkCompoundSelector(i + spaceBefore)) i += spaceBefore + l;else break;
21554 var spaceAfter = checkSC(i);
21555 var comma = checkCombinator(i + spaceAfter);
21556 if (!spaceAfter && !comma) break;
21558 i += spaceAfter + comma;
21562 tokens[start].selectorEnd = i;
21566 function getSelector2() {
21567 var type = NodeType.SelectorType;
21568 var token = tokens[pos];
21569 var line = token.ln;
21570 var column = token.col;
21571 var selectorEnd = token.selectorEnd;
21572 var content = [getCombinator()];
21574 while (pos < selectorEnd) {
21575 if (checkSC(pos)) content = content.concat(getSC());else if (checkCombinator(pos)) content.push(getCombinator());else if (checkCompoundSelector(pos)) content = content.concat(getCompoundSelector());
21578 return newNode(type, content, line, column);
21581 function checkCompoundSelector(i) {
21584 if (l = checkCompoundSelector1(i)) {
21585 tokens[i].compoundSelectorType = 1;
21586 } else if (l = checkCompoundSelector2(i)) {
21587 tokens[i].compoundSelectorType = 2;
21593 function getCompoundSelector() {
21594 var type = tokens[pos].compoundSelectorType;
21595 if (type === 1) return getCompoundSelector1();
21596 if (type === 2) return getCompoundSelector2();
21600 * Check for compound selectors that start with either a type selector,
21601 * placeholder or parent selector with extension
21603 * (2) `foo[attr=val]`
21604 * (3) `foo:first-of-type`
21606 * @param {number} i Token's index
21607 * @return {number} Compound selector's length
21609 function checkCompoundSelector1(i) {
21610 if (i >= tokensLength) return 0;
21615 if (l = checkUniversalSelector(i) || checkTypeSelector(i) || checkPlaceholder(i) || checkParentSelectorWithExtension(i)) i += l;else return 0;
21617 while (i < tokensLength) {
21618 var _l2 = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i) || checkInterpolation(i);
21620 if (_l2) i += _l2;else break;
21623 tokens[start].compoundSelectorEnd = i;
21629 * @return {Array} An array of nodes that make up the compound selector
21631 function getCompoundSelector1() {
21633 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
21635 if (checkUniversalSelector(pos)) sequence.push(getUniversalSelector());else if (checkTypeSelector(pos)) sequence.push(getTypeSelector());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkParentSelectorWithExtension(pos)) sequence = sequence.concat(getParentSelectorWithExtension());
21637 while (pos < compoundSelectorEnd) {
21638 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkInterpolation(pos)) sequence.push(getInterpolation());else break;
21645 * Check for all other compound selectors
21647 * (2) `.foo[attr=val]`
21648 * (3) `.foo:first-of-type`
21650 * (5) `.foo#{$bar}`
21651 * @param {number} i Token's index
21652 * @return {number} Compound selector's length
21654 function checkCompoundSelector2(i) {
21655 if (i >= tokensLength) return 0;
21659 while (i < tokensLength) {
21660 var l = checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i) || checkInterpolation(i);
21662 if (l) i += l;else break;
21665 tokens[start].compoundSelectorEnd = i;
21671 * @return {Array} An array of nodes that make up the compound selector
21673 function getCompoundSelector2() {
21675 var compoundSelectorEnd = tokens[pos].compoundSelectorEnd;
21677 while (pos < compoundSelectorEnd) {
21678 if (checkShash(pos)) sequence.push(getShash());else if (checkClass(pos)) sequence.push(getClass());else if (checkAttributeSelector(pos)) sequence.push(getAttributeSelector());else if (checkPseudo(pos)) sequence.push(getPseudo());else if (checkPlaceholder(pos)) sequence.push(getPlaceholder());else if (checkInterpolation(pos)) sequence.push(getInterpolation());else break;
21684 function checkUniversalSelector(i) {
21685 if (i >= tokensLength) return 0;
21690 if (l = checkNamePrefix(i)) i += l;
21692 if (tokens[i].type === TokenType.Asterisk) i++;else return 0;
21697 function getUniversalSelector() {
21698 var type = NodeType.UniversalSelectorType;
21699 var token = tokens[pos];
21700 var line = token.ln;
21701 var column = token.col;
21705 if (checkNamePrefix(pos)) {
21706 content.push(getNamePrefix());
21707 end = getLastPosition(content, line, column, 1);
21712 return newNode(type, content, line, column, end);
21716 * Check if token is part of a type selector
21717 * @param {number} i Token's index
21718 * @return {number} Type selector's length
21720 function checkTypeSelector(i) {
21721 if (i >= tokensLength) return 0;
21726 if (l = checkNamePrefix(i)) i += l;
21728 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
21734 * Get type selector node
21737 function getTypeSelector() {
21738 var type = NodeType.TypeSelectorType;
21739 var token = tokens[pos];
21740 var line = token.ln;
21741 var column = token.col;
21744 if (checkNamePrefix(pos)) content.push(getNamePrefix());
21746 content = content.concat(getIdentOrInterpolation());
21748 return newNode(type, content, line, column);
21751 function checkAttributeSelector(i) {
21753 if (l = checkAttributeSelector1(i)) tokens[i].attributeSelectorType = 1;else if (l = checkAttributeSelector2(i)) tokens[i].attributeSelectorType = 2;
21758 function getAttributeSelector() {
21759 var type = tokens[pos].attributeSelectorType;
21760 if (type === 1) return getAttributeSelector1();else return getAttributeSelector2();
21764 * (1) `[panda=nani]`
21765 * (2) `[panda='nani']`
21766 * (3) `[panda='nani' i]`
21769 function checkAttributeSelector1(i) {
21772 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
21775 if (l = checkSC(i)) i += l;
21777 if (l = checkAttributeName(i)) i += l;else return 0;
21779 if (l = checkSC(i)) i += l;
21781 if (l = checkAttributeMatch(i)) i += l;else return 0;
21783 if (l = checkSC(i)) i += l;
21785 if (l = checkAttributeValue(i)) i += l;else return 0;
21787 if (l = checkSC(i)) i += l;
21789 if (l = checkAttributeFlags(i)) {
21791 if (l = checkSC(i)) i += l;
21794 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
21799 function getAttributeSelector1() {
21800 var type = NodeType.AttributeSelectorType;
21801 var token = tokens[pos];
21802 var line = token.ln;
21803 var column = token.col;
21809 content = content.concat(getSC(), getAttributeName(), getSC(), getAttributeMatch(), getSC(), getAttributeValue(), getSC());
21811 if (checkAttributeFlags(pos)) {
21812 content.push(getAttributeFlags());
21813 content = content.concat(getSC());
21819 var end = getLastPosition(content, line, column, 1);
21820 return newNode(type, content, line, column, end);
21826 function checkAttributeSelector2(i) {
21829 if (tokens[i].type === TokenType.LeftSquareBracket) i++;else return 0;
21832 if (l = checkSC(i)) i += l;
21834 if (l = checkAttributeName(i)) i += l;else return 0;
21836 if (l = checkSC(i)) i += l;
21838 if (tokens[i].type === TokenType.RightSquareBracket) i++;else return 0;
21843 function getAttributeSelector2() {
21844 var type = NodeType.AttributeSelectorType;
21845 var token = tokens[pos];
21846 var line = token.ln;
21847 var column = token.col;
21853 content = content.concat(getSC(), getAttributeName(), getSC());
21858 var end = getLastPosition(content, line, column, 1);
21859 return newNode(type, content, line, column, end);
21862 function checkAttributeName(i) {
21866 if (l = checkNamePrefix(i)) i += l;
21868 if (l = checkIdentOrInterpolation(i)) i += l;else return 0;
21873 function getAttributeName() {
21874 var type = NodeType.AttributeNameType;
21875 var token = tokens[pos];
21876 var line = token.ln;
21877 var column = token.col;
21880 if (checkNamePrefix(pos)) content.push(getNamePrefix());
21881 content = content.concat(getIdentOrInterpolation());
21883 return newNode(type, content, line, column);
21886 function checkAttributeMatch(i) {
21888 if (l = checkAttributeMatch1(i)) tokens[i].attributeMatchType = 1;else if (l = checkAttributeMatch2(i)) tokens[i].attributeMatchType = 2;
21893 function getAttributeMatch() {
21894 var type = tokens[pos].attributeMatchType;
21895 if (type === 1) return getAttributeMatch1();else return getAttributeMatch2();
21898 function checkAttributeMatch1(i) {
21901 var type = tokens[i].type;
21902 if (type === TokenType.Tilde || type === TokenType.VerticalLine || type === TokenType.CircumflexAccent || type === TokenType.DollarSign || type === TokenType.Asterisk) i++;else return 0;
21904 if (tokens[i].type === TokenType.EqualsSign) i++;else return 0;
21909 function getAttributeMatch1() {
21910 var type = NodeType.AttributeMatchType;
21911 var token = tokens[pos];
21912 var line = token.ln;
21913 var column = token.col;
21914 var content = tokens[pos].value + tokens[pos + 1].value;
21917 return newNode(type, content, line, column);
21920 function checkAttributeMatch2(i) {
21921 if (tokens[i].type === TokenType.EqualsSign) return 1;else return 0;
21924 function getAttributeMatch2() {
21925 var type = NodeType.AttributeMatchType;
21926 var token = tokens[pos];
21927 var line = token.ln;
21928 var column = token.col;
21932 return newNode(type, content, line, column);
21935 function checkAttributeValue(i) {
21936 return checkString(i) || checkIdentOrInterpolation(i);
21939 function getAttributeValue() {
21940 var type = NodeType.AttributeValueType;
21941 var token = tokens[pos];
21942 var line = token.ln;
21943 var column = token.col;
21946 if (checkString(pos)) content.push(getString());else content = content.concat(getIdentOrInterpolation());
21948 return newNode(type, content, line, column);
21951 function checkAttributeFlags(i) {
21952 return checkIdentOrInterpolation(i);
21955 function getAttributeFlags() {
21956 var type = NodeType.AttributeFlagsType;
21957 var token = tokens[pos];
21958 var line = token.ln;
21959 var column = token.col;
21960 var content = getIdentOrInterpolation();
21962 return newNode(type, content, line, column);
21965 function checkNamePrefix(i) {
21966 if (i >= tokensLength) return 0;
21969 if (l = checkNamePrefix1(i)) tokens[i].namePrefixType = 1;else if (l = checkNamePrefix2(i)) tokens[i].namePrefixType = 2;
21974 function getNamePrefix() {
21975 var type = tokens[pos].namePrefixType;
21976 if (type === 1) return getNamePrefix1();else return getNamePrefix2();
21981 * (2) `panda<comment>|`
21983 function checkNamePrefix1(i) {
21987 if (l = checkNamespacePrefix(i)) i += l;else return 0;
21989 if (l = checkCommentML(i)) i += l;
21991 if (l = checkNamespaceSeparator(i)) i += l;else return 0;
21996 function getNamePrefix1() {
21997 var type = NodeType.NamePrefixType;
21998 var token = tokens[pos];
21999 var line = token.ln;
22000 var column = token.col;
22003 content.push(getNamespacePrefix());
22005 if (checkCommentML(pos)) content.push(getCommentML());
22007 content.push(getNamespaceSeparator());
22009 return newNode(type, content, line, column);
22015 function checkNamePrefix2(i) {
22016 return checkNamespaceSeparator(i);
22019 function getNamePrefix2() {
22020 var type = NodeType.NamePrefixType;
22021 var token = tokens[pos];
22022 var line = token.ln;
22023 var column = token.col;
22024 var content = [getNamespaceSeparator()];
22026 return newNode(type, content, line, column);
22033 function checkNamespacePrefix(i) {
22034 if (i >= tokensLength) return 0;
22038 if (tokens[i].type === TokenType.Asterisk) return 1;else if (l = checkIdentOrInterpolation(i)) return l;else return 0;
22041 function getNamespacePrefix() {
22042 var type = NodeType.NamespacePrefixType;
22043 var token = tokens[pos];
22044 var line = token.ln;
22045 var column = token.col;
22048 if (token.type === TokenType.Asterisk) {
22049 var asteriskNode = newNode(NodeType.IdentType, '*', line, column);
22050 content.push(asteriskNode);
22052 } else if (checkIdentOrInterpolation(pos)) content = content.concat(getIdentOrInterpolation());
22054 return newNode(type, content, line, column);
22060 function checkNamespaceSeparator(i) {
22061 if (i >= tokensLength) return 0;
22063 if (tokens[i].type !== TokenType.VerticalLine) return 0;
22065 // Return false if `|=` - [attr|=value]
22066 if (tokens[i + 1] && tokens[i + 1].type === TokenType.EqualsSign) return 0;
22071 function getNamespaceSeparator() {
22072 var type = NodeType.NamespaceSeparatorType;
22073 var token = tokens[pos];
22074 var line = token.ln;
22075 var column = token.col;
22079 return newNode(type, content, line, column);
22082 module.exports = function (_tokens, context) {
22084 tokensLength = tokens.length;
22087 return contexts[context]();
22092 /***/ (function(module, exports, __webpack_require__) {
22096 module.exports = function (css, tabSize) {
22097 var TokenType = __webpack_require__(13);
22100 var urlMode = false;
22101 var c = void 0; // Current character
22102 var cn = void 0; // Next character
22108 var Punctuation = {
22109 ' ': TokenType.Space,
22110 '\n': TokenType.Newline,
22111 '\r': TokenType.Newline,
22112 '\t': TokenType.Tab,
22113 '!': TokenType.ExclamationMark,
22114 '"': TokenType.QuotationMark,
22115 '#': TokenType.NumberSign,
22116 '$': TokenType.DollarSign,
22117 '%': TokenType.PercentSign,
22118 '&': TokenType.Ampersand,
22119 '\'': TokenType.Apostrophe,
22120 '(': TokenType.LeftParenthesis,
22121 ')': TokenType.RightParenthesis,
22122 '*': TokenType.Asterisk,
22123 '+': TokenType.PlusSign,
22124 ',': TokenType.Comma,
22125 '-': TokenType.HyphenMinus,
22126 '.': TokenType.FullStop,
22127 '/': TokenType.Solidus,
22128 ':': TokenType.Colon,
22129 ';': TokenType.Semicolon,
22130 '<': TokenType.LessThanSign,
22131 '=': TokenType.EqualsSign,
22132 '==': TokenType.EqualitySign,
22133 '!=': TokenType.InequalitySign,
22134 '>': TokenType.GreaterThanSign,
22135 '?': TokenType.QuestionMark,
22136 '@': TokenType.CommercialAt,
22137 '[': TokenType.LeftSquareBracket,
22138 ']': TokenType.RightSquareBracket,
22139 '^': TokenType.CircumflexAccent,
22140 '_': TokenType.LowLine,
22141 '{': TokenType.LeftCurlyBracket,
22142 '|': TokenType.VerticalLine,
22143 '}': TokenType.RightCurlyBracket,
22144 '~': TokenType.Tilde,
22145 '`': TokenType.Backtick
22149 * Add a token to the token list
22150 * @param {string} type
22151 * @param {string} value
22153 function pushToken(type, value, column) {
22164 * Check if a character is a decimal digit
22165 * @param {string} c Character
22166 * @returns {boolean}
22168 function isDecimalDigit(c) {
22169 return '0123456789'.indexOf(c) >= 0;
22174 * @param {string} css Unparsed part of CSS string
22176 function parseSpaces(css) {
22179 // Read the string until we meet a non-space character:
22180 for (; pos < css.length; pos++) {
22181 if (css.charAt(pos) !== ' ') break;
22184 // Add a substring containing only spaces to tokens:
22185 pushToken(TokenType.Space, css.substring(start, pos--), col);
22186 col += pos - start;
22190 * Parse a string within quotes
22191 * @param {string} css Unparsed part of CSS string
22192 * @param {string} q Quote (either `'` or `"`)
22194 function parseString(css, q) {
22197 // Read the string until we meet a matching quote:
22198 for (pos++; pos < css.length; pos++) {
22199 // Skip escaped quotes:
22200 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) === q) break;
22203 // Add the string (including quotes) to tokens:
22204 var type = q === '"' ? TokenType.StringDQ : TokenType.StringSQ;
22205 pushToken(type, css.substring(start, pos + 1), col);
22206 col += pos - start;
22211 * @param {string} css Unparsed part of CSS string
22213 function parseDecimalNumber(css) {
22216 // Read the string until we meet a character that's not a digit:
22217 for (; pos < css.length; pos++) {
22218 if (!isDecimalDigit(css.charAt(pos))) break;
22221 // Add the number to tokens:
22222 pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);
22223 col += pos - start;
22228 * @param {string} css Unparsed part of CSS string
22230 function parseIdentifier(css) {
22233 // Skip all opening slashes:
22234 while (css.charAt(pos) === '/') {
22236 } // Read the string until we meet a punctuation mark:
22237 for (; pos < css.length; pos++) {
22239 if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) in Punctuation) break;
22242 var ident = css.substring(start, pos--);
22244 // Enter url mode if parsed substring is `url`:
22245 if (!urlMode && ident === 'url' && css.charAt(pos + 1) === '(') {
22249 // Add identifier to tokens:
22250 pushToken(TokenType.Identifier, ident, col);
22251 col += pos - start;
22255 * Parse equality sign
22257 function parseEquality() {
22258 pushToken(TokenType.EqualitySign, '==', col);
22264 * Parse inequality sign
22266 function parseInequality() {
22267 pushToken(TokenType.InequalitySign, '!=', col);
22273 * Parse a multiline comment
22274 * @param {string} css Unparsed part of CSS string
22276 function parseMLComment(css) {
22279 // Read the string until we meet `*/`.
22280 // Since we already know first 2 characters (`/*`), start reading
22282 for (pos += 2; pos < css.length; pos++) {
22283 if (css.charAt(pos) === '*' && css.charAt(pos + 1) === '/') {
22289 // Add full comment (including `/*` and `*/`) to the list of tokens:
22290 var comment = css.substring(start, pos + 1);
22291 pushToken(TokenType.CommentML, comment, col);
22293 var newlines = comment.split('\n');
22294 if (newlines.length > 1) {
22295 ln += newlines.length - 1;
22296 col = newlines[newlines.length - 1].length;
22298 col += pos - start;
22303 * Parse a single line comment
22304 * @param {string} css Unparsed part of CSS string
22306 function parseSLComment(css) {
22309 // Read the string until we meet line break.
22310 // Since we already know first 2 characters (`//`), start reading
22312 for (pos += 2; pos < css.length; pos++) {
22313 if (css.charAt(pos) === '\n' || css.charAt(pos) === '\r') {
22318 // Add comment (including `//` and line break) to the list of tokens:
22319 pushToken(TokenType.CommentSL, css.substring(start, pos--), col);
22320 col += pos - start;
22324 * Convert a CSS string to a list of tokens
22325 * @param {string} css CSS string
22326 * @returns {Array} List of tokens
22329 function getTokens(css) {
22330 // Parse string, character by character:
22331 for (pos = 0; pos < css.length; col++, pos++) {
22332 c = css.charAt(pos);
22333 cn = css.charAt(pos + 1);
22335 // If we meet `/*`, it's a start of a multiline comment.
22336 // Parse following characters as a multiline comment:
22337 if (c === '/' && cn === '*') {
22338 parseMLComment(css);
22341 // If we meet `//` and it is not a part of url:
22342 else if (!urlMode && c === '/' && cn === '/') {
22343 // If we're currently inside a block, treat `//` as a start
22344 // of identifier. Else treat `//` as a start of a single-line
22346 parseSLComment(css);
22349 // If current character is a double or single quote, it's a start
22351 else if (c === '"' || c === "'") {
22352 parseString(css, c);
22355 // If current character is a space:
22356 else if (c === ' ') {
22360 // If current character is `=`, it must be combined with next `=`
22361 else if (c === '=' && cn === '=') {
22362 parseEquality(css);
22365 // If we meet `!=`, this must be inequality
22366 else if (c === '!' && cn === '=') {
22367 parseInequality(css);
22370 // If current character is a punctuation mark:
22371 else if (c in Punctuation) {
22372 // Check for CRLF here or just LF
22373 if (c === '\r' && cn === '\n' || c === '\n') {
22374 // If \r we know the next character is \n due to statement above
22375 // so we push a CRLF token type to the token list and importantly
22376 // skip the next character so as not to double count newlines or
22379 pushToken(TokenType.Newline, '\r\n', col);
22380 pos++; // If CRLF skip the next character and push crlf token
22381 } else if (c === '\n') {
22382 // If just a LF newline and not part of CRLF newline we can just
22383 // push punctuation as usual
22384 pushToken(Punctuation[c], c, col);
22387 ln++; // Go to next line
22388 col = 0; // Reset the column count
22389 } else if (c !== '\r' && c !== '\n') {
22390 // Handle all other punctuation and add to list of tokens
22391 pushToken(Punctuation[c], c, col);
22392 } // Go to next line
22393 if (c === ')') urlMode = false; // Exit url mode
22394 else if (c === '\t' && tabSize > 1) col += tabSize - 1;
22397 // If current character is a decimal digit:
22398 else if (isDecimalDigit(c)) {
22399 parseDecimalNumber(css);
22402 // If current character is anything else:
22404 parseIdentifier(css);
22411 return getTokens(css);
22416 /***/ (function(module, exports, __webpack_require__) {
22420 var Node = __webpack_require__(1);
22421 var NodeTypes = __webpack_require__(15);
22423 module.exports = function () {
22425 type: NodeTypes.StylesheetType,