From 22a25ded9f7d9c9a96cce8d1bc12475ca0434201 Mon Sep 17 00:00:00 2001 From: Minteck Date: Wed, 9 Feb 2022 17:58:07 +0100 Subject: Major update --- node_modules/css-what/lib/parse.js | 432 +++++++++++++++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 node_modules/css-what/lib/parse.js (limited to 'node_modules/css-what/lib/parse.js') diff --git a/node_modules/css-what/lib/parse.js b/node_modules/css-what/lib/parse.js new file mode 100644 index 0000000..786b13e --- /dev/null +++ b/node_modules/css-what/lib/parse.js @@ -0,0 +1,432 @@ +"use strict"; +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)); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isTraversal = void 0; +var reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/; +var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi; +var actionTypes = new Map([ + ["~", "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", + "where", + "host", + "host-context", +]); +var traversalNames = new Set(__spreadArray([ + "descendant" +], Object.keys(Traversals).map(function (k) { return Traversals[k]; }), true)); +/** + * Attributes that are case-insensitive in HTML. + * + * @private + * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + */ +var caseInsensitiveAttributes = new Set([ + "accept", + "accept-charset", + "align", + "alink", + "axis", + "bgcolor", + "charset", + "checked", + "clear", + "codetype", + "color", + "compact", + "declare", + "defer", + "dir", + "direction", + "disabled", + "enctype", + "face", + "frame", + "hreflang", + "http-equiv", + "lang", + "language", + "link", + "media", + "method", + "multiple", + "nohref", + "noresize", + "noshade", + "nowrap", + "readonly", + "rel", + "rev", + "rules", + "scope", + "scrolling", + "selected", + "shape", + "target", + "text", + "type", + "valign", + "valuetype", + "vlink", +]); +/** + * 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) { + return traversalNames.has(selector.type); +} +exports.isTraversal = isTraversal; +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"; +} +/** + * 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, options) { + var subselects = []; + var endIndex = parseSelector(subselects, "" + selector, options, 0); + if (endIndex < selector.length) { + throw new Error("Unmatched selector: " + selector.slice(endIndex)); + } + return subselects; +} +exports.default = parse; +function parseSelector(subselects, selector, options, selectorIndex) { + var _a, _b; + if (options === void 0) { options = {}; } + var tokens = []; + var sawWS = false; + function getName(offset) { + var match = selector.slice(selectorIndex + offset).match(reName); + if (!match) { + throw new Error("Expected name, found " + selector.slice(selectorIndex)); + } + var name = match[0]; + selectorIndex += offset + name.length; + return unescapeCSS(name); + } + function stripWhitespace(offset) { + while (isWhitespace(selector.charAt(selectorIndex + offset))) + offset++; + selectorIndex += offset; + } + function isEscaped(pos) { + var slashCount = 0; + while (selector.charAt(--pos) === "\\") + slashCount++; + return (slashCount & 1) === 1; + } + function ensureNotTraversal() { + if (tokens.length > 0 && isTraversal(tokens[tokens.length - 1])) { + throw new Error("Did not expect successive traversals."); + } + } + stripWhitespace(0); + while (selector !== "") { + var firstChar = selector.charAt(selectorIndex); + if (isWhitespace(firstChar)) { + sawWS = true; + stripWhitespace(1); + } + else if (firstChar in Traversals) { + ensureNotTraversal(); + 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 (selector.startsWith("/*", selectorIndex)) { + var endIndex = selector.indexOf("*/", selectorIndex + 2); + if (endIndex < 0) { + throw new Error("Comment was not terminated"); + } + selectorIndex = endIndex + 2; + } + else { + if (sawWS) { + ensureNotTraversal(); + tokens.push({ type: "descendant" }); + sawWS = false; + } + if (firstChar in attribSelectors) { + var _c = attribSelectors[firstChar], name_1 = _c[0], action = _c[1]; + tokens.push({ + type: "attribute", + name: name_1, + action: action, + value: getName(1), + namespace: null, + // TODO: Add quirksMode option, which makes `ignoreCase` `true` for HTML. + ignoreCase: options.xmlMode ? null : false, + }); + } + else if (firstChar === "[") { + stripWhitespace(1); + // Determine attribute name and namespace + var namespace = null; + if (selector.charAt(selectorIndex) === "|") { + namespace = ""; + selectorIndex += 1; + } + if (selector.startsWith("*|", selectorIndex)) { + namespace = "*"; + selectorIndex += 2; + } + var name_2 = getName(0); + if (namespace === null && + selector.charAt(selectorIndex) === "|" && + selector.charAt(selectorIndex + 1) !== "=") { + namespace = name_2; + name_2 = getName(1); + } + if ((_a = options.lowerCaseAttributeNames) !== null && _a !== void 0 ? _a : !options.xmlMode) { + name_2 = name_2.toLowerCase(); + } + stripWhitespace(0); + // Determine comparison operation + var action = "exists"; + var possibleAction = actionTypes.get(selector.charAt(selectorIndex)); + if (possibleAction) { + action = possibleAction; + if (selector.charAt(selectorIndex + 1) !== "=") { + throw new Error("Expected `=`"); + } + stripWhitespace(2); + } + else if (selector.charAt(selectorIndex) === "=") { + action = "equals"; + stripWhitespace(1); + } + // Determine value + var value = ""; + var ignoreCase = null; + if (action !== "exists") { + if (quotes.has(selector.charAt(selectorIndex))) { + var quote = selector.charAt(selectorIndex); + var sectionEnd = selectorIndex + 1; + while (sectionEnd < selector.length && + (selector.charAt(sectionEnd) !== quote || + isEscaped(sectionEnd))) { + sectionEnd += 1; + } + if (selector.charAt(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.charAt(selectorIndex)) && + selector.charAt(selectorIndex) !== "]") || + isEscaped(selectorIndex))) { + selectorIndex += 1; + } + value = unescapeCSS(selector.slice(valueStart, selectorIndex)); + } + stripWhitespace(0); + // See if we have a force ignore flag + var forceIgnore = selector.charAt(selectorIndex); + // If the forceIgnore flag is set (either `i` or `s`), use that value + if (forceIgnore === "s" || forceIgnore === "S") { + ignoreCase = false; + stripWhitespace(1); + } + else if (forceIgnore === "i" || forceIgnore === "I") { + ignoreCase = true; + stripWhitespace(1); + } + } + // If `xmlMode` is set, there are no rules; otherwise, use the `caseInsensitiveAttributes` list. + if (!options.xmlMode) { + // TODO: Skip this for `exists`, as there is no value to compare to. + ignoreCase !== null && ignoreCase !== void 0 ? ignoreCase : (ignoreCase = caseInsensitiveAttributes.has(name_2)); + } + if (selector.charAt(selectorIndex) !== "]") { + throw new Error("Attribute selector didn't terminate"); + } + selectorIndex += 1; + var attributeSelector = { + type: "attribute", + name: name_2, + action: action, + value: value, + namespace: namespace, + ignoreCase: ignoreCase, + }; + tokens.push(attributeSelector); + } + else if (firstChar === ":") { + if (selector.charAt(selectorIndex + 1) === ":") { + tokens.push({ + type: "pseudo-element", + name: getName(2).toLowerCase(), + }); + continue; + } + var name_3 = getName(1).toLowerCase(); + var data = null; + if (selector.charAt(selectorIndex) === "(") { + if (unpackPseudos.has(name_3)) { + if (quotes.has(selector.charAt(selectorIndex + 1))) { + throw new Error("Pseudo-selector " + name_3 + " cannot be quoted"); + } + data = []; + selectorIndex = parseSelector(data, selector, options, selectorIndex + 1); + if (selector.charAt(selectorIndex) !== ")") { + throw new Error("Missing closing parenthesis in :" + name_3 + " (" + selector + ")"); + } + selectorIndex += 1; + } + else { + selectorIndex += 1; + var start = selectorIndex; + var counter = 1; + for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) { + if (selector.charAt(selectorIndex) === "(" && + !isEscaped(selectorIndex)) { + counter++; + } + else if (selector.charAt(selectorIndex) === ")" && + !isEscaped(selectorIndex)) { + counter--; + } + } + if (counter) { + throw new Error("Parenthesis not matched"); + } + data = selector.slice(start, selectorIndex - 1); + 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 { + var namespace = null; + var name_4 = void 0; + if (firstChar === "*") { + selectorIndex += 1; + name_4 = "*"; + } + else if (reName.test(selector.slice(selectorIndex))) { + if (selector.charAt(selectorIndex) === "|") { + namespace = ""; + selectorIndex += 1; + } + name_4 = getName(0); + } + else { + /* + * We have finished parsing 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. + */ + if (tokens.length && + tokens[tokens.length - 1].type === "descendant") { + tokens.pop(); + } + addToken(subselects, tokens); + return selectorIndex; + } + if (selector.charAt(selectorIndex) === "|") { + namespace = name_4; + if (selector.charAt(selectorIndex + 1) === "*") { + name_4 = "*"; + selectorIndex += 2; + } + else { + name_4 = getName(1); + } + } + if (name_4 === "*") { + tokens.push({ type: "universal", namespace: namespace }); + } + else { + if ((_b = options.lowerCaseTags) !== null && _b !== void 0 ? _b : !options.xmlMode) { + name_4 = name_4.toLowerCase(); + } + tokens.push({ type: "tag", name: name_4, namespace: namespace }); + } + } + } + } + addToken(subselects, tokens); + return selectorIndex; +} +function addToken(subselects, tokens) { + if (subselects.length > 0 && tokens.length === 0) { + throw new Error("Empty sub-selector"); + } + subselects.push(tokens); +} -- cgit