@projectwallace/css-parser 0.13.5 → 0.13.8

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-DqyvMXBN.d.ts +313 -0
  2. package/dist/css-node-Uj4oBgaw.js +647 -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 -167
  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 +37 -8
  20. package/dist/parse.js +252 -353
  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 -60
  27. package/dist/arena.js +0 -291
  28. package/dist/char-types.d.ts +0 -14
  29. package/dist/char-types.js +0 -53
  30. package/dist/constants.d.ts +0 -44
  31. package/dist/constants.js +0 -51
  32. package/dist/css-node.d.ts +0 -203
  33. package/dist/css-node.js +0 -498
  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
package/dist/parse.js CHANGED
@@ -1,356 +1,255 @@
1
- import { Lexer } from './tokenize.js';
2
- import { CSSDataArena, STYLESHEET, STYLE_RULE, FLAG_HAS_BLOCK, BLOCK, FLAG_HAS_DECLARATIONS, SELECTOR_LIST, RAW, AT_RULE, AT_RULE_PRELUDE } from './arena.js';
3
- import { CSSNode } from './css-node.js';
4
- import { SelectorParser } from './parse-selector.js';
5
- import { AtRulePreludeParser } from './parse-atrule-prelude.js';
6
- import { DeclarationParser } from './parse-declaration.js';
7
- import { TOKEN_EOF, TOKEN_AT_KEYWORD, TOKEN_LEFT_BRACE, TOKEN_RIGHT_BRACE, TOKEN_IDENT, TOKEN_HASH, TOKEN_DELIM, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_LEFT_BRACKET, TOKEN_RIGHT_BRACKET, TOKEN_COMMA, TOKEN_COLON, TOKEN_SEMICOLON, TOKEN_FUNCTION } from './token-types.js';
8
- import { trim_boundaries } from './parse-utils.js';
9
- import { CHAR_PERIOD, CHAR_GREATER_THAN, CHAR_PLUS, CHAR_TILDE, CHAR_AMPERSAND } from './string-utils.js';
10
-
11
- let DECLARATION_AT_RULES = /* @__PURE__ */ new Set(["font-face", "font-feature-values", "page", "property", "counter-style", "color-profile", "font-palette-values", "position-try", "view-transition"]);
12
- let CONDITIONAL_AT_RULES = /* @__PURE__ */ new Set(["media", "supports", "container", "layer", "nest", "scope", "starting-style"]);
13
- class Parser {
14
- source;
15
- lexer;
16
- arena;
17
- selector_parser;
18
- prelude_parser;
19
- declaration_parser;
20
- parse_values_enabled;
21
- parse_selectors_enabled;
22
- parse_atrule_preludes_enabled;
23
- constructor(source, options) {
24
- this.source = source;
25
- let opts = options || {};
26
- this.parse_values_enabled = opts.parse_values ?? true;
27
- this.parse_selectors_enabled = opts.parse_selectors ?? true;
28
- this.parse_atrule_preludes_enabled = opts.parse_atrule_preludes ?? true;
29
- this.lexer = new Lexer(source, opts.on_comment);
30
- let capacity = CSSDataArena.capacity_for_source(source.length);
31
- this.arena = new CSSDataArena(capacity);
32
- this.selector_parser = this.parse_selectors_enabled ? new SelectorParser(this.arena, source) : null;
33
- this.prelude_parser = this.parse_atrule_preludes_enabled ? new AtRulePreludeParser(this.arena, source) : null;
34
- this.declaration_parser = new DeclarationParser(this.arena, source, this.parse_values_enabled);
35
- }
36
- // Get the arena (for internal/advanced use only)
37
- get_arena() {
38
- return this.arena;
39
- }
40
- // Get the source code
41
- get_source() {
42
- return this.source;
43
- }
44
- // Advance to the next token, skipping whitespace
45
- next_token() {
46
- this.lexer.next_token_fast(true);
47
- }
48
- // Peek at current token type
49
- peek_type() {
50
- return this.lexer.token_type;
51
- }
52
- // Check if we're at the end of input
53
- is_eof() {
54
- return this.peek_type() === TOKEN_EOF;
55
- }
56
- // Parse the entire stylesheet and return the root CSSNode
57
- parse() {
58
- this.next_token();
59
- let stylesheet = this.arena.create_node(STYLESHEET, 0, this.source.length, 1, 1);
60
- let rules = [];
61
- while (!this.is_eof()) {
62
- let rule = this.parse_rule();
63
- if (rule !== null) {
64
- rules.push(rule);
65
- } else {
66
- this.next_token();
67
- }
68
- }
69
- this.arena.append_children(stylesheet, rules);
70
- return new CSSNode(this.arena, this.source, stylesheet);
71
- }
72
- // Parse a rule (style rule or at-rule)
73
- parse_rule() {
74
- if (this.is_eof()) {
75
- return null;
76
- }
77
- if (this.peek_type() === TOKEN_AT_KEYWORD) {
78
- return this.parse_atrule();
79
- }
80
- return this.parse_style_rule();
81
- }
82
- // Parse a style rule: selector { declarations }
83
- parse_style_rule() {
84
- if (this.is_eof()) return null;
85
- let rule_start = this.lexer.token_start;
86
- let rule_line = this.lexer.token_line;
87
- let rule_column = this.lexer.token_column;
88
- let style_rule = this.arena.create_node(
89
- STYLE_RULE,
90
- rule_start,
91
- 0,
92
- // length unknown yet
93
- rule_line,
94
- rule_column
95
- );
96
- let selector = this.parse_selector();
97
- if (this.peek_type() !== TOKEN_LEFT_BRACE) {
98
- return null;
99
- }
100
- let block_start = this.lexer.token_end;
101
- this.next_token();
102
- this.arena.set_flag(style_rule, FLAG_HAS_BLOCK);
103
- let block_line = this.lexer.token_line;
104
- let block_column = this.lexer.token_column;
105
- let block_node = this.arena.create_node(
106
- BLOCK,
107
- block_start,
108
- 0,
109
- // length unknown yet
110
- block_line,
111
- block_column
112
- );
113
- let block_children = [];
114
- while (!this.is_eof()) {
115
- let token_type = this.peek_type();
116
- if (token_type === TOKEN_RIGHT_BRACE) break;
117
- if (token_type === TOKEN_AT_KEYWORD) {
118
- let nested_at_rule = this.parse_atrule();
119
- if (nested_at_rule !== null) {
120
- block_children.push(nested_at_rule);
121
- } else {
122
- this.next_token();
123
- }
124
- continue;
125
- }
126
- let declaration = this.parse_declaration();
127
- if (declaration !== null) {
128
- this.arena.set_flag(style_rule, FLAG_HAS_DECLARATIONS);
129
- block_children.push(declaration);
130
- continue;
131
- }
132
- let nested_rule = this.parse_style_rule();
133
- if (nested_rule !== null) {
134
- block_children.push(nested_rule);
135
- } else {
136
- this.next_token();
137
- }
138
- }
139
- let block_end = this.lexer.token_start;
140
- let rule_end = this.lexer.token_end;
141
- if (this.peek_type() === TOKEN_RIGHT_BRACE) {
142
- block_end = this.lexer.token_start;
143
- rule_end = this.lexer.token_end;
144
- this.next_token();
145
- }
146
- this.arena.set_length(block_node, block_end - block_start);
147
- this.arena.append_children(block_node, block_children);
148
- this.arena.set_length(style_rule, rule_end - rule_start);
149
- let style_rule_children = [];
150
- if (selector !== null) {
151
- style_rule_children.push(selector);
152
- }
153
- style_rule_children.push(block_node);
154
- this.arena.append_children(style_rule, style_rule_children);
155
- return style_rule;
156
- }
157
- // Parse a selector (everything before '{')
158
- parse_selector() {
159
- if (this.is_eof()) return null;
160
- let selector_start = this.lexer.token_start;
161
- let selector_line = this.lexer.token_line;
162
- let selector_column = this.lexer.token_column;
163
- let last_end = this.lexer.token_end;
164
- while (!this.is_eof() && this.peek_type() !== TOKEN_LEFT_BRACE) {
165
- last_end = this.lexer.token_end;
166
- this.next_token();
167
- }
168
- if (this.parse_selectors_enabled && this.selector_parser) {
169
- let selector = this.selector_parser.parse_selector(selector_start, last_end, selector_line, selector_column);
170
- if (selector !== null) {
171
- return selector;
172
- }
173
- }
174
- let node_type = this.parse_selectors_enabled ? SELECTOR_LIST : RAW;
175
- let selector_node = this.arena.create_node(node_type, selector_start, last_end - selector_start, selector_line, selector_column);
176
- return selector_node;
177
- }
178
- // Parse a declaration: property: value;
179
- parse_declaration() {
180
- const token_type = this.peek_type();
181
- if (token_type === TOKEN_IDENT || token_type === TOKEN_AT_KEYWORD || token_type === TOKEN_HASH) {
182
- return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
183
- }
184
- if (token_type === TOKEN_DELIM || token_type === TOKEN_LEFT_PAREN || token_type === TOKEN_RIGHT_PAREN || token_type === TOKEN_LEFT_BRACKET || token_type === TOKEN_RIGHT_BRACKET || token_type === TOKEN_COMMA || token_type === TOKEN_COLON) {
185
- const char_code = this.source.charCodeAt(this.lexer.token_start);
186
- if (char_code === CHAR_PERIOD || char_code === CHAR_GREATER_THAN || char_code === CHAR_PLUS || char_code === CHAR_TILDE || char_code === CHAR_AMPERSAND) {
187
- return null;
188
- }
189
- return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
190
- }
191
- return null;
192
- }
193
- // Parse an at-rule: @media, @import, @font-face, etc.
194
- parse_atrule() {
195
- if (this.peek_type() !== TOKEN_AT_KEYWORD) {
196
- return null;
197
- }
198
- let at_rule_start = this.lexer.token_start;
199
- let at_rule_line = this.lexer.token_line;
200
- let at_rule_column = this.lexer.token_column;
201
- let name_start = this.lexer.token_start + 1;
202
- let name_length = this.lexer.token_end - name_start;
203
- let at_rule_name = this.source.substring(name_start, this.lexer.token_end);
204
- this.next_token();
205
- let at_rule = this.arena.create_node(
206
- AT_RULE,
207
- at_rule_start,
208
- 0,
209
- // length unknown yet
210
- at_rule_line,
211
- at_rule_column
212
- );
213
- this.arena.set_content_start_delta(at_rule, name_start - at_rule_start);
214
- this.arena.set_content_length(at_rule, name_length);
215
- let prelude_start = this.lexer.token_start;
216
- let prelude_end = prelude_start;
217
- let paren_depth = 0;
218
- while (!this.is_eof()) {
219
- let token_type = this.peek_type();
220
- if (token_type === TOKEN_LEFT_PAREN || token_type === TOKEN_FUNCTION) {
221
- paren_depth++;
222
- } else if (token_type === TOKEN_RIGHT_PAREN) {
223
- paren_depth--;
224
- }
225
- if (token_type === TOKEN_LEFT_BRACE && paren_depth === 0) break;
226
- if (token_type === TOKEN_SEMICOLON && paren_depth === 0) break;
227
- prelude_end = this.lexer.token_end;
228
- this.next_token();
229
- }
230
- let trimmed = trim_boundaries(this.source, prelude_start, prelude_end);
231
- let prelude_wrapper = null;
232
- if (trimmed) {
233
- this.arena.set_value_start_delta(at_rule, trimmed[0] - at_rule_start);
234
- this.arena.set_value_length(at_rule, trimmed[1] - trimmed[0]);
235
- if (this.prelude_parser) {
236
- prelude_wrapper = this.arena.create_node(AT_RULE_PRELUDE, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
237
- let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name, trimmed[0], trimmed[1], at_rule_line, at_rule_column);
238
- if (prelude_nodes.length > 0) {
239
- this.arena.append_children(prelude_wrapper, prelude_nodes);
240
- }
241
- } else {
242
- prelude_wrapper = this.arena.create_node(RAW, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
243
- }
244
- }
245
- let last_end = this.lexer.token_end;
246
- if (this.peek_type() === TOKEN_LEFT_BRACE) {
247
- let block_start = this.lexer.token_end;
248
- this.next_token();
249
- this.arena.set_flag(at_rule, FLAG_HAS_BLOCK);
250
- let block_line = this.lexer.token_line;
251
- let block_column = this.lexer.token_column;
252
- let block_node = this.arena.create_node(
253
- BLOCK,
254
- block_start,
255
- 0,
256
- // length unknown yet
257
- block_line,
258
- block_column
259
- );
260
- let has_declarations = this.atrule_has_declarations(at_rule_name);
261
- let is_conditional = this.atrule_is_conditional(at_rule_name);
262
- let block_children = [];
263
- if (has_declarations) {
264
- while (!this.is_eof()) {
265
- let token_type = this.peek_type();
266
- if (token_type === TOKEN_RIGHT_BRACE) break;
267
- let declaration = this.parse_declaration();
268
- if (declaration !== null) {
269
- block_children.push(declaration);
270
- } else {
271
- this.next_token();
272
- }
273
- }
274
- } else if (is_conditional) {
275
- while (!this.is_eof()) {
276
- let token_type = this.peek_type();
277
- if (token_type === TOKEN_RIGHT_BRACE) break;
278
- if (token_type === TOKEN_AT_KEYWORD) {
279
- let nested_at_rule = this.parse_atrule();
280
- if (nested_at_rule !== null) {
281
- block_children.push(nested_at_rule);
282
- } else {
283
- this.next_token();
284
- }
285
- continue;
286
- }
287
- let declaration = this.parse_declaration();
288
- if (declaration !== null) {
289
- block_children.push(declaration);
290
- continue;
291
- }
292
- let nested_rule = this.parse_style_rule();
293
- if (nested_rule !== null) {
294
- block_children.push(nested_rule);
295
- } else {
296
- this.next_token();
297
- }
298
- }
299
- } else {
300
- while (!this.is_eof()) {
301
- let token_type = this.peek_type();
302
- if (token_type === TOKEN_RIGHT_BRACE) break;
303
- let rule = this.parse_rule();
304
- if (rule !== null) {
305
- block_children.push(rule);
306
- } else {
307
- this.next_token();
308
- }
309
- }
310
- }
311
- if (this.peek_type() === TOKEN_RIGHT_BRACE) {
312
- let block_end = this.lexer.token_start;
313
- last_end = this.lexer.token_end;
314
- this.next_token();
315
- this.arena.set_length(block_node, block_end - block_start);
316
- } else {
317
- this.arena.set_length(block_node, last_end - block_start);
318
- }
319
- this.arena.append_children(block_node, block_children);
320
- let at_rule_children = [];
321
- if (prelude_wrapper !== null) {
322
- at_rule_children.push(prelude_wrapper);
323
- }
324
- at_rule_children.push(block_node);
325
- this.arena.set_length(at_rule, last_end - at_rule_start);
326
- this.arena.append_children(at_rule, at_rule_children);
327
- } else if (this.peek_type() === TOKEN_SEMICOLON) {
328
- last_end = this.lexer.token_end;
329
- this.next_token();
330
- this.arena.set_length(at_rule, last_end - at_rule_start);
331
- if (prelude_wrapper !== null) {
332
- this.arena.append_children(at_rule, [prelude_wrapper]);
333
- }
334
- } else {
335
- this.arena.set_length(at_rule, last_end - at_rule_start);
336
- if (prelude_wrapper !== null) {
337
- this.arena.append_children(at_rule, [prelude_wrapper]);
338
- }
339
- }
340
- return at_rule;
341
- }
342
- // Determine if an at-rule contains declarations or nested rules
343
- atrule_has_declarations(name) {
344
- return DECLARATION_AT_RULES.has(name.toLowerCase());
345
- }
346
- // Determine if an at-rule is conditional (can contain both declarations and rules in CSS Nesting)
347
- atrule_is_conditional(name) {
348
- return CONDITIONAL_AT_RULES.has(name.toLowerCase());
349
- }
350
- }
1
+ import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
+ import { i as trim_boundaries } from "./parse-utils-DnsZRpfd.js";
4
+ import { SelectorParser } from "./parse-selector.js";
5
+ import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
6
+ import { DeclarationParser } from "./parse-declaration.js";
7
+ //#region src/parse.ts
8
+ let DECLARATION_AT_RULES = new Set([
9
+ "font-face",
10
+ "font-feature-values",
11
+ "page",
12
+ "property",
13
+ "counter-style",
14
+ "color-profile",
15
+ "font-palette-values",
16
+ "position-try",
17
+ "view-transition"
18
+ ]);
19
+ /** @internal */
20
+ var Parser = class {
21
+ source;
22
+ lexer;
23
+ arena;
24
+ selector_parser;
25
+ prelude_parser;
26
+ declaration_parser;
27
+ parse_values_enabled;
28
+ parse_selectors_enabled;
29
+ parse_atrule_preludes_enabled;
30
+ constructor(source, options) {
31
+ this.source = source;
32
+ let opts = options || {};
33
+ this.parse_values_enabled = opts.parse_values ?? true;
34
+ this.parse_selectors_enabled = opts.parse_selectors ?? true;
35
+ this.parse_atrule_preludes_enabled = opts.parse_atrule_preludes ?? true;
36
+ this.lexer = new Lexer(source, opts.on_comment);
37
+ this.arena = new CSSDataArena(CSSDataArena.capacity_for_source(source.length));
38
+ this.selector_parser = this.parse_selectors_enabled ? new SelectorParser(this.arena, source) : null;
39
+ this.prelude_parser = this.parse_atrule_preludes_enabled ? new AtRulePreludeParser(this.arena, source) : null;
40
+ this.declaration_parser = new DeclarationParser(this.arena, source, this.parse_values_enabled);
41
+ }
42
+ get_arena() {
43
+ return this.arena;
44
+ }
45
+ get_source() {
46
+ return this.source;
47
+ }
48
+ next_token() {
49
+ this.lexer.next_token_fast(true);
50
+ }
51
+ peek_type() {
52
+ return this.lexer.token_type;
53
+ }
54
+ is_eof() {
55
+ return this.peek_type() === 26;
56
+ }
57
+ parse() {
58
+ this.next_token();
59
+ let stylesheet = this.arena.create_node(1, 0, this.source.length, 1, 1);
60
+ let rules = [];
61
+ while (!this.is_eof()) {
62
+ let rule = this.parse_rule();
63
+ if (rule !== null) rules.push(rule);
64
+ else this.next_token();
65
+ }
66
+ this.arena.append_children(stylesheet, rules);
67
+ return new CSSNode(this.arena, this.source, stylesheet);
68
+ }
69
+ parse_rule() {
70
+ if (this.is_eof()) return null;
71
+ if (this.peek_type() === 3) return this.parse_atrule();
72
+ return this.parse_style_rule();
73
+ }
74
+ parse_style_rule() {
75
+ if (this.is_eof()) return null;
76
+ let rule_start = this.lexer.token_start;
77
+ let rule_line = this.lexer.token_line;
78
+ let rule_column = this.lexer.token_column;
79
+ let style_rule = this.arena.create_node(2, rule_start, 0, rule_line, rule_column);
80
+ let selector = this.parse_selector();
81
+ if (this.peek_type() !== 23) return null;
82
+ let block_start = this.lexer.token_end;
83
+ this.next_token();
84
+ this.arena.set_flag(style_rule, 8);
85
+ let block_line = this.lexer.token_line;
86
+ let block_column = this.lexer.token_column;
87
+ let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
88
+ let block_children = [];
89
+ while (!this.is_eof()) {
90
+ let token_type = this.peek_type();
91
+ if (token_type === 24) break;
92
+ if (token_type === 3) {
93
+ let nested_at_rule = this.parse_atrule();
94
+ if (nested_at_rule !== null) block_children.push(nested_at_rule);
95
+ else this.next_token();
96
+ continue;
97
+ }
98
+ let declaration = this.parse_declaration();
99
+ if (declaration !== null) {
100
+ this.arena.set_flag(style_rule, 32);
101
+ block_children.push(declaration);
102
+ continue;
103
+ }
104
+ let nested_rule = this.parse_style_rule();
105
+ if (nested_rule !== null) block_children.push(nested_rule);
106
+ else this.next_token();
107
+ }
108
+ let block_end = this.lexer.token_start;
109
+ let rule_end = this.lexer.token_end;
110
+ if (this.peek_type() === 24) {
111
+ block_end = this.lexer.token_start;
112
+ rule_end = this.lexer.token_end;
113
+ this.next_token();
114
+ }
115
+ this.arena.set_length(block_node, block_end - block_start);
116
+ this.arena.append_children(block_node, block_children);
117
+ this.arena.set_length(style_rule, rule_end - rule_start);
118
+ let style_rule_children = [];
119
+ if (selector !== null) style_rule_children.push(selector);
120
+ style_rule_children.push(block_node);
121
+ this.arena.append_children(style_rule, style_rule_children);
122
+ return style_rule;
123
+ }
124
+ parse_selector() {
125
+ if (this.is_eof()) return null;
126
+ let selector_start = this.lexer.token_start;
127
+ let selector_line = this.lexer.token_line;
128
+ let selector_column = this.lexer.token_column;
129
+ let last_end = this.lexer.token_end;
130
+ while (!this.is_eof() && this.peek_type() !== 23) {
131
+ last_end = this.lexer.token_end;
132
+ this.next_token();
133
+ }
134
+ if (this.parse_selectors_enabled && this.selector_parser) {
135
+ let selector = this.selector_parser.parse_selector(selector_start, last_end, selector_line, selector_column);
136
+ if (selector !== null) return selector;
137
+ }
138
+ let node_type = this.parse_selectors_enabled ? 20 : 8;
139
+ return this.arena.create_node(node_type, selector_start, last_end - selector_start, selector_line, selector_column);
140
+ }
141
+ parse_declaration() {
142
+ const token_type = this.peek_type();
143
+ if (token_type === 1 || token_type === 3 || token_type === 4) return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
144
+ if (token_type === 9 || token_type === 21 || token_type === 22 || token_type === 19 || token_type === 20 || token_type === 18 || token_type === 16) {
145
+ const char_code = this.source.charCodeAt(this.lexer.token_start);
146
+ if (char_code === 46 || char_code === 62 || char_code === 43 || char_code === 126 || char_code === 38) return null;
147
+ return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
148
+ }
149
+ return null;
150
+ }
151
+ parse_atrule() {
152
+ if (this.peek_type() !== 3) return null;
153
+ let at_rule_start = this.lexer.token_start;
154
+ let at_rule_line = this.lexer.token_line;
155
+ let at_rule_column = this.lexer.token_column;
156
+ let name_start = this.lexer.token_start + 1;
157
+ let name_length = this.lexer.token_end - name_start;
158
+ let at_rule_name = this.source.substring(name_start, this.lexer.token_end);
159
+ this.next_token();
160
+ let at_rule = this.arena.create_node(3, at_rule_start, 0, at_rule_line, at_rule_column);
161
+ this.arena.set_content_start_delta(at_rule, name_start - at_rule_start);
162
+ this.arena.set_content_length(at_rule, name_length);
163
+ let prelude_start = this.lexer.token_start;
164
+ let prelude_end = prelude_start;
165
+ let paren_depth = 0;
166
+ while (!this.is_eof()) {
167
+ let token_type = this.peek_type();
168
+ if (token_type === 21 || token_type === 2) paren_depth++;
169
+ else if (token_type === 22) paren_depth--;
170
+ if (token_type === 23 && paren_depth === 0) break;
171
+ if (token_type === 17 && paren_depth === 0) break;
172
+ prelude_end = this.lexer.token_end;
173
+ this.next_token();
174
+ }
175
+ let trimmed = trim_boundaries(this.source, prelude_start, prelude_end);
176
+ let prelude_wrapper = null;
177
+ if (trimmed) if (this.prelude_parser) {
178
+ let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name, trimmed[0], trimmed[1], at_rule_line, at_rule_column);
179
+ if (prelude_nodes.length > 0) {
180
+ prelude_wrapper = this.arena.create_node(40, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
181
+ this.arena.append_children(prelude_wrapper, prelude_nodes);
182
+ } else prelude_wrapper = this.arena.create_node(8, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
183
+ } else prelude_wrapper = this.arena.create_node(8, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
184
+ let last_end = this.lexer.token_end;
185
+ if (this.peek_type() === 23) {
186
+ let block_start = this.lexer.token_end;
187
+ this.next_token();
188
+ this.arena.set_flag(at_rule, 8);
189
+ let block_line = this.lexer.token_line;
190
+ let block_column = this.lexer.token_column;
191
+ let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
192
+ let has_declarations = this.atrule_has_declarations(at_rule_name);
193
+ let block_children = [];
194
+ if (has_declarations) while (!this.is_eof()) {
195
+ if (this.peek_type() === 24) break;
196
+ let declaration = this.parse_declaration();
197
+ if (declaration !== null) block_children.push(declaration);
198
+ else this.next_token();
199
+ }
200
+ else while (!this.is_eof()) {
201
+ let token_type = this.peek_type();
202
+ if (token_type === 24) break;
203
+ if (token_type === 3) {
204
+ let nested_at_rule = this.parse_atrule();
205
+ if (nested_at_rule !== null) block_children.push(nested_at_rule);
206
+ else this.next_token();
207
+ continue;
208
+ }
209
+ let declaration = this.parse_declaration();
210
+ if (declaration !== null) {
211
+ block_children.push(declaration);
212
+ continue;
213
+ }
214
+ let nested_rule = this.parse_style_rule();
215
+ if (nested_rule !== null) block_children.push(nested_rule);
216
+ else this.next_token();
217
+ }
218
+ if (this.peek_type() === 24) {
219
+ let block_end = this.lexer.token_start;
220
+ last_end = this.lexer.token_end;
221
+ this.next_token();
222
+ this.arena.set_length(block_node, block_end - block_start);
223
+ } else this.arena.set_length(block_node, last_end - block_start);
224
+ this.arena.append_children(block_node, block_children);
225
+ let at_rule_children = [];
226
+ if (prelude_wrapper !== null) at_rule_children.push(prelude_wrapper);
227
+ at_rule_children.push(block_node);
228
+ this.arena.set_length(at_rule, last_end - at_rule_start);
229
+ this.arena.append_children(at_rule, at_rule_children);
230
+ } else if (this.peek_type() === 17) {
231
+ last_end = this.lexer.token_end;
232
+ this.next_token();
233
+ this.arena.set_length(at_rule, last_end - at_rule_start);
234
+ if (prelude_wrapper !== null) this.arena.append_children(at_rule, [prelude_wrapper]);
235
+ } else {
236
+ this.arena.set_length(at_rule, last_end - at_rule_start);
237
+ if (prelude_wrapper !== null) this.arena.append_children(at_rule, [prelude_wrapper]);
238
+ }
239
+ return at_rule;
240
+ }
241
+ atrule_has_declarations(name) {
242
+ return DECLARATION_AT_RULES.has(name.toLowerCase());
243
+ }
244
+ };
245
+ /**
246
+ * Parse CSS and return an AST
247
+ * @param source - The CSS source code to parse
248
+ * @param options - Parser options
249
+ * @returns The root CSSNode of the AST
250
+ */
351
251
  function parse(source, options) {
352
- const parser = new Parser(source, options);
353
- return parser.parse();
252
+ return new Parser(source, options).parse();
354
253
  }
355
-
254
+ //#endregion
356
255
  export { Parser, parse };