"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.stringify = void 0; var types_1 = require("./types"); var attribValChars = ["\\", '"']; var pseudoValChars = __spreadArray(__spreadArray([], attribValChars, true), ["(", ")"], false); var charsToEscapeInAttributeValue = new Set(attribValChars.map(function (c) { return c.charCodeAt(0); })); var charsToEscapeInPseudoValue = new Set(pseudoValChars.map(function (c) { return c.charCodeAt(0); })); var charsToEscapeInName = new Set(__spreadArray(__spreadArray([], pseudoValChars, true), [ "~", "^", "$", "*", "+", "!", "|", ":", "[", "]", " ", ".", ], false).map(function (c) { return c.charCodeAt(0); })); /** * Turns `selector` back into a string. * * @param selector Selector to stringify. */ function stringify(selector) { return selector .map(function (token) { return token.map(stringifyToken).join(""); }) .join(", "); } exports.stringify = stringify; function stringifyToken(token, index, arr) { switch (token.type) { // Simple types case types_1.SelectorType.Child: return index === 0 ? "> " : " > "; case types_1.SelectorType.Parent: return index === 0 ? "< " : " < "; case types_1.SelectorType.Sibling: return index === 0 ? "~ " : " ~ "; case types_1.SelectorType.Adjacent: return index === 0 ? "+ " : " + "; case types_1.SelectorType.Descendant: return " "; case types_1.SelectorType.ColumnCombinator: return index === 0 ? "|| " : " || "; case types_1.SelectorType.Universal: // Return an empty string if the selector isn't needed. return token.namespace === "*" && index + 1 < arr.length && "name" in arr[index + 1] ? "" : "".concat(getNamespace(token.namespace), "*"); case types_1.SelectorType.Tag: return getNamespacedName(token); case types_1.SelectorType.PseudoElement: return "::".concat(escapeName(token.name, charsToEscapeInName)).concat(token.data === null ? "" : "(".concat(escapeName(token.data, charsToEscapeInPseudoValue), ")")); case types_1.SelectorType.Pseudo: return ":".concat(escapeName(token.name, charsToEscapeInName)).concat(token.data === null ? "" : "(".concat(typeof token.data === "string" ? escapeName(token.data, charsToEscapeInPseudoValue) : stringify(token.data), ")")); case types_1.SelectorType.Attribute: { if (token.name === "id" && token.action === types_1.AttributeAction.Equals && token.ignoreCase === "quirks" && !token.namespace) { return "#".concat(escapeName(token.value, charsToEscapeInName)); } if (token.name === "class" && token.action === types_1.AttributeAction.Element && token.ignoreCase === "quirks" && !token.namespace) { return ".".concat(escapeName(token.value, charsToEscapeInName)); } var name_1 = getNamespacedName(token); if (token.action === types_1.AttributeAction.Exists) { return "[".concat(name_1, "]"); } return "[".concat(name_1).concat(getActionValue(token.action), "=\"").concat(escapeName(token.value, charsToEscapeInAttributeValue), "\"").concat(token.ignoreCase === null ? "" : token.ignoreCase ? " i" : " s", "]"); } } } function getActionValue(action) { switch (action) { case types_1.AttributeAction.Equals: return ""; case types_1.AttributeAction.Element: return "~"; case types_1.AttributeAction.Start: return "^"; case types_1.AttributeAction.End: return "$"; case types_1.AttributeAction.Any: return "*"; case types_1.AttributeAction.Not: return "!"; case types_1.AttributeAction.Hyphen: return "|"; case types_1.AttributeAction.Exists: throw new Error("Shouldn't be here"); } } function getNamespacedName(token) { return "".concat(getNamespace(token.namespace)).concat(escapeName(token.name, charsToEscapeInName)); } function getNamespace(namespace) { return namespace !== null ? "".concat(namespace === "*" ? "*" : escapeName(namespace, charsToEscapeInName), "|") : ""; } function escapeName(str, charsToEscape) { var lastIdx = 0; var ret = ""; for (var i = 0; i < str.length; i++) { if (charsToEscape.has(str.charCodeAt(i))) { ret += "".concat(str.slice(lastIdx, i), "\\").concat(str.charAt(i)); lastIdx = i + 1; } } return ret.length > 0 ? ret + str.slice(lastIdx) : str; }