source: trip-planner-front/node_modules/css-what/lib/parse.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 15.6 KB
RevLine 
[6a3a178]1"use strict";
2var __spreadArray = (this && this.__spreadArray) || function (to, from) {
3 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
4 to[j] = from[i];
5 return to;
6};
7Object.defineProperty(exports, "__esModule", { value: true });
8exports.isTraversal = void 0;
9var reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
10var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
11var actionTypes = new Map([
12 ["~", "element"],
13 ["^", "start"],
14 ["$", "end"],
15 ["*", "any"],
16 ["!", "not"],
17 ["|", "hyphen"],
18]);
19var Traversals = {
20 ">": "child",
21 "<": "parent",
22 "~": "sibling",
23 "+": "adjacent",
24};
25var attribSelectors = {
26 "#": ["id", "equals"],
27 ".": ["class", "element"],
28};
29// Pseudos, whose data property is parsed as well.
30var unpackPseudos = new Set([
31 "has",
32 "not",
33 "matches",
34 "is",
35 "host",
36 "host-context",
37]);
38var traversalNames = new Set(__spreadArray([
39 "descendant"
40], Object.keys(Traversals).map(function (k) { return Traversals[k]; })));
41/**
42 * Attributes that are case-insensitive in HTML.
43 *
44 * @private
45 * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
46 */
47var caseInsensitiveAttributes = new Set([
48 "accept",
49 "accept-charset",
50 "align",
51 "alink",
52 "axis",
53 "bgcolor",
54 "charset",
55 "checked",
56 "clear",
57 "codetype",
58 "color",
59 "compact",
60 "declare",
61 "defer",
62 "dir",
63 "direction",
64 "disabled",
65 "enctype",
66 "face",
67 "frame",
68 "hreflang",
69 "http-equiv",
70 "lang",
71 "language",
72 "link",
73 "media",
74 "method",
75 "multiple",
76 "nohref",
77 "noresize",
78 "noshade",
79 "nowrap",
80 "readonly",
81 "rel",
82 "rev",
83 "rules",
84 "scope",
85 "scrolling",
86 "selected",
87 "shape",
88 "target",
89 "text",
90 "type",
91 "valign",
92 "valuetype",
93 "vlink",
94]);
95/**
96 * Checks whether a specific selector is a traversal.
97 * This is useful eg. in swapping the order of elements that
98 * are not traversals.
99 *
100 * @param selector Selector to check.
101 */
102function isTraversal(selector) {
103 return traversalNames.has(selector.type);
104}
105exports.isTraversal = isTraversal;
106var stripQuotesFromPseudos = new Set(["contains", "icontains"]);
107var quotes = new Set(['"', "'"]);
108// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152
109function funescape(_, escaped, escapedWhitespace) {
110 var high = parseInt(escaped, 16) - 0x10000;
111 // NaN means non-codepoint
112 return high !== high || escapedWhitespace
113 ? escaped
114 : high < 0
115 ? // BMP codepoint
116 String.fromCharCode(high + 0x10000)
117 : // Supplemental Plane codepoint (surrogate pair)
118 String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
119}
120function unescapeCSS(str) {
121 return str.replace(reEscape, funescape);
122}
123function isWhitespace(c) {
124 return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
125}
126/**
127 * Parses `selector`, optionally with the passed `options`.
128 *
129 * @param selector Selector to parse.
130 * @param options Options for parsing.
131 * @returns Returns a two-dimensional array.
132 * The first dimension represents selectors separated by commas (eg. `sub1, sub2`),
133 * the second contains the relevant tokens for that selector.
134 */
135function parse(selector, options) {
136 var subselects = [];
137 var endIndex = parseSelector(subselects, "" + selector, options, 0);
138 if (endIndex < selector.length) {
139 throw new Error("Unmatched selector: " + selector.slice(endIndex));
140 }
141 return subselects;
142}
143exports.default = parse;
144function parseSelector(subselects, selector, options, selectorIndex) {
145 var _a, _b;
146 if (options === void 0) { options = {}; }
147 var tokens = [];
148 var sawWS = false;
149 function getName(offset) {
150 var match = selector.slice(selectorIndex + offset).match(reName);
151 if (!match) {
152 throw new Error("Expected name, found " + selector.slice(selectorIndex));
153 }
154 var name = match[0];
155 selectorIndex += offset + name.length;
156 return unescapeCSS(name);
157 }
158 function stripWhitespace(offset) {
159 while (isWhitespace(selector.charAt(selectorIndex + offset)))
160 offset++;
161 selectorIndex += offset;
162 }
163 function isEscaped(pos) {
164 var slashCount = 0;
165 while (selector.charAt(--pos) === "\\")
166 slashCount++;
167 return (slashCount & 1) === 1;
168 }
169 function ensureNotTraversal() {
170 if (tokens.length > 0 && isTraversal(tokens[tokens.length - 1])) {
171 throw new Error("Did not expect successive traversals.");
172 }
173 }
174 stripWhitespace(0);
175 while (selector !== "") {
176 var firstChar = selector.charAt(selectorIndex);
177 if (isWhitespace(firstChar)) {
178 sawWS = true;
179 stripWhitespace(1);
180 }
181 else if (firstChar in Traversals) {
182 ensureNotTraversal();
183 tokens.push({ type: Traversals[firstChar] });
184 sawWS = false;
185 stripWhitespace(1);
186 }
187 else if (firstChar === ",") {
188 if (tokens.length === 0) {
189 throw new Error("Empty sub-selector");
190 }
191 subselects.push(tokens);
192 tokens = [];
193 sawWS = false;
194 stripWhitespace(1);
195 }
196 else if (selector.startsWith("/*", selectorIndex)) {
197 var endIndex = selector.indexOf("*/", selectorIndex + 2);
198 if (endIndex < 0) {
199 throw new Error("Comment was not terminated");
200 }
201 selectorIndex = endIndex + 2;
202 }
203 else {
204 if (sawWS) {
205 ensureNotTraversal();
206 tokens.push({ type: "descendant" });
207 sawWS = false;
208 }
209 if (firstChar in attribSelectors) {
210 var _c = attribSelectors[firstChar], name_1 = _c[0], action = _c[1];
211 tokens.push({
212 type: "attribute",
213 name: name_1,
214 action: action,
215 value: getName(1),
216 namespace: null,
217 // TODO: Add quirksMode option, which makes `ignoreCase` `true` for HTML.
218 ignoreCase: options.xmlMode ? null : false,
219 });
220 }
221 else if (firstChar === "[") {
222 stripWhitespace(1);
223 // Determine attribute name and namespace
224 var name_2 = void 0;
225 var namespace = null;
226 if (selector.charAt(selectorIndex) === "|") {
227 namespace = "";
228 selectorIndex += 1;
229 }
230 if (selector.startsWith("*|", selectorIndex)) {
231 namespace = "*";
232 selectorIndex += 2;
233 }
234 name_2 = getName(0);
235 if (namespace === null &&
236 selector.charAt(selectorIndex) === "|" &&
237 selector.charAt(selectorIndex + 1) !== "=") {
238 namespace = name_2;
239 name_2 = getName(1);
240 }
241 if ((_a = options.lowerCaseAttributeNames) !== null && _a !== void 0 ? _a : !options.xmlMode) {
242 name_2 = name_2.toLowerCase();
243 }
244 stripWhitespace(0);
245 // Determine comparison operation
246 var action = "exists";
247 var possibleAction = actionTypes.get(selector.charAt(selectorIndex));
248 if (possibleAction) {
249 action = possibleAction;
250 if (selector.charAt(selectorIndex + 1) !== "=") {
251 throw new Error("Expected `=`");
252 }
253 stripWhitespace(2);
254 }
255 else if (selector.charAt(selectorIndex) === "=") {
256 action = "equals";
257 stripWhitespace(1);
258 }
259 // Determine value
260 var value = "";
261 var ignoreCase = null;
262 if (action !== "exists") {
263 if (quotes.has(selector.charAt(selectorIndex))) {
264 var quote = selector.charAt(selectorIndex);
265 var sectionEnd = selectorIndex + 1;
266 while (sectionEnd < selector.length &&
267 (selector.charAt(sectionEnd) !== quote ||
268 isEscaped(sectionEnd))) {
269 sectionEnd += 1;
270 }
271 if (selector.charAt(sectionEnd) !== quote) {
272 throw new Error("Attribute value didn't end");
273 }
274 value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));
275 selectorIndex = sectionEnd + 1;
276 }
277 else {
278 var valueStart = selectorIndex;
279 while (selectorIndex < selector.length &&
280 ((!isWhitespace(selector.charAt(selectorIndex)) &&
281 selector.charAt(selectorIndex) !== "]") ||
282 isEscaped(selectorIndex))) {
283 selectorIndex += 1;
284 }
285 value = unescapeCSS(selector.slice(valueStart, selectorIndex));
286 }
287 stripWhitespace(0);
288 // See if we have a force ignore flag
289 var forceIgnore = selector.charAt(selectorIndex);
290 // If the forceIgnore flag is set (either `i` or `s`), use that value
291 if (forceIgnore === "s" || forceIgnore === "S") {
292 ignoreCase = false;
293 stripWhitespace(1);
294 }
295 else if (forceIgnore === "i" || forceIgnore === "I") {
296 ignoreCase = true;
297 stripWhitespace(1);
298 }
299 }
300 // If `xmlMode` is set, there are no rules; otherwise, use the `caseInsensitiveAttributes` list.
301 if (!options.xmlMode) {
302 // TODO: Skip this for `exists`, as there is no value to compare to.
303 ignoreCase !== null && ignoreCase !== void 0 ? ignoreCase : (ignoreCase = caseInsensitiveAttributes.has(name_2));
304 }
305 if (selector.charAt(selectorIndex) !== "]") {
306 throw new Error("Attribute selector didn't terminate");
307 }
308 selectorIndex += 1;
309 var attributeSelector = {
310 type: "attribute",
311 name: name_2,
312 action: action,
313 value: value,
314 namespace: namespace,
315 ignoreCase: ignoreCase,
316 };
317 tokens.push(attributeSelector);
318 }
319 else if (firstChar === ":") {
320 if (selector.charAt(selectorIndex + 1) === ":") {
321 tokens.push({
322 type: "pseudo-element",
323 name: getName(2).toLowerCase(),
324 });
325 continue;
326 }
327 var name_3 = getName(1).toLowerCase();
328 var data = null;
329 if (selector.charAt(selectorIndex) === "(") {
330 if (unpackPseudos.has(name_3)) {
331 if (quotes.has(selector.charAt(selectorIndex + 1))) {
332 throw new Error("Pseudo-selector " + name_3 + " cannot be quoted");
333 }
334 data = [];
335 selectorIndex = parseSelector(data, selector, options, selectorIndex + 1);
336 if (selector.charAt(selectorIndex) !== ")") {
337 throw new Error("Missing closing parenthesis in :" + name_3 + " (" + selector + ")");
338 }
339 selectorIndex += 1;
340 }
341 else {
342 selectorIndex += 1;
343 var start = selectorIndex;
344 var counter = 1;
345 for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {
346 if (selector.charAt(selectorIndex) === "(" &&
347 !isEscaped(selectorIndex)) {
348 counter++;
349 }
350 else if (selector.charAt(selectorIndex) === ")" &&
351 !isEscaped(selectorIndex)) {
352 counter--;
353 }
354 }
355 if (counter) {
356 throw new Error("Parenthesis not matched");
357 }
358 data = selector.slice(start, selectorIndex - 1);
359 if (stripQuotesFromPseudos.has(name_3)) {
360 var quot = data.charAt(0);
361 if (quot === data.slice(-1) && quotes.has(quot)) {
362 data = data.slice(1, -1);
363 }
364 data = unescapeCSS(data);
365 }
366 }
367 }
368 tokens.push({ type: "pseudo", name: name_3, data: data });
369 }
370 else {
371 var namespace = null;
372 var name_4 = void 0;
373 if (firstChar === "*") {
374 selectorIndex += 1;
375 name_4 = "*";
376 }
377 else if (reName.test(selector.slice(selectorIndex))) {
378 if (selector.charAt(selectorIndex) === "|") {
379 namespace = "";
380 selectorIndex += 1;
381 }
382 name_4 = getName(0);
383 }
384 else {
385 /*
386 * We have finished parsing the selector.
387 * Remove descendant tokens at the end if they exist,
388 * and return the last index, so that parsing can be
389 * picked up from here.
390 */
391 if (tokens.length &&
392 tokens[tokens.length - 1].type === "descendant") {
393 tokens.pop();
394 }
395 addToken(subselects, tokens);
396 return selectorIndex;
397 }
398 if (selector.charAt(selectorIndex) === "|") {
399 namespace = name_4;
400 if (selector.charAt(selectorIndex + 1) === "*") {
401 name_4 = "*";
402 selectorIndex += 2;
403 }
404 else {
405 name_4 = getName(1);
406 }
407 }
408 if (name_4 === "*") {
409 tokens.push({ type: "universal", namespace: namespace });
410 }
411 else {
412 if ((_b = options.lowerCaseTags) !== null && _b !== void 0 ? _b : !options.xmlMode) {
413 name_4 = name_4.toLowerCase();
414 }
415 tokens.push({ type: "tag", name: name_4, namespace: namespace });
416 }
417 }
418 }
419 }
420 addToken(subselects, tokens);
421 return selectorIndex;
422}
423function addToken(subselects, tokens) {
424 if (subselects.length > 0 && tokens.length === 0) {
425 throw new Error("Empty sub-selector");
426 }
427 subselects.push(tokens);
428}
Note: See TracBrowser for help on using the repository browser.