summaryrefslogtreecommitdiff
path: root/includes/external/addressbook/node_modules/css-what/lib/es/parse.js
diff options
context:
space:
mode:
authorRaindropsSys <contact@minteck.org>2023-04-06 22:18:28 +0200
committerRaindropsSys <contact@minteck.org>2023-04-06 22:18:28 +0200
commit83354b2b88218090988dd6e526b0a2505b57e0f1 (patch)
treee3c73c38a122a78bb7e66fbb99056407edd9d4b9 /includes/external/addressbook/node_modules/css-what/lib/es/parse.js
parent47b8f2299a483024c4a6a8876af825a010954caa (diff)
downloadpluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.tar.gz
pluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.tar.bz2
pluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.zip
Updated 5 files and added 1110 files (automated)
Diffstat (limited to 'includes/external/addressbook/node_modules/css-what/lib/es/parse.js')
-rw-r--r--includes/external/addressbook/node_modules/css-what/lib/es/parse.js420
1 files changed, 420 insertions, 0 deletions
diff --git a/includes/external/addressbook/node_modules/css-what/lib/es/parse.js b/includes/external/addressbook/node_modules/css-what/lib/es/parse.js
new file mode 100644
index 0000000..fe6ea9a
--- /dev/null
+++ b/includes/external/addressbook/node_modules/css-what/lib/es/parse.js
@@ -0,0 +1,420 @@
+import { SelectorType, AttributeAction, } from "./types";
+const reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
+const reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
+const actionTypes = new Map([
+ [126 /* Tilde */, AttributeAction.Element],
+ [94 /* Circumflex */, AttributeAction.Start],
+ [36 /* Dollar */, AttributeAction.End],
+ [42 /* Asterisk */, AttributeAction.Any],
+ [33 /* ExclamationMark */, AttributeAction.Not],
+ [124 /* Pipe */, AttributeAction.Hyphen],
+]);
+// Pseudos, whose data property is parsed as well.
+const 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.
+ */
+export function isTraversal(selector) {
+ switch (selector.type) {
+ case SelectorType.Adjacent:
+ case SelectorType.Child:
+ case SelectorType.Descendant:
+ case SelectorType.Parent:
+ case SelectorType.Sibling:
+ case SelectorType.ColumnCombinator:
+ return true;
+ default:
+ return false;
+ }
+}
+const stripQuotesFromPseudos = new Set(["contains", "icontains"]);
+// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152
+function funescape(_, escaped, escapedWhitespace) {
+ const 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.
+ */
+export function parse(selector) {
+ const subselects = [];
+ const endIndex = parseSelector(subselects, `${selector}`, 0);
+ if (endIndex < selector.length) {
+ throw new Error(`Unmatched selector: ${selector.slice(endIndex)}`);
+ }
+ return subselects;
+}
+function parseSelector(subselects, selector, selectorIndex) {
+ let tokens = [];
+ function getName(offset) {
+ const match = selector.slice(selectorIndex + offset).match(reName);
+ if (!match) {
+ throw new Error(`Expected name, found ${selector.slice(selectorIndex)}`);
+ }
+ const [name] = match;
+ 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;
+ const start = selectorIndex;
+ let 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) {
+ let 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 === SelectorType.Descendant) {
+ tokens[tokens.length - 1].type = type;
+ return;
+ }
+ ensureNotTraversal();
+ tokens.push({ type });
+ }
+ function addSpecialAttribute(name, action) {
+ tokens.push({
+ type: SelectorType.Attribute,
+ name,
+ 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 === 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) {
+ const 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 !== SelectorType.Descendant) {
+ ensureNotTraversal();
+ tokens.push({ type: SelectorType.Descendant });
+ }
+ stripWhitespace(1);
+ break;
+ }
+ // Traversals
+ case 62 /* GreaterThan */: {
+ addTraversal(SelectorType.Child);
+ stripWhitespace(1);
+ break;
+ }
+ case 60 /* LessThan */: {
+ addTraversal(SelectorType.Parent);
+ stripWhitespace(1);
+ break;
+ }
+ case 126 /* Tilde */: {
+ addTraversal(SelectorType.Sibling);
+ stripWhitespace(1);
+ break;
+ }
+ case 43 /* Plus */: {
+ addTraversal(SelectorType.Adjacent);
+ stripWhitespace(1);
+ break;
+ }
+ // Special attribute selectors: .class, #id
+ case 46 /* Period */: {
+ addSpecialAttribute("class", AttributeAction.Element);
+ break;
+ }
+ case 35 /* Hash */: {
+ addSpecialAttribute("id", AttributeAction.Equals);
+ break;
+ }
+ case 91 /* LeftSquareBracket */: {
+ stripWhitespace(1);
+ // Determine attribute name and namespace
+ let name;
+ let namespace = null;
+ if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */) {
+ // Equivalent to no namespace
+ name = getName(1);
+ }
+ else if (selector.startsWith("*|", selectorIndex)) {
+ namespace = "*";
+ name = getName(2);
+ }
+ else {
+ name = getName(0);
+ if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&
+ selector.charCodeAt(selectorIndex + 1) !==
+ 61 /* Equal */) {
+ namespace = name;
+ name = getName(1);
+ }
+ }
+ stripWhitespace(0);
+ // Determine comparison operation
+ let action = AttributeAction.Exists;
+ const 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 = AttributeAction.Equals;
+ stripWhitespace(1);
+ }
+ // Determine value
+ let value = "";
+ let ignoreCase = null;
+ if (action !== "exists") {
+ if (isQuote(selector.charCodeAt(selectorIndex))) {
+ const quote = selector.charCodeAt(selectorIndex);
+ let 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 {
+ const 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
+ const 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;
+ const attributeSelector = {
+ type: SelectorType.Attribute,
+ name,
+ action,
+ value,
+ namespace,
+ ignoreCase,
+ };
+ tokens.push(attributeSelector);
+ break;
+ }
+ case 58 /* Colon */: {
+ if (selector.charCodeAt(selectorIndex + 1) === 58 /* Colon */) {
+ tokens.push({
+ type: SelectorType.PseudoElement,
+ name: getName(2).toLowerCase(),
+ data: selector.charCodeAt(selectorIndex) ===
+ 40 /* LeftParenthesis */
+ ? readValueWithParenthesis()
+ : null,
+ });
+ continue;
+ }
+ const name = getName(1).toLowerCase();
+ let data = null;
+ if (selector.charCodeAt(selectorIndex) ===
+ 40 /* LeftParenthesis */) {
+ if (unpackPseudos.has(name)) {
+ if (isQuote(selector.charCodeAt(selectorIndex + 1))) {
+ throw new Error(`Pseudo-selector ${name} cannot be quoted`);
+ }
+ data = [];
+ selectorIndex = parseSelector(data, selector, selectorIndex + 1);
+ if (selector.charCodeAt(selectorIndex) !==
+ 41 /* RightParenthesis */) {
+ throw new Error(`Missing closing parenthesis in :${name} (${selector})`);
+ }
+ selectorIndex += 1;
+ }
+ else {
+ data = readValueWithParenthesis();
+ if (stripQuotesFromPseudos.has(name)) {
+ const quot = data.charCodeAt(0);
+ if (quot === data.charCodeAt(data.length - 1) &&
+ isQuote(quot)) {
+ data = data.slice(1, -1);
+ }
+ }
+ data = unescapeCSS(data);
+ }
+ }
+ tokens.push({ type: SelectorType.Pseudo, name, data });
+ break;
+ }
+ case 44 /* Comma */: {
+ finalizeSubselector();
+ tokens = [];
+ stripWhitespace(1);
+ break;
+ }
+ default: {
+ if (selector.startsWith("/*", selectorIndex)) {
+ const 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;
+ }
+ let namespace = null;
+ let name;
+ if (firstChar === 42 /* Asterisk */) {
+ selectorIndex += 1;
+ name = "*";
+ }
+ else if (firstChar === 124 /* Pipe */) {
+ name = "";
+ if (selector.charCodeAt(selectorIndex + 1) === 124 /* Pipe */) {
+ addTraversal(SelectorType.ColumnCombinator);
+ stripWhitespace(2);
+ break;
+ }
+ }
+ else if (reName.test(selector.slice(selectorIndex))) {
+ name = getName(0);
+ }
+ else {
+ break loop;
+ }
+ if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&
+ selector.charCodeAt(selectorIndex + 1) !== 124 /* Pipe */) {
+ namespace = name;
+ if (selector.charCodeAt(selectorIndex + 1) ===
+ 42 /* Asterisk */) {
+ name = "*";
+ selectorIndex += 2;
+ }
+ else {
+ name = getName(1);
+ }
+ }
+ tokens.push(name === "*"
+ ? { type: SelectorType.Universal, namespace }
+ : { type: SelectorType.Tag, name, namespace });
+ }
+ }
+ }
+ finalizeSubselector();
+ return selectorIndex;
+}