blob: f11c9ad14171073e7eb3e4b9f3185a16c5e60fe7 [file] [log] [blame]
Tim van der Lippe706ec962021-06-04 13:24:42 +01001"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.compileGeneralSelector = void 0;
4var attributes_1 = require("./attributes");
5var pseudo_selectors_1 = require("./pseudo-selectors");
6/*
7 * All available rules
8 */
9function compileGeneralSelector(next, selector, options, context, compileToken) {
10 var adapter = options.adapter, equals = options.equals;
11 switch (selector.type) {
12 case "pseudo-element":
13 throw new Error("Pseudo-elements are not supported by css-select");
14 case "attribute":
15 if (options.strict &&
16 (selector.ignoreCase || selector.action === "not")) {
17 throw new Error("Unsupported attribute selector");
18 }
19 return attributes_1.attributeRules[selector.action](next, selector, options);
20 case "pseudo":
21 return pseudo_selectors_1.compilePseudoSelector(next, selector, options, context, compileToken);
22 // Tags
23 case "tag":
24 return function tag(elem) {
25 return adapter.getName(elem) === selector.name && next(elem);
26 };
27 // Traversal
28 case "descendant":
29 if (options.cacheResults === false ||
30 typeof WeakSet === "undefined") {
31 return function descendant(elem) {
32 var current = elem;
33 while ((current = adapter.getParent(current))) {
34 if (adapter.isTag(current) && next(current)) {
35 return true;
36 }
37 }
38 return false;
39 };
40 }
41 // @ts-expect-error `ElementNode` is not extending object
42 // eslint-disable-next-line no-case-declarations
43 var isFalseCache_1 = new WeakSet();
44 return function cachedDescendant(elem) {
45 var current = elem;
46 while ((current = adapter.getParent(current))) {
47 if (!isFalseCache_1.has(current)) {
48 if (adapter.isTag(current) && next(current)) {
49 return true;
50 }
51 isFalseCache_1.add(current);
52 }
53 }
54 return false;
55 };
56 case "_flexibleDescendant":
57 // Include element itself, only used while querying an array
58 return function flexibleDescendant(elem) {
59 var current = elem;
60 do {
61 if (adapter.isTag(current) && next(current))
62 return true;
63 } while ((current = adapter.getParent(current)));
64 return false;
65 };
66 case "parent":
67 if (options.strict) {
68 throw new Error("Parent selector isn't part of CSS3");
69 }
70 return function parent(elem) {
71 return adapter
72 .getChildren(elem)
73 .some(function (elem) { return adapter.isTag(elem) && next(elem); });
74 };
75 case "child":
76 return function child(elem) {
77 var parent = adapter.getParent(elem);
78 return !!parent && adapter.isTag(parent) && next(parent);
79 };
80 case "sibling":
81 return function sibling(elem) {
82 var siblings = adapter.getSiblings(elem);
83 for (var i = 0; i < siblings.length; i++) {
84 var currentSibling = siblings[i];
85 if (equals(elem, currentSibling))
86 break;
87 if (adapter.isTag(currentSibling) && next(currentSibling)) {
88 return true;
89 }
90 }
91 return false;
92 };
93 case "adjacent":
94 return function adjacent(elem) {
95 var siblings = adapter.getSiblings(elem);
96 var lastElement;
97 for (var i = 0; i < siblings.length; i++) {
98 var currentSibling = siblings[i];
99 if (equals(elem, currentSibling))
100 break;
101 if (adapter.isTag(currentSibling)) {
102 lastElement = currentSibling;
103 }
104 }
105 return !!lastElement && next(lastElement);
106 };
107 case "universal":
108 return next;
109 }
110}
111exports.compileGeneralSelector = compileGeneralSelector;