@projectwallace/css-parser 0.18.1 → 0.18.4

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.
@@ -1,8 +1,8 @@
1
- import { t as Lexer } from "./tokenize-BiRLfVbm.js";
2
- import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
1
+ import { t as Lexer } from "./tokenize-DK24ACbY.js";
2
+ import { l as CSSDataArena } from "./arena-C-ZXJe7F.js";
3
3
  import { i as is_vendor_prefixed } from "./parse-dimension-ouWXNHdx.js";
4
- import { t as CSSNode } from "./css-node-Cf8K9nWd.js";
5
- import { i as trim_boundaries } from "./parse-utils-D7srNG13.js";
4
+ import { t as CSSNode } from "./css-node-Briho45Z.js";
5
+ import { i as trim_boundaries, t as skip_whitespace_and_comments_backward } from "./parse-utils-D7srNG13.js";
6
6
  import { ValueParser } from "./parse-value.js";
7
7
  //#region src/parse-declaration.ts
8
8
  /** @internal */
@@ -70,39 +70,70 @@ var DeclarationParser = class {
70
70
  lexer.restore_position(has_delimiter_prefix ? initial_saved : saved);
71
71
  return null;
72
72
  }
73
- lexer.next_token_fast(true);
73
+ lexer.pos = lexer.token_end;
74
+ lexer.skip_whitespace_in_range(this.source.length);
74
75
  let declaration = this.arena.create_node(4, prop_start, 0, decl_line, decl_column);
75
76
  this.arena.set_content_start_delta(declaration, 0);
76
77
  this.arena.set_content_length(declaration, prop_end - prop_start);
77
- let value_start = lexer.token_start;
78
- let value_start_line = lexer.token_line;
79
- let value_start_column = lexer.token_column;
78
+ let value_start = lexer.pos;
79
+ let value_start_line = lexer.line;
80
+ let value_start_column = lexer.column;
80
81
  let value_end = value_start;
81
82
  let has_important = false;
82
- let last_end = lexer.token_end;
83
+ let last_end = value_start;
83
84
  let paren_depth = 0;
84
- while (lexer.token_type !== 26 && lexer.token_start < end) {
85
- let token_type = lexer.token_type;
86
- if (token_type === 21 || token_type === 2) paren_depth++;
87
- else if (token_type === 22) paren_depth--;
88
- if (token_type === 17 && paren_depth === 0) break;
89
- if (token_type === 24 && paren_depth === 0) break;
90
- if (token_type === 23) {
85
+ while (true) {
86
+ let stop_ch = lexer.skip_to_declaration_stop(end);
87
+ if (stop_ch === 40) {
88
+ paren_depth++;
89
+ lexer.pos++;
90
+ continue;
91
+ }
92
+ if (stop_ch === 41) {
93
+ paren_depth--;
94
+ lexer.pos++;
95
+ continue;
96
+ }
97
+ if (stop_ch === 59 && paren_depth === 0) {
98
+ value_end = skip_whitespace_and_comments_backward(this.source, lexer.pos, value_start);
99
+ lexer.next_token_fast(false);
100
+ break;
101
+ }
102
+ if (stop_ch === 125 && paren_depth === 0) {
103
+ if (lexer.pos === value_start) {
104
+ last_end = lexer.pos + 1;
105
+ value_end = value_start;
106
+ } else {
107
+ last_end = skip_whitespace_and_comments_backward(this.source, lexer.pos, value_start);
108
+ value_end = last_end;
109
+ }
110
+ lexer.next_token_fast(false);
111
+ break;
112
+ }
113
+ if (stop_ch === 123) {
91
114
  lexer.restore_position(saved);
92
115
  return null;
93
116
  }
94
- if (token_type === 9 && this.source[lexer.token_start] === "!") {
95
- value_end = lexer.token_start;
117
+ if (stop_ch === 33) {
118
+ value_end = lexer.pos;
119
+ lexer.pos++;
96
120
  if (lexer.next_token_fast(true) === 1) {
97
121
  has_important = true;
98
122
  last_end = lexer.token_end;
99
123
  lexer.next_token_fast(true);
100
124
  break;
101
125
  }
126
+ last_end = lexer.token_end;
127
+ value_end = last_end;
128
+ continue;
102
129
  }
103
- last_end = lexer.token_end;
104
- value_end = last_end;
105
- lexer.next_token_fast(true);
130
+ if (stop_ch === 0) {
131
+ last_end = skip_whitespace_and_comments_backward(this.source, lexer.pos, value_start);
132
+ value_end = last_end;
133
+ lexer.next_token_fast(false);
134
+ break;
135
+ }
136
+ lexer.pos++;
106
137
  }
107
138
  let trimmed = trim_boundaries(this.source, value_start, value_end);
108
139
  if (trimmed) {
@@ -141,7 +172,10 @@ var DeclarationParser = class {
141
172
  function parse_declaration(source) {
142
173
  const arena = new CSSDataArena(CSSDataArena.capacity_for_source(source.length));
143
174
  const decl_index = new DeclarationParser(arena, source).parse_declaration(0, source.length);
144
- if (decl_index === null) return new CSSNode(arena, source, arena.create_node(4, 0, 0, 1, 1));
175
+ if (decl_index === null) {
176
+ const empty = arena.create_node(4, 0, 0, 1, 1);
177
+ return new CSSNode(arena, source, empty);
178
+ }
145
179
  return new CSSNode(arena, source, decl_index);
146
180
  }
147
181
  //#endregion
@@ -1,5 +1,5 @@
1
- import { l as CSSDataArena } from "./arena-Bx5vp6Sl.js";
2
- import { F as Selector, I as SelectorList } from "./node-types-D41wr72y.js";
1
+ import { l as CSSDataArena } from "./arena-C-uRgG5-.js";
2
+ import { I as Selector, L as SelectorList } from "./node-types-Dh1wEDRK.js";
3
3
  //#region src/parse-selector.d.ts
4
4
  /** @internal */
5
5
  declare class SelectorParser {
@@ -30,7 +30,6 @@ declare class SelectorParser {
30
30
  private parse_nth_expression;
31
31
  private find_of_keyword;
32
32
  private create_node;
33
- private create_node_at;
34
33
  private skip_whitespace;
35
34
  }
36
35
  declare function parse_selector_list(source: string): SelectorList;
@@ -1,7 +1,7 @@
1
- import { t as Lexer } from "./tokenize-BiRLfVbm.js";
2
- import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
1
+ import { t as Lexer } from "./tokenize-DK24ACbY.js";
2
+ import { l as CSSDataArena } from "./arena-C-ZXJe7F.js";
3
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-Cf8K9nWd.js";
4
+ import { t as CSSNode } from "./css-node-Briho45Z.js";
5
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
@@ -69,7 +69,7 @@ var SelectorParser = class {
69
69
  if (this.lexer.token_type === 9) {
70
70
  let ch = this.source.charCodeAt(this.lexer.token_start);
71
71
  if (ch === 62 || ch === 43 || ch === 126) {
72
- let combinator = this.create_node_at(27, this.lexer.token_start, this.lexer.token_end, this.lexer.token_line, this.lexer.token_column);
72
+ let combinator = this.create_node(27, this.lexer.token_start, this.lexer.token_end);
73
73
  first_component = combinator;
74
74
  chain_tail = combinator;
75
75
  this.skip_whitespace();
@@ -205,12 +205,13 @@ var SelectorParser = class {
205
205
  }
206
206
  this.lexer.next_token_fast(false);
207
207
  if (this.lexer.token_type === 9) {
208
- if (is_combinator(this.source.charCodeAt(this.lexer.token_start))) return this.create_node_at(27, this.lexer.token_start, this.lexer.token_end, this.lexer.token_line, this.lexer.token_column);
208
+ let ch = this.source.charCodeAt(this.lexer.token_start);
209
+ if (is_combinator(ch)) return this.create_node(27, this.lexer.token_start, this.lexer.token_end);
209
210
  }
210
211
  if (has_whitespace) {
211
212
  this.lexer.restore_position(saved_whitespace_start);
212
213
  this.skip_whitespace();
213
- return this.create_node_at(27, saved_whitespace_start.pos, this.lexer.pos, saved_whitespace_start.line, saved_whitespace_start.column);
214
+ return this.create_node(27, saved_whitespace_start.pos, this.lexer.pos, saved_whitespace_start.line, saved_whitespace_start.column);
214
215
  }
215
216
  this.lexer.restore_position(saved_whitespace_start);
216
217
  return null;
@@ -293,7 +294,8 @@ var SelectorParser = class {
293
294
  else pos++;
294
295
  }
295
296
  } else while (pos < end) {
296
- if (is_whitespace(this.source.charCodeAt(pos))) break;
297
+ let c = this.source.charCodeAt(pos);
298
+ if (is_whitespace(c)) break;
297
299
  pos++;
298
300
  }
299
301
  value_end = pos;
@@ -433,44 +435,23 @@ var SelectorParser = class {
433
435
  }
434
436
  return -1;
435
437
  }
436
- create_node(type, start, end) {
437
- let node = this.arena.create_node(type, start, end - start, this.lexer.token_line, this.lexer.token_column);
438
- this.arena.set_content_start_delta(node, 0);
439
- this.arena.set_content_length(node, end - start);
440
- return node;
441
- }
442
- create_node_at(type, start, end, line, column) {
438
+ create_node(type, start, end, line = this.lexer.token_line, column = this.lexer.token_column) {
443
439
  let node = this.arena.create_node(type, start, end - start, line, column);
444
440
  this.arena.set_content_start_delta(node, 0);
445
441
  this.arena.set_content_length(node, end - start);
446
442
  return node;
447
443
  }
448
444
  skip_whitespace() {
449
- while (this.lexer.pos < this.selector_end) {
450
- let ch = this.source.charCodeAt(this.lexer.pos);
451
- if (is_whitespace(ch)) {
452
- this.lexer.advance();
453
- continue;
454
- }
455
- if (ch === 47 && this.lexer.pos + 1 < this.selector_end && this.source.charCodeAt(this.lexer.pos + 1) === 42) {
456
- this.lexer.advance(2);
457
- while (this.lexer.pos < this.selector_end) {
458
- if (this.source.charCodeAt(this.lexer.pos) === 42 && this.lexer.pos + 1 < this.selector_end && this.source.charCodeAt(this.lexer.pos + 1) === 47) {
459
- this.lexer.advance(2);
460
- break;
461
- }
462
- this.lexer.advance();
463
- }
464
- continue;
465
- }
466
- break;
467
- }
445
+ this.lexer.skip_whitespace_in_range(this.selector_end);
468
446
  }
469
447
  };
470
448
  function parse_selector_list(source) {
471
449
  const arena = new CSSDataArena(CSSDataArena.capacity_for_source(source.length));
472
450
  const selector_index = new SelectorParser(arena, source).parse_selector(0, source.length);
473
- if (selector_index === null) return new CSSNode(arena, source, arena.create_node(20, 0, 0, 1, 1));
451
+ if (selector_index === null) {
452
+ const empty = arena.create_node(20, 0, 0, 1, 1);
453
+ return new CSSNode(arena, source, empty);
454
+ }
474
455
  return new CSSNode(arena, source, selector_index);
475
456
  }
476
457
  function parse_selector(source) {
@@ -1,5 +1,5 @@
1
- import { l as CSSDataArena } from "./arena-Bx5vp6Sl.js";
2
- import { q as Value } from "./node-types-D41wr72y.js";
1
+ import { l as CSSDataArena } from "./arena-C-uRgG5-.js";
2
+ import { J as Value } from "./node-types-Dh1wEDRK.js";
3
3
  //#region src/parse-value.d.ts
4
4
  /** @internal */
5
5
  declare class ValueParser {
@@ -1,6 +1,6 @@
1
- import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
2
- import { t as CSSNode } from "./css-node-Cf8K9nWd.js";
3
- import { t as ValueNodeParser } from "./value-node-parser-CZ47v3hp.js";
1
+ import { l as CSSDataArena } from "./arena-C-ZXJe7F.js";
2
+ import { t as CSSNode } from "./css-node-Briho45Z.js";
3
+ import { t as ValueNodeParser } from "./value-node-parser-B0WfJCvC.js";
4
4
  //#region src/parse-value.ts
5
5
  /** @internal */
6
6
  var ValueParser = class {
@@ -28,7 +28,8 @@ var ValueParser = class {
28
28
  */
29
29
  function parse_value(value_string) {
30
30
  const arena = new CSSDataArena(CSSDataArena.capacity_for_source(value_string.length));
31
- return new CSSNode(arena, value_string, new ValueParser(arena, value_string).parse_value(0, value_string.length, 1, 1));
31
+ const value_node_index = new ValueParser(arena, value_string).parse_value(0, value_string.length, 1, 1);
32
+ return new CSSNode(arena, value_string, value_node_index);
32
33
  }
33
34
  //#endregion
34
35
  export { ValueParser, parse_value };
package/dist/parse.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { l as CSSDataArena } from "./arena-Bx5vp6Sl.js";
2
- import { t as CommentInfo } from "./tokenize-DeZYFa9R.js";
3
- import { z as StyleSheet } from "./node-types-D41wr72y.js";
1
+ import { l as CSSDataArena } from "./arena-C-uRgG5-.js";
2
+ import { t as CommentInfo } from "./tokenize-CDEnYcVG.js";
3
+ import { B as StyleSheet } from "./node-types-Dh1wEDRK.js";
4
4
  //#region src/parse.d.ts
5
5
  interface ParserOptions {
6
6
  parse_values?: boolean;
@@ -27,6 +27,7 @@ declare class Parser {
27
27
  private is_eof;
28
28
  parse(): StyleSheet;
29
29
  private parse_rule;
30
+ private parse_block_children;
30
31
  private parse_style_rule;
31
32
  private parse_selector;
32
33
  private parse_declaration;
package/dist/parse.js CHANGED
@@ -1,7 +1,7 @@
1
- import { t as Lexer } from "./tokenize-BiRLfVbm.js";
2
- import { l as CSSDataArena } from "./arena-CFwM4uQs.js";
3
- import { t as CSSNode } from "./css-node-Cf8K9nWd.js";
4
- import { i as trim_boundaries } from "./parse-utils-D7srNG13.js";
1
+ import { t as Lexer } from "./tokenize-DK24ACbY.js";
2
+ import { l as CSSDataArena } from "./arena-C-ZXJe7F.js";
3
+ import { t as CSSNode } from "./css-node-Briho45Z.js";
4
+ import { i as trim_boundaries, t as skip_whitespace_and_comments_backward } from "./parse-utils-D7srNG13.js";
5
5
  import { SelectorParser } from "./parse-selector.js";
6
6
  import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
7
7
  import { DeclarationParser } from "./parse-declaration.js";
@@ -79,35 +79,24 @@ var Parser = class {
79
79
  if (this.peek_type() === 3) return this.parse_atrule();
80
80
  return this.parse_style_rule();
81
81
  }
82
- parse_style_rule() {
83
- if (this.is_eof()) return null;
84
- let rule_start = this.lexer.token_start;
85
- let rule_line = this.lexer.token_line;
86
- let rule_column = this.lexer.token_column;
87
- let style_rule = this.arena.create_node(2, rule_start, 0, rule_line, rule_column);
88
- let selector = this.parse_selector();
89
- if (this.peek_type() !== 23) return null;
90
- let block_start = this.lexer.token_end;
91
- this.next_token();
92
- this.arena.set_flag(style_rule, 8);
93
- let block_line = this.lexer.token_line;
94
- let block_column = this.lexer.token_column;
95
- let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
82
+ parse_block_children(owner, declarations_only) {
96
83
  let first_child = 0;
97
84
  let last_child = 0;
98
85
  while (!this.is_eof()) {
99
86
  let token_type = this.peek_type();
100
87
  if (token_type === 24) break;
101
88
  let child = null;
102
- if (token_type === 3) {
89
+ if (!declarations_only && token_type === 3) {
103
90
  child = this.parse_atrule();
104
91
  if (child === null) this.next_token();
105
92
  } else {
106
93
  child = this.parse_declaration();
107
- if (child === null) {
94
+ if (child !== null) this.arena.set_flag(owner, 32);
95
+ else if (declarations_only) this.next_token();
96
+ else {
108
97
  child = this.parse_style_rule();
109
98
  if (child === null) this.next_token();
110
- } else this.arena.set_flag(style_rule, 32);
99
+ }
111
100
  }
112
101
  if (child !== null) {
113
102
  if (first_child === 0) first_child = child;
@@ -115,6 +104,23 @@ var Parser = class {
115
104
  last_child = child;
116
105
  }
117
106
  }
107
+ return first_child;
108
+ }
109
+ parse_style_rule() {
110
+ if (this.is_eof()) return null;
111
+ let rule_start = this.lexer.token_start;
112
+ let rule_line = this.lexer.token_line;
113
+ let rule_column = this.lexer.token_column;
114
+ let style_rule = this.arena.create_node(2, rule_start, 0, rule_line, rule_column);
115
+ let selector = this.parse_selector();
116
+ if (this.peek_type() !== 23) return null;
117
+ let block_start = this.lexer.token_end;
118
+ this.next_token();
119
+ this.arena.set_flag(style_rule, 8);
120
+ let block_line = this.lexer.token_line;
121
+ let block_column = this.lexer.token_column;
122
+ let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
123
+ let first_child = this.parse_block_children(style_rule, false);
118
124
  let block_end = this.lexer.token_start;
119
125
  let rule_end = this.lexer.token_end;
120
126
  if (this.peek_type() === 24) {
@@ -138,8 +144,9 @@ var Parser = class {
138
144
  let selector_line = this.lexer.token_line;
139
145
  let selector_column = this.lexer.token_column;
140
146
  let last_end = this.lexer.token_end;
141
- while (!this.is_eof() && this.peek_type() !== 23) {
142
- last_end = this.lexer.token_end;
147
+ if (this.peek_type() !== 23) {
148
+ this.lexer.skip_to_unquoted(123);
149
+ last_end = skip_whitespace_and_comments_backward(this.source, this.lexer.pos, selector_start);
143
150
  this.next_token();
144
151
  }
145
152
  if (this.parse_selectors_enabled && this.selector_parser) {
@@ -151,13 +158,11 @@ var Parser = class {
151
158
  }
152
159
  parse_declaration() {
153
160
  const token_type = this.peek_type();
154
- if (token_type === 1 || token_type === 3 || token_type === 4) return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
155
161
  if (token_type === 9 || token_type === 21 || token_type === 22 || token_type === 19 || token_type === 20 || token_type === 18 || token_type === 16) {
156
162
  const char_code = this.source.charCodeAt(this.lexer.token_start);
157
163
  if (char_code === 46 || char_code === 62 || char_code === 43 || char_code === 126 || char_code === 38) return null;
158
- return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
159
- }
160
- return null;
164
+ } else if (token_type !== 1 && token_type !== 3 && token_type !== 4) return null;
165
+ return this.declaration_parser.parse_declaration_with_lexer(this.lexer, this.source.length);
161
166
  }
162
167
  parse_atrule() {
163
168
  if (this.peek_type() !== 3) return null;
@@ -200,39 +205,8 @@ var Parser = class {
200
205
  let block_line = this.lexer.token_line;
201
206
  let block_column = this.lexer.token_column;
202
207
  let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
203
- let has_declarations = this.atrule_has_declarations(at_rule_name);
204
- let first_child = 0;
205
- let last_child = 0;
206
- if (has_declarations) while (!this.is_eof()) {
207
- if (this.peek_type() === 24) break;
208
- let declaration = this.parse_declaration();
209
- if (declaration === null) this.next_token();
210
- else {
211
- if (first_child === 0) first_child = declaration;
212
- else this.arena.set_next_sibling(last_child, declaration);
213
- last_child = declaration;
214
- }
215
- }
216
- else while (!this.is_eof()) {
217
- let token_type = this.peek_type();
218
- if (token_type === 24) break;
219
- let child = null;
220
- if (token_type === 3) {
221
- child = this.parse_atrule();
222
- if (child === null) this.next_token();
223
- } else {
224
- child = this.parse_declaration();
225
- if (child === null) {
226
- child = this.parse_style_rule();
227
- if (child === null) this.next_token();
228
- }
229
- }
230
- if (child !== null) {
231
- if (first_child === 0) first_child = child;
232
- else this.arena.set_next_sibling(last_child, child);
233
- last_child = child;
234
- }
235
- }
208
+ let declarations_only = this.atrule_has_declarations(at_rule_name);
209
+ let first_child = this.parse_block_children(at_rule, declarations_only);
236
210
  if (this.peek_type() === 24) {
237
211
  let block_end = this.lexer.token_start;
238
212
  last_end = this.lexer.token_end;
@@ -72,6 +72,28 @@ declare class Lexer {
72
72
  seek(pos: number, line: number, column?: number): void;
73
73
  next_token_fast(skip_whitespace?: boolean): TokenType;
74
74
  private _scan_newlines;
75
+ private _skip_comment;
76
+ /**
77
+ * Fast-forward to the next `target` char that isn't inside a string or comment, without
78
+ * fully tokenizing what's in between — used by callers that only need to know *where a
79
+ * construct ends* (e.g. a selector's `{`), since the sub-parser for that construct
80
+ * re-tokenizes the span properly afterward.
81
+ *
82
+ * Strings go through consume_string and comments through _skip_comment, so escapes and
83
+ * on_comment callbacks behave identically to real tokenization. Ordinary characters cost
84
+ * one SKIP_SCAN_INTERESTING lookup each, same as consume_ident_or_function's inner loop.
85
+ *
86
+ * Returns true with this.pos at target, or false with this.pos at source_length.
87
+ */
88
+ skip_to_unquoted(target: number): boolean;
89
+ /**
90
+ * Same approach as skip_to_unquoted, but stops at any of `; { } ( ) !` — the stop
91
+ * characters parse-declaration.ts's value scan needs (paren depth, statement end,
92
+ * !important). The caller decides what each one means; this only locates the next one.
93
+ *
94
+ * Returns the stop character's code (this.pos left at it), or 0 at `end` if none found.
95
+ */
96
+ skip_to_declaration_stop(end: number): number;
75
97
  consume_whitespace(start_line: number, start_column: number): TokenType;
76
98
  consume_string(quote: number, start_line: number, start_column: number): TokenType;
77
99
  consume_hex_escape(): void;