diff options
Diffstat (limited to 'includes/external/addressbook/node_modules/css-what/lib/es/stringify.js')
-rw-r--r-- | includes/external/addressbook/node_modules/css-what/lib/es/stringify.js | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/includes/external/addressbook/node_modules/css-what/lib/es/stringify.js b/includes/external/addressbook/node_modules/css-what/lib/es/stringify.js new file mode 100644 index 0000000..5f3b8ef --- /dev/null +++ b/includes/external/addressbook/node_modules/css-what/lib/es/stringify.js @@ -0,0 +1,126 @@ +import { SelectorType, AttributeAction } from "./types"; +const attribValChars = ["\\", '"']; +const pseudoValChars = [...attribValChars, "(", ")"]; +const charsToEscapeInAttributeValue = new Set(attribValChars.map((c) => c.charCodeAt(0))); +const charsToEscapeInPseudoValue = new Set(pseudoValChars.map((c) => c.charCodeAt(0))); +const charsToEscapeInName = new Set([ + ...pseudoValChars, + "~", + "^", + "$", + "*", + "+", + "!", + "|", + ":", + "[", + "]", + " ", + ".", +].map((c) => c.charCodeAt(0))); +/** + * Turns `selector` back into a string. + * + * @param selector Selector to stringify. + */ +export function stringify(selector) { + return selector + .map((token) => token.map(stringifyToken).join("")) + .join(", "); +} +function stringifyToken(token, index, arr) { + switch (token.type) { + // Simple types + case SelectorType.Child: + return index === 0 ? "> " : " > "; + case SelectorType.Parent: + return index === 0 ? "< " : " < "; + case SelectorType.Sibling: + return index === 0 ? "~ " : " ~ "; + case SelectorType.Adjacent: + return index === 0 ? "+ " : " + "; + case SelectorType.Descendant: + return " "; + case SelectorType.ColumnCombinator: + return index === 0 ? "|| " : " || "; + case SelectorType.Universal: + // Return an empty string if the selector isn't needed. + return token.namespace === "*" && + index + 1 < arr.length && + "name" in arr[index + 1] + ? "" + : `${getNamespace(token.namespace)}*`; + case SelectorType.Tag: + return getNamespacedName(token); + case SelectorType.PseudoElement: + return `::${escapeName(token.name, charsToEscapeInName)}${token.data === null + ? "" + : `(${escapeName(token.data, charsToEscapeInPseudoValue)})`}`; + case SelectorType.Pseudo: + return `:${escapeName(token.name, charsToEscapeInName)}${token.data === null + ? "" + : `(${typeof token.data === "string" + ? escapeName(token.data, charsToEscapeInPseudoValue) + : stringify(token.data)})`}`; + case SelectorType.Attribute: { + if (token.name === "id" && + token.action === AttributeAction.Equals && + token.ignoreCase === "quirks" && + !token.namespace) { + return `#${escapeName(token.value, charsToEscapeInName)}`; + } + if (token.name === "class" && + token.action === AttributeAction.Element && + token.ignoreCase === "quirks" && + !token.namespace) { + return `.${escapeName(token.value, charsToEscapeInName)}`; + } + const name = getNamespacedName(token); + if (token.action === AttributeAction.Exists) { + return `[${name}]`; + } + return `[${name}${getActionValue(token.action)}="${escapeName(token.value, charsToEscapeInAttributeValue)}"${token.ignoreCase === null ? "" : token.ignoreCase ? " i" : " s"}]`; + } + } +} +function getActionValue(action) { + switch (action) { + case AttributeAction.Equals: + return ""; + case AttributeAction.Element: + return "~"; + case AttributeAction.Start: + return "^"; + case AttributeAction.End: + return "$"; + case AttributeAction.Any: + return "*"; + case AttributeAction.Not: + return "!"; + case AttributeAction.Hyphen: + return "|"; + case AttributeAction.Exists: + throw new Error("Shouldn't be here"); + } +} +function getNamespacedName(token) { + return `${getNamespace(token.namespace)}${escapeName(token.name, charsToEscapeInName)}`; +} +function getNamespace(namespace) { + return namespace !== null + ? `${namespace === "*" + ? "*" + : escapeName(namespace, charsToEscapeInName)}|` + : ""; +} +function escapeName(str, charsToEscape) { + let lastIdx = 0; + let ret = ""; + for (let i = 0; i < str.length; i++) { + if (charsToEscape.has(str.charCodeAt(i))) { + ret += `${str.slice(lastIdx, i)}\\${str.charAt(i)}`; + lastIdx = i + 1; + } + } + return ret.length > 0 ? ret + str.slice(lastIdx) : str; +} |