File Explorer

/var/lang/lib/node_modules/npm/node_modules/postcss-selector-parser/dist

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

parser.js46.1 KB · 1105 lines
"use strict";var __assign = (this && this.__assign) || function () {    __assign = Object.assign || function(t) {        for (var s, i = 1, n = arguments.length; i < n; i++) {            s = arguments[i];            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))                t[p] = s[p];        }        return t;    };    return __assign.apply(this, arguments);};var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    var desc = Object.getOwnPropertyDescriptor(m, k);    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {      desc = { enumerable: true, get: function() { return m[k]; } };    }    Object.defineProperty(o, k2, desc);}) : (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    o[k2] = m[k];}));var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {    Object.defineProperty(o, "default", { enumerable: true, value: v });}) : function(o, v) {    o["default"] = v;});var __importStar = (this && this.__importStar) || (function () {    var ownKeys = function(o) {        ownKeys = Object.getOwnPropertyNames || function (o) {            var ar = [];            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;            return ar;        };        return ownKeys(o);    };    return function (mod) {        if (mod && mod.__esModule) return mod;        var result = {};        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);        __setModuleDefault(result, mod);        return result;    };})();var __read = (this && this.__read) || function (o, n) {    var m = typeof Symbol === "function" && o[Symbol.iterator];    if (!m) return o;    var i = m.call(o), r, ar = [], e;    try {        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);    }    catch (error) { e = { error: error }; }    finally {        try {            if (r && !r.done && (m = i["return"])) m.call(i);        }        finally { if (e) throw e.error; }    }    return ar;};var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {        if (ar || !(i in from)) {            if (!ar) ar = Array.prototype.slice.call(from, 0, i);            ar[i] = from[i];        }    }    return to.concat(ar || Array.prototype.slice.call(from));};var __importDefault = (this && this.__importDefault) || function (mod) {    return (mod && mod.__esModule) ? mod : { "default": mod };};var _a, _b;Object.defineProperty(exports, "__esModule", { value: true });var root_1 = __importDefault(require("./selectors/root"));var selector_1 = __importDefault(require("./selectors/selector"));var className_1 = __importDefault(require("./selectors/className"));var comment_1 = __importDefault(require("./selectors/comment"));var id_1 = __importDefault(require("./selectors/id"));var tag_1 = __importDefault(require("./selectors/tag"));var string_1 = __importDefault(require("./selectors/string"));var pseudo_1 = __importDefault(require("./selectors/pseudo"));var attribute_1 = __importStar(require("./selectors/attribute"));var universal_1 = __importDefault(require("./selectors/universal"));var combinator_1 = __importDefault(require("./selectors/combinator"));var nesting_1 = __importDefault(require("./selectors/nesting"));var sortAscending_1 = __importDefault(require("./sortAscending"));var tokenize_1 = __importStar(require("./tokenize"));var tokens = __importStar(require("./tokenTypes"));var types = __importStar(require("./selectors/types"));var util_1 = require("./util");var WHITESPACE_TOKENS = (_a = {},    _a[tokens.space] = true,    _a[tokens.cr] = true,    _a[tokens.feed] = true,    _a[tokens.newline] = true,    _a[tokens.tab] = true,    _a);var WHITESPACE_EQUIV_TOKENS = __assign(__assign({}, WHITESPACE_TOKENS), (_b = {}, _b[tokens.comment] = true, _b));function tokenStart(token) {    return {        line: token[tokenize_1.FIELDS.START_LINE],        column: token[tokenize_1.FIELDS.START_COL],    };}function tokenEnd(token) {    return {        line: token[tokenize_1.FIELDS.END_LINE],        column: token[tokenize_1.FIELDS.END_COL],    };}function getSource(startLine, startColumn, endLine, endColumn) {    return {        start: {            line: startLine,            column: startColumn,        },        end: {            line: endLine,            column: endColumn,        },    };}function getTokenSource(token) {    return getSource(token[tokenize_1.FIELDS.START_LINE], token[tokenize_1.FIELDS.START_COL], token[tokenize_1.FIELDS.END_LINE], token[tokenize_1.FIELDS.END_COL]);}function getTokenSourceSpan(startToken, endToken) {    if (!startToken) {        return undefined;    }    return getSource(startToken[tokenize_1.FIELDS.START_LINE], startToken[tokenize_1.FIELDS.START_COL], endToken[tokenize_1.FIELDS.END_LINE], endToken[tokenize_1.FIELDS.END_COL]);}function unescapeProp(node, prop) {    var value = node[prop];    if (typeof value !== "string") {        return;    }    if (value.indexOf("\\") !== -1) {        (0, util_1.ensureObject)(node, "raws");        node[prop] = (0, util_1.unesc)(value);        if (node.raws[prop] === undefined) {            node.raws[prop] = value;        }    }    return node;}function indexesOf(array, item) {    var i = -1;    var indexes = [];    while ((i = array.indexOf(item, i + 1)) !== -1) {        indexes.push(i);    }    return indexes;}function uniqs() {    var list = Array.prototype.concat.apply([], arguments);    return list.filter(function (item, i) { return i === list.indexOf(item); });}var Parser = /** @class */ (function () {    function Parser(rule, options) {        if (options === void 0) { options = {}; }        this.rule = rule;        this.options = Object.assign({ lossy: false, safe: false }, options);        this.position = 0;        this.nestingDepth = 0;        this.maxNestingDepth = (0, util_1.resolveMaxNestingDepth)(this.options.maxNestingDepth);        this.css = typeof this.rule === "string" ? this.rule : this.rule.selector;        this.tokens = (0, tokenize_1.default)({            css: this.css,            error: this._errorGenerator(),            safe: this.options.safe,        });        var rootSource = getTokenSourceSpan(this.tokens[0], this.tokens[this.tokens.length - 1]);        this.root = new root_1.default({ source: rootSource });        this.root.errorGenerator = this._errorGenerator();        var selector = new selector_1.default({            source: { start: { line: 1, column: 1 } },            sourceIndex: 0,        });        this.root.append(selector);        this.current = selector;        this.loop();    }    Parser.prototype._errorGenerator = function () {        var _this = this;        return function (message, errorOptions) {            if (typeof _this.rule === "string") {                return new Error(message);            }            return _this.rule.error(message, errorOptions);        };    };    Parser.prototype.attribute = function () {        var attr = [];        var startingToken = this.currToken;        this.position++;        while (this.position < this.tokens.length &&            this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) {            attr.push(this.currToken);            this.position++;        }        if (this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) {            return this.expected("closing square bracket", this.currToken[tokenize_1.FIELDS.START_POS]);        }        var len = attr.length;        var node = {            source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]),            sourceIndex: startingToken[tokenize_1.FIELDS.START_POS],        };        if (len === 1 && !~[tokens.word].indexOf(attr[0][tokenize_1.FIELDS.TYPE])) {            return this.expected("attribute", attr[0][tokenize_1.FIELDS.START_POS]);        }        var pos = 0;        var spaceBefore = "";        var commentBefore = "";        var lastAdded = null;        var spaceAfterMeaningfulToken = false;        while (pos < len) {            var token = attr[pos];            var content = this.content(token);            var next = attr[pos + 1];            switch (token[tokenize_1.FIELDS.TYPE]) {                case tokens.space:                    // if (                    //     len === 1 ||                    //     pos === 0 && this.content(next) === '|'                    // ) {                    //     return this.expected('attribute', token[TOKEN.START_POS], content);                    // }                    spaceAfterMeaningfulToken = true;                    if (this.options.lossy) {                        break;                    }                    if (lastAdded) {                        (0, util_1.ensureObject)(node, "spaces", lastAdded);                        var prevContent = node.spaces[lastAdded].after || "";                        node.spaces[lastAdded].after = prevContent + content;                        var existingComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") || null;                        if (existingComment) {                            node.raws.spaces[lastAdded].after = existingComment + content;                        }                    }                    else {                        spaceBefore = spaceBefore + content;                        commentBefore = commentBefore + content;                    }                    break;                case tokens.asterisk:                    if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {                        node.operator = content;                        lastAdded = "operator";                    }                    else if ((!node.namespace || (lastAdded === "namespace" && !spaceAfterMeaningfulToken)) &&                        next) {                        if (spaceBefore) {                            (0, util_1.ensureObject)(node, "spaces", "attribute");                            node.spaces.attribute.before = spaceBefore;                            spaceBefore = "";                        }                        if (commentBefore) {                            (0, util_1.ensureObject)(node, "raws", "spaces", "attribute");                            node.raws.spaces.attribute.before = spaceBefore;                            commentBefore = "";                        }                        node.namespace = (node.namespace || "") + content;                        var rawValue = (0, util_1.getProp)(node, "raws", "namespace") || null;                        if (rawValue) {                            node.raws.namespace += content;                        }                        lastAdded = "namespace";                    }                    spaceAfterMeaningfulToken = false;                    break;                case tokens.dollar:                    if (lastAdded === "value") {                        var oldRawValue = (0, util_1.getProp)(node, "raws", "value");                        node.value += "$";                        if (oldRawValue) {                            node.raws.value = oldRawValue + "$";                        }                        break;                    }                // Falls through                case tokens.caret:                    if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {                        node.operator = content;                        lastAdded = "operator";                    }                    spaceAfterMeaningfulToken = false;                    break;                case tokens.combinator:                    if (content === "~" && next[tokenize_1.FIELDS.TYPE] === tokens.equals) {                        node.operator = content;                        lastAdded = "operator";                    }                    if (content !== "|") {                        spaceAfterMeaningfulToken = false;                        break;                    }                    if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) {                        node.operator = content;                        lastAdded = "operator";                    }                    else if (!node.namespace && !node.attribute) {                        node.namespace = true;                    }                    spaceAfterMeaningfulToken = false;                    break;                case tokens.word:                    if (next &&                        this.content(next) === "|" &&                        attr[pos + 2] &&                        attr[pos + 2][tokenize_1.FIELDS.TYPE] !== tokens.equals && // this look-ahead probably fails with comment nodes involved.                        !node.operator &&                        !node.namespace) {                        node.namespace = content;                        lastAdded = "namespace";                    }                    else if (!node.attribute || (lastAdded === "attribute" && !spaceAfterMeaningfulToken)) {                        if (spaceBefore) {                            (0, util_1.ensureObject)(node, "spaces", "attribute");                            node.spaces.attribute.before = spaceBefore;                            spaceBefore = "";                        }                        if (commentBefore) {                            (0, util_1.ensureObject)(node, "raws", "spaces", "attribute");                            node.raws.spaces.attribute.before = commentBefore;                            commentBefore = "";                        }                        node.attribute = (node.attribute || "") + content;                        var rawValue = (0, util_1.getProp)(node, "raws", "attribute") || null;                        if (rawValue) {                            node.raws.attribute += content;                        }                        lastAdded = "attribute";                    }                    else if ((!node.value && node.value !== "") ||                        (lastAdded === "value" && !(spaceAfterMeaningfulToken || node.quoteMark))) {                        var unescaped_1 = (0, util_1.unesc)(content);                        var oldRawValue = (0, util_1.getProp)(node, "raws", "value") || "";                        var oldValue = node.value || "";                        node.value = oldValue + unescaped_1;                        node.quoteMark = null;                        if (unescaped_1 !== content || oldRawValue) {                            (0, util_1.ensureObject)(node, "raws");                            node.raws.value = (oldRawValue || oldValue) + content;                        }                        lastAdded = "value";                    }                    else {                        var insensitive = content === "i" || content === "I";                        if ((node.value || node.value === "") &&                            (node.quoteMark || spaceAfterMeaningfulToken)) {                            node.insensitive = insensitive;                            if (!insensitive || content === "I") {                                (0, util_1.ensureObject)(node, "raws");                                node.raws.insensitiveFlag = content;                            }                            lastAdded = "insensitive";                            if (spaceBefore) {                                (0, util_1.ensureObject)(node, "spaces", "insensitive");                                node.spaces.insensitive.before = spaceBefore;                                spaceBefore = "";                            }                            if (commentBefore) {                                (0, util_1.ensureObject)(node, "raws", "spaces", "insensitive");                                node.raws.spaces.insensitive.before = commentBefore;                                commentBefore = "";                            }                        }                        else if (node.value || node.value === "") {                            lastAdded = "value";                            node.value += content;                            if (node.raws.value) {                                node.raws.value += content;                            }                        }                    }                    spaceAfterMeaningfulToken = false;                    break;                case tokens.str:                    if (!node.attribute || !node.operator) {                        return this.error("Expected an attribute followed by an operator preceding the string.", {                            index: token[tokenize_1.FIELDS.START_POS],                        });                    }                    var _a = (0, attribute_1.unescapeValue)(content), unescaped = _a.unescaped, quoteMark = _a.quoteMark;                    node.value = unescaped;                    node.quoteMark = quoteMark;                    lastAdded = "value";                    (0, util_1.ensureObject)(node, "raws");                    node.raws.value = content;                    spaceAfterMeaningfulToken = false;                    break;                case tokens.equals:                    if (!node.attribute) {                        return this.expected("attribute", token[tokenize_1.FIELDS.START_POS], content);                    }                    if (node.value) {                        return this.error('Unexpected "=" found; an operator was already defined.', {                            index: token[tokenize_1.FIELDS.START_POS],                        });                    }                    node.operator = node.operator ? node.operator + content : content;                    lastAdded = "operator";                    spaceAfterMeaningfulToken = false;                    break;                case tokens.comment:                    if (lastAdded) {                        if (spaceAfterMeaningfulToken ||                            (next && next[tokenize_1.FIELDS.TYPE] === tokens.space) ||                            lastAdded === "insensitive") {                            var lastComment = (0, util_1.getProp)(node, "spaces", lastAdded, "after") || "";                            var rawLastComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") || lastComment;                            (0, util_1.ensureObject)(node, "raws", "spaces", lastAdded);                            node.raws.spaces[lastAdded].after = rawLastComment + content;                        }                        else {                            var lastValue = node[lastAdded] || "";                            var rawLastValue = (0, util_1.getProp)(node, "raws", lastAdded) || lastValue;                            (0, util_1.ensureObject)(node, "raws");                            node.raws[lastAdded] = rawLastValue + content;                        }                    }                    else {                        commentBefore = commentBefore + content;                    }                    break;                default:                    return this.error("Unexpected \"".concat(content, "\" found."), { index: token[tokenize_1.FIELDS.START_POS] });            }            pos++;        }        unescapeProp(node, "attribute");        unescapeProp(node, "namespace");        this.newNode(new attribute_1.default(node));        this.position++;    };    /**     * return a node containing meaningless garbage up to (but not including) the specified token position.     * if the token position is negative, all remaining tokens are consumed.     *     * This returns an array containing a single string node if all whitespace,     * otherwise an array of comment nodes with space before and after.     *     * These tokens are not added to the current selector, the caller can add them or use them to amend     * a previous node's space metadata.     *     * In lossy mode, this returns only comments.     */    Parser.prototype.parseWhitespaceEquivalentTokens = function (stopPosition) {        if (stopPosition < 0) {            stopPosition = this.tokens.length;        }        var startPosition = this.position;        var nodes = [];        var space = "";        var lastComment = undefined;        do {            if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) {                if (!this.options.lossy) {                    space += this.content();                }            }            else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.comment) {                var spaces = {};                if (space) {                    spaces.before = space;                    space = "";                }                lastComment = new comment_1.default({                    value: this.content(),                    source: getTokenSource(this.currToken),                    sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],                    spaces: spaces,                });                nodes.push(lastComment);            }        } while (++this.position < stopPosition);        if (space) {            if (lastComment) {                lastComment.spaces.after = space;            }            else if (!this.options.lossy) {                var firstToken = this.tokens[startPosition];                var lastToken = this.tokens[this.position - 1];                nodes.push(new string_1.default({                    value: "",                    source: getSource(firstToken[tokenize_1.FIELDS.START_LINE], firstToken[tokenize_1.FIELDS.START_COL], lastToken[tokenize_1.FIELDS.END_LINE], lastToken[tokenize_1.FIELDS.END_COL]),                    sourceIndex: firstToken[tokenize_1.FIELDS.START_POS],                    spaces: { before: space, after: "" },                }));            }        }        return nodes;    };    /**     *     * @param {*} nodes     */    Parser.prototype.convertWhitespaceNodesToSpace = function (nodes, requiredSpace) {        var _this = this;        if (requiredSpace === void 0) { requiredSpace = false; }        var space = "";        var rawSpace = "";        nodes.forEach(function (n) {            var spaceBefore = _this.lossySpace(n.spaces.before, requiredSpace);            var rawSpaceBefore = _this.lossySpace(n.rawSpaceBefore, requiredSpace);            space +=                spaceBefore + _this.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0);            rawSpace +=                spaceBefore +                    n.value +                    _this.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0);        });        if (rawSpace === space) {            rawSpace = undefined;        }        var result = { space: space, rawSpace: rawSpace };        return result;    };    Parser.prototype.isNamedCombinator = function (position) {        if (position === void 0) { position = this.position; }        return (this.tokens[position + 0] &&            this.tokens[position + 0][tokenize_1.FIELDS.TYPE] === tokens.slash &&            this.tokens[position + 1] &&            this.tokens[position + 1][tokenize_1.FIELDS.TYPE] === tokens.word &&            this.tokens[position + 2] &&            this.tokens[position + 2][tokenize_1.FIELDS.TYPE] === tokens.slash);    };    Parser.prototype.namedCombinator = function () {        if (this.isNamedCombinator()) {            var nameRaw = this.content(this.tokens[this.position + 1]);            var name = (0, util_1.unesc)(nameRaw).toLowerCase();            var raws = {};            if (name !== nameRaw) {                raws.value = "/".concat(nameRaw, "/");            }            var node = new combinator_1.default({                value: "/".concat(name, "/"),                source: getSource(this.currToken[tokenize_1.FIELDS.START_LINE], this.currToken[tokenize_1.FIELDS.START_COL], this.tokens[this.position + 2][tokenize_1.FIELDS.END_LINE], this.tokens[this.position + 2][tokenize_1.FIELDS.END_COL]),                sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],                raws: raws,            });            this.position = this.position + 3;            return node;        }        else {            this.unexpected();        }    };    Parser.prototype.combinator = function () {        var _this = this;        if (this.content() === "|") {            return this.namespace();        }        // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector.        var nextSigTokenPos = this.locateNextMeaningfulToken(this.position);        if (nextSigTokenPos < 0 ||            this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.comma ||            this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {            var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos);            if (nodes.length > 0) {                var last = this.current.last;                if (last) {                    var _a = this.convertWhitespaceNodesToSpace(nodes), space = _a.space, rawSpace = _a.rawSpace;                    if (rawSpace !== undefined) {                        last.rawSpaceAfter += rawSpace;                    }                    last.spaces.after += space;                }                else {                    nodes.forEach(function (n) { return _this.newNode(n); });                }            }            return;        }        var firstToken = this.currToken;        var spaceOrDescendantSelectorNodes = undefined;        if (nextSigTokenPos > this.position) {            spaceOrDescendantSelectorNodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos);        }        var node;        if (this.isNamedCombinator()) {            node = this.namedCombinator();        }        else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.combinator) {            node = new combinator_1.default({                value: this.content(),                source: getTokenSource(this.currToken),                sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS],            });            this.position++;        }        else if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) {            // pass        }        else if (!spaceOrDescendantSelectorNodes) {            this.unexpected();        }        if (node) {            if (spaceOrDescendantSelectorNodes) {                var _b = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes), space = _b.space, rawSpace = _b.rawSpace;                node.spaces.before = space;                node.rawSpaceBefore = rawSpace;            }        }        else {            // descendant combinator            var _c = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true), space = _c.space, rawSpace = _c.rawSpace;            if (!rawSpace) {                rawSpace = space;            }            var spaces = {};            var raws = { spaces: {} };            if (space.endsWith(" ") && rawSpace.endsWith(" ")) {                spaces.before = space.slice(0, space.length - 1);                raws.spaces.before = rawSpace.slice(0, rawSpace.length - 1);            }            else if (space[0] === " " && rawSpace[0] === " ") {                spaces.after = space.slice(1);                raws.spaces.after = rawSpace.slice(1);            }            else {                raws.value = rawSpace;            }            node = new combinator_1.default({                value: " ",                source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]),                sourceIndex: firstToken[tokenize_1.FIELDS.START_POS],                spaces: spaces,                raws: raws,            });        }        if (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.space) {            node.spaces.after = this.optionalSpace(this.content());            this.position++;        }        return this.newNode(node);    };    Parser.prototype.comma = function () {        if (this.position === this.tokens.length - 1) {            this.root.trailingComma = true;            this.position++;            return;        }        this.current._inferEndPosition();        var selector = new selector_1.default({            source: {                start: tokenStart(this.tokens[this.position + 1]),            },            sourceIndex: this.tokens[this.position + 1][tokenize_1.FIELDS.START_POS],        });        this.current.parent.append(selector);        this.current = selector;        this.position++;    };    Parser.prototype.comment = function () {        var current = this.currToken;        this.newNode(new comment_1.default({            value: this.content(),            source: getTokenSource(current),            sourceIndex: current[tokenize_1.FIELDS.START_POS],        }));        this.position++;    };    Parser.prototype.error = function (message, opts) {        throw this.root.error(message, opts);    };    Parser.prototype.missingBackslash = function () {        return this.error("Expected a backslash preceding the semicolon.", {            index: this.currToken[tokenize_1.FIELDS.START_POS],        });    };    Parser.prototype.missingParenthesis = function () {        return this.expected("opening parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]);    };    Parser.prototype.missingSquareBracket = function () {        return this.expected("opening square bracket", this.currToken[tokenize_1.FIELDS.START_POS]);    };    Parser.prototype.unexpected = function () {        return this.error("Unexpected '".concat(this.content(), "'. Escaping special characters with \\ may help."), this.currToken[tokenize_1.FIELDS.START_POS]);    };    Parser.prototype.unexpectedPipe = function () {        return this.error("Unexpected '|'.", this.currToken[tokenize_1.FIELDS.START_POS]);    };    Parser.prototype.namespace = function () {        var before = (this.prevToken && this.content(this.prevToken)) || true;        if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.word) {            this.position++;            return this.word(before);        }        else if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.asterisk) {            this.position++;            return this.universal(before);        }        this.unexpectedPipe();    };    Parser.prototype.nesting = function () {        if (this.nextToken) {            var nextContent = this.content(this.nextToken);            if (nextContent === "|") {                this.position++;                return;            }        }        var current = this.currToken;        this.newNode(new nesting_1.default({            value: this.content(),            source: getTokenSource(current),            sourceIndex: current[tokenize_1.FIELDS.START_POS],        }));        this.position++;    };    Parser.prototype.parentheses = function () {        var last = this.current.last;        var unbalanced = 1;        this.position++;        if (last && last.type === types.PSEUDO) {            var selector = new selector_1.default({                source: { start: tokenStart(this.tokens[this.position]) },                sourceIndex: this.tokens[this.position][tokenize_1.FIELDS.START_POS],            });            var cache = this.current;            last.append(selector);            this.current = selector;            // Track nesting depth so deeply nested pseudo selectors raise a            // catchable error instead of overflowing the call stack. The            // counter is restored in `finally` so the parser is never left in            // an inconsistent state, even on the error path.            this.nestingDepth++;            try {                if (this.nestingDepth > this.maxNestingDepth) {                    this.error("Cannot parse selector: nesting depth exceeds the maximum of ".concat(this.maxNestingDepth, "."), { index: this.currToken[tokenize_1.FIELDS.START_POS] });                }                while (this.position < this.tokens.length && unbalanced) {                    if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {                        unbalanced++;                    }                    if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {                        unbalanced--;                    }                    if (unbalanced) {                        this.parse();                    }                    else {                        this.current.source.end = tokenEnd(this.currToken);                        this.current.parent.source.end = tokenEnd(this.currToken);                        this.position++;                    }                }            }            finally {                this.nestingDepth--;            }            this.current = cache;        }        else {            // I think this case should be an error. It's used to implement a basic parse of media queries            // but I don't think it's a good idea.            var parenStart = this.currToken;            var parenValue = "(";            var parenEnd = void 0;            while (this.position < this.tokens.length && unbalanced) {                if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {                    unbalanced++;                }                if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {                    unbalanced--;                }                parenEnd = this.currToken;                parenValue += this.parseParenthesisToken(this.currToken);                this.position++;            }            if (last) {                last.appendToPropertyAndEscape("value", parenValue, parenValue);            }            else {                this.newNode(new string_1.default({                    value: parenValue,                    source: getSource(parenStart[tokenize_1.FIELDS.START_LINE], parenStart[tokenize_1.FIELDS.START_COL], parenEnd[tokenize_1.FIELDS.END_LINE], parenEnd[tokenize_1.FIELDS.END_COL]),                    sourceIndex: parenStart[tokenize_1.FIELDS.START_POS],                }));            }        }        if (unbalanced) {            return this.expected("closing parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]);        }    };    Parser.prototype.pseudo = function () {        var _this = this;        var pseudoStr = "";        var startingToken = this.currToken;        while (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.colon) {            pseudoStr += this.content();            this.position++;        }        if (!this.currToken) {            return this.expected(["pseudo-class", "pseudo-element"], this.position - 1);        }        if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.word) {            this.splitWord(false, function (first, length) {                pseudoStr += first;                _this.newNode(new pseudo_1.default({                    value: pseudoStr,                    source: getTokenSourceSpan(startingToken, _this.currToken),                    sourceIndex: startingToken[tokenize_1.FIELDS.START_POS],                }));                if (length > 1 && _this.nextToken && _this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) {                    _this.error("Misplaced parenthesis.", {                        index: _this.nextToken[tokenize_1.FIELDS.START_POS],                    });                }            });        }        else {            return this.expected(["pseudo-class", "pseudo-element"], this.currToken[tokenize_1.FIELDS.START_POS]);        }    };    Parser.prototype.space = function () {        var content = this.content();        // Handle space before and after the selector        if (this.position === 0 ||            this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.comma ||            this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis ||            this.current.nodes.every(function (node) { return node.type === "comment"; })) {            this.spaces = this.optionalSpace(content);            this.position++;        }        else if (this.position === this.tokens.length - 1 ||            this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.comma ||            this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) {            this.current.last.spaces.after = this.optionalSpace(content);            this.position++;        }        else {            this.combinator();        }    };    Parser.prototype.string = function () {        var current = this.currToken;        this.newNode(new string_1.default({            value: this.content(),            source: getTokenSource(current),            sourceIndex: current[tokenize_1.FIELDS.START_POS],        }));        this.position++;    };    Parser.prototype.universal = function (namespace) {        var nextToken = this.nextToken;        if (nextToken && this.content(nextToken) === "|") {            this.position++;            return this.namespace();        }        var current = this.currToken;        this.newNode(new universal_1.default({            value: this.content(),            source: getTokenSource(current),            sourceIndex: current[tokenize_1.FIELDS.START_POS],        }), namespace);        this.position++;    };    Parser.prototype.splitWord = function (namespace, firstCallback) {        var _this = this;        var nextToken = this.nextToken;        var word = this.content();        while (nextToken &&            ~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[tokenize_1.FIELDS.TYPE])) {            this.position++;            var current = this.content();            word += current;            if (current.lastIndexOf("\\") === current.length - 1) {                var next = this.nextToken;                if (next && next[tokenize_1.FIELDS.TYPE] === tokens.space) {                    word += this.requiredSpace(this.content(next));                    this.position++;                }            }            nextToken = this.nextToken;        }        var hasClass = indexesOf(word, ".").filter(function (i) {            // Allow escaped dot within class name            var escapedDot = word[i - 1] === "\\";            // Allow decimal numbers percent in @keyframes            var isKeyframesPercent = /^\d+\.\d+%$/.test(word);            return !escapedDot && !isKeyframesPercent;        });        var hasId = indexesOf(word, "#").filter(function (i) { return word[i - 1] !== "\\"; });        // Eliminate Sass interpolations from the list of id indexes        var interpolations = indexesOf(word, "#{");        if (interpolations.length) {            hasId = hasId.filter(function (hashIndex) { return !~interpolations.indexOf(hashIndex); });        }        var indices = (0, sortAscending_1.default)(uniqs(__spreadArray(__spreadArray([0], __read(hasClass), false), __read(hasId), false)));        indices.forEach(function (ind, i) {            var index = indices[i + 1] || word.length;            var value = word.slice(ind, index);            if (i === 0 && firstCallback) {                return firstCallback.call(_this, value, indices.length);            }            var node;            var current = _this.currToken;            var sourceIndex = current[tokenize_1.FIELDS.START_POS] + indices[i];            var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1));            if (~hasClass.indexOf(ind)) {                var classNameOpts = {                    value: value.slice(1),                    source: source,                    sourceIndex: sourceIndex,                };                node = new className_1.default(unescapeProp(classNameOpts, "value"));            }            else if (~hasId.indexOf(ind)) {                var idOpts = {                    value: value.slice(1),                    source: source,                    sourceIndex: sourceIndex,                };                node = new id_1.default(unescapeProp(idOpts, "value"));            }            else {                var tagOpts = {                    value: value,                    source: source,                    sourceIndex: sourceIndex,                };                unescapeProp(tagOpts, "value");                node = new tag_1.default(tagOpts);            }            _this.newNode(node, namespace);            // Ensure that the namespace is used only once            namespace = null;        });        this.position++;    };    Parser.prototype.word = function (namespace) {        var nextToken = this.nextToken;        if (nextToken && this.content(nextToken) === "|") {            this.position++;            return this.namespace();        }        return this.splitWord(namespace);    };    Parser.prototype.loop = function () {        while (this.position < this.tokens.length) {            this.parse(true);        }        this.current._inferEndPosition();        return this.root;    };    Parser.prototype.parse = function (throwOnParenthesis) {        switch (this.currToken[tokenize_1.FIELDS.TYPE]) {            case tokens.space:                this.space();                break;            case tokens.comment:                this.comment();                break;            case tokens.openParenthesis:                this.parentheses();                break;            case tokens.closeParenthesis:                if (throwOnParenthesis) {                    this.missingParenthesis();                }                break;            case tokens.openSquare:                this.attribute();                break;            case tokens.dollar:            case tokens.caret:            case tokens.equals:            case tokens.word:                this.word();                break;            case tokens.colon:                this.pseudo();                break;            case tokens.comma:                this.comma();                break;            case tokens.asterisk:                this.universal();                break;            case tokens.ampersand:                this.nesting();                break;            case tokens.slash:            case tokens.combinator:                this.combinator();                break;            case tokens.str:                this.string();                break;            // These cases throw; no break needed.            case tokens.closeSquare:                this.missingSquareBracket();            case tokens.semicolon:                this.missingBackslash();            default:                this.unexpected();        }    };    /**     * Helpers     */    Parser.prototype.expected = function (description, index, found) {        if (Array.isArray(description)) {            var last = description.pop();            description = "".concat(description.join(", "), " or ").concat(last);        }        var an = /^[aeiou]/.test(description[0]) ? "an" : "a";        if (!found) {            return this.error("Expected ".concat(an, " ").concat(description, "."), { index: index });        }        return this.error("Expected ".concat(an, " ").concat(description, ", found \"").concat(found, "\" instead."), { index: index });    };    Parser.prototype.requiredSpace = function (space) {        return this.options.lossy ? " " : space;    };    Parser.prototype.optionalSpace = function (space) {        return this.options.lossy ? "" : space;    };    Parser.prototype.lossySpace = function (space, required) {        if (this.options.lossy) {            return required ? " " : "";        }        else {            return space;        }    };    Parser.prototype.parseParenthesisToken = function (token) {        var content = this.content(token);        if (token[tokenize_1.FIELDS.TYPE] === tokens.space) {            return this.requiredSpace(content);        }        else {            return content;        }    };    Parser.prototype.newNode = function (node, namespace) {        if (namespace) {            if (/^ +$/.test(namespace)) {                if (!this.options.lossy) {                    this.spaces = (this.spaces || "") + namespace;                }                namespace = true;            }            node.namespace = namespace;            unescapeProp(node, "namespace");        }        if (this.spaces) {            node.spaces.before = this.spaces;            this.spaces = "";        }        return this.current.append(node);    };    Parser.prototype.content = function (token) {        if (token === void 0) { token = this.currToken; }        return this.css.slice(token[tokenize_1.FIELDS.START_POS], token[tokenize_1.FIELDS.END_POS]);    };    Object.defineProperty(Parser.prototype, "currToken", {        get: function () {            return this.tokens[this.position];        },        enumerable: false,        configurable: true    });    Object.defineProperty(Parser.prototype, "nextToken", {        get: function () {            return this.tokens[this.position + 1];        },        enumerable: false,        configurable: true    });    Object.defineProperty(Parser.prototype, "prevToken", {        get: function () {            return this.tokens[this.position - 1];        },        enumerable: false,        configurable: true    });    /**     * returns the index of the next non-whitespace, non-comment token.     * returns -1 if no meaningful token is found.     */    Parser.prototype.locateNextMeaningfulToken = function (startPosition) {        if (startPosition === void 0) { startPosition = this.position + 1; }        var searchPosition = startPosition;        while (searchPosition < this.tokens.length) {            if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][tokenize_1.FIELDS.TYPE]]) {                searchPosition++;                continue;            }            else {                return searchPosition;            }        }        return -1;    };    return Parser;}());exports.default = Parser;//# sourceMappingURL=parser.js.map