@projectwallace/css-parser 0.13.4 → 0.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/css-node-2ejJUrIw.js +645 -0
  2. package/dist/css-node-DqyvMXBN.d.ts +313 -0
  3. package/dist/index.d.ts +150 -16
  4. package/dist/index.js +103 -13
  5. package/dist/parse-anplusb.d.ts +26 -2
  6. package/dist/parse-anplusb.js +191 -207
  7. package/dist/parse-atrule-prelude.d.ts +40 -2
  8. package/dist/parse-atrule-prelude.js +556 -652
  9. package/dist/parse-declaration.d.ts +16 -2
  10. package/dist/parse-declaration.js +140 -164
  11. package/dist/parse-dimension-CCn_XRDe.js +177 -0
  12. package/dist/parse-dimension.d.ts +6 -3
  13. package/dist/parse-dimension.js +1 -35
  14. package/dist/parse-selector.d.ts +37 -2
  15. package/dist/parse-selector.js +508 -635
  16. package/dist/parse-utils-DnsZRpfd.js +98 -0
  17. package/dist/parse-value.d.ts +23 -2
  18. package/dist/parse-value.js +176 -224
  19. package/dist/parse.d.ts +38 -8
  20. package/dist/parse.js +274 -350
  21. package/dist/tokenize-BQFB1jXg.js +540 -0
  22. package/dist/tokenize-odLrcjj2.d.ts +110 -0
  23. package/dist/tokenize.d.ts +2 -26
  24. package/dist/tokenize.js +1 -545
  25. package/package.json +20 -26
  26. package/dist/arena.d.ts +0 -59
  27. package/dist/arena.js +0 -290
  28. package/dist/char-types.d.ts +0 -14
  29. package/dist/char-types.js +0 -53
  30. package/dist/constants.d.ts +0 -43
  31. package/dist/constants.js +0 -50
  32. package/dist/css-node.d.ts +0 -202
  33. package/dist/css-node.js +0 -497
  34. package/dist/parse-utils.d.ts +0 -1
  35. package/dist/parse-utils.js +0 -60
  36. package/dist/string-utils.d.ts +0 -99
  37. package/dist/string-utils.js +0 -129
  38. package/dist/token-types.d.ts +0 -35
  39. package/dist/token-types.js +0 -29
  40. package/dist/walk.d.ts +0 -28
  41. package/dist/walk.js +0 -51
@@ -0,0 +1,645 @@
1
+ import { a as is_whitespace, c as str_starts_with, i as is_vendor_prefixed, t as parse_dimension } from "./parse-dimension-CCn_XRDe.js";
2
+ //#region src/arena.ts
3
+ let BYTES_PER_NODE = 36;
4
+ const STYLESHEET = 1;
5
+ const STYLE_RULE = 2;
6
+ const AT_RULE = 3;
7
+ const DECLARATION = 4;
8
+ const SELECTOR = 5;
9
+ const COMMENT = 6;
10
+ const BLOCK = 7;
11
+ const RAW = 8;
12
+ const IDENTIFIER = 10;
13
+ const NUMBER = 11;
14
+ const DIMENSION = 12;
15
+ const STRING = 13;
16
+ const HASH = 14;
17
+ const FUNCTION = 15;
18
+ const OPERATOR = 16;
19
+ const PARENTHESIS = 17;
20
+ const URL = 18;
21
+ const SELECTOR_LIST = 20;
22
+ const TYPE_SELECTOR = 21;
23
+ const CLASS_SELECTOR = 22;
24
+ const ID_SELECTOR = 23;
25
+ const ATTRIBUTE_SELECTOR = 24;
26
+ const PSEUDO_CLASS_SELECTOR = 25;
27
+ const PSEUDO_ELEMENT_SELECTOR = 26;
28
+ const COMBINATOR = 27;
29
+ const UNIVERSAL_SELECTOR = 28;
30
+ const NESTING_SELECTOR = 29;
31
+ const NTH_SELECTOR = 30;
32
+ const NTH_OF_SELECTOR = 31;
33
+ const LANG_SELECTOR = 56;
34
+ const MEDIA_QUERY = 32;
35
+ const MEDIA_FEATURE = 33;
36
+ const MEDIA_TYPE = 34;
37
+ const CONTAINER_QUERY = 35;
38
+ const SUPPORTS_QUERY = 36;
39
+ const LAYER_NAME = 37;
40
+ const PRELUDE_OPERATOR = 38;
41
+ const FEATURE_RANGE = 39;
42
+ const AT_RULE_PRELUDE = 40;
43
+ const VALUE = 50;
44
+ const FLAG_IMPORTANT = 1;
45
+ const ATTR_OPERATOR_NONE = 0;
46
+ const ATTR_OPERATOR_EQUAL = 1;
47
+ const ATTR_OPERATOR_TILDE_EQUAL = 2;
48
+ const ATTR_OPERATOR_PIPE_EQUAL = 3;
49
+ const ATTR_OPERATOR_CARET_EQUAL = 4;
50
+ const ATTR_OPERATOR_DOLLAR_EQUAL = 5;
51
+ const ATTR_OPERATOR_STAR_EQUAL = 6;
52
+ const ATTR_FLAG_NONE = 0;
53
+ const ATTR_FLAG_CASE_INSENSITIVE = 1;
54
+ const ATTR_FLAG_CASE_SENSITIVE = 2;
55
+ /** @internal */
56
+ var CSSDataArena = class CSSDataArena {
57
+ buffer;
58
+ view;
59
+ capacity;
60
+ count;
61
+ growth_count;
62
+ overflow_lengths;
63
+ static GROWTH_FACTOR = 1.3;
64
+ static NODES_PER_KB = 325;
65
+ static CAPACITY_BUFFER = 1.2;
66
+ constructor(initial_capacity = 1024) {
67
+ this.capacity = initial_capacity;
68
+ this.count = 1;
69
+ this.growth_count = 0;
70
+ this.buffer = new ArrayBuffer(initial_capacity * BYTES_PER_NODE);
71
+ this.view = new DataView(this.buffer);
72
+ this.overflow_lengths = /* @__PURE__ */ new Map();
73
+ }
74
+ static capacity_for_source(source_length) {
75
+ let size_in_kb = source_length / 1024;
76
+ let estimated_nodes = Math.ceil(size_in_kb * CSSDataArena.NODES_PER_KB);
77
+ let capacity = Math.ceil(estimated_nodes * CSSDataArena.CAPACITY_BUFFER);
78
+ return Math.max(16, capacity);
79
+ }
80
+ get_count() {
81
+ return this.count;
82
+ }
83
+ get_capacity() {
84
+ return this.capacity;
85
+ }
86
+ get_growth_count() {
87
+ return this.growth_count;
88
+ }
89
+ node_offset(node_index) {
90
+ return node_index * BYTES_PER_NODE;
91
+ }
92
+ get_type(node_index) {
93
+ return this.view.getUint8(this.node_offset(node_index));
94
+ }
95
+ get_flags(node_index) {
96
+ return this.view.getUint8(this.node_offset(node_index) + 1);
97
+ }
98
+ get_start_offset(node_index) {
99
+ return this.view.getUint32(this.node_offset(node_index) + 12, true);
100
+ }
101
+ get_length(node_index) {
102
+ if (this.has_flag(node_index, 4)) {
103
+ const overflow_length = this.overflow_lengths.get(node_index);
104
+ if (overflow_length !== void 0) return overflow_length;
105
+ }
106
+ return this.view.getUint16(this.node_offset(node_index) + 2, true);
107
+ }
108
+ get_content_start(node_index) {
109
+ return this.get_start_offset(node_index) + this.view.getUint16(this.node_offset(node_index) + 16, true);
110
+ }
111
+ get_content_length(node_index) {
112
+ return this.view.getUint16(this.node_offset(node_index) + 20, true);
113
+ }
114
+ get_attr_operator(node_index) {
115
+ return this.view.getUint8(this.node_offset(node_index) + 32);
116
+ }
117
+ get_attr_flags(node_index) {
118
+ return this.view.getUint8(this.node_offset(node_index) + 33);
119
+ }
120
+ get_first_child(node_index) {
121
+ return this.view.getUint32(this.node_offset(node_index) + 4, true);
122
+ }
123
+ get_next_sibling(node_index) {
124
+ return this.view.getUint32(this.node_offset(node_index) + 8, true);
125
+ }
126
+ get_start_line(node_index) {
127
+ return this.view.getUint32(this.node_offset(node_index) + 24, true);
128
+ }
129
+ get_start_column(node_index) {
130
+ return this.view.getUint32(this.node_offset(node_index) + 28, true);
131
+ }
132
+ get_value_start(node_index) {
133
+ return this.get_start_offset(node_index) + this.view.getUint16(this.node_offset(node_index) + 18, true);
134
+ }
135
+ get_value_length(node_index) {
136
+ return this.view.getUint16(this.node_offset(node_index) + 22, true);
137
+ }
138
+ set_type(node_index, type) {
139
+ this.view.setUint8(this.node_offset(node_index), type);
140
+ }
141
+ set_flags(node_index, flags) {
142
+ this.view.setUint8(this.node_offset(node_index) + 1, flags);
143
+ }
144
+ set_length(node_index, length) {
145
+ if (length > 65535) {
146
+ this.view.setUint16(this.node_offset(node_index) + 2, 65535, true);
147
+ this.set_flag(node_index, 4);
148
+ this.overflow_lengths.set(node_index, length);
149
+ } else this.view.setUint16(this.node_offset(node_index) + 2, length, true);
150
+ }
151
+ set_content_start_delta(node_index, delta) {
152
+ this.view.setUint16(this.node_offset(node_index) + 16, delta, true);
153
+ }
154
+ set_content_length(node_index, length) {
155
+ this.view.setUint16(this.node_offset(node_index) + 20, length, true);
156
+ }
157
+ set_attr_operator(node_index, operator) {
158
+ this.view.setUint8(this.node_offset(node_index) + 32, operator);
159
+ }
160
+ set_attr_flags(node_index, flags) {
161
+ this.view.setUint8(this.node_offset(node_index) + 33, flags);
162
+ }
163
+ set_first_child(node_index, childIndex) {
164
+ this.view.setUint32(this.node_offset(node_index) + 4, childIndex, true);
165
+ }
166
+ set_next_sibling(node_index, siblingIndex) {
167
+ this.view.setUint32(this.node_offset(node_index) + 8, siblingIndex, true);
168
+ }
169
+ set_value_start_delta(node_index, delta) {
170
+ this.view.setUint16(this.node_offset(node_index) + 18, delta, true);
171
+ }
172
+ set_value_length(node_index, length) {
173
+ this.view.setUint16(this.node_offset(node_index) + 22, length, true);
174
+ }
175
+ grow() {
176
+ this.growth_count++;
177
+ let new_capacity = Math.ceil(this.capacity * CSSDataArena.GROWTH_FACTOR);
178
+ let new_buffer = new ArrayBuffer(new_capacity * BYTES_PER_NODE);
179
+ new Uint8Array(new_buffer).set(new Uint8Array(this.buffer));
180
+ this.buffer = new_buffer;
181
+ this.view = new DataView(new_buffer);
182
+ this.capacity = new_capacity;
183
+ }
184
+ create_node(type, start_offset, length, start_line, start_column) {
185
+ if (this.count >= this.capacity) this.grow();
186
+ const node_index = this.count;
187
+ this.count++;
188
+ const offset = node_index * BYTES_PER_NODE;
189
+ this.view.setUint8(offset, type);
190
+ this.view.setUint32(offset + 12, start_offset, true);
191
+ this.view.setUint32(offset + 24, start_line, true);
192
+ this.view.setUint32(offset + 28, start_column, true);
193
+ this.set_length(node_index, length);
194
+ return node_index;
195
+ }
196
+ append_children(parent_index, children) {
197
+ if (children.length === 0) return;
198
+ const offset = this.node_offset(parent_index);
199
+ this.view.setUint32(offset + 4, children[0], true);
200
+ for (let i = 0; i < children.length - 1; i++) this.set_next_sibling(children[i], children[i + 1]);
201
+ }
202
+ has_children(node_index) {
203
+ return this.get_first_child(node_index) !== 0;
204
+ }
205
+ has_next_sibling(node_index) {
206
+ return this.get_next_sibling(node_index) !== 0;
207
+ }
208
+ set_flag(node_index, flag) {
209
+ let current_flags = this.get_flags(node_index);
210
+ this.set_flags(node_index, current_flags | flag);
211
+ }
212
+ clear_flag(node_index, flag) {
213
+ let current_flags = this.get_flags(node_index);
214
+ this.set_flags(node_index, current_flags & ~flag);
215
+ }
216
+ has_flag(node_index, flag) {
217
+ return (this.get_flags(node_index) & flag) !== 0;
218
+ }
219
+ };
220
+ //#endregion
221
+ //#region src/css-node.ts
222
+ const TYPE_NAMES = {
223
+ [1]: "StyleSheet",
224
+ [2]: "Rule",
225
+ [3]: "Atrule",
226
+ [4]: "Declaration",
227
+ [5]: "Selector",
228
+ [6]: "Comment",
229
+ [7]: "Block",
230
+ [8]: "Raw",
231
+ [10]: "Identifier",
232
+ [11]: "Number",
233
+ [12]: "Dimension",
234
+ [13]: "String",
235
+ [14]: "Hash",
236
+ [15]: "Function",
237
+ [16]: "Operator",
238
+ [17]: "Parentheses",
239
+ [18]: "Url",
240
+ [19]: "UnicodeRange",
241
+ [50]: "Value",
242
+ [20]: "SelectorList",
243
+ [21]: "TypeSelector",
244
+ [22]: "ClassSelector",
245
+ [23]: "IdSelector",
246
+ [24]: "AttributeSelector",
247
+ [25]: "PseudoClassSelector",
248
+ [26]: "PseudoElementSelector",
249
+ [27]: "Combinator",
250
+ [28]: "UniversalSelector",
251
+ [29]: "NestingSelector",
252
+ [30]: "Nth",
253
+ [31]: "NthOf",
254
+ [56]: "Lang",
255
+ [32]: "MediaQuery",
256
+ [33]: "Feature",
257
+ [34]: "MediaType",
258
+ [35]: "ContainerQuery",
259
+ [36]: "SupportsQuery",
260
+ [37]: "Layer",
261
+ [38]: "Operator",
262
+ [39]: "MediaFeatureRange",
263
+ [40]: "AtrulePrelude"
264
+ };
265
+ const ATTR_OPERATOR_NAMES = {
266
+ [0]: null,
267
+ [1]: "=",
268
+ [2]: "~=",
269
+ [3]: "|=",
270
+ [4]: "^=",
271
+ [5]: "$=",
272
+ [6]: "*="
273
+ };
274
+ const ATTR_FLAG_NAMES = {
275
+ [0]: null,
276
+ [1]: "i",
277
+ [2]: "s"
278
+ };
279
+ var CSSNode = class CSSNode {
280
+ arena;
281
+ source;
282
+ index;
283
+ constructor(arena, source, index) {
284
+ this.arena = arena;
285
+ this.source = source;
286
+ this.index = index;
287
+ }
288
+ /**
289
+ * @internal
290
+ * Get the arena (for internal/advanced use only)
291
+ */
292
+ __get_arena() {
293
+ return this.arena;
294
+ }
295
+ get_content() {
296
+ let start = this.arena.get_content_start(this.index);
297
+ let length = this.arena.get_content_length(this.index);
298
+ if (length === 0) return "";
299
+ return this.source.substring(start, start + length);
300
+ }
301
+ /** Get node type as number (for performance) */
302
+ get type() {
303
+ return this.arena.get_type(this.index);
304
+ }
305
+ /** Get node type as human-readable string */
306
+ get type_name() {
307
+ return TYPE_NAMES[this.type] || "unknown";
308
+ }
309
+ /** Get the full text of this node from source */
310
+ get text() {
311
+ let start = this.arena.get_start_offset(this.index);
312
+ let length = this.arena.get_length(this.index);
313
+ return this.source.substring(start, start + length);
314
+ }
315
+ /** Get the "content" text (at-rule name for at-rules, layer name for import layers) */
316
+ get name() {
317
+ let { type } = this;
318
+ if (type === 4 || type === 16 || type === 5) return;
319
+ return this.get_content();
320
+ }
321
+ /**
322
+ * Alias for name (for declarations: "color" in "color: blue")
323
+ * More semantic than `name` for declaration nodes
324
+ */
325
+ get property() {
326
+ let { type } = this;
327
+ if (type !== 4 && type !== 33) return;
328
+ return this.get_content();
329
+ }
330
+ /**
331
+ * Get the value text (for declarations: "blue" in "color: blue")
332
+ * For dimension/number nodes: returns the numeric value as a number
333
+ * For string nodes: returns the string content without quotes
334
+ * For URL nodes with quoted string: returns the string with quotes (consistent with STRING node)
335
+ * For URL nodes with unquoted URL: returns the URL content without quotes
336
+ */
337
+ get value() {
338
+ let { type, text, first_child } = this;
339
+ if (type === 4 && first_child) return first_child;
340
+ if (type === 12) return parse_dimension(text).value;
341
+ if (type === 11) return Number.parseFloat(text);
342
+ if (type === 18) {
343
+ if (first_child?.type === 13) return first_child.text;
344
+ if (str_starts_with(text, "url(")) {
345
+ let open_paren = text.indexOf("(");
346
+ let close_paren = text.lastIndexOf(")");
347
+ if (open_paren !== -1 && close_paren !== -1 && close_paren > open_paren) return text.substring(open_paren + 1, close_paren).trim();
348
+ } else if (text.startsWith("\"") || text.startsWith("'")) return text;
349
+ }
350
+ if (type === 16) return this.get_content();
351
+ let start = this.arena.get_value_start(this.index);
352
+ let length = this.arena.get_value_length(this.index);
353
+ if (length === 0) return null;
354
+ return this.source.substring(start, start + length);
355
+ }
356
+ /** Get the numeric value for NUMBER and DIMENSION nodes, or null for other node types */
357
+ get value_as_number() {
358
+ let { text, type } = this;
359
+ if (type === 11) return Number.parseFloat(text);
360
+ if (type === 12) return parse_dimension(text).value;
361
+ return null;
362
+ }
363
+ /**
364
+ * Get the prelude node:
365
+ * - For at-rules: AT_RULE_PRELUDE wrapper containing structured prelude children (media queries, layer names, etc.)
366
+ * - For style rules: SELECTOR_LIST or SELECTOR node
367
+ * Returns null if no prelude exists
368
+ */
369
+ get prelude() {
370
+ if (this.type === 3) {
371
+ let first = this.first_child;
372
+ if (first?.type === 40 || first?.type === 8) return first;
373
+ return null;
374
+ }
375
+ if (this.type === 2) return this.first_child;
376
+ }
377
+ /**
378
+ * Get the attribute operator (for attribute selectors: =, ~=, |=, ^=, $=, *=)
379
+ * Returns one of the ATTR_OPERATOR_* constants
380
+ */
381
+ get attr_operator() {
382
+ if (this.type !== 24) return void 0;
383
+ return this.arena.get_attr_operator(this.index);
384
+ }
385
+ /**
386
+ * Get the attribute flags (for attribute selectors: i, s)
387
+ * Returns one of the ATTR_FLAG_* constants
388
+ */
389
+ get attr_flags() {
390
+ if (this.type !== 24) return void 0;
391
+ return this.arena.get_attr_flags(this.index);
392
+ }
393
+ /** Get the unit for dimension nodes (e.g., "px" from "100px", "%" from "50%") */
394
+ get unit() {
395
+ if (this.type !== 12) return void 0;
396
+ return parse_dimension(this.text).unit;
397
+ }
398
+ /** Check if this declaration has !important */
399
+ get is_important() {
400
+ if (this.type !== 4) return void 0;
401
+ return this.arena.has_flag(this.index, 1);
402
+ }
403
+ /** Check if this declaration has a browser hack prefix */
404
+ get is_browserhack() {
405
+ if (this.type !== 4) return void 0;
406
+ return this.arena.has_flag(this.index, 128);
407
+ }
408
+ /** Check if this has a vendor prefix (computed on-demand) */
409
+ get is_vendor_prefixed() {
410
+ switch (this.type) {
411
+ case 4: return is_vendor_prefixed(this.get_content());
412
+ case 25:
413
+ case 26: return is_vendor_prefixed(this.get_content());
414
+ case 3: return is_vendor_prefixed(this.get_content());
415
+ case 15: return is_vendor_prefixed(this.get_content());
416
+ case 10: return is_vendor_prefixed(this.text);
417
+ default: return false;
418
+ }
419
+ }
420
+ /** Check if this node has an error */
421
+ get has_error() {
422
+ return this.arena.has_flag(this.index, 2);
423
+ }
424
+ /** Check if this node has a prelude (at-rules and style rules) */
425
+ get has_prelude() {
426
+ let { type } = this;
427
+ if (type === 3) return this.arena.get_value_length(this.index) > 0;
428
+ if (type === 2) return this.first_child !== null;
429
+ return false;
430
+ }
431
+ /** Check if this rule has a block { } */
432
+ get has_block() {
433
+ return this.arena.has_flag(this.index, 8);
434
+ }
435
+ /** Check if this style rule has declarations */
436
+ get has_declarations() {
437
+ return this.arena.has_flag(this.index, 32);
438
+ }
439
+ /** Get the block node (for style rules and at-rules with blocks) */
440
+ get block() {
441
+ let { type } = this;
442
+ if (type === 2) {
443
+ let first = this.first_child;
444
+ if (!first) return null;
445
+ let block_node = first.next_sibling;
446
+ if (block_node?.type === 7) return block_node;
447
+ return null;
448
+ }
449
+ if (type === 3) {
450
+ let child = this.first_child;
451
+ while (child) {
452
+ if (child.type === 7 && !child.next_sibling) return child;
453
+ child = child.next_sibling;
454
+ }
455
+ return null;
456
+ }
457
+ return null;
458
+ }
459
+ /** Check if this block is empty (no declarations or rules, only comments allowed) */
460
+ get is_empty() {
461
+ if (this.type !== 7) return void 0;
462
+ let child = this.first_child;
463
+ while (child) {
464
+ if (child.type !== 6) return false;
465
+ child = child.next_sibling;
466
+ }
467
+ return true;
468
+ }
469
+ /** Get start line number */
470
+ get line() {
471
+ return this.arena.get_start_line(this.index);
472
+ }
473
+ /** Get start column number */
474
+ get column() {
475
+ return this.arena.get_start_column(this.index);
476
+ }
477
+ /** Get start offset in source */
478
+ get start() {
479
+ return this.arena.get_start_offset(this.index);
480
+ }
481
+ /** Get length in source */
482
+ get length() {
483
+ return this.arena.get_length(this.index);
484
+ }
485
+ /**
486
+ * Get end offset in source
487
+ * End is not stored, must be calculated
488
+ */
489
+ get end() {
490
+ return this.start + this.length;
491
+ }
492
+ /** Get first child node */
493
+ get first_child() {
494
+ let child_index = this.arena.get_first_child(this.index);
495
+ if (child_index === 0) return null;
496
+ return new CSSNode(this.arena, this.source, child_index);
497
+ }
498
+ /** Get next sibling node */
499
+ get next_sibling() {
500
+ let sibling_index = this.arena.get_next_sibling(this.index);
501
+ if (sibling_index === 0) return null;
502
+ return new CSSNode(this.arena, this.source, sibling_index);
503
+ }
504
+ /** Check if this node has a next sibling */
505
+ get has_next() {
506
+ return this.arena.get_next_sibling(this.index) !== 0;
507
+ }
508
+ /**
509
+ * Check if this node has children
510
+ * For pseudo-class/pseudo-element functions, returns true if FLAG_HAS_PARENS is set
511
+ * This allows formatters to distinguish :lang() from :hover
512
+ */
513
+ get has_children() {
514
+ let { type } = this;
515
+ if (type === 25 || type === 26) {
516
+ if (this.arena.has_flag(this.index, 64)) return true;
517
+ }
518
+ return this.arena.has_children(this.index);
519
+ }
520
+ /** Get all children as an array */
521
+ get children() {
522
+ let result = [];
523
+ let child = this.first_child;
524
+ while (child) {
525
+ result.push(child);
526
+ child = child.next_sibling;
527
+ }
528
+ return result;
529
+ }
530
+ /** Make CSSNode iterable over its children */
531
+ *[Symbol.iterator]() {
532
+ let child = this.first_child;
533
+ while (child) {
534
+ yield child;
535
+ child = child.next_sibling;
536
+ }
537
+ }
538
+ /** Get the 'a' coefficient from An+B expression (e.g., "2n" from "2n+1", "odd" from "odd") */
539
+ get nth_a() {
540
+ let { type, arena, index } = this;
541
+ if (type !== 30 && type !== 31) return void 0;
542
+ let len = arena.get_content_length(index);
543
+ if (len === 0) return void 0;
544
+ let start = arena.get_content_start(index);
545
+ return this.source.substring(start, start + len);
546
+ }
547
+ /** Get the 'b' coefficient from An+B expression (e.g., "+1" from "2n+1") */
548
+ get nth_b() {
549
+ let { type, arena, index, source } = this;
550
+ if (type !== 30 && type !== 31) return void 0;
551
+ let len = arena.get_value_length(index);
552
+ if (len === 0) return void 0;
553
+ let start = arena.get_value_start(index);
554
+ let value = source.substring(start, start + len);
555
+ let check_pos = start - 1;
556
+ while (check_pos >= 0) {
557
+ let ch = source.charCodeAt(check_pos);
558
+ if (is_whitespace(ch)) {
559
+ check_pos--;
560
+ continue;
561
+ }
562
+ if (ch === 45) value = "-" + value;
563
+ else if (ch === 43) value = "+" + value;
564
+ break;
565
+ }
566
+ return value;
567
+ }
568
+ /** Get the An+B formula node from :nth-child(2n+1 of .foo) */
569
+ get nth() {
570
+ if (this.type !== 31) return void 0;
571
+ return this.first_child ?? void 0;
572
+ }
573
+ /** Get the selector list from :nth-child(2n+1 of .foo) */
574
+ get selector() {
575
+ if (this.type !== 31) return void 0;
576
+ return this.first_child?.next_sibling ?? void 0;
577
+ }
578
+ /**
579
+ * Get selector list from pseudo-class functions
580
+ * Works for :is(.a), :not(.b), :has(.c), :where(.d), :nth-child(2n of .e)
581
+ */
582
+ get selector_list() {
583
+ if (this.type !== 25) return void 0;
584
+ let child = this.first_child;
585
+ if (!child) return void 0;
586
+ if (child.type === 20) return child;
587
+ if (child.type === 31) return child.selector;
588
+ }
589
+ /**
590
+ * Clone this node as a mutable plain JavaScript object with children as arrays.
591
+ * See API.md for examples.
592
+ *
593
+ * @param options - Cloning configuration
594
+ * @param options.deep - Recursively clone children (default: true)
595
+ * @param options.locations - Include line/column/start/length (default: false)
596
+ */
597
+ clone(options = {}) {
598
+ const { deep = true, locations = false } = options;
599
+ let { type, name, property, value, unit } = this;
600
+ let plain = {
601
+ type,
602
+ type_name: this.type_name,
603
+ text: this.text
604
+ };
605
+ if (name) plain.name = name;
606
+ if (property) plain.property = property;
607
+ if (value) {
608
+ plain.value = value;
609
+ if (unit) plain.unit = unit;
610
+ }
611
+ if (type === 4) {
612
+ let { is_important, is_browserhack } = this;
613
+ if (is_important) plain.is_important = true;
614
+ if (is_browserhack) plain.is_browserhack = true;
615
+ }
616
+ let { is_vendor_prefixed, has_error } = this;
617
+ if (is_vendor_prefixed) plain.is_vendor_prefixed = true;
618
+ if (has_error) plain.has_error = true;
619
+ if (type === 24) {
620
+ plain.attr_operator = ATTR_OPERATOR_NAMES[this.attr_operator];
621
+ plain.attr_flags = ATTR_FLAG_NAMES[this.attr_flags];
622
+ }
623
+ if (type === 30 || type === 31) {
624
+ plain.nth_a = this.nth_a;
625
+ plain.nth_b = this.nth_b;
626
+ }
627
+ if (locations) {
628
+ plain.line = this.line;
629
+ plain.column = this.column;
630
+ plain.start = this.start;
631
+ plain.length = this.length;
632
+ plain.end = this.end;
633
+ }
634
+ if (deep && type !== 4) {
635
+ plain.children = [];
636
+ for (let child of this.children) plain.children.push(child.clone({
637
+ deep: true,
638
+ locations
639
+ }));
640
+ }
641
+ return plain;
642
+ }
643
+ };
644
+ //#endregion
645
+ export { TYPE_SELECTOR as $, IDENTIFIER as A, NUMBER as B, CSSDataArena as C, FLAG_IMPORTANT as D, FEATURE_RANGE as E, MEDIA_QUERY as F, PSEUDO_ELEMENT_SELECTOR as G, PARENTHESIS as H, MEDIA_TYPE as I, SELECTOR_LIST as J, RAW as K, NESTING_SELECTOR as L, LANG_SELECTOR as M, LAYER_NAME as N, FUNCTION as O, MEDIA_FEATURE as P, SUPPORTS_QUERY as Q, NTH_OF_SELECTOR as R, CONTAINER_QUERY as S, DIMENSION as T, PRELUDE_OPERATOR as U, OPERATOR as V, PSEUDO_CLASS_SELECTOR as W, STYLESHEET as X, STRING as Y, STYLE_RULE as Z, AT_RULE_PRELUDE as _, ATTRIBUTE_SELECTOR as a, COMBINATOR as b, ATTR_FLAG_NONE as c, ATTR_OPERATOR_EQUAL as d, UNIVERSAL_SELECTOR as et, ATTR_OPERATOR_NONE as f, AT_RULE as g, ATTR_OPERATOR_TILDE_EQUAL as h, TYPE_NAMES as i, ID_SELECTOR as j, HASH as k, ATTR_OPERATOR_CARET_EQUAL as l, ATTR_OPERATOR_STAR_EQUAL as m, ATTR_OPERATOR_NAMES as n, VALUE as nt, ATTR_FLAG_CASE_INSENSITIVE as o, ATTR_OPERATOR_PIPE_EQUAL as p, SELECTOR as q, CSSNode as r, ATTR_FLAG_CASE_SENSITIVE as s, ATTR_FLAG_NAMES as t, URL as tt, ATTR_OPERATOR_DOLLAR_EQUAL as u, BLOCK as v, DECLARATION as w, COMMENT as x, CLASS_SELECTOR as y, NTH_SELECTOR as z };