| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 | "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.parse = exports.isTraversal = void 0;var types_1 = require("./types");var reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;var actionTypes = new Map([    [126 /* Tilde */, types_1.AttributeAction.Element],    [94 /* Circumflex */, types_1.AttributeAction.Start],    [36 /* Dollar */, types_1.AttributeAction.End],    [42 /* Asterisk */, types_1.AttributeAction.Any],    [33 /* ExclamationMark */, types_1.AttributeAction.Not],    [124 /* Pipe */, types_1.AttributeAction.Hyphen],]);// Pseudos, whose data property is parsed as well.var unpackPseudos = new Set([    "has",    "not",    "matches",    "is",    "where",    "host",    "host-context",]);/** * Checks whether a specific selector is a traversal. * This is useful eg. in swapping the order of elements that * are not traversals. * * @param selector Selector to check. */function isTraversal(selector) {    switch (selector.type) {        case types_1.SelectorType.Adjacent:        case types_1.SelectorType.Child:        case types_1.SelectorType.Descendant:        case types_1.SelectorType.Parent:        case types_1.SelectorType.Sibling:        case types_1.SelectorType.ColumnCombinator:            return true;        default:            return false;    }}exports.isTraversal = isTraversal;var stripQuotesFromPseudos = new Set(["contains", "icontains"]);// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152function funescape(_, escaped, escapedWhitespace) {    var high = parseInt(escaped, 16) - 0x10000;    // NaN means non-codepoint    return high !== high || escapedWhitespace        ? escaped        : high < 0            ? // BMP codepoint                String.fromCharCode(high + 0x10000)            : // Supplemental Plane codepoint (surrogate pair)                String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);}function unescapeCSS(str) {    return str.replace(reEscape, funescape);}function isQuote(c) {    return c === 39 /* SingleQuote */ || c === 34 /* DoubleQuote */;}function isWhitespace(c) {    return (c === 32 /* Space */ ||        c === 9 /* Tab */ ||        c === 10 /* NewLine */ ||        c === 12 /* FormFeed */ ||        c === 13 /* CarriageReturn */);}/** * Parses `selector`, optionally with the passed `options`. * * @param selector Selector to parse. * @param options Options for parsing. * @returns Returns a two-dimensional array. * The first dimension represents selectors separated by commas (eg. `sub1, sub2`), * the second contains the relevant tokens for that selector. */function parse(selector) {    var subselects = [];    var endIndex = parseSelector(subselects, "".concat(selector), 0);    if (endIndex < selector.length) {        throw new Error("Unmatched selector: ".concat(selector.slice(endIndex)));    }    return subselects;}exports.parse = parse;function parseSelector(subselects, selector, selectorIndex) {    var tokens = [];    function getName(offset) {        var match = selector.slice(selectorIndex + offset).match(reName);        if (!match) {            throw new Error("Expected name, found ".concat(selector.slice(selectorIndex)));        }        var name = match[0];        selectorIndex += offset + name.length;        return unescapeCSS(name);    }    function stripWhitespace(offset) {        selectorIndex += offset;        while (selectorIndex < selector.length &&            isWhitespace(selector.charCodeAt(selectorIndex))) {            selectorIndex++;        }    }    function readValueWithParenthesis() {        selectorIndex += 1;        var start = selectorIndex;        var counter = 1;        for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {            if (selector.charCodeAt(selectorIndex) ===                40 /* LeftParenthesis */ &&                !isEscaped(selectorIndex)) {                counter++;            }            else if (selector.charCodeAt(selectorIndex) ===                41 /* RightParenthesis */ &&                !isEscaped(selectorIndex)) {                counter--;            }        }        if (counter) {            throw new Error("Parenthesis not matched");        }        return unescapeCSS(selector.slice(start, selectorIndex - 1));    }    function isEscaped(pos) {        var slashCount = 0;        while (selector.charCodeAt(--pos) === 92 /* BackSlash */)            slashCount++;        return (slashCount & 1) === 1;    }    function ensureNotTraversal() {        if (tokens.length > 0 && isTraversal(tokens[tokens.length - 1])) {            throw new Error("Did not expect successive traversals.");        }    }    function addTraversal(type) {        if (tokens.length > 0 &&            tokens[tokens.length - 1].type === types_1.SelectorType.Descendant) {            tokens[tokens.length - 1].type = type;            return;        }        ensureNotTraversal();        tokens.push({ type: type });    }    function addSpecialAttribute(name, action) {        tokens.push({            type: types_1.SelectorType.Attribute,            name: name,            action: action,            value: getName(1),            namespace: null,            ignoreCase: "quirks",        });    }    /**     * We have finished parsing the current part of the selector.     *     * Remove descendant tokens at the end if they exist,     * and return the last index, so that parsing can be     * picked up from here.     */    function finalizeSubselector() {        if (tokens.length &&            tokens[tokens.length - 1].type === types_1.SelectorType.Descendant) {            tokens.pop();        }        if (tokens.length === 0) {            throw new Error("Empty sub-selector");        }        subselects.push(tokens);    }    stripWhitespace(0);    if (selector.length === selectorIndex) {        return selectorIndex;    }    loop: while (selectorIndex < selector.length) {        var firstChar = selector.charCodeAt(selectorIndex);        switch (firstChar) {            // Whitespace            case 32 /* Space */:            case 9 /* Tab */:            case 10 /* NewLine */:            case 12 /* FormFeed */:            case 13 /* CarriageReturn */: {                if (tokens.length === 0 ||                    tokens[0].type !== types_1.SelectorType.Descendant) {                    ensureNotTraversal();                    tokens.push({ type: types_1.SelectorType.Descendant });                }                stripWhitespace(1);                break;            }            // Traversals            case 62 /* GreaterThan */: {                addTraversal(types_1.SelectorType.Child);                stripWhitespace(1);                break;            }            case 60 /* LessThan */: {                addTraversal(types_1.SelectorType.Parent);                stripWhitespace(1);                break;            }            case 126 /* Tilde */: {                addTraversal(types_1.SelectorType.Sibling);                stripWhitespace(1);                break;            }            case 43 /* Plus */: {                addTraversal(types_1.SelectorType.Adjacent);                stripWhitespace(1);                break;            }            // Special attribute selectors: .class, #id            case 46 /* Period */: {                addSpecialAttribute("class", types_1.AttributeAction.Element);                break;            }            case 35 /* Hash */: {                addSpecialAttribute("id", types_1.AttributeAction.Equals);                break;            }            case 91 /* LeftSquareBracket */: {                stripWhitespace(1);                // Determine attribute name and namespace                var name_1 = void 0;                var namespace = null;                if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */) {                    // Equivalent to no namespace                    name_1 = getName(1);                }                else if (selector.startsWith("*|", selectorIndex)) {                    namespace = "*";                    name_1 = getName(2);                }                else {                    name_1 = getName(0);                    if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&                        selector.charCodeAt(selectorIndex + 1) !==                            61 /* Equal */) {                        namespace = name_1;                        name_1 = getName(1);                    }                }                stripWhitespace(0);                // Determine comparison operation                var action = types_1.AttributeAction.Exists;                var possibleAction = actionTypes.get(selector.charCodeAt(selectorIndex));                if (possibleAction) {                    action = possibleAction;                    if (selector.charCodeAt(selectorIndex + 1) !==                        61 /* Equal */) {                        throw new Error("Expected `=`");                    }                    stripWhitespace(2);                }                else if (selector.charCodeAt(selectorIndex) === 61 /* Equal */) {                    action = types_1.AttributeAction.Equals;                    stripWhitespace(1);                }                // Determine value                var value = "";                var ignoreCase = null;                if (action !== "exists") {                    if (isQuote(selector.charCodeAt(selectorIndex))) {                        var quote = selector.charCodeAt(selectorIndex);                        var sectionEnd = selectorIndex + 1;                        while (sectionEnd < selector.length &&                            (selector.charCodeAt(sectionEnd) !== quote ||                                isEscaped(sectionEnd))) {                            sectionEnd += 1;                        }                        if (selector.charCodeAt(sectionEnd) !== quote) {                            throw new Error("Attribute value didn't end");                        }                        value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));                        selectorIndex = sectionEnd + 1;                    }                    else {                        var valueStart = selectorIndex;                        while (selectorIndex < selector.length &&                            ((!isWhitespace(selector.charCodeAt(selectorIndex)) &&                                selector.charCodeAt(selectorIndex) !==                                    93 /* RightSquareBracket */) ||                                isEscaped(selectorIndex))) {                            selectorIndex += 1;                        }                        value = unescapeCSS(selector.slice(valueStart, selectorIndex));                    }                    stripWhitespace(0);                    // See if we have a force ignore flag                    var forceIgnore = selector.charCodeAt(selectorIndex) | 0x20;                    // If the forceIgnore flag is set (either `i` or `s`), use that value                    if (forceIgnore === 115 /* LowerS */) {                        ignoreCase = false;                        stripWhitespace(1);                    }                    else if (forceIgnore === 105 /* LowerI */) {                        ignoreCase = true;                        stripWhitespace(1);                    }                }                if (selector.charCodeAt(selectorIndex) !==                    93 /* RightSquareBracket */) {                    throw new Error("Attribute selector didn't terminate");                }                selectorIndex += 1;                var attributeSelector = {                    type: types_1.SelectorType.Attribute,                    name: name_1,                    action: action,                    value: value,                    namespace: namespace,                    ignoreCase: ignoreCase,                };                tokens.push(attributeSelector);                break;            }            case 58 /* Colon */: {                if (selector.charCodeAt(selectorIndex + 1) === 58 /* Colon */) {                    tokens.push({                        type: types_1.SelectorType.PseudoElement,                        name: getName(2).toLowerCase(),                        data: selector.charCodeAt(selectorIndex) ===                            40 /* LeftParenthesis */                            ? readValueWithParenthesis()                            : null,                    });                    continue;                }                var name_2 = getName(1).toLowerCase();                var data = null;                if (selector.charCodeAt(selectorIndex) ===                    40 /* LeftParenthesis */) {                    if (unpackPseudos.has(name_2)) {                        if (isQuote(selector.charCodeAt(selectorIndex + 1))) {                            throw new Error("Pseudo-selector ".concat(name_2, " cannot be quoted"));                        }                        data = [];                        selectorIndex = parseSelector(data, selector, selectorIndex + 1);                        if (selector.charCodeAt(selectorIndex) !==                            41 /* RightParenthesis */) {                            throw new Error("Missing closing parenthesis in :".concat(name_2, " (").concat(selector, ")"));                        }                        selectorIndex += 1;                    }                    else {                        data = readValueWithParenthesis();                        if (stripQuotesFromPseudos.has(name_2)) {                            var quot = data.charCodeAt(0);                            if (quot === data.charCodeAt(data.length - 1) &&                                isQuote(quot)) {                                data = data.slice(1, -1);                            }                        }                        data = unescapeCSS(data);                    }                }                tokens.push({ type: types_1.SelectorType.Pseudo, name: name_2, data: data });                break;            }            case 44 /* Comma */: {                finalizeSubselector();                tokens = [];                stripWhitespace(1);                break;            }            default: {                if (selector.startsWith("/*", selectorIndex)) {                    var endIndex = selector.indexOf("*/", selectorIndex + 2);                    if (endIndex < 0) {                        throw new Error("Comment was not terminated");                    }                    selectorIndex = endIndex + 2;                    // Remove leading whitespace                    if (tokens.length === 0) {                        stripWhitespace(0);                    }                    break;                }                var namespace = null;                var name_3 = void 0;                if (firstChar === 42 /* Asterisk */) {                    selectorIndex += 1;                    name_3 = "*";                }                else if (firstChar === 124 /* Pipe */) {                    name_3 = "";                    if (selector.charCodeAt(selectorIndex + 1) === 124 /* Pipe */) {                        addTraversal(types_1.SelectorType.ColumnCombinator);                        stripWhitespace(2);                        break;                    }                }                else if (reName.test(selector.slice(selectorIndex))) {                    name_3 = getName(0);                }                else {                    break loop;                }                if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&                    selector.charCodeAt(selectorIndex + 1) !== 124 /* Pipe */) {                    namespace = name_3;                    if (selector.charCodeAt(selectorIndex + 1) ===                        42 /* Asterisk */) {                        name_3 = "*";                        selectorIndex += 2;                    }                    else {                        name_3 = getName(1);                    }                }                tokens.push(name_3 === "*"                    ? { type: types_1.SelectorType.Universal, namespace: namespace }                    : { type: types_1.SelectorType.Tag, name: name_3, namespace: namespace });            }        }    }    finalizeSubselector();    return selectorIndex;}
 |