| "use strict"; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.default = parse; |
| var reName = /^[^\\]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/; |
| var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi; |
| // Modified version of https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L87 |
| var reAttr = /^\s*((?:\\.|[\w\u00b0-\uFFFF-])+)\s*(?:(\S?)=\s*(?:(['"])((?:[^\\]|\\[^])*?)\3|(#?(?:\\.|[\w\u00b0-\uFFFF-])*)|)|)\s*(i)?\]/; |
| var actionTypes = { |
| undefined: "exists", |
| "": "equals", |
| "~": "element", |
| "^": "start", |
| $: "end", |
| "*": "any", |
| "!": "not", |
| "|": "hyphen", |
| }; |
| var Traversals = { |
| ">": "child", |
| "<": "parent", |
| "~": "sibling", |
| "+": "adjacent", |
| }; |
| var attribSelectors = { |
| "#": ["id", "equals"], |
| ".": ["class", "element"], |
| }; |
| // Pseudos, whose data property is parsed as well. |
| var unpackPseudos = new Set([ |
| "has", |
| "not", |
| "matches", |
| "is", |
| "host", |
| "host-context", |
| ]); |
| var stripQuotesFromPseudos = new Set(["contains", "icontains"]); |
| var quotes = new Set(['"', "'"]); |
| // Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152 |
| function 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 isWhitespace(c) { |
| return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r"; |
| } |
| function parse(selector, options) { |
| var subselects = []; |
| selector = parseSelector(subselects, "" + selector, options); |
| if (selector !== "") { |
| throw new Error("Unmatched selector: " + selector); |
| } |
| return subselects; |
| } |
| function parseSelector(subselects, selector, options) { |
| var _a, _b; |
| if (options === void 0) { options = {}; } |
| var tokens = []; |
| var sawWS = false; |
| function getName() { |
| var match = selector.match(reName); |
| if (!match) { |
| throw new Error("Expected name, found " + selector); |
| } |
| var sub = match[0]; |
| selector = selector.substr(sub.length); |
| return unescapeCSS(sub); |
| } |
| function stripWhitespace(start) { |
| while (isWhitespace(selector.charAt(start))) |
| start++; |
| selector = selector.substr(start); |
| } |
| function isEscaped(pos) { |
| var slashCount = 0; |
| while (selector.charAt(--pos) === "\\") |
| slashCount++; |
| return (slashCount & 1) === 1; |
| } |
| stripWhitespace(0); |
| while (selector !== "") { |
| var firstChar = selector.charAt(0); |
| if (isWhitespace(firstChar)) { |
| sawWS = true; |
| stripWhitespace(1); |
| } |
| else if (firstChar in Traversals) { |
| tokens.push({ type: Traversals[firstChar] }); |
| sawWS = false; |
| stripWhitespace(1); |
| } |
| else if (firstChar === ",") { |
| if (tokens.length === 0) { |
| throw new Error("Empty sub-selector"); |
| } |
| subselects.push(tokens); |
| tokens = []; |
| sawWS = false; |
| stripWhitespace(1); |
| } |
| else { |
| if (sawWS) { |
| if (tokens.length > 0) { |
| tokens.push({ type: "descendant" }); |
| } |
| sawWS = false; |
| } |
| if (firstChar === "*") { |
| selector = selector.substr(1); |
| tokens.push({ type: "universal" }); |
| } |
| else if (firstChar in attribSelectors) { |
| var _c = attribSelectors[firstChar], name_1 = _c[0], action = _c[1]; |
| selector = selector.substr(1); |
| tokens.push({ |
| type: "attribute", |
| name: name_1, |
| action: action, |
| value: getName(), |
| ignoreCase: false, |
| }); |
| } |
| else if (firstChar === "[") { |
| selector = selector.substr(1); |
| var attributeMatch = selector.match(reAttr); |
| if (!attributeMatch) { |
| throw new Error("Malformed attribute selector: " + selector); |
| } |
| var completeSelector = attributeMatch[0], baseName = attributeMatch[1], actionType = attributeMatch[2], _d = attributeMatch[4], quotedValue = _d === void 0 ? "" : _d, _e = attributeMatch[5], value = _e === void 0 ? quotedValue : _e, ignoreCase = attributeMatch[6]; |
| selector = selector.substr(completeSelector.length); |
| var name_2 = unescapeCSS(baseName); |
| if ((_a = options.lowerCaseAttributeNames) !== null && _a !== void 0 ? _a : !options.xmlMode) { |
| name_2 = name_2.toLowerCase(); |
| } |
| tokens.push({ |
| type: "attribute", |
| name: name_2, |
| action: actionTypes[actionType], |
| value: unescapeCSS(value), |
| ignoreCase: !!ignoreCase, |
| }); |
| } |
| else if (firstChar === ":") { |
| if (selector.charAt(1) === ":") { |
| selector = selector.substr(2); |
| tokens.push({ |
| type: "pseudo-element", |
| name: getName().toLowerCase(), |
| }); |
| continue; |
| } |
| selector = selector.substr(1); |
| var name_3 = getName().toLowerCase(); |
| var data = null; |
| if (selector.startsWith("(")) { |
| if (unpackPseudos.has(name_3)) { |
| var quot = selector.charAt(1); |
| var quoted = quotes.has(quot); |
| selector = selector.substr(quoted ? 2 : 1); |
| data = []; |
| selector = parseSelector(data, selector, options); |
| if (quoted) { |
| if (!selector.startsWith(quot)) { |
| throw new Error("Unmatched quotes in :" + name_3); |
| } |
| else { |
| selector = selector.substr(1); |
| } |
| } |
| if (!selector.startsWith(")")) { |
| throw new Error("Missing closing parenthesis in :" + name_3 + " (" + selector + ")"); |
| } |
| selector = selector.substr(1); |
| } |
| else { |
| var pos = 1; |
| var counter = 1; |
| for (; counter > 0 && pos < selector.length; pos++) { |
| if (selector.charAt(pos) === "(" && |
| !isEscaped(pos)) { |
| counter++; |
| } |
| else if (selector.charAt(pos) === ")" && |
| !isEscaped(pos)) { |
| counter--; |
| } |
| } |
| if (counter) { |
| throw new Error("Parenthesis not matched"); |
| } |
| data = selector.substr(1, pos - 2); |
| selector = selector.substr(pos); |
| if (stripQuotesFromPseudos.has(name_3)) { |
| var quot = data.charAt(0); |
| if (quot === data.slice(-1) && quotes.has(quot)) { |
| data = data.slice(1, -1); |
| } |
| data = unescapeCSS(data); |
| } |
| } |
| } |
| tokens.push({ type: "pseudo", name: name_3, data: data }); |
| } |
| else if (reName.test(selector)) { |
| var name_4 = getName(); |
| if ((_b = options.lowerCaseTags) !== null && _b !== void 0 ? _b : !options.xmlMode) { |
| name_4 = name_4.toLowerCase(); |
| } |
| tokens.push({ type: "tag", name: name_4 }); |
| } |
| else { |
| if (tokens.length && |
| tokens[tokens.length - 1].type === "descendant") { |
| tokens.pop(); |
| } |
| addToken(subselects, tokens); |
| return selector; |
| } |
| } |
| } |
| addToken(subselects, tokens); |
| return selector; |
| } |
| function addToken(subselects, tokens) { |
| if (subselects.length > 0 && tokens.length === 0) { |
| throw new Error("Empty sub-selector"); |
| } |
| subselects.push(tokens); |
| } |