@projectwallace/css-parser 0.16.2 → 0.18.0
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.
- package/dist/{arena-DfpuGV9Y.d.ts → arena-Bx5vp6Sl.d.ts} +2 -7
- package/dist/{arena-CCye9VYE.js → arena-CFwM4uQs.js} +10 -7
- package/dist/constants.d.ts +1 -2
- package/dist/constants.js +1 -1
- package/dist/{css-node-TR2T5Q7D.js → css-node-B3EzCweR.js} +12 -46
- package/dist/index.d.ts +6 -56
- package/dist/index.js +3 -3
- package/dist/node-types-BRnQyc9B.d.ts +395 -0
- package/dist/parse-anplusb.d.ts +2 -3
- package/dist/parse-anplusb.js +3 -3
- package/dist/parse-atrule-prelude.d.ts +3 -4
- package/dist/parse-atrule-prelude.js +78 -81
- package/dist/parse-declaration.d.ts +2 -3
- package/dist/parse-declaration.js +7 -7
- package/dist/{parse-dimension-B0AZRxxt.js → parse-dimension-ouWXNHdx.js} +5 -58
- package/dist/parse-dimension.d.ts +1 -12
- package/dist/parse-dimension.js +1 -1
- package/dist/parse-selector.d.ts +2 -3
- package/dist/parse-selector.js +27 -30
- package/dist/{parse-utils-BmXnziOy.js → parse-utils-D7srNG13.js} +5 -38
- package/dist/parse-value.d.ts +3 -14
- package/dist/parse-value.js +11 -157
- package/dist/parse.d.ts +2 -3
- package/dist/parse.js +59 -43
- package/dist/value-node-parser-CZ47v3hp.js +176 -0
- package/dist/walk.d.ts +7 -18
- package/dist/walk.js +7 -14
- package/package.json +7 -6
- package/dist/node-types-BrZu8T2C.d.ts +0 -508
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { t as Lexer } from "./tokenize-BiRLfVbm.js";
|
|
2
|
-
import { l as CSSDataArena } from "./arena-
|
|
3
|
-
import {
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { i as trim_boundaries, n as skip_whitespace_and_comments_forward } from "./parse-utils-
|
|
2
|
+
import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
|
|
3
|
+
import { l as strip_vendor_prefix, o as str_equals } from "./parse-dimension-ouWXNHdx.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-B3EzCweR.js";
|
|
5
|
+
import { i as trim_boundaries, n as skip_whitespace_and_comments_forward } from "./parse-utils-D7srNG13.js";
|
|
6
|
+
import { t as ValueNodeParser } from "./value-node-parser-CZ47v3hp.js";
|
|
6
7
|
//#region src/parse-atrule-prelude.ts
|
|
7
8
|
/** @internal */
|
|
8
9
|
var AtRulePreludeParser = class {
|
|
@@ -10,11 +11,13 @@ var AtRulePreludeParser = class {
|
|
|
10
11
|
arena;
|
|
11
12
|
source;
|
|
12
13
|
prelude_end;
|
|
14
|
+
value_node_parser;
|
|
13
15
|
constructor(arena, source) {
|
|
14
16
|
this.arena = arena;
|
|
15
17
|
this.source = source;
|
|
16
18
|
this.lexer = new Lexer(source);
|
|
17
19
|
this.prelude_end = 0;
|
|
20
|
+
this.value_node_parser = new ValueNodeParser(arena, source);
|
|
18
21
|
}
|
|
19
22
|
parse_prelude(at_rule_name, start, end, line = 1, column = 1) {
|
|
20
23
|
this.prelude_end = end;
|
|
@@ -74,30 +77,30 @@ var AtRulePreludeParser = class {
|
|
|
74
77
|
let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
|
|
75
78
|
if (!str_equals("only", text) && !str_equals("not", text)) this.lexer.restore_position(saved_token_start);
|
|
76
79
|
} else this.lexer.restore_position(saved_token_start);
|
|
77
|
-
let
|
|
80
|
+
let first_component = 0;
|
|
81
|
+
let last_component = 0;
|
|
78
82
|
while (this.lexer.pos < this.prelude_end) {
|
|
79
83
|
this.skip_whitespace();
|
|
80
84
|
if (this.lexer.pos >= this.prelude_end) break;
|
|
81
85
|
if (this.peek_token_type() === 18) break;
|
|
82
86
|
this.next_token();
|
|
83
87
|
let token_type = this.lexer.token_type;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} else if (token_type === 1) {
|
|
88
|
+
let component = null;
|
|
89
|
+
if (token_type === 21) component = this.parse_media_feature();
|
|
90
|
+
else if (token_type === 1) {
|
|
88
91
|
let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
|
|
89
|
-
if (this.is_and_or_not(text))
|
|
90
|
-
|
|
91
|
-
components.push(op);
|
|
92
|
-
} else {
|
|
93
|
-
let media_type = this.create_node(34, this.lexer.token_start, this.lexer.token_end);
|
|
94
|
-
components.push(media_type);
|
|
95
|
-
}
|
|
92
|
+
if (this.is_and_or_not(text)) component = this.create_node(38, this.lexer.token_start, this.lexer.token_end);
|
|
93
|
+
else component = this.create_node(34, this.lexer.token_start, this.lexer.token_end);
|
|
96
94
|
} else break;
|
|
95
|
+
if (component !== null) {
|
|
96
|
+
if (first_component === 0) first_component = component;
|
|
97
|
+
else this.arena.set_next_sibling(last_component, component);
|
|
98
|
+
last_component = component;
|
|
99
|
+
}
|
|
97
100
|
}
|
|
98
|
-
if (
|
|
101
|
+
if (first_component === 0) return null;
|
|
99
102
|
let query_node = this.create_node(32, query_start, this.lexer.pos);
|
|
100
|
-
this.arena.
|
|
103
|
+
this.arena.set_first_child(query_node, first_component);
|
|
101
104
|
return query_node;
|
|
102
105
|
}
|
|
103
106
|
parse_media_feature() {
|
|
@@ -107,7 +110,7 @@ var AtRulePreludeParser = class {
|
|
|
107
110
|
while (this.lexer.pos < this.prelude_end && depth > 0) {
|
|
108
111
|
this.next_token();
|
|
109
112
|
let token_type = this.lexer.token_type;
|
|
110
|
-
if (token_type === 21) depth++;
|
|
113
|
+
if (token_type === 21 || token_type === 2) depth++;
|
|
111
114
|
else if (token_type === 22) depth--;
|
|
112
115
|
}
|
|
113
116
|
if (depth !== 0) return null;
|
|
@@ -152,25 +155,24 @@ var AtRulePreludeParser = class {
|
|
|
152
155
|
}
|
|
153
156
|
let value_trimmed = trim_boundaries(this.source, colon_pos + 1, content_end);
|
|
154
157
|
if (value_trimmed) {
|
|
155
|
-
let
|
|
156
|
-
if (
|
|
158
|
+
let value_first = this.parse_feature_value(value_trimmed[0], value_trimmed[1]);
|
|
159
|
+
if (value_first !== 0) this.arena.set_first_child(feature, value_first);
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
162
|
return feature;
|
|
160
163
|
}
|
|
161
164
|
parse_container_query() {
|
|
162
|
-
let nodes = [];
|
|
163
165
|
let query_start = this.lexer.pos;
|
|
164
|
-
let
|
|
166
|
+
let first_component = 0;
|
|
167
|
+
let last_component = 0;
|
|
165
168
|
while (this.lexer.pos < this.prelude_end) {
|
|
166
169
|
this.skip_whitespace();
|
|
167
170
|
if (this.lexer.pos >= this.prelude_end) break;
|
|
168
171
|
this.next_token();
|
|
169
172
|
let token_type = this.lexer.token_type;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
} else if (token_type === 2) {
|
|
173
|
+
let component = null;
|
|
174
|
+
if (token_type === 21) component = this.parse_media_feature();
|
|
175
|
+
else if (token_type === 2) {
|
|
174
176
|
let func_name = this.source.substring(this.lexer.token_start, this.lexer.token_end - 1);
|
|
175
177
|
let func_start = this.lexer.token_start;
|
|
176
178
|
let content_start = this.lexer.token_end;
|
|
@@ -194,23 +196,22 @@ var AtRulePreludeParser = class {
|
|
|
194
196
|
this.arena.set_content_length(func_node, func_name.length);
|
|
195
197
|
this.arena.set_value_start_delta(func_node, content_start - func_start);
|
|
196
198
|
this.arena.set_value_length(func_node, content_end - content_start);
|
|
197
|
-
|
|
199
|
+
component = func_node;
|
|
198
200
|
} else if (token_type === 1) {
|
|
199
201
|
let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
|
|
200
|
-
if (this.is_and_or_not(text))
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
if (this.is_and_or_not(text)) component = this.create_node(38, this.lexer.token_start, this.lexer.token_end);
|
|
203
|
+
else component = this.create_node(10, this.lexer.token_start, this.lexer.token_end);
|
|
204
|
+
}
|
|
205
|
+
if (component !== null) {
|
|
206
|
+
if (first_component === 0) first_component = component;
|
|
207
|
+
else this.arena.set_next_sibling(last_component, component);
|
|
208
|
+
last_component = component;
|
|
207
209
|
}
|
|
208
210
|
}
|
|
209
|
-
if (
|
|
211
|
+
if (first_component === 0) return [];
|
|
210
212
|
let query_node = this.create_node(35, query_start, this.lexer.pos);
|
|
211
|
-
this.arena.
|
|
212
|
-
|
|
213
|
-
return nodes;
|
|
213
|
+
this.arena.set_first_child(query_node, first_component);
|
|
214
|
+
return [query_node];
|
|
214
215
|
}
|
|
215
216
|
parse_supports_query() {
|
|
216
217
|
let nodes = [];
|
|
@@ -226,7 +227,7 @@ var AtRulePreludeParser = class {
|
|
|
226
227
|
while (this.lexer.pos < this.prelude_end && depth > 0) {
|
|
227
228
|
this.next_token();
|
|
228
229
|
let inner_token_type = this.lexer.token_type;
|
|
229
|
-
if (inner_token_type === 21) depth++;
|
|
230
|
+
if (inner_token_type === 21 || inner_token_type === 2) depth++;
|
|
230
231
|
else if (inner_token_type === 22) depth--;
|
|
231
232
|
}
|
|
232
233
|
if (depth === 0) {
|
|
@@ -240,7 +241,7 @@ var AtRulePreludeParser = class {
|
|
|
240
241
|
let colon_pos = this.find_colon_at_depth_zero(trimmed[0], trimmed[1]);
|
|
241
242
|
if (colon_pos !== -1) {
|
|
242
243
|
let decl_child = this.create_supports_declaration(trimmed[0], trimmed[1], colon_pos);
|
|
243
|
-
this.arena.
|
|
244
|
+
this.arena.set_first_child(query, decl_child);
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
nodes.push(query);
|
|
@@ -275,17 +276,17 @@ var AtRulePreludeParser = class {
|
|
|
275
276
|
this.arena.set_content_start_delta(decl, 0);
|
|
276
277
|
this.arena.set_content_length(decl, prop_trimmed[1] - prop_trimmed[0]);
|
|
277
278
|
if (val_trimmed) {
|
|
278
|
-
let
|
|
279
|
+
let value_first = this.parse_feature_value(val_trimmed[0], val_trimmed[1]);
|
|
279
280
|
let value_node;
|
|
280
|
-
if (
|
|
281
|
+
if (value_first === 0) value_node = this.arena.create_node(50, val_trimmed[0], 0, this.lexer.token_line, this.lexer.token_column);
|
|
281
282
|
else {
|
|
282
283
|
value_node = this.arena.create_node(50, val_trimmed[0], val_trimmed[1] - val_trimmed[0], this.lexer.token_line, this.lexer.token_column);
|
|
283
|
-
this.arena.
|
|
284
|
+
this.arena.set_first_child(value_node, value_first);
|
|
284
285
|
}
|
|
285
|
-
this.arena.
|
|
286
|
+
this.arena.set_first_child(decl, value_node);
|
|
286
287
|
}
|
|
287
288
|
let supports_decl = this.create_node(57, content_start, content_end);
|
|
288
|
-
this.arena.
|
|
289
|
+
this.arena.set_first_child(supports_decl, decl);
|
|
289
290
|
return supports_decl;
|
|
290
291
|
}
|
|
291
292
|
parse_layer_names() {
|
|
@@ -296,9 +297,24 @@ var AtRulePreludeParser = class {
|
|
|
296
297
|
this.next_token();
|
|
297
298
|
let token_type = this.lexer.token_type;
|
|
298
299
|
if (token_type === 1) {
|
|
299
|
-
let
|
|
300
|
+
let name_start = this.lexer.token_start;
|
|
301
|
+
let name_end = this.lexer.token_end;
|
|
302
|
+
while (this.lexer.pos < this.prelude_end) {
|
|
303
|
+
let saved = this.lexer.save_position();
|
|
304
|
+
if (this.next_token() !== 9 || this.source.charCodeAt(this.lexer.token_start) !== 46 || this.lexer.token_start !== name_end) {
|
|
305
|
+
this.lexer.restore_position(saved);
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
let dot_end = this.lexer.token_end;
|
|
309
|
+
if (this.next_token() !== 1 || this.lexer.token_start !== dot_end) {
|
|
310
|
+
this.lexer.restore_position(saved);
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
name_end = this.lexer.token_end;
|
|
314
|
+
}
|
|
315
|
+
let layer = this.create_node(37, name_start, name_end);
|
|
300
316
|
this.arena.set_content_start_delta(layer, 0);
|
|
301
|
-
this.arena.set_content_length(layer,
|
|
317
|
+
this.arena.set_content_length(layer, name_end - name_start);
|
|
302
318
|
nodes.push(layer);
|
|
303
319
|
} else if (token_type === 18) continue;
|
|
304
320
|
else if (token_type === 13) continue;
|
|
@@ -457,34 +473,8 @@ var AtRulePreludeParser = class {
|
|
|
457
473
|
}
|
|
458
474
|
return this.lexer.next_token_fast(false);
|
|
459
475
|
}
|
|
460
|
-
parse_value_token() {
|
|
461
|
-
switch (this.lexer.token_type) {
|
|
462
|
-
case 1: return this.create_node(10, this.lexer.token_start, this.lexer.token_end);
|
|
463
|
-
case 10: return this.create_node(11, this.lexer.token_start, this.lexer.token_end);
|
|
464
|
-
case 11:
|
|
465
|
-
case 12: return this.create_node(12, this.lexer.token_start, this.lexer.token_end);
|
|
466
|
-
case 5: return this.create_node(13, this.lexer.token_start, this.lexer.token_end);
|
|
467
|
-
default: return null;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
476
|
parse_feature_value(start, end) {
|
|
471
|
-
|
|
472
|
-
this.lexer.seek(start, this.lexer.line, this.lexer.column);
|
|
473
|
-
let nodes = [];
|
|
474
|
-
while (this.lexer.pos < end) {
|
|
475
|
-
this.lexer.next_token_fast(false);
|
|
476
|
-
if (this.lexer.token_start >= end) break;
|
|
477
|
-
let all_whitespace = true;
|
|
478
|
-
for (let i = this.lexer.token_start; i < this.lexer.token_end && i < end; i++) if (!is_whitespace(this.source.charCodeAt(i))) {
|
|
479
|
-
all_whitespace = false;
|
|
480
|
-
break;
|
|
481
|
-
}
|
|
482
|
-
if (all_whitespace) continue;
|
|
483
|
-
let node = this.parse_value_token();
|
|
484
|
-
if (node !== null) nodes.push(node);
|
|
485
|
-
}
|
|
486
|
-
this.lexer.restore_position(saved_position);
|
|
487
|
-
return nodes;
|
|
477
|
+
return this.value_node_parser.parse_chain(start, end, this.lexer.line, this.lexer.column);
|
|
488
478
|
}
|
|
489
479
|
parse_namespace_prelude() {
|
|
490
480
|
let nodes = [];
|
|
@@ -513,7 +503,7 @@ var AtRulePreludeParser = class {
|
|
|
513
503
|
let depth = 1;
|
|
514
504
|
while (this.lexer.pos < this.prelude_end && depth > 0) {
|
|
515
505
|
this.next_token();
|
|
516
|
-
if (this.lexer.token_type === 21) depth++;
|
|
506
|
+
if (this.lexer.token_type === 21 || this.lexer.token_type === 2) depth++;
|
|
517
507
|
else if (this.lexer.token_type === 22) depth--;
|
|
518
508
|
}
|
|
519
509
|
let content_end = this.lexer.token_start;
|
|
@@ -543,7 +533,8 @@ var AtRulePreludeParser = class {
|
|
|
543
533
|
}
|
|
544
534
|
parse_feature_range(feature_start, feature_end, content_start, content_end) {
|
|
545
535
|
let range_node = this.create_node(39, feature_start, feature_end);
|
|
546
|
-
let
|
|
536
|
+
let first_child = 0;
|
|
537
|
+
let last_child = 0;
|
|
547
538
|
let feature_name_start = -1;
|
|
548
539
|
let feature_name_end = -1;
|
|
549
540
|
let pos = content_start;
|
|
@@ -555,7 +546,9 @@ var AtRulePreludeParser = class {
|
|
|
555
546
|
let op_start = pos++;
|
|
556
547
|
if (pos < content_end && this.source.charCodeAt(pos) === 61) pos++;
|
|
557
548
|
let op = this.create_node(38, op_start, pos);
|
|
558
|
-
|
|
549
|
+
if (first_child === 0) first_child = op;
|
|
550
|
+
else this.arena.set_next_sibling(last_child, op);
|
|
551
|
+
last_child = op;
|
|
559
552
|
} else {
|
|
560
553
|
let saved = this.lexer.save_position();
|
|
561
554
|
this.lexer.pos = pos;
|
|
@@ -564,8 +557,12 @@ var AtRulePreludeParser = class {
|
|
|
564
557
|
feature_name_start = this.lexer.token_start;
|
|
565
558
|
feature_name_end = this.lexer.token_end;
|
|
566
559
|
} else {
|
|
567
|
-
let
|
|
568
|
-
|
|
560
|
+
let value_first = this.parse_feature_value(this.lexer.token_start, this.lexer.token_end);
|
|
561
|
+
if (value_first !== 0) {
|
|
562
|
+
if (first_child === 0) first_child = value_first;
|
|
563
|
+
else this.arena.set_next_sibling(last_child, value_first);
|
|
564
|
+
last_child = this.arena.get_last_sibling(value_first);
|
|
565
|
+
}
|
|
569
566
|
}
|
|
570
567
|
pos = this.lexer.pos;
|
|
571
568
|
this.lexer.restore_position(saved);
|
|
@@ -575,7 +572,7 @@ var AtRulePreludeParser = class {
|
|
|
575
572
|
this.arena.set_content_start_delta(range_node, feature_name_start - feature_start);
|
|
576
573
|
this.arena.set_content_length(range_node, feature_name_end - feature_name_start);
|
|
577
574
|
}
|
|
578
|
-
this.arena.
|
|
575
|
+
if (first_child !== 0) this.arena.set_first_child(range_node, first_child);
|
|
579
576
|
return range_node;
|
|
580
577
|
}
|
|
581
578
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { l as CSSDataArena } from "./arena-
|
|
1
|
+
import { l as CSSDataArena } from "./arena-Bx5vp6Sl.js";
|
|
2
2
|
import { n as Lexer } from "./tokenize-DeZYFa9R.js";
|
|
3
|
-
import { d as Declaration } from "./node-types-
|
|
4
|
-
|
|
3
|
+
import { d as Declaration } from "./node-types-BRnQyc9B.js";
|
|
5
4
|
//#region src/parse-declaration.d.ts
|
|
6
5
|
/** @internal */
|
|
7
6
|
declare class DeclarationParser {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as Lexer } from "./tokenize-BiRLfVbm.js";
|
|
2
|
-
import { l as CSSDataArena } from "./arena-
|
|
3
|
-
import { i as is_vendor_prefixed } from "./parse-dimension-
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { i as trim_boundaries } from "./parse-utils-
|
|
2
|
+
import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
|
|
3
|
+
import { i as is_vendor_prefixed } from "./parse-dimension-ouWXNHdx.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-B3EzCweR.js";
|
|
5
|
+
import { i as trim_boundaries } from "./parse-utils-D7srNG13.js";
|
|
6
6
|
import { ValueParser } from "./parse-value.js";
|
|
7
7
|
//#region src/parse-declaration.ts
|
|
8
8
|
/** @internal */
|
|
@@ -110,17 +110,17 @@ var DeclarationParser = class {
|
|
|
110
110
|
this.arena.set_value_length(declaration, trimmed[1] - trimmed[0]);
|
|
111
111
|
if (this.value_parser) {
|
|
112
112
|
let valueNode = this.value_parser.parse_value(value_start, trimmed[1], value_start_line, value_start_column);
|
|
113
|
-
this.arena.
|
|
113
|
+
this.arena.set_first_child(declaration, valueNode);
|
|
114
114
|
} else {
|
|
115
115
|
let rawNode = this.arena.create_node(8, trimmed[0], trimmed[1] - trimmed[0], value_start_line, value_start_column);
|
|
116
|
-
this.arena.
|
|
116
|
+
this.arena.set_first_child(declaration, rawNode);
|
|
117
117
|
}
|
|
118
118
|
} else {
|
|
119
119
|
this.arena.set_value_start_delta(declaration, value_start - prop_start);
|
|
120
120
|
this.arena.set_value_length(declaration, 0);
|
|
121
121
|
if (this.value_parser) {
|
|
122
122
|
let valueNode = this.value_parser.parse_value(value_start, value_start, value_start_line, value_start_column);
|
|
123
|
-
this.arena.
|
|
123
|
+
this.arena.set_first_child(declaration, valueNode);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
if (has_important) this.arena.set_flag(declaration, 1);
|
|
@@ -27,15 +27,7 @@ function str_equals(a, b) {
|
|
|
27
27
|
}
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Case-insensitive ASCII prefix check without allocations
|
|
32
|
-
* Returns true if string `str` starts with prefix (case-insensitive)
|
|
33
|
-
*
|
|
34
|
-
* IMPORTANT: prefix MUST be lowercase for correct comparison
|
|
35
|
-
*
|
|
36
|
-
* @param str - The string to check
|
|
37
|
-
* @param prefix - The lowercase prefix to match against
|
|
38
|
-
*/
|
|
30
|
+
/** Case-insensitive ASCII prefix check without allocations. `prefix` MUST be lowercase. */
|
|
39
31
|
function str_starts_with(str, prefix) {
|
|
40
32
|
if (str.length < prefix.length) return false;
|
|
41
33
|
for (let i = 0; i < prefix.length; i++) {
|
|
@@ -46,16 +38,7 @@ function str_starts_with(str, prefix) {
|
|
|
46
38
|
}
|
|
47
39
|
return true;
|
|
48
40
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Case-insensitive character/substring search without allocations
|
|
51
|
-
* Returns the index of the first occurrence of searchChar (case-insensitive)
|
|
52
|
-
*
|
|
53
|
-
* IMPORTANT: searchChar MUST be lowercase for correct comparison
|
|
54
|
-
*
|
|
55
|
-
* @param str - The string to search in
|
|
56
|
-
* @param searchChar - The lowercase character/substring to find
|
|
57
|
-
* @returns The index of the first match, or -1 if not found
|
|
58
|
-
*/
|
|
41
|
+
/** Case-insensitive substring search without allocations, or -1 if not found. `searchChar` MUST be lowercase. */
|
|
59
42
|
function str_index_of(str, searchChar) {
|
|
60
43
|
if (searchChar.length === 0) return -1;
|
|
61
44
|
if (searchChar.length === 1) {
|
|
@@ -93,37 +76,12 @@ function is_vendor_prefixed(source, start, end) {
|
|
|
93
76
|
for (let i = start + 2; i < end; i++) if (source.charCodeAt(i) === 45) return true;
|
|
94
77
|
return false;
|
|
95
78
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Check if a string is a CSS custom property (starts with --)
|
|
98
|
-
*
|
|
99
|
-
* @param str - The string to check
|
|
100
|
-
* @returns true if the string starts with -- (custom property)
|
|
101
|
-
*
|
|
102
|
-
* Examples:
|
|
103
|
-
* - `--primary-color` → true
|
|
104
|
-
* - `--my-var` → true
|
|
105
|
-
* - `-webkit-transform` → false (vendor prefix, not custom)
|
|
106
|
-
* - `border-radius` → false (standard property)
|
|
107
|
-
* - `color` → false
|
|
108
|
-
*/
|
|
79
|
+
/** True if the string is a CSS custom property (starts with `--`). */
|
|
109
80
|
function is_custom(str) {
|
|
110
81
|
if (str.length < 3) return false;
|
|
111
82
|
return str.charCodeAt(0) === 45 && str.charCodeAt(1) === 45;
|
|
112
83
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Strip vendor prefix from a string
|
|
115
|
-
*
|
|
116
|
-
* @param str - The string to strip vendor prefix from
|
|
117
|
-
* @returns The string without vendor prefix, or original string if no prefix found
|
|
118
|
-
*
|
|
119
|
-
* Examples:
|
|
120
|
-
* - `-webkit-keyframes` → `keyframes`
|
|
121
|
-
* - `-moz-appearance` → `appearance`
|
|
122
|
-
* - `-ms-filter` → `filter`
|
|
123
|
-
* - `-o-border-image` → `border-image`
|
|
124
|
-
* - `keyframes` → `keyframes` (no change)
|
|
125
|
-
* - `--custom-property` → `--custom-property` (custom property, not vendor prefix)
|
|
126
|
-
*/
|
|
84
|
+
/** Strip a vendor prefix, e.g. `-webkit-keyframes` → `keyframes`. Returns the input unchanged if it has no prefix. */
|
|
127
85
|
function strip_vendor_prefix(str) {
|
|
128
86
|
if (!is_vendor_prefixed(str)) return str;
|
|
129
87
|
for (let i = 2; i < str.length; i++) if (str.charCodeAt(i) === 45) return str.substring(i + 1);
|
|
@@ -131,18 +89,7 @@ function strip_vendor_prefix(str) {
|
|
|
131
89
|
}
|
|
132
90
|
//#endregion
|
|
133
91
|
//#region src/parse-dimension.ts
|
|
134
|
-
/**
|
|
135
|
-
* Parse a dimension string into numeric value and unit
|
|
136
|
-
*
|
|
137
|
-
* @param text - Dimension text like "100px", "50%", "1.5em"
|
|
138
|
-
* @returns Object with value (number) and unit (string)
|
|
139
|
-
*
|
|
140
|
-
* Examples:
|
|
141
|
-
* - "100px" → { value: 100, unit: "px" }
|
|
142
|
-
* - "50%" → { value: 50, unit: "%" }
|
|
143
|
-
* - "1.5em" → { value: 1.5, unit: "em" }
|
|
144
|
-
* - "-10rem" → { value: -10, unit: "rem" }
|
|
145
|
-
*/
|
|
92
|
+
/** Parse a dimension string into value and unit, e.g. "100px" → { value: 100, unit: "px" } or "2%" → { value: 2, unit: "%" } */
|
|
146
93
|
function parse_dimension(text) {
|
|
147
94
|
let num_end = 0;
|
|
148
95
|
for (let i = 0; i < text.length; i++) {
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
//#region src/parse-dimension.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Parse a dimension string into numeric value and unit
|
|
4
|
-
*
|
|
5
|
-
* @param text - Dimension text like "100px", "50%", "1.5em"
|
|
6
|
-
* @returns Object with value (number) and unit (string)
|
|
7
|
-
*
|
|
8
|
-
* Examples:
|
|
9
|
-
* - "100px" → { value: 100, unit: "px" }
|
|
10
|
-
* - "50%" → { value: 50, unit: "%" }
|
|
11
|
-
* - "1.5em" → { value: 1.5, unit: "em" }
|
|
12
|
-
* - "-10rem" → { value: -10, unit: "rem" }
|
|
13
|
-
*/
|
|
2
|
+
/** Parse a dimension string into value and unit, e.g. "100px" → { value: 100, unit: "px" } or "2%" → { value: 2, unit: "%" } */
|
|
14
3
|
declare function parse_dimension(text: string): {
|
|
15
4
|
value: number;
|
|
16
5
|
unit: string;
|
package/dist/parse-dimension.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as parse_dimension } from "./parse-dimension-
|
|
1
|
+
import { t as parse_dimension } from "./parse-dimension-ouWXNHdx.js";
|
|
2
2
|
export { parse_dimension };
|
package/dist/parse-selector.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { l as CSSDataArena } from "./arena-
|
|
2
|
-
import { F as Selector, I as SelectorList } from "./node-types-
|
|
3
|
-
|
|
1
|
+
import { l as CSSDataArena } from "./arena-Bx5vp6Sl.js";
|
|
2
|
+
import { F as Selector, I as SelectorList } from "./node-types-BRnQyc9B.js";
|
|
4
3
|
//#region src/parse-selector.d.ts
|
|
5
4
|
/** @internal */
|
|
6
5
|
declare class SelectorParser {
|
package/dist/parse-selector.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as Lexer } from "./tokenize-BiRLfVbm.js";
|
|
2
|
-
import { l as CSSDataArena } from "./arena-
|
|
3
|
-
import { a as is_whitespace, n as is_combinator, o as str_equals } from "./parse-dimension-
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { n as skip_whitespace_and_comments_forward, r as skip_whitespace_forward, t as skip_whitespace_and_comments_backward } from "./parse-utils-
|
|
2
|
+
import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
|
|
3
|
+
import { a as is_whitespace, n as is_combinator, o as str_equals } from "./parse-dimension-ouWXNHdx.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-B3EzCweR.js";
|
|
5
|
+
import { n as skip_whitespace_and_comments_forward, r as skip_whitespace_forward, t as skip_whitespace_and_comments_backward } from "./parse-utils-D7srNG13.js";
|
|
6
6
|
import { ANplusBParser } from "./parse-anplusb.js";
|
|
7
7
|
//#region src/parse-selector.ts
|
|
8
8
|
/** @internal */
|
|
@@ -25,7 +25,8 @@ var SelectorParser = class {
|
|
|
25
25
|
return this.parse_selector_list(allow_relative);
|
|
26
26
|
}
|
|
27
27
|
parse_selector_list(allow_relative = true) {
|
|
28
|
-
let
|
|
28
|
+
let first_selector = 0;
|
|
29
|
+
let last_selector = 0;
|
|
29
30
|
let list_start = this.lexer.pos;
|
|
30
31
|
let list_line = this.lexer.line;
|
|
31
32
|
let list_column = this.lexer.column;
|
|
@@ -38,14 +39,10 @@ var SelectorParser = class {
|
|
|
38
39
|
let selector_wrapper = this.arena.create_node(5, selector_start, this.lexer.pos - selector_start, selector_line, selector_column);
|
|
39
40
|
this.arena.set_content_start_delta(selector_wrapper, 0);
|
|
40
41
|
this.arena.set_content_length(selector_wrapper, this.lexer.pos - selector_start);
|
|
41
|
-
let last_component = complex_selector;
|
|
42
|
-
let next_sibling = this.arena.get_next_sibling(last_component);
|
|
43
|
-
while (next_sibling !== 0) {
|
|
44
|
-
last_component = next_sibling;
|
|
45
|
-
next_sibling = this.arena.get_next_sibling(last_component);
|
|
46
|
-
}
|
|
47
42
|
this.arena.set_first_child(selector_wrapper, complex_selector);
|
|
48
|
-
|
|
43
|
+
if (first_selector === 0) first_selector = selector_wrapper;
|
|
44
|
+
else this.arena.set_next_sibling(last_selector, selector_wrapper);
|
|
45
|
+
last_selector = selector_wrapper;
|
|
49
46
|
}
|
|
50
47
|
this.skip_whitespace();
|
|
51
48
|
if (this.lexer.pos >= this.selector_end) break;
|
|
@@ -55,15 +52,16 @@ var SelectorParser = class {
|
|
|
55
52
|
continue;
|
|
56
53
|
} else break;
|
|
57
54
|
}
|
|
58
|
-
if (
|
|
55
|
+
if (first_selector !== 0) {
|
|
59
56
|
let list_node = this.arena.create_node(20, list_start, this.lexer.pos - list_start, list_line, list_column);
|
|
60
|
-
this.arena.
|
|
57
|
+
this.arena.set_first_child(list_node, first_selector);
|
|
61
58
|
return list_node;
|
|
62
59
|
}
|
|
63
60
|
return null;
|
|
64
61
|
}
|
|
65
62
|
parse_complex_selector(allow_relative = true) {
|
|
66
|
-
let
|
|
63
|
+
let first_component = 0;
|
|
64
|
+
let chain_tail = 0;
|
|
67
65
|
this.skip_whitespace();
|
|
68
66
|
if (allow_relative && this.lexer.pos < this.selector_end) {
|
|
69
67
|
const saved = this.lexer.save_position();
|
|
@@ -72,7 +70,8 @@ var SelectorParser = class {
|
|
|
72
70
|
let ch = this.source.charCodeAt(this.lexer.token_start);
|
|
73
71
|
if (ch === 62 || ch === 43 || ch === 126) {
|
|
74
72
|
let combinator = this.create_node_at(27, this.lexer.token_start, this.lexer.token_end, this.lexer.token_line, this.lexer.token_column);
|
|
75
|
-
|
|
73
|
+
first_component = combinator;
|
|
74
|
+
chain_tail = combinator;
|
|
76
75
|
this.skip_whitespace();
|
|
77
76
|
} else this.lexer.restore_position(saved);
|
|
78
77
|
} else this.lexer.restore_position(saved);
|
|
@@ -80,10 +79,13 @@ var SelectorParser = class {
|
|
|
80
79
|
while (this.lexer.pos < this.selector_end) {
|
|
81
80
|
let compound = this.parse_compound_selector();
|
|
82
81
|
if (compound === null) break;
|
|
83
|
-
|
|
82
|
+
if (chain_tail === 0) first_component = compound;
|
|
83
|
+
else this.arena.set_next_sibling(chain_tail, compound);
|
|
84
|
+
chain_tail = this.arena.get_last_sibling(compound);
|
|
84
85
|
let combinator = this.try_parse_combinator();
|
|
85
86
|
if (combinator !== null) {
|
|
86
|
-
|
|
87
|
+
this.arena.set_next_sibling(chain_tail, combinator);
|
|
88
|
+
chain_tail = combinator;
|
|
87
89
|
this.skip_whitespace();
|
|
88
90
|
continue;
|
|
89
91
|
}
|
|
@@ -101,16 +103,11 @@ var SelectorParser = class {
|
|
|
101
103
|
this.lexer.restore_position(saved);
|
|
102
104
|
break;
|
|
103
105
|
}
|
|
104
|
-
|
|
105
|
-
for (let i = 0; i < components.length - 1; i++) {
|
|
106
|
-
let last_node = components[i];
|
|
107
|
-
while (this.arena.get_next_sibling(last_node) !== 0) last_node = this.arena.get_next_sibling(last_node);
|
|
108
|
-
this.arena.set_next_sibling(last_node, components[i + 1]);
|
|
109
|
-
}
|
|
110
|
-
return components[0];
|
|
106
|
+
return first_component === 0 ? null : first_component;
|
|
111
107
|
}
|
|
112
108
|
parse_compound_selector() {
|
|
113
|
-
let
|
|
109
|
+
let first_part = 0;
|
|
110
|
+
let last_part = 0;
|
|
114
111
|
while (this.lexer.pos < this.selector_end) {
|
|
115
112
|
const saved = this.lexer.save_position();
|
|
116
113
|
this.lexer.next_token_fast(false);
|
|
@@ -121,11 +118,11 @@ var SelectorParser = class {
|
|
|
121
118
|
this.lexer.restore_position(saved);
|
|
122
119
|
break;
|
|
123
120
|
}
|
|
124
|
-
|
|
121
|
+
if (first_part === 0) first_part = part;
|
|
122
|
+
else this.arena.set_next_sibling(last_part, part);
|
|
123
|
+
last_part = part;
|
|
125
124
|
}
|
|
126
|
-
|
|
127
|
-
for (let i = 0; i < parts.length - 1; i++) this.arena.set_next_sibling(parts[i], parts[i + 1]);
|
|
128
|
-
return parts[0];
|
|
125
|
+
return first_part === 0 ? null : first_part;
|
|
129
126
|
}
|
|
130
127
|
parse_simple_selector() {
|
|
131
128
|
let token_type = this.lexer.token_type;
|
|
@@ -1,27 +1,11 @@
|
|
|
1
|
-
import { a as is_whitespace } from "./parse-dimension-
|
|
1
|
+
import { a as is_whitespace } from "./parse-dimension-ouWXNHdx.js";
|
|
2
2
|
//#region src/parse-utils.ts
|
|
3
|
-
/**
|
|
4
|
-
* Skip whitespace forward from a position
|
|
5
|
-
*
|
|
6
|
-
* @param source - The source string
|
|
7
|
-
* @param pos - Starting position
|
|
8
|
-
* @param end - End boundary (exclusive)
|
|
9
|
-
* @returns New position after skipping whitespace
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
3
|
+
/** @internal */
|
|
12
4
|
function skip_whitespace_forward(source, pos, end) {
|
|
13
5
|
while (pos < end && is_whitespace(source.charCodeAt(pos))) pos++;
|
|
14
6
|
return pos;
|
|
15
7
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Skip whitespace and comments forward from a position
|
|
18
|
-
*
|
|
19
|
-
* @param source - The source string
|
|
20
|
-
* @param pos - Starting position
|
|
21
|
-
* @param end - End boundary (exclusive)
|
|
22
|
-
* @returns New position after skipping whitespace/comments
|
|
23
|
-
* @internal
|
|
24
|
-
*/
|
|
8
|
+
/** @internal */
|
|
25
9
|
function skip_whitespace_and_comments_forward(source, pos, end) {
|
|
26
10
|
while (pos < end) {
|
|
27
11
|
let ch = source.charCodeAt(pos);
|
|
@@ -44,15 +28,7 @@ function skip_whitespace_and_comments_forward(source, pos, end) {
|
|
|
44
28
|
}
|
|
45
29
|
return pos;
|
|
46
30
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Skip whitespace and comments backward from a position
|
|
49
|
-
*
|
|
50
|
-
* @param source - The source string
|
|
51
|
-
* @param pos - Starting position (exclusive, scanning backward from pos-1)
|
|
52
|
-
* @param start - Start boundary (inclusive, won't go before this)
|
|
53
|
-
* @returns New position after skipping whitespace/comments backward
|
|
54
|
-
* @internal
|
|
55
|
-
*/
|
|
31
|
+
/** @internal */
|
|
56
32
|
function skip_whitespace_and_comments_backward(source, pos, start) {
|
|
57
33
|
while (pos > start) {
|
|
58
34
|
let ch = source.charCodeAt(pos - 1);
|
|
@@ -76,17 +52,8 @@ function skip_whitespace_and_comments_backward(source, pos, start) {
|
|
|
76
52
|
return pos;
|
|
77
53
|
}
|
|
78
54
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @param source - The source string
|
|
82
|
-
* @param start - Start offset in source
|
|
83
|
-
* @param end - End offset in source
|
|
84
|
-
* @returns [trimmed_start, trimmed_end] or null if all whitespace/comments
|
|
55
|
+
* Trims whitespace and CSS comments from both ends; returns null if the range is only whitespace/comments.
|
|
85
56
|
* @internal
|
|
86
|
-
*
|
|
87
|
-
* Skips whitespace (space, tab, newline, CR, FF) and CSS comments from both ends
|
|
88
|
-
* of the specified range. Returns the trimmed boundaries or null if the range
|
|
89
|
-
* contains only whitespace and comments.
|
|
90
57
|
*/
|
|
91
58
|
function trim_boundaries(source, start, end) {
|
|
92
59
|
start = skip_whitespace_and_comments_forward(source, start, end);
|