basant307/AI_Governance_Project
048
1"use strict";2Object.defineProperty(exports, "__esModule", { value: true });3exports.parse = exports.isTraversal = void 0;4var types_1 = require("./types");5var reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;6var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;7var actionTypes = new Map([8 [126 /* Tilde */, types_1.AttributeAction.Element],9 [94 /* Circumflex */, types_1.AttributeAction.Start],10 [36 /* Dollar */, types_1.AttributeAction.End],11 [42 /* Asterisk */, types_1.AttributeAction.Any],12 [33 /* ExclamationMark */, types_1.AttributeAction.Not],13 [124 /* Pipe */, types_1.AttributeAction.Hyphen],14]);15// Pseudos, whose data property is parsed as well.16var unpackPseudos = new Set([17 "has",18 "not",19 "matches",20 "is",21 "where",22 "host",23 "host-context",24]);25/**26 * Checks whether a specific selector is a traversal.27 * This is useful eg. in swapping the order of elements that28 * are not traversals.29 *30 * @param selector Selector to check.31 */32function isTraversal(selector) {33 switch (selector.type) {34 case types_1.SelectorType.Adjacent:35 case types_1.SelectorType.Child:36 case types_1.SelectorType.Descendant:37 case types_1.SelectorType.Parent:38 case types_1.SelectorType.Sibling:39 case types_1.SelectorType.ColumnCombinator:40 return true;41 default:42 return false;43 }44}45exports.isTraversal = isTraversal;46var stripQuotesFromPseudos = new Set(["contains", "icontains"]);47// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L15248function funescape(_, escaped, escapedWhitespace) {49 var high = parseInt(escaped, 16) - 0x10000;50 // NaN means non-codepoint51 return high !== high || escapedWhitespace52 ? escaped53 : high < 054 ? // BMP codepoint55 String.fromCharCode(high + 0x10000)56 : // Supplemental Plane codepoint (surrogate pair)57 String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);58}59function unescapeCSS(str) {60 return str.replace(reEscape, funescape);61}62function isQuote(c) {63 return c === 39 /* SingleQuote */ || c === 34 /* DoubleQuote */;64}65function isWhitespace(c) {66 return (c === 32 /* Space */ ||67 c === 9 /* Tab */ ||68 c === 10 /* NewLine */ ||69 c === 12 /* FormFeed */ ||70 c === 13 /* CarriageReturn */);71}72/**73 * Parses `selector`, optionally with the passed `options`.74 *75 * @param selector Selector to parse.76 * @param options Options for parsing.77 * @returns Returns a two-dimensional array.78 * The first dimension represents selectors separated by commas (eg. `sub1, sub2`),79 * the second contains the relevant tokens for that selector.80 */81function parse(selector) {82 var subselects = [];83 var endIndex = parseSelector(subselects, "".concat(selector), 0);84 if (endIndex < selector.length) {85 throw new Error("Unmatched selector: ".concat(selector.slice(endIndex)));86 }87 return subselects;88}89exports.parse = parse;90function parseSelector(subselects, selector, selectorIndex) {91 var tokens = [];92 function getName(offset) {93 var match = selector.slice(selectorIndex + offset).match(reName);94 if (!match) {95 throw new Error("Expected name, found ".concat(selector.slice(selectorIndex)));96 }97 var name = match[0];98 selectorIndex += offset + name.length;99 return unescapeCSS(name);100 }101 function stripWhitespace(offset) {102 selectorIndex += offset;103 while (selectorIndex < selector.length &&104 isWhitespace(selector.charCodeAt(selectorIndex))) {105 selectorIndex++;106 }107 }108 function readValueWithParenthesis() {109 selectorIndex += 1;110 var start = selectorIndex;111 var counter = 1;112 for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {113 if (selector.charCodeAt(selectorIndex) ===114 40 /* LeftParenthesis */ &&115 !isEscaped(selectorIndex)) {116 counter++;117 }118 else if (selector.charCodeAt(selectorIndex) ===119 41 /* RightParenthesis */ &&120 !isEscaped(selectorIndex)) {121 counter--;122 }123 }124 if (counter) {125 throw new Error("Parenthesis not matched");126 }127 return unescapeCSS(selector.slice(start, selectorIndex - 1));128 }129 function isEscaped(pos) {130 var slashCount = 0;131 while (selector.charCodeAt(--pos) === 92 /* BackSlash */)132 slashCount++;133 return (slashCount & 1) === 1;134 }135 function ensureNotTraversal() {136 if (tokens.length > 0 && isTraversal(tokens[tokens.length - 1])) {137 throw new Error("Did not expect successive traversals.");138 }139 }140 function addTraversal(type) {141 if (tokens.length > 0 &&142 tokens[tokens.length - 1].type === types_1.SelectorType.Descendant) {143 tokens[tokens.length - 1].type = type;144 return;145 }146 ensureNotTraversal();147 tokens.push({ type: type });148 }149 function addSpecialAttribute(name, action) {150 tokens.push({151 type: types_1.SelectorType.Attribute,152 name: name,153 action: action,154 value: getName(1),155 namespace: null,156 ignoreCase: "quirks",157 });158 }159 /**160 * We have finished parsing the current part of the selector.161 *162 * Remove descendant tokens at the end if they exist,163 * and return the last index, so that parsing can be164 * picked up from here.165 */166 function finalizeSubselector() {167 if (tokens.length &&168 tokens[tokens.length - 1].type === types_1.SelectorType.Descendant) {169 tokens.pop();170 }171 if (tokens.length === 0) {172 throw new Error("Empty sub-selector");173 }174 subselects.push(tokens);175 }176 stripWhitespace(0);177 if (selector.length === selectorIndex) {178 return selectorIndex;179 }180 loop: while (selectorIndex < selector.length) {181 var firstChar = selector.charCodeAt(selectorIndex);182 switch (firstChar) {183 // Whitespace184 case 32 /* Space */:185 case 9 /* Tab */:186 case 10 /* NewLine */:187 case 12 /* FormFeed */:188 case 13 /* CarriageReturn */: {189 if (tokens.length === 0 ||190 tokens[0].type !== types_1.SelectorType.Descendant) {191 ensureNotTraversal();192 tokens.push({ type: types_1.SelectorType.Descendant });193 }194 stripWhitespace(1);195 break;196 }197 // Traversals198 case 62 /* GreaterThan */: {199 addTraversal(types_1.SelectorType.Child);200 stripWhitespace(1);201 break;202 }203 case 60 /* LessThan */: {204 addTraversal(types_1.SelectorType.Parent);205 stripWhitespace(1);206 break;207 }208 case 126 /* Tilde */: {209 addTraversal(types_1.SelectorType.Sibling);210 stripWhitespace(1);211 break;212 }213 case 43 /* Plus */: {214 addTraversal(types_1.SelectorType.Adjacent);215 stripWhitespace(1);216 break;217 }218 // Special attribute selectors: .class, #id219 case 46 /* Period */: {220 addSpecialAttribute("class", types_1.AttributeAction.Element);221 break;222 }223 case 35 /* Hash */: {224 addSpecialAttribute("id", types_1.AttributeAction.Equals);225 break;226 }227 case 91 /* LeftSquareBracket */: {228 stripWhitespace(1);229 // Determine attribute name and namespace230 var name_1 = void 0;231 var namespace = null;232 if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */) {233 // Equivalent to no namespace234 name_1 = getName(1);235 }236 else if (selector.startsWith("*|", selectorIndex)) {237 namespace = "*";238 name_1 = getName(2);239 }240 else {241 name_1 = getName(0);242 if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&243 selector.charCodeAt(selectorIndex + 1) !==244 61 /* Equal */) {245 namespace = name_1;246 name_1 = getName(1);247 }248 }249 stripWhitespace(0);250 // Determine comparison operation251 var action = types_1.AttributeAction.Exists;252 var possibleAction = actionTypes.get(selector.charCodeAt(selectorIndex));253 if (possibleAction) {254 action = possibleAction;255 if (selector.charCodeAt(selectorIndex + 1) !==256 61 /* Equal */) {257 throw new Error("Expected `=`");258 }259 stripWhitespace(2);260 }261 else if (selector.charCodeAt(selectorIndex) === 61 /* Equal */) {262 action = types_1.AttributeAction.Equals;263 stripWhitespace(1);264 }265 // Determine value266 var value = "";267 var ignoreCase = null;268 if (action !== "exists") {269 if (isQuote(selector.charCodeAt(selectorIndex))) {270 var quote = selector.charCodeAt(selectorIndex);271 var sectionEnd = selectorIndex + 1;272 while (sectionEnd < selector.length &&273 (selector.charCodeAt(sectionEnd) !== quote ||274 isEscaped(sectionEnd))) {275 sectionEnd += 1;276 }277 if (selector.charCodeAt(sectionEnd) !== quote) {278 throw new Error("Attribute value didn't end");279 }280 value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));281 selectorIndex = sectionEnd + 1;282 }283 else {284 var valueStart = selectorIndex;285 while (selectorIndex < selector.length &&286 ((!isWhitespace(selector.charCodeAt(selectorIndex)) &&287 selector.charCodeAt(selectorIndex) !==288 93 /* RightSquareBracket */) ||289 isEscaped(selectorIndex))) {290 selectorIndex += 1;291 }292 value = unescapeCSS(selector.slice(valueStart, selectorIndex));293 }294 stripWhitespace(0);295 // See if we have a force ignore flag296 var forceIgnore = selector.charCodeAt(selectorIndex) | 0x20;297 // If the forceIgnore flag is set (either `i` or `s`), use that value298 if (forceIgnore === 115 /* LowerS */) {299 ignoreCase = false;300 stripWhitespace(1);301 }302 else if (forceIgnore === 105 /* LowerI */) {303 ignoreCase = true;304 stripWhitespace(1);305 }306 }307 if (selector.charCodeAt(selectorIndex) !==308 93 /* RightSquareBracket */) {309 throw new Error("Attribute selector didn't terminate");310 }311 selectorIndex += 1;312 var attributeSelector = {313 type: types_1.SelectorType.Attribute,314 name: name_1,315 action: action,316 value: value,317 namespace: namespace,318 ignoreCase: ignoreCase,319 };320 tokens.push(attributeSelector);321 break;322 }323 case 58 /* Colon */: {324 if (selector.charCodeAt(selectorIndex + 1) === 58 /* Colon */) {325 tokens.push({326 type: types_1.SelectorType.PseudoElement,327 name: getName(2).toLowerCase(),328 data: selector.charCodeAt(selectorIndex) ===329 40 /* LeftParenthesis */330 ? readValueWithParenthesis()331 : null,332 });333 continue;334 }335 var name_2 = getName(1).toLowerCase();336 var data = null;337 if (selector.charCodeAt(selectorIndex) ===338 40 /* LeftParenthesis */) {339 if (unpackPseudos.has(name_2)) {340 if (isQuote(selector.charCodeAt(selectorIndex + 1))) {341 throw new Error("Pseudo-selector ".concat(name_2, " cannot be quoted"));342 }343 data = [];344 selectorIndex = parseSelector(data, selector, selectorIndex + 1);345 if (selector.charCodeAt(selectorIndex) !==346 41 /* RightParenthesis */) {347 throw new Error("Missing closing parenthesis in :".concat(name_2, " (").concat(selector, ")"));348 }349 selectorIndex += 1;350 }351 else {352 data = readValueWithParenthesis();353 if (stripQuotesFromPseudos.has(name_2)) {354 var quot = data.charCodeAt(0);355 if (quot === data.charCodeAt(data.length - 1) &&356 isQuote(quot)) {357 data = data.slice(1, -1);358 }359 }360 data = unescapeCSS(data);361 }362 }363 tokens.push({ type: types_1.SelectorType.Pseudo, name: name_2, data: data });364 break;365 }366 case 44 /* Comma */: {367 finalizeSubselector();368 tokens = [];369 stripWhitespace(1);370 break;371 }372 default: {373 if (selector.startsWith("/*", selectorIndex)) {374 var endIndex = selector.indexOf("*/", selectorIndex + 2);375 if (endIndex < 0) {376 throw new Error("Comment was not terminated");377 }378 selectorIndex = endIndex + 2;379 // Remove leading whitespace380 if (tokens.length === 0) {381 stripWhitespace(0);382 }383 break;384 }385 var namespace = null;386 var name_3 = void 0;387 if (firstChar === 42 /* Asterisk */) {388 selectorIndex += 1;389 name_3 = "*";390 }391 else if (firstChar === 124 /* Pipe */) {392 name_3 = "";393 if (selector.charCodeAt(selectorIndex + 1) === 124 /* Pipe */) {394 addTraversal(types_1.SelectorType.ColumnCombinator);395 stripWhitespace(2);396 break;397 }398 }399 else if (reName.test(selector.slice(selectorIndex))) {400 name_3 = getName(0);401 }402 else {403 break loop;404 }405 if (selector.charCodeAt(selectorIndex) === 124 /* Pipe */ &&406 selector.charCodeAt(selectorIndex + 1) !== 124 /* Pipe */) {407 namespace = name_3;408 if (selector.charCodeAt(selectorIndex + 1) ===409 42 /* Asterisk */) {410 name_3 = "*";411 selectorIndex += 2;412 }413 else {414 name_3 = getName(1);415 }416 }417 tokens.push(name_3 === "*"418 ? { type: types_1.SelectorType.Universal, namespace: namespace }419 : { type: types_1.SelectorType.Tag, name: name_3, namespace: namespace });420 }421 }422 }423 finalizeSubselector();424 return selectorIndex;425}426 