@projectwallace/css-parser 0.6.2 → 0.6.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.
package/README.md CHANGED
@@ -7,13 +7,14 @@
7
7
 
8
8
  Built for speed and efficiency, this parser handles large CSS files with minimal memory overhead and blazing-fast parse times. Designed with a data-oriented architecture using a single contiguous memory arena for zero allocations during parsing.
9
9
 
10
+ This parser was heavily influenced by [CSSTree](https://github.com/csstree/csstree), one of the most robust CSS parsers available. Some of the parsing mechanics are taken from CSSTree, as well as some of the performance mechanics, but a lot of things are very different which is why this isn't a direct fork.
11
+
10
12
  ## Features
11
13
 
12
14
  - **Modern CSS support** - CSS Nesting, `:is()`, `:where()`, `:has()`, `@layer`, `@container`
13
15
  - **Error recovery** - Continues parsing on malformed CSS
14
- - **Comment preservation** - Comments stored as first-class AST nodes
15
16
  - **Location tracking** - Line, column, offset, and length for all nodes
16
- - **Built-in vendor prefix detection** - Automatic detection of `-webkit-`, `-moz-`, etc. for selectors, values, properties and more
17
+ - **Performance** - Low memory usage and excellent parsing speed
17
18
 
18
19
  ## Installation
19
20
 
@@ -57,14 +58,12 @@ for (const rule of ast) {
57
58
 
58
59
  ## Performance
59
60
 
60
- - **Tiny install size**
61
+ - **Small install size** (~200kB)
61
62
  - **Zero allocations during parsing** - all memory allocated upfront based on real world heuristics, which also helps prevent garbage collection running often
62
- - **Cache-friendly data layout** - contiguous memory for sequential access powered by concepts or Data Oriented Design
63
+ - **Cache-friendly data layout** - contiguous memory for sequential access powered by concepts of Data Oriented Design
63
64
  - **First-class comment and location support** - while still being performant because analysis requires constant access to lines and columns
64
65
  - **No syntax validation** - focusing only on the raw data we can skip expensive syntax files and MDN data syncs
65
66
 
66
- This parser was heavily influenced by [CSSTree](https://github.com/csstree/csstree), one of the most robust CSS parsers available.
67
-
68
67
  ## Documentation
69
68
 
70
69
  See [API.md](./API.md) for complete documentation of all parser functions and options.
@@ -72,6 +71,7 @@ See [API.md](./API.md) for complete documentation of all parser functions and op
72
71
  ## Non-goals
73
72
 
74
73
  - **No syntax validation** - this parser does not try to validate your CSS structure. Everything can be anything
74
+ - **No custom syntax support** - we're leaving the era of CSS preprocessors so we only focus on CSS
75
75
 
76
76
  ## License
77
77
 
@@ -666,4 +666,4 @@ class CSSNode {
666
666
  }
667
667
  }
668
668
 
669
- export { FLAG_HAS_DECLARATIONS as $, ATTR_OPERATOR_NONE as A, NODE_SELECTOR_ATTRIBUTE as B, CSSNode as C, NODE_SELECTOR_PSEUDO_CLASS as D, NODE_SELECTOR_PSEUDO_ELEMENT as E, NODE_SELECTOR_COMBINATOR as F, NODE_SELECTOR_UNIVERSAL as G, NODE_SELECTOR_NESTING as H, NODE_SELECTOR_NTH as I, NODE_SELECTOR_NTH_OF as J, NODE_SELECTOR_LANG as K, NODE_PRELUDE_MEDIA_QUERY as L, NODE_PRELUDE_MEDIA_FEATURE as M, NODE_STYLE_RULE as N, NODE_PRELUDE_MEDIA_TYPE as O, NODE_PRELUDE_CONTAINER_QUERY as P, NODE_PRELUDE_SUPPORTS_QUERY as Q, NODE_PRELUDE_LAYER_NAME as R, NODE_PRELUDE_IDENTIFIER as S, NODE_PRELUDE_OPERATOR as T, NODE_PRELUDE_IMPORT_URL as U, NODE_PRELUDE_IMPORT_LAYER as V, NODE_PRELUDE_IMPORT_SUPPORTS as W, FLAG_IMPORTANT as X, CSSDataArena as Y, FLAG_HAS_BLOCK as Z, NODE_BLOCK as _, ATTR_OPERATOR_EQUAL as a, is_vendor_prefixed as a0, FLAG_VENDOR_PREFIXED as a1, trim_boundaries as a2, CHAR_GREATER_THAN as a3, CHAR_PLUS as a4, CHAR_TILDE as a5, CHAR_PERIOD as a6, CHAR_ASTERISK as a7, CHAR_AMPERSAND as a8, is_whitespace as a9, is_combinator as aa, skip_whitespace_and_comments_forward as ab, skip_whitespace_and_comments_backward as ac, CHAR_EQUALS as ad, CHAR_PIPE as ae, CHAR_CARET as af, CHAR_DOLLAR as ag, CHAR_SINGLE_QUOTE as ah, CHAR_DOUBLE_QUOTE as ai, CHAR_COLON as aj, FLAG_HAS_PARENS as ak, skip_whitespace_forward as al, str_equals as am, CHAR_MINUS_HYPHEN as an, CHAR_FORWARD_SLASH as ao, ATTR_OPERATOR_TILDE_EQUAL as b, ATTR_OPERATOR_PIPE_EQUAL as c, ATTR_OPERATOR_CARET_EQUAL as d, ATTR_OPERATOR_DOLLAR_EQUAL as e, ATTR_OPERATOR_STAR_EQUAL as f, ATTR_FLAG_NONE as g, ATTR_FLAG_CASE_INSENSITIVE as h, ATTR_FLAG_CASE_SENSITIVE as i, NODE_AT_RULE as j, NODE_COMMENT as k, NODE_DECLARATION as l, NODE_SELECTOR as m, NODE_STYLESHEET as n, NODE_VALUE_KEYWORD as o, NODE_VALUE_NUMBER as p, NODE_VALUE_DIMENSION as q, NODE_VALUE_STRING as r, NODE_VALUE_COLOR as s, NODE_VALUE_FUNCTION as t, NODE_VALUE_OPERATOR as u, NODE_VALUE_PARENTHESIS as v, NODE_SELECTOR_LIST as w, NODE_SELECTOR_TYPE as x, NODE_SELECTOR_CLASS as y, NODE_SELECTOR_ID as z };
669
+ export { FLAG_HAS_DECLARATIONS as $, ATTR_OPERATOR_NONE as A, NODE_SELECTOR_ATTRIBUTE as B, CSSNode as C, NODE_SELECTOR_PSEUDO_CLASS as D, NODE_SELECTOR_PSEUDO_ELEMENT as E, NODE_SELECTOR_COMBINATOR as F, NODE_SELECTOR_UNIVERSAL as G, NODE_SELECTOR_NESTING as H, NODE_SELECTOR_NTH as I, NODE_SELECTOR_NTH_OF as J, NODE_SELECTOR_LANG as K, NODE_PRELUDE_MEDIA_QUERY as L, NODE_PRELUDE_MEDIA_FEATURE as M, NODE_STYLE_RULE as N, NODE_PRELUDE_MEDIA_TYPE as O, NODE_PRELUDE_CONTAINER_QUERY as P, NODE_PRELUDE_SUPPORTS_QUERY as Q, NODE_PRELUDE_LAYER_NAME as R, NODE_PRELUDE_IDENTIFIER as S, NODE_PRELUDE_OPERATOR as T, NODE_PRELUDE_IMPORT_URL as U, NODE_PRELUDE_IMPORT_LAYER as V, NODE_PRELUDE_IMPORT_SUPPORTS as W, FLAG_IMPORTANT as X, CSSDataArena as Y, FLAG_HAS_BLOCK as Z, NODE_BLOCK as _, ATTR_OPERATOR_EQUAL as a, is_vendor_prefixed as a0, FLAG_VENDOR_PREFIXED as a1, trim_boundaries as a2, CHAR_GREATER_THAN as a3, CHAR_PLUS as a4, CHAR_TILDE as a5, CHAR_PERIOD as a6, CHAR_ASTERISK as a7, CHAR_AMPERSAND as a8, CHAR_PIPE as a9, is_whitespace as aa, is_combinator as ab, skip_whitespace_and_comments_forward as ac, skip_whitespace_and_comments_backward as ad, CHAR_EQUALS as ae, CHAR_CARET as af, CHAR_DOLLAR as ag, CHAR_SINGLE_QUOTE as ah, CHAR_DOUBLE_QUOTE as ai, CHAR_COLON as aj, FLAG_HAS_PARENS as ak, skip_whitespace_forward as al, str_equals as am, CHAR_MINUS_HYPHEN as an, CHAR_FORWARD_SLASH as ao, ATTR_OPERATOR_TILDE_EQUAL as b, ATTR_OPERATOR_PIPE_EQUAL as c, ATTR_OPERATOR_CARET_EQUAL as d, ATTR_OPERATOR_DOLLAR_EQUAL as e, ATTR_OPERATOR_STAR_EQUAL as f, ATTR_FLAG_NONE as g, ATTR_FLAG_CASE_INSENSITIVE as h, ATTR_FLAG_CASE_SENSITIVE as i, NODE_AT_RULE as j, NODE_COMMENT as k, NODE_DECLARATION as l, NODE_SELECTOR as m, NODE_STYLESHEET as n, NODE_VALUE_KEYWORD as o, NODE_VALUE_NUMBER as p, NODE_VALUE_DIMENSION as q, NODE_VALUE_STRING as r, NODE_VALUE_COLOR as s, NODE_VALUE_FUNCTION as t, NODE_VALUE_OPERATOR as u, NODE_VALUE_PARENTHESIS as v, NODE_SELECTOR_LIST as w, NODE_SELECTOR_TYPE as x, NODE_SELECTOR_CLASS as y, NODE_SELECTOR_ID as z };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export { parse_selector } from './parse-selector.js';
3
3
  export { parse_atrule_prelude } from './parse-atrule-prelude.js';
4
4
  export { parse_value } from './parse-value.js';
5
5
  export { tokenize } from './tokenize.js';
6
- export { h as ATTR_FLAG_CASE_INSENSITIVE, i as ATTR_FLAG_CASE_SENSITIVE, g as ATTR_FLAG_NONE, d as ATTR_OPERATOR_CARET_EQUAL, e as ATTR_OPERATOR_DOLLAR_EQUAL, a as ATTR_OPERATOR_EQUAL, A as ATTR_OPERATOR_NONE, c as ATTR_OPERATOR_PIPE_EQUAL, f as ATTR_OPERATOR_STAR_EQUAL, b as ATTR_OPERATOR_TILDE_EQUAL, C as CSSNode, X as FLAG_IMPORTANT, j as NODE_AT_RULE, k as NODE_COMMENT, l as NODE_DECLARATION, P as NODE_PRELUDE_CONTAINER_QUERY, S as NODE_PRELUDE_IDENTIFIER, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, U as NODE_PRELUDE_IMPORT_URL, R as NODE_PRELUDE_LAYER_NAME, M as NODE_PRELUDE_MEDIA_FEATURE, L as NODE_PRELUDE_MEDIA_QUERY, O as NODE_PRELUDE_MEDIA_TYPE, T as NODE_PRELUDE_OPERATOR, Q as NODE_PRELUDE_SUPPORTS_QUERY, m as NODE_SELECTOR, B as NODE_SELECTOR_ATTRIBUTE, y as NODE_SELECTOR_CLASS, F as NODE_SELECTOR_COMBINATOR, z as NODE_SELECTOR_ID, K as NODE_SELECTOR_LANG, w as NODE_SELECTOR_LIST, H as NODE_SELECTOR_NESTING, I as NODE_SELECTOR_NTH, J as NODE_SELECTOR_NTH_OF, D as NODE_SELECTOR_PSEUDO_CLASS, E as NODE_SELECTOR_PSEUDO_ELEMENT, x as NODE_SELECTOR_TYPE, G as NODE_SELECTOR_UNIVERSAL, n as NODE_STYLESHEET, N as NODE_STYLE_RULE, s as NODE_VALUE_COLOR, q as NODE_VALUE_DIMENSION, t as NODE_VALUE_FUNCTION, o as NODE_VALUE_KEYWORD, p as NODE_VALUE_NUMBER, u as NODE_VALUE_OPERATOR, v as NODE_VALUE_PARENTHESIS, r as NODE_VALUE_STRING } from './css-node-aIMm9_Cb.js';
6
+ export { h as ATTR_FLAG_CASE_INSENSITIVE, i as ATTR_FLAG_CASE_SENSITIVE, g as ATTR_FLAG_NONE, d as ATTR_OPERATOR_CARET_EQUAL, e as ATTR_OPERATOR_DOLLAR_EQUAL, a as ATTR_OPERATOR_EQUAL, A as ATTR_OPERATOR_NONE, c as ATTR_OPERATOR_PIPE_EQUAL, f as ATTR_OPERATOR_STAR_EQUAL, b as ATTR_OPERATOR_TILDE_EQUAL, C as CSSNode, X as FLAG_IMPORTANT, j as NODE_AT_RULE, k as NODE_COMMENT, l as NODE_DECLARATION, P as NODE_PRELUDE_CONTAINER_QUERY, S as NODE_PRELUDE_IDENTIFIER, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, U as NODE_PRELUDE_IMPORT_URL, R as NODE_PRELUDE_LAYER_NAME, M as NODE_PRELUDE_MEDIA_FEATURE, L as NODE_PRELUDE_MEDIA_QUERY, O as NODE_PRELUDE_MEDIA_TYPE, T as NODE_PRELUDE_OPERATOR, Q as NODE_PRELUDE_SUPPORTS_QUERY, m as NODE_SELECTOR, B as NODE_SELECTOR_ATTRIBUTE, y as NODE_SELECTOR_CLASS, F as NODE_SELECTOR_COMBINATOR, z as NODE_SELECTOR_ID, K as NODE_SELECTOR_LANG, w as NODE_SELECTOR_LIST, H as NODE_SELECTOR_NESTING, I as NODE_SELECTOR_NTH, J as NODE_SELECTOR_NTH_OF, D as NODE_SELECTOR_PSEUDO_CLASS, E as NODE_SELECTOR_PSEUDO_ELEMENT, x as NODE_SELECTOR_TYPE, G as NODE_SELECTOR_UNIVERSAL, n as NODE_STYLESHEET, N as NODE_STYLE_RULE, s as NODE_VALUE_COLOR, q as NODE_VALUE_DIMENSION, t as NODE_VALUE_FUNCTION, o as NODE_VALUE_KEYWORD, p as NODE_VALUE_NUMBER, u as NODE_VALUE_OPERATOR, v as NODE_VALUE_PARENTHESIS, r as NODE_VALUE_STRING } from './css-node-DC75Lj1U.js';
7
7
  export { b as TOKEN_AT_KEYWORD, e as TOKEN_BAD_STRING, g as TOKEN_BAD_URL, n as TOKEN_CDC, m as TOKEN_CDO, o as TOKEN_COLON, q as TOKEN_COMMA, x as TOKEN_COMMENT, h as TOKEN_DELIM, k as TOKEN_DIMENSION, y as TOKEN_EOF, a as TOKEN_FUNCTION, c as TOKEN_HASH, T as TOKEN_IDENT, v as TOKEN_LEFT_BRACE, r as TOKEN_LEFT_BRACKET, t as TOKEN_LEFT_PAREN, i as TOKEN_NUMBER, j as TOKEN_PERCENTAGE, w as TOKEN_RIGHT_BRACE, s as TOKEN_RIGHT_BRACKET, u as TOKEN_RIGHT_PAREN, p as TOKEN_SEMICOLON, d as TOKEN_STRING, f as TOKEN_URL, l as TOKEN_WHITESPACE } from './lexer-CtBKgfVv.js';
8
8
 
9
9
  function walk(node, callback, depth = 0) {
@@ -1,5 +1,5 @@
1
1
  import { L as Lexer, T as TOKEN_IDENT, h as TOKEN_DELIM, k as TOKEN_DIMENSION, i as TOKEN_NUMBER } from './lexer-CtBKgfVv.js';
2
- import { an as CHAR_MINUS_HYPHEN, a4 as CHAR_PLUS, al as skip_whitespace_forward, I as NODE_SELECTOR_NTH, C as CSSNode, Y as CSSDataArena } from './css-node-aIMm9_Cb.js';
2
+ import { an as CHAR_MINUS_HYPHEN, a4 as CHAR_PLUS, al as skip_whitespace_forward, I as NODE_SELECTOR_NTH, C as CSSNode, Y as CSSDataArena } from './css-node-DC75Lj1U.js';
3
3
 
4
4
  class ANplusBParser {
5
5
  lexer;
@@ -8,6 +8,7 @@ export declare class AtRulePreludeParser {
8
8
  constructor(arena: CSSDataArena, source: string);
9
9
  parse_prelude(at_rule_name: string, start: number, end: number, line?: number, column?: number): number[];
10
10
  private parse_media_query_list;
11
+ private create_node;
11
12
  private is_and_or_not;
12
13
  private parse_single_media_query;
13
14
  private parse_media_feature;
@@ -1,5 +1,5 @@
1
1
  import { L as Lexer, q as TOKEN_COMMA, T as TOKEN_IDENT, t as TOKEN_LEFT_PAREN, u as TOKEN_RIGHT_PAREN, l as TOKEN_WHITESPACE, f as TOKEN_URL, a as TOKEN_FUNCTION, d as TOKEN_STRING, y as TOKEN_EOF } from './lexer-CtBKgfVv.js';
2
- import { Y as CSSDataArena, C as CSSNode, am as str_equals, T as NODE_PRELUDE_OPERATOR, O as NODE_PRELUDE_MEDIA_TYPE, L as NODE_PRELUDE_MEDIA_QUERY, M as NODE_PRELUDE_MEDIA_FEATURE, a2 as trim_boundaries, S as NODE_PRELUDE_IDENTIFIER, P as NODE_PRELUDE_CONTAINER_QUERY, Q as NODE_PRELUDE_SUPPORTS_QUERY, R as NODE_PRELUDE_LAYER_NAME, U as NODE_PRELUDE_IMPORT_URL, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, al as skip_whitespace_forward } from './css-node-aIMm9_Cb.js';
2
+ import { Y as CSSDataArena, C as CSSNode, am as str_equals, T as NODE_PRELUDE_OPERATOR, O as NODE_PRELUDE_MEDIA_TYPE, L as NODE_PRELUDE_MEDIA_QUERY, M as NODE_PRELUDE_MEDIA_FEATURE, a2 as trim_boundaries, S as NODE_PRELUDE_IDENTIFIER, P as NODE_PRELUDE_CONTAINER_QUERY, Q as NODE_PRELUDE_SUPPORTS_QUERY, R as NODE_PRELUDE_LAYER_NAME, U as NODE_PRELUDE_IMPORT_URL, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, al as skip_whitespace_forward } from './css-node-DC75Lj1U.js';
3
3
 
4
4
  class AtRulePreludeParser {
5
5
  lexer;
@@ -52,6 +52,15 @@ class AtRulePreludeParser {
52
52
  }
53
53
  return nodes;
54
54
  }
55
+ create_node(type, start, end) {
56
+ let node = this.arena.create_node();
57
+ this.arena.set_type(node, type);
58
+ this.arena.set_start_offset(node, start);
59
+ this.arena.set_length(node, end - start);
60
+ this.arena.set_start_line(node, this.lexer.token_line);
61
+ this.arena.set_start_column(node, this.lexer.token_column);
62
+ return node;
63
+ }
55
64
  is_and_or_not(str) {
56
65
  if (str.length > 3 || str.length < 2) return false;
57
66
  return str_equals("and", str) || str_equals("or", str) || str_equals("not", str);
@@ -59,7 +68,7 @@ class AtRulePreludeParser {
59
68
  // Parse a single media query: screen and (min-width: 768px)
60
69
  parse_single_media_query() {
61
70
  let query_start = this.lexer.pos;
62
- let query_line = this.lexer.line;
71
+ this.lexer.line;
63
72
  this.skip_whitespace();
64
73
  if (this.lexer.pos >= this.prelude_end) return null;
65
74
  let token_start = this.lexer.pos;
@@ -87,19 +96,10 @@ class AtRulePreludeParser {
87
96
  } else if (token_type === TOKEN_IDENT) {
88
97
  let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
89
98
  if (this.is_and_or_not(text)) {
90
- let op = this.arena.create_node();
91
- this.arena.set_type(op, NODE_PRELUDE_OPERATOR);
92
- this.arena.set_start_offset(op, this.lexer.token_start);
93
- this.arena.set_length(op, this.lexer.token_end - this.lexer.token_start);
94
- this.arena.set_start_line(op, this.lexer.token_line);
99
+ let op = this.create_node(NODE_PRELUDE_OPERATOR, this.lexer.token_start, this.lexer.token_end);
95
100
  components.push(op);
96
101
  } else {
97
- let media_type = this.arena.create_node();
98
- this.arena.set_type(media_type, NODE_PRELUDE_MEDIA_TYPE);
99
- this.arena.set_start_offset(media_type, this.lexer.token_start);
100
- this.arena.set_length(media_type, this.lexer.token_end - this.lexer.token_start);
101
- this.arena.set_start_line(media_type, this.lexer.token_line);
102
- this.arena.set_start_column(media_type, this.lexer.token_column);
102
+ let media_type = this.create_node(NODE_PRELUDE_MEDIA_TYPE, this.lexer.token_start, this.lexer.token_end);
103
103
  components.push(media_type);
104
104
  }
105
105
  } else {
@@ -107,11 +107,7 @@ class AtRulePreludeParser {
107
107
  }
108
108
  }
109
109
  if (components.length === 0) return null;
110
- let query_node = this.arena.create_node();
111
- this.arena.set_type(query_node, NODE_PRELUDE_MEDIA_QUERY);
112
- this.arena.set_start_offset(query_node, query_start);
113
- this.arena.set_length(query_node, this.lexer.pos - query_start);
114
- this.arena.set_start_line(query_node, query_line);
110
+ let query_node = this.create_node(NODE_PRELUDE_MEDIA_QUERY, query_start, this.lexer.pos);
115
111
  for (let component of components) {
116
112
  this.arena.append_child(query_node, component);
117
113
  }
@@ -120,7 +116,7 @@ class AtRulePreludeParser {
120
116
  // Parse media feature: (min-width: 768px)
121
117
  parse_media_feature() {
122
118
  let feature_start = this.lexer.token_start;
123
- let feature_line = this.lexer.token_line;
119
+ this.lexer.token_line;
124
120
  let depth = 1;
125
121
  let content_start = this.lexer.pos;
126
122
  while (this.lexer.pos < this.prelude_end && depth > 0) {
@@ -135,11 +131,7 @@ class AtRulePreludeParser {
135
131
  if (depth !== 0) return null;
136
132
  let content_end = this.lexer.token_start;
137
133
  let feature_end = this.lexer.token_end;
138
- let feature = this.arena.create_node();
139
- this.arena.set_type(feature, NODE_PRELUDE_MEDIA_FEATURE);
140
- this.arena.set_start_offset(feature, feature_start);
141
- this.arena.set_length(feature, feature_end - feature_start);
142
- this.arena.set_start_line(feature, feature_line);
134
+ let feature = this.create_node(NODE_PRELUDE_MEDIA_FEATURE, feature_start, feature_end);
143
135
  let trimmed = trim_boundaries(this.source, content_start, content_end);
144
136
  if (trimmed) {
145
137
  this.arena.set_value_start(feature, trimmed[0]);
@@ -151,7 +143,7 @@ class AtRulePreludeParser {
151
143
  parse_container_query() {
152
144
  let nodes = [];
153
145
  let query_start = this.lexer.pos;
154
- let query_line = this.lexer.line;
146
+ this.lexer.line;
155
147
  let components = [];
156
148
  while (this.lexer.pos < this.prelude_end) {
157
149
  this.skip_whitespace();
@@ -166,28 +158,16 @@ class AtRulePreludeParser {
166
158
  } else if (token_type === TOKEN_IDENT) {
167
159
  let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
168
160
  if (this.is_and_or_not(text)) {
169
- let op = this.arena.create_node();
170
- this.arena.set_type(op, NODE_PRELUDE_OPERATOR);
171
- this.arena.set_start_offset(op, this.lexer.token_start);
172
- this.arena.set_length(op, this.lexer.token_end - this.lexer.token_start);
173
- this.arena.set_start_line(op, this.lexer.token_line);
161
+ let op = this.create_node(NODE_PRELUDE_OPERATOR, this.lexer.token_start, this.lexer.token_end);
174
162
  components.push(op);
175
163
  } else {
176
- let name = this.arena.create_node();
177
- this.arena.set_type(name, NODE_PRELUDE_IDENTIFIER);
178
- this.arena.set_start_offset(name, this.lexer.token_start);
179
- this.arena.set_length(name, this.lexer.token_end - this.lexer.token_start);
180
- this.arena.set_start_line(name, this.lexer.token_line);
164
+ let name = this.create_node(NODE_PRELUDE_IDENTIFIER, this.lexer.token_start, this.lexer.token_end);
181
165
  components.push(name);
182
166
  }
183
167
  }
184
168
  }
185
169
  if (components.length === 0) return [];
186
- let query_node = this.arena.create_node();
187
- this.arena.set_type(query_node, NODE_PRELUDE_CONTAINER_QUERY);
188
- this.arena.set_start_offset(query_node, query_start);
189
- this.arena.set_length(query_node, this.lexer.pos - query_start);
190
- this.arena.set_start_line(query_node, query_line);
170
+ let query_node = this.create_node(NODE_PRELUDE_CONTAINER_QUERY, query_start, this.lexer.pos);
191
171
  for (let component of components) {
192
172
  this.arena.append_child(query_node, component);
193
173
  }
@@ -204,7 +184,7 @@ class AtRulePreludeParser {
204
184
  let token_type = this.lexer.token_type;
205
185
  if (token_type === TOKEN_LEFT_PAREN) {
206
186
  let feature_start = this.lexer.token_start;
207
- let feature_line = this.lexer.token_line;
187
+ this.lexer.token_line;
208
188
  let depth = 1;
209
189
  let content_start = this.lexer.pos;
210
190
  while (this.lexer.pos < this.prelude_end && depth > 0) {
@@ -219,11 +199,7 @@ class AtRulePreludeParser {
219
199
  if (depth === 0) {
220
200
  let content_end = this.lexer.token_start;
221
201
  let feature_end = this.lexer.token_end;
222
- let query = this.arena.create_node();
223
- this.arena.set_type(query, NODE_PRELUDE_SUPPORTS_QUERY);
224
- this.arena.set_start_offset(query, feature_start);
225
- this.arena.set_length(query, feature_end - feature_start);
226
- this.arena.set_start_line(query, feature_line);
202
+ let query = this.create_node(NODE_PRELUDE_SUPPORTS_QUERY, feature_start, feature_end);
227
203
  let trimmed = trim_boundaries(this.source, content_start, content_end);
228
204
  if (trimmed) {
229
205
  this.arena.set_value_start(query, trimmed[0]);
@@ -234,11 +210,7 @@ class AtRulePreludeParser {
234
210
  } else if (token_type === TOKEN_IDENT) {
235
211
  let text = this.source.substring(this.lexer.token_start, this.lexer.token_end);
236
212
  if (this.is_and_or_not(text)) {
237
- let op = this.arena.create_node();
238
- this.arena.set_type(op, NODE_PRELUDE_OPERATOR);
239
- this.arena.set_start_offset(op, this.lexer.token_start);
240
- this.arena.set_length(op, this.lexer.token_end - this.lexer.token_start);
241
- this.arena.set_start_line(op, this.lexer.token_line);
213
+ let op = this.create_node(NODE_PRELUDE_OPERATOR, this.lexer.token_start, this.lexer.token_end);
242
214
  nodes.push(op);
243
215
  }
244
216
  }
@@ -254,11 +226,7 @@ class AtRulePreludeParser {
254
226
  this.next_token();
255
227
  let token_type = this.lexer.token_type;
256
228
  if (token_type === TOKEN_IDENT) {
257
- let layer = this.arena.create_node();
258
- this.arena.set_type(layer, NODE_PRELUDE_LAYER_NAME);
259
- this.arena.set_start_offset(layer, this.lexer.token_start);
260
- this.arena.set_length(layer, this.lexer.token_end - this.lexer.token_start);
261
- this.arena.set_start_line(layer, this.lexer.token_line);
229
+ let layer = this.create_node(NODE_PRELUDE_LAYER_NAME, this.lexer.token_start, this.lexer.token_end);
262
230
  nodes.push(layer);
263
231
  } else if (token_type === TOKEN_COMMA) {
264
232
  continue;
@@ -274,11 +242,7 @@ class AtRulePreludeParser {
274
242
  if (this.lexer.pos >= this.prelude_end) return [];
275
243
  this.next_token();
276
244
  if (this.lexer.token_type !== TOKEN_IDENT) return [];
277
- let ident = this.arena.create_node();
278
- this.arena.set_type(ident, NODE_PRELUDE_IDENTIFIER);
279
- this.arena.set_start_offset(ident, this.lexer.token_start);
280
- this.arena.set_length(ident, this.lexer.token_end - this.lexer.token_start);
281
- this.arena.set_start_line(ident, this.lexer.token_line);
245
+ let ident = this.create_node(NODE_PRELUDE_IDENTIFIER, this.lexer.token_start, this.lexer.token_end);
282
246
  return [ident];
283
247
  }
284
248
  // Parse @import prelude: url() [layer] [supports()] [media-query-list]
@@ -319,7 +283,7 @@ class AtRulePreludeParser {
319
283
  }
320
284
  let url_start = this.lexer.token_start;
321
285
  let url_end = this.lexer.token_end;
322
- let url_line = this.lexer.token_line;
286
+ this.lexer.token_line;
323
287
  if (this.lexer.token_type === TOKEN_FUNCTION) {
324
288
  let paren_depth = 1;
325
289
  while (this.lexer.pos < this.prelude_end && paren_depth > 0) {
@@ -336,11 +300,7 @@ class AtRulePreludeParser {
336
300
  }
337
301
  }
338
302
  }
339
- let url_node = this.arena.create_node();
340
- this.arena.set_type(url_node, NODE_PRELUDE_IMPORT_URL);
341
- this.arena.set_start_offset(url_node, url_start);
342
- this.arena.set_length(url_node, url_end - url_start);
343
- this.arena.set_start_line(url_node, url_line);
303
+ let url_node = this.create_node(NODE_PRELUDE_IMPORT_URL, url_start, url_end);
344
304
  return url_node;
345
305
  }
346
306
  // Parse import layer: layer or layer(name)
@@ -355,7 +315,7 @@ class AtRulePreludeParser {
355
315
  if (str_equals("layer", text)) {
356
316
  let layer_start = this.lexer.token_start;
357
317
  let layer_end = this.lexer.token_end;
358
- let layer_line = this.lexer.token_line;
318
+ this.lexer.token_line;
359
319
  let content_start = 0;
360
320
  let content_length = 0;
361
321
  if (this.lexer.token_type === TOKEN_FUNCTION) {
@@ -376,11 +336,7 @@ class AtRulePreludeParser {
376
336
  }
377
337
  }
378
338
  }
379
- let layer_node = this.arena.create_node();
380
- this.arena.set_type(layer_node, NODE_PRELUDE_IMPORT_LAYER);
381
- this.arena.set_start_offset(layer_node, layer_start);
382
- this.arena.set_length(layer_node, layer_end - layer_start);
383
- this.arena.set_start_line(layer_node, layer_line);
339
+ let layer_node = this.create_node(NODE_PRELUDE_IMPORT_LAYER, layer_start, layer_end);
384
340
  if (content_length > 0) {
385
341
  let trimmed = trim_boundaries(this.source, content_start, content_start + content_length);
386
342
  if (trimmed) {
@@ -402,7 +358,7 @@ class AtRulePreludeParser {
402
358
  let text = this.source.substring(this.lexer.token_start, this.lexer.token_end - 1);
403
359
  if (str_equals("supports", text)) {
404
360
  let supports_start = this.lexer.token_start;
405
- let supports_line = this.lexer.token_line;
361
+ this.lexer.token_line;
406
362
  let paren_depth = 1;
407
363
  let supports_end = this.lexer.token_end;
408
364
  while (this.lexer.pos < this.prelude_end && paren_depth > 0) {
@@ -418,11 +374,7 @@ class AtRulePreludeParser {
418
374
  break;
419
375
  }
420
376
  }
421
- let supports_node = this.arena.create_node();
422
- this.arena.set_type(supports_node, NODE_PRELUDE_IMPORT_SUPPORTS);
423
- this.arena.set_start_offset(supports_node, supports_start);
424
- this.arena.set_length(supports_node, supports_end - supports_start);
425
- this.arena.set_start_line(supports_node, supports_line);
377
+ let supports_node = this.create_node(NODE_PRELUDE_IMPORT_SUPPORTS, supports_start, supports_end);
426
378
  return supports_node;
427
379
  }
428
380
  }
@@ -11,6 +11,10 @@ export declare class SelectorParser {
11
11
  private parse_complex_selector;
12
12
  private parse_compound_selector;
13
13
  private parse_simple_selector;
14
+ private parse_namespace_local_part;
15
+ private parse_type_or_namespace_selector;
16
+ private parse_universal_or_namespace_selector;
17
+ private parse_empty_namespace_selector;
14
18
  private try_parse_combinator;
15
19
  private parse_class_selector;
16
20
  private parse_attribute_selector;
@@ -22,11 +26,7 @@ export declare class SelectorParser {
22
26
  private parse_lang_identifiers;
23
27
  private parse_nth_expression;
24
28
  private find_of_keyword;
25
- private create_type_selector;
26
- private create_id_selector;
27
- private create_universal_selector;
28
- private create_nesting_selector;
29
- private create_combinator;
29
+ private create_node;
30
30
  private skip_whitespace;
31
31
  }
32
32
  /**
@@ -1,5 +1,5 @@
1
1
  import { L as Lexer, q as TOKEN_COMMA, h as TOKEN_DELIM, y as TOKEN_EOF, l as TOKEN_WHITESPACE, a as TOKEN_FUNCTION, o as TOKEN_COLON, r as TOKEN_LEFT_BRACKET, c as TOKEN_HASH, T as TOKEN_IDENT, s as TOKEN_RIGHT_BRACKET, t as TOKEN_LEFT_PAREN, u as TOKEN_RIGHT_PAREN, d as TOKEN_STRING } from './lexer-CtBKgfVv.js';
2
- import { Y as CSSDataArena, w as NODE_SELECTOR_LIST, C as CSSNode, m as NODE_SELECTOR, a3 as CHAR_GREATER_THAN, a4 as CHAR_PLUS, a5 as CHAR_TILDE, a6 as CHAR_PERIOD, a7 as CHAR_ASTERISK, a8 as CHAR_AMPERSAND, a9 as is_whitespace, aa as is_combinator, y as NODE_SELECTOR_CLASS, B as NODE_SELECTOR_ATTRIBUTE, ab as skip_whitespace_and_comments_forward, ac as skip_whitespace_and_comments_backward, ad as CHAR_EQUALS, ae as CHAR_PIPE, af as CHAR_CARET, ag as CHAR_DOLLAR, A as ATTR_OPERATOR_NONE, g as ATTR_FLAG_NONE, a as ATTR_OPERATOR_EQUAL, b as ATTR_OPERATOR_TILDE_EQUAL, c as ATTR_OPERATOR_PIPE_EQUAL, d as ATTR_OPERATOR_CARET_EQUAL, e as ATTR_OPERATOR_DOLLAR_EQUAL, f as ATTR_OPERATOR_STAR_EQUAL, ah as CHAR_SINGLE_QUOTE, ai as CHAR_DOUBLE_QUOTE, h as ATTR_FLAG_CASE_INSENSITIVE, i as ATTR_FLAG_CASE_SENSITIVE, aj as CHAR_COLON, E as NODE_SELECTOR_PSEUDO_ELEMENT, D as NODE_SELECTOR_PSEUDO_CLASS, a0 as is_vendor_prefixed, a1 as FLAG_VENDOR_PREFIXED, ak as FLAG_HAS_PARENS, K as NODE_SELECTOR_LANG, al as skip_whitespace_forward, J as NODE_SELECTOR_NTH_OF, x as NODE_SELECTOR_TYPE, z as NODE_SELECTOR_ID, G as NODE_SELECTOR_UNIVERSAL, H as NODE_SELECTOR_NESTING, F as NODE_SELECTOR_COMBINATOR } from './css-node-aIMm9_Cb.js';
2
+ import { Y as CSSDataArena, w as NODE_SELECTOR_LIST, C as CSSNode, m as NODE_SELECTOR, a3 as CHAR_GREATER_THAN, a4 as CHAR_PLUS, a5 as CHAR_TILDE, F as NODE_SELECTOR_COMBINATOR, a6 as CHAR_PERIOD, a7 as CHAR_ASTERISK, a8 as CHAR_AMPERSAND, H as NODE_SELECTOR_NESTING, a9 as CHAR_PIPE, z as NODE_SELECTOR_ID, x as NODE_SELECTOR_TYPE, G as NODE_SELECTOR_UNIVERSAL, aa as is_whitespace, ab as is_combinator, y as NODE_SELECTOR_CLASS, B as NODE_SELECTOR_ATTRIBUTE, ac as skip_whitespace_and_comments_forward, ad as skip_whitespace_and_comments_backward, ae as CHAR_EQUALS, af as CHAR_CARET, ag as CHAR_DOLLAR, A as ATTR_OPERATOR_NONE, g as ATTR_FLAG_NONE, a as ATTR_OPERATOR_EQUAL, b as ATTR_OPERATOR_TILDE_EQUAL, c as ATTR_OPERATOR_PIPE_EQUAL, d as ATTR_OPERATOR_CARET_EQUAL, e as ATTR_OPERATOR_DOLLAR_EQUAL, f as ATTR_OPERATOR_STAR_EQUAL, ah as CHAR_SINGLE_QUOTE, ai as CHAR_DOUBLE_QUOTE, h as ATTR_FLAG_CASE_INSENSITIVE, i as ATTR_FLAG_CASE_SENSITIVE, aj as CHAR_COLON, E as NODE_SELECTOR_PSEUDO_ELEMENT, D as NODE_SELECTOR_PSEUDO_CLASS, a0 as is_vendor_prefixed, a1 as FLAG_VENDOR_PREFIXED, ak as FLAG_HAS_PARENS, K as NODE_SELECTOR_LANG, al as skip_whitespace_forward, J as NODE_SELECTOR_NTH_OF } from './css-node-DC75Lj1U.js';
3
3
  import { ANplusBParser } from './parse-anplusb.js';
4
4
 
5
5
  class SelectorParser {
@@ -30,16 +30,9 @@ class SelectorParser {
30
30
  let list_column = this.lexer.column;
31
31
  while (this.lexer.pos < this.selector_end) {
32
32
  let selector_start = this.lexer.pos;
33
- let selector_line = this.lexer.line;
34
- let selector_column = this.lexer.column;
35
33
  let complex_selector = this.parse_complex_selector(allow_relative);
36
34
  if (complex_selector !== null) {
37
- let selector_wrapper = this.arena.create_node();
38
- this.arena.set_type(selector_wrapper, NODE_SELECTOR);
39
- this.arena.set_start_offset(selector_wrapper, selector_start);
40
- this.arena.set_length(selector_wrapper, this.lexer.pos - selector_start);
41
- this.arena.set_start_line(selector_wrapper, selector_line);
42
- this.arena.set_start_column(selector_wrapper, selector_column);
35
+ let selector_wrapper = this.create_node(NODE_SELECTOR, selector_start, this.lexer.pos);
43
36
  let last_component = complex_selector;
44
37
  while (this.arena.get_next_sibling(last_component) !== 0) {
45
38
  last_component = this.arena.get_next_sibling(last_component);
@@ -88,7 +81,7 @@ class SelectorParser {
88
81
  if (token_type === TOKEN_DELIM) {
89
82
  let ch = this.source.charCodeAt(this.lexer.token_start);
90
83
  if (ch === CHAR_GREATER_THAN || ch === CHAR_PLUS || ch === CHAR_TILDE) {
91
- let combinator = this.create_combinator(this.lexer.token_start, this.lexer.token_end);
84
+ let combinator = this.create_node(NODE_SELECTOR_COMBINATOR, this.lexer.token_start, this.lexer.token_end);
92
85
  components.push(combinator);
93
86
  this.skip_whitespace();
94
87
  } else {
@@ -165,17 +158,19 @@ class SelectorParser {
165
158
  let end = this.lexer.token_end;
166
159
  switch (token_type) {
167
160
  case TOKEN_IDENT:
168
- return this.create_type_selector(start, end);
161
+ return this.parse_type_or_namespace_selector(start, end);
169
162
  case TOKEN_HASH:
170
- return this.create_id_selector(start, end);
163
+ return this.create_node(NODE_SELECTOR_ID, start, end);
171
164
  case TOKEN_DELIM:
172
165
  let ch = this.source.charCodeAt(start);
173
166
  if (ch === CHAR_PERIOD) {
174
167
  return this.parse_class_selector(start);
175
168
  } else if (ch === CHAR_ASTERISK) {
176
- return this.create_universal_selector(start, end);
169
+ return this.parse_universal_or_namespace_selector(start, end);
177
170
  } else if (ch === CHAR_AMPERSAND) {
178
- return this.create_nesting_selector(start, end);
171
+ return this.create_node(NODE_SELECTOR_NESTING, start, end);
172
+ } else if (ch === CHAR_PIPE) {
173
+ return this.parse_empty_namespace_selector(start);
179
174
  }
180
175
  return null;
181
176
  case TOKEN_LEFT_BRACKET:
@@ -191,6 +186,52 @@ class SelectorParser {
191
186
  return null;
192
187
  }
193
188
  }
189
+ // Parse the local part after | in a namespace selector (E or *)
190
+ // Returns the node type (TYPE or UNIVERSAL) or null if invalid
191
+ parse_namespace_local_part(selector_start, namespace_start, namespace_length) {
192
+ const saved = this.lexer.save_position();
193
+ this.lexer.next_token_fast(false);
194
+ let node_type;
195
+ if (this.lexer.token_type === TOKEN_IDENT) {
196
+ node_type = NODE_SELECTOR_TYPE;
197
+ } else if (this.lexer.token_type === TOKEN_DELIM && this.source.charCodeAt(this.lexer.token_start) === CHAR_ASTERISK) {
198
+ node_type = NODE_SELECTOR_UNIVERSAL;
199
+ } else {
200
+ this.lexer.restore_position(saved);
201
+ return null;
202
+ }
203
+ let node = this.create_node(node_type, selector_start, this.lexer.token_end);
204
+ this.arena.set_content_start(node, namespace_start);
205
+ this.arena.set_content_length(node, namespace_length);
206
+ return node;
207
+ }
208
+ // Parse type selector or namespace selector (ns|E or ns|*)
209
+ // Called when we've seen an IDENT token
210
+ parse_type_or_namespace_selector(start, end) {
211
+ if (this.lexer.pos < this.selector_end && this.source.charCodeAt(this.lexer.pos) === CHAR_PIPE) {
212
+ this.lexer.pos++;
213
+ let node = this.parse_namespace_local_part(start, start, end - start);
214
+ if (node !== null) return node;
215
+ this.lexer.pos = end;
216
+ }
217
+ return this.create_node(NODE_SELECTOR_TYPE, start, end);
218
+ }
219
+ // Parse universal selector or namespace selector (*|E or *|*)
220
+ // Called when we've seen a * DELIM token
221
+ parse_universal_or_namespace_selector(start, end) {
222
+ if (this.lexer.pos < this.selector_end && this.source.charCodeAt(this.lexer.pos) === CHAR_PIPE) {
223
+ this.lexer.pos++;
224
+ let node = this.parse_namespace_local_part(start, start, end - start);
225
+ if (node !== null) return node;
226
+ this.lexer.pos = end;
227
+ }
228
+ return this.create_node(NODE_SELECTOR_UNIVERSAL, start, end);
229
+ }
230
+ // Parse empty namespace selector (|E or |*)
231
+ // Called when we've seen a | DELIM token at the start
232
+ parse_empty_namespace_selector(start) {
233
+ return this.parse_namespace_local_part(start, start, 1);
234
+ }
194
235
  // Parse combinator (>, +, ~, or descendant space)
195
236
  try_parse_combinator() {
196
237
  let whitespace_start = this.lexer.pos;
@@ -209,7 +250,7 @@ class SelectorParser {
209
250
  if (this.lexer.token_type === TOKEN_DELIM) {
210
251
  let ch = this.source.charCodeAt(this.lexer.token_start);
211
252
  if (is_combinator(ch)) {
212
- return this.create_combinator(this.lexer.token_start, this.lexer.token_end);
253
+ return this.create_node(NODE_SELECTOR_COMBINATOR, this.lexer.token_start, this.lexer.token_end);
213
254
  }
214
255
  }
215
256
  if (has_whitespace) {
@@ -222,7 +263,7 @@ class SelectorParser {
222
263
  break;
223
264
  }
224
265
  }
225
- return this.create_combinator(whitespace_start, this.lexer.pos);
266
+ return this.create_node(NODE_SELECTOR_COMBINATOR, whitespace_start, this.lexer.pos);
226
267
  }
227
268
  this.lexer.pos = whitespace_start;
228
269
  return null;
@@ -235,15 +276,7 @@ class SelectorParser {
235
276
  this.lexer.restore_position(saved);
236
277
  return null;
237
278
  }
238
- let node = this.arena.create_node();
239
- this.arena.set_type(node, NODE_SELECTOR_CLASS);
240
- this.arena.set_start_offset(node, dot_pos);
241
- this.arena.set_length(node, this.lexer.token_end - dot_pos);
242
- this.arena.set_start_line(node, this.lexer.line);
243
- this.arena.set_start_column(node, this.lexer.column);
244
- this.arena.set_content_start(node, this.lexer.token_start);
245
- this.arena.set_content_length(node, this.lexer.token_end - this.lexer.token_start);
246
- return node;
279
+ return this.create_node(NODE_SELECTOR_CLASS, dot_pos, this.lexer.token_end);
247
280
  }
248
281
  // Parse attribute selector ([attr], [attr=value], etc.)
249
282
  parse_attribute_selector(start) {
@@ -265,12 +298,7 @@ class SelectorParser {
265
298
  }
266
299
  }
267
300
  }
268
- let node = this.arena.create_node();
269
- this.arena.set_type(node, NODE_SELECTOR_ATTRIBUTE);
270
- this.arena.set_start_offset(node, start);
271
- this.arena.set_length(node, end - start);
272
- this.arena.set_start_line(node, this.lexer.line);
273
- this.arena.set_start_column(node, this.lexer.column);
301
+ let node = this.create_node(NODE_SELECTOR_ATTRIBUTE, start, end);
274
302
  this.parse_attribute_content(node, content_start, content_end);
275
303
  return node;
276
304
  }
@@ -388,12 +416,11 @@ class SelectorParser {
388
416
  this.lexer.next_token_fast(false);
389
417
  let token_type = this.lexer.token_type;
390
418
  if (token_type === TOKEN_IDENT) {
391
- let node = this.arena.create_node();
392
- this.arena.set_type(node, is_pseudo_element ? NODE_SELECTOR_PSEUDO_ELEMENT : NODE_SELECTOR_PSEUDO_CLASS);
393
- this.arena.set_start_offset(node, start);
394
- this.arena.set_length(node, this.lexer.token_end - start);
395
- this.arena.set_start_line(node, this.lexer.line);
396
- this.arena.set_start_column(node, this.lexer.column);
419
+ let node = this.create_node(
420
+ is_pseudo_element ? NODE_SELECTOR_PSEUDO_ELEMENT : NODE_SELECTOR_PSEUDO_CLASS,
421
+ start,
422
+ this.lexer.token_end
423
+ );
397
424
  this.arena.set_content_start(node, this.lexer.token_start);
398
425
  this.arena.set_content_length(node, this.lexer.token_end - this.lexer.token_start);
399
426
  if (is_vendor_prefixed(this.source, this.lexer.token_start, this.lexer.token_end)) {
@@ -432,12 +459,7 @@ class SelectorParser {
432
459
  }
433
460
  }
434
461
  }
435
- let node = this.arena.create_node();
436
- this.arena.set_type(node, is_pseudo_element ? NODE_SELECTOR_PSEUDO_ELEMENT : NODE_SELECTOR_PSEUDO_CLASS);
437
- this.arena.set_start_offset(node, start);
438
- this.arena.set_length(node, end - start);
439
- this.arena.set_start_line(node, this.lexer.line);
440
- this.arena.set_start_column(node, this.lexer.column);
462
+ let node = this.create_node(is_pseudo_element ? NODE_SELECTOR_PSEUDO_ELEMENT : NODE_SELECTOR_PSEUDO_CLASS, start, end);
441
463
  this.arena.set_content_start(node, func_name_start);
442
464
  this.arena.set_content_length(node, func_name_end - func_name_start);
443
465
  this.arena.set_flag(node, FLAG_HAS_PARENS);
@@ -494,12 +516,7 @@ class SelectorParser {
494
516
  continue;
495
517
  }
496
518
  if (token_type === TOKEN_STRING || token_type === TOKEN_IDENT) {
497
- let lang_node = this.arena.create_node();
498
- this.arena.set_type(lang_node, NODE_SELECTOR_LANG);
499
- this.arena.set_start_offset(lang_node, token_start);
500
- this.arena.set_length(lang_node, token_end - token_start);
501
- this.arena.set_start_line(lang_node, this.lexer.line);
502
- this.arena.set_start_column(lang_node, this.lexer.column);
519
+ let lang_node = this.create_node(NODE_SELECTOR_LANG, token_start, token_end);
503
520
  if (first_child === null) {
504
521
  first_child = lang_node;
505
522
  }
@@ -569,54 +586,9 @@ class SelectorParser {
569
586
  }
570
587
  return -1;
571
588
  }
572
- // Create simple selector nodes
573
- create_type_selector(start, end) {
574
- let node = this.arena.create_node();
575
- this.arena.set_type(node, NODE_SELECTOR_TYPE);
576
- this.arena.set_start_offset(node, start);
577
- this.arena.set_length(node, end - start);
578
- this.arena.set_start_line(node, this.lexer.line);
579
- this.arena.set_start_column(node, this.lexer.column);
580
- this.arena.set_content_start(node, start);
581
- this.arena.set_content_length(node, end - start);
582
- return node;
583
- }
584
- create_id_selector(start, end) {
585
- let node = this.arena.create_node();
586
- this.arena.set_type(node, NODE_SELECTOR_ID);
587
- this.arena.set_start_offset(node, start);
588
- this.arena.set_length(node, end - start);
589
- this.arena.set_start_line(node, this.lexer.line);
590
- this.arena.set_start_column(node, this.lexer.column);
591
- this.arena.set_content_start(node, start + 1);
592
- this.arena.set_content_length(node, end - start - 1);
593
- return node;
594
- }
595
- create_universal_selector(start, end) {
596
- let node = this.arena.create_node();
597
- this.arena.set_type(node, NODE_SELECTOR_UNIVERSAL);
598
- this.arena.set_start_offset(node, start);
599
- this.arena.set_length(node, end - start);
600
- this.arena.set_start_line(node, this.lexer.line);
601
- this.arena.set_start_column(node, this.lexer.column);
602
- this.arena.set_content_start(node, start);
603
- this.arena.set_content_length(node, end - start);
604
- return node;
605
- }
606
- create_nesting_selector(start, end) {
607
- let node = this.arena.create_node();
608
- this.arena.set_type(node, NODE_SELECTOR_NESTING);
609
- this.arena.set_start_offset(node, start);
610
- this.arena.set_length(node, end - start);
611
- this.arena.set_start_line(node, this.lexer.line);
612
- this.arena.set_start_column(node, this.lexer.column);
613
- this.arena.set_content_start(node, start);
614
- this.arena.set_content_length(node, end - start);
615
- return node;
616
- }
617
- create_combinator(start, end) {
589
+ create_node(type, start, end) {
618
590
  let node = this.arena.create_node();
619
- this.arena.set_type(node, NODE_SELECTOR_COMBINATOR);
591
+ this.arena.set_type(node, type);
620
592
  this.arena.set_start_offset(node, start);
621
593
  this.arena.set_length(node, end - start);
622
594
  this.arena.set_start_line(node, this.lexer.line);
@@ -1,5 +1,5 @@
1
1
  import { L as Lexer, y as TOKEN_EOF, t as TOKEN_LEFT_PAREN, q as TOKEN_COMMA, h as TOKEN_DELIM, a as TOKEN_FUNCTION, c as TOKEN_HASH, d as TOKEN_STRING, k as TOKEN_DIMENSION, j as TOKEN_PERCENTAGE, i as TOKEN_NUMBER, T as TOKEN_IDENT, u as TOKEN_RIGHT_PAREN } from './lexer-CtBKgfVv.js';
2
- import { Y as CSSDataArena, C as CSSNode, a9 as is_whitespace, u as NODE_VALUE_OPERATOR, s as NODE_VALUE_COLOR, r as NODE_VALUE_STRING, q as NODE_VALUE_DIMENSION, p as NODE_VALUE_NUMBER, o as NODE_VALUE_KEYWORD, a4 as CHAR_PLUS, an as CHAR_MINUS_HYPHEN, a7 as CHAR_ASTERISK, ao as CHAR_FORWARD_SLASH, t as NODE_VALUE_FUNCTION, v as NODE_VALUE_PARENTHESIS } from './css-node-aIMm9_Cb.js';
2
+ import { Y as CSSDataArena, C as CSSNode, aa as is_whitespace, u as NODE_VALUE_OPERATOR, s as NODE_VALUE_COLOR, r as NODE_VALUE_STRING, q as NODE_VALUE_DIMENSION, p as NODE_VALUE_NUMBER, o as NODE_VALUE_KEYWORD, a4 as CHAR_PLUS, an as CHAR_MINUS_HYPHEN, a7 as CHAR_ASTERISK, ao as CHAR_FORWARD_SLASH, t as NODE_VALUE_FUNCTION, v as NODE_VALUE_PARENTHESIS } from './css-node-DC75Lj1U.js';
3
3
 
4
4
  class ValueParser {
5
5
  lexer;
package/dist/parse.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { L as Lexer, y as TOKEN_EOF, b as TOKEN_AT_KEYWORD, v as TOKEN_LEFT_BRACE, w as TOKEN_RIGHT_BRACE, T as TOKEN_IDENT, o as TOKEN_COLON, p as TOKEN_SEMICOLON, h as TOKEN_DELIM } from './lexer-CtBKgfVv.js';
2
- import { Y as CSSDataArena, n as NODE_STYLESHEET, C as CSSNode, N as NODE_STYLE_RULE, Z as FLAG_HAS_BLOCK, _ as NODE_BLOCK, $ as FLAG_HAS_DECLARATIONS, w as NODE_SELECTOR_LIST, l as NODE_DECLARATION, a0 as is_vendor_prefixed, a1 as FLAG_VENDOR_PREFIXED, a2 as trim_boundaries, X as FLAG_IMPORTANT, j as NODE_AT_RULE } from './css-node-aIMm9_Cb.js';
3
- export { k as NODE_COMMENT, P as NODE_PRELUDE_CONTAINER_QUERY, S as NODE_PRELUDE_IDENTIFIER, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, U as NODE_PRELUDE_IMPORT_URL, R as NODE_PRELUDE_LAYER_NAME, M as NODE_PRELUDE_MEDIA_FEATURE, L as NODE_PRELUDE_MEDIA_QUERY, O as NODE_PRELUDE_MEDIA_TYPE, T as NODE_PRELUDE_OPERATOR, Q as NODE_PRELUDE_SUPPORTS_QUERY, m as NODE_SELECTOR, B as NODE_SELECTOR_ATTRIBUTE, y as NODE_SELECTOR_CLASS, F as NODE_SELECTOR_COMBINATOR, z as NODE_SELECTOR_ID, K as NODE_SELECTOR_LANG, H as NODE_SELECTOR_NESTING, I as NODE_SELECTOR_NTH, J as NODE_SELECTOR_NTH_OF, D as NODE_SELECTOR_PSEUDO_CLASS, E as NODE_SELECTOR_PSEUDO_ELEMENT, x as NODE_SELECTOR_TYPE, G as NODE_SELECTOR_UNIVERSAL, s as NODE_VALUE_COLOR, q as NODE_VALUE_DIMENSION, t as NODE_VALUE_FUNCTION, o as NODE_VALUE_KEYWORD, p as NODE_VALUE_NUMBER, u as NODE_VALUE_OPERATOR, v as NODE_VALUE_PARENTHESIS, r as NODE_VALUE_STRING } from './css-node-aIMm9_Cb.js';
2
+ import { Y as CSSDataArena, n as NODE_STYLESHEET, C as CSSNode, N as NODE_STYLE_RULE, Z as FLAG_HAS_BLOCK, _ as NODE_BLOCK, $ as FLAG_HAS_DECLARATIONS, w as NODE_SELECTOR_LIST, l as NODE_DECLARATION, a0 as is_vendor_prefixed, a1 as FLAG_VENDOR_PREFIXED, a2 as trim_boundaries, X as FLAG_IMPORTANT, j as NODE_AT_RULE } from './css-node-DC75Lj1U.js';
3
+ export { k as NODE_COMMENT, P as NODE_PRELUDE_CONTAINER_QUERY, S as NODE_PRELUDE_IDENTIFIER, V as NODE_PRELUDE_IMPORT_LAYER, W as NODE_PRELUDE_IMPORT_SUPPORTS, U as NODE_PRELUDE_IMPORT_URL, R as NODE_PRELUDE_LAYER_NAME, M as NODE_PRELUDE_MEDIA_FEATURE, L as NODE_PRELUDE_MEDIA_QUERY, O as NODE_PRELUDE_MEDIA_TYPE, T as NODE_PRELUDE_OPERATOR, Q as NODE_PRELUDE_SUPPORTS_QUERY, m as NODE_SELECTOR, B as NODE_SELECTOR_ATTRIBUTE, y as NODE_SELECTOR_CLASS, F as NODE_SELECTOR_COMBINATOR, z as NODE_SELECTOR_ID, K as NODE_SELECTOR_LANG, H as NODE_SELECTOR_NESTING, I as NODE_SELECTOR_NTH, J as NODE_SELECTOR_NTH_OF, D as NODE_SELECTOR_PSEUDO_CLASS, E as NODE_SELECTOR_PSEUDO_ELEMENT, x as NODE_SELECTOR_TYPE, G as NODE_SELECTOR_UNIVERSAL, s as NODE_VALUE_COLOR, q as NODE_VALUE_DIMENSION, t as NODE_VALUE_FUNCTION, o as NODE_VALUE_KEYWORD, p as NODE_VALUE_NUMBER, u as NODE_VALUE_OPERATOR, v as NODE_VALUE_PARENTHESIS, r as NODE_VALUE_STRING } from './css-node-DC75Lj1U.js';
4
4
  import { ValueParser } from './parse-value.js';
5
5
  import { SelectorParser } from './parse-selector.js';
6
6
  import { AtRulePreludeParser } from './parse-atrule-prelude.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectwallace/css-parser",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "High-performance CSS lexer and parser, optimized for CSS inspection and analysis",
5
5
  "author": "Bart Veneman <bat@projectwallace.com>",
6
6
  "license": "MIT",