@projectwallace/css-parser 0.13.6 → 0.13.9

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.
@@ -315,7 +315,7 @@ var CSSNode = class CSSNode {
315
315
  /** Get the "content" text (at-rule name for at-rules, layer name for import layers) */
316
316
  get name() {
317
317
  let { type } = this;
318
- if (type === 4 || type === 16 || type === 5) return;
318
+ if (type === 4 || type === 16 || type === 5 || type === 33) return;
319
319
  return this.get_content();
320
320
  }
321
321
  /**
@@ -336,6 +336,8 @@ var CSSNode = class CSSNode {
336
336
  */
337
337
  get value() {
338
338
  let { type, text, first_child } = this;
339
+ if (type === 3) return void 0;
340
+ if (type === 34) return text;
339
341
  if (type === 4 && first_child) return first_child;
340
342
  if (type === 12) return parse_dimension(text).value;
341
343
  if (type === 11) return Number.parseFloat(text);
@@ -424,7 +426,7 @@ var CSSNode = class CSSNode {
424
426
  /** Check if this node has a prelude (at-rules and style rules) */
425
427
  get has_prelude() {
426
428
  let { type } = this;
427
- if (type === 3) return this.arena.get_value_length(this.index) > 0;
429
+ if (type === 3) return this.first_child !== null && this.first_child.type !== 7;
428
430
  if (type === 2) return this.first_child !== null;
429
431
  return false;
430
432
  }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { C as TOKEN_RIGHT_BRACKET, D as TOKEN_UNICODE_RANGE, E as TOKEN_STRING, O as TOKEN_URL, S as TOKEN_RIGHT_BRACE, T as TOKEN_SEMICOLON, _ as TOKEN_LEFT_BRACE, a as TOKEN_BAD_URL, b as TOKEN_NUMBER, c as TOKEN_COLON, d as TOKEN_DELIM, f as TOKEN_DIMENSION, g as TOKEN_IDENT, h as TOKEN_HASH, i as TOKEN_BAD_STRING, k as TOKEN_WHITESPACE, l as TOKEN_COMMA, m as TOKEN_FUNCTION, n as tokenize, o as TOKEN_CDC, p as TOKEN_EOF, r as TOKEN_AT_KEYWORD, s as TOKEN_CDO, u as TOKEN_COMMENT, v as TOKEN_LEFT_BRACKET, w as TOKEN_RIGHT_PAREN, x as TOKEN_PERCENTAGE, y as TOKEN_LEFT_PAREN } from "./tokenize-BQFB1jXg.js";
2
- import { $ as TYPE_SELECTOR, A as IDENTIFIER, B as NUMBER, D as FLAG_IMPORTANT, E as FEATURE_RANGE, F as MEDIA_QUERY, G as PSEUDO_ELEMENT_SELECTOR, H as PARENTHESIS, I as MEDIA_TYPE, J as SELECTOR_LIST, K as RAW, L as NESTING_SELECTOR, M as LANG_SELECTOR, N as LAYER_NAME, O as FUNCTION, P as MEDIA_FEATURE, Q as SUPPORTS_QUERY, R as NTH_OF_SELECTOR, S as CONTAINER_QUERY, T as DIMENSION, U as PRELUDE_OPERATOR, V as OPERATOR, W as PSEUDO_CLASS_SELECTOR, X as STYLESHEET, Y as STRING, Z as STYLE_RULE, _ as AT_RULE_PRELUDE, a as ATTRIBUTE_SELECTOR, b as COMBINATOR, c as ATTR_FLAG_NONE, d as ATTR_OPERATOR_EQUAL, et as UNIVERSAL_SELECTOR, f as ATTR_OPERATOR_NONE, g as AT_RULE, h as ATTR_OPERATOR_TILDE_EQUAL, i as TYPE_NAMES, j as ID_SELECTOR, k as HASH, l as ATTR_OPERATOR_CARET_EQUAL, m as ATTR_OPERATOR_STAR_EQUAL, n as ATTR_OPERATOR_NAMES, nt as VALUE, o as ATTR_FLAG_CASE_INSENSITIVE, p as ATTR_OPERATOR_PIPE_EQUAL, q as SELECTOR, r as CSSNode, s as ATTR_FLAG_CASE_SENSITIVE, t as ATTR_FLAG_NAMES, tt as URL, u as ATTR_OPERATOR_DOLLAR_EQUAL, v as BLOCK, w as DECLARATION, x as COMMENT, y as CLASS_SELECTOR, z as NTH_SELECTOR } from "./css-node-2ejJUrIw.js";
1
+ import { C as TOKEN_RIGHT_BRACKET, D as TOKEN_UNICODE_RANGE, E as TOKEN_STRING, O as TOKEN_URL, S as TOKEN_RIGHT_BRACE, T as TOKEN_SEMICOLON, _ as TOKEN_LEFT_BRACE, a as TOKEN_BAD_URL, b as TOKEN_NUMBER, c as TOKEN_COLON, d as TOKEN_DELIM, f as TOKEN_DIMENSION, g as TOKEN_IDENT, h as TOKEN_HASH, i as TOKEN_BAD_STRING, k as TOKEN_WHITESPACE, l as TOKEN_COMMA, m as TOKEN_FUNCTION, n as tokenize, o as TOKEN_CDC, p as TOKEN_EOF, r as TOKEN_AT_KEYWORD, s as TOKEN_CDO, u as TOKEN_COMMENT, v as TOKEN_LEFT_BRACKET, w as TOKEN_RIGHT_PAREN, x as TOKEN_PERCENTAGE, y as TOKEN_LEFT_PAREN } from "./tokenize-BSycRGm0.js";
2
+ import { $ as TYPE_SELECTOR, A as IDENTIFIER, B as NUMBER, D as FLAG_IMPORTANT, E as FEATURE_RANGE, F as MEDIA_QUERY, G as PSEUDO_ELEMENT_SELECTOR, H as PARENTHESIS, I as MEDIA_TYPE, J as SELECTOR_LIST, K as RAW, L as NESTING_SELECTOR, M as LANG_SELECTOR, N as LAYER_NAME, O as FUNCTION, P as MEDIA_FEATURE, Q as SUPPORTS_QUERY, R as NTH_OF_SELECTOR, S as CONTAINER_QUERY, T as DIMENSION, U as PRELUDE_OPERATOR, V as OPERATOR, W as PSEUDO_CLASS_SELECTOR, X as STYLESHEET, Y as STRING, Z as STYLE_RULE, _ as AT_RULE_PRELUDE, a as ATTRIBUTE_SELECTOR, b as COMBINATOR, c as ATTR_FLAG_NONE, d as ATTR_OPERATOR_EQUAL, et as UNIVERSAL_SELECTOR, f as ATTR_OPERATOR_NONE, g as AT_RULE, h as ATTR_OPERATOR_TILDE_EQUAL, i as TYPE_NAMES, j as ID_SELECTOR, k as HASH, l as ATTR_OPERATOR_CARET_EQUAL, m as ATTR_OPERATOR_STAR_EQUAL, n as ATTR_OPERATOR_NAMES, nt as VALUE, o as ATTR_FLAG_CASE_INSENSITIVE, p as ATTR_OPERATOR_PIPE_EQUAL, q as SELECTOR, r as CSSNode, s as ATTR_FLAG_CASE_SENSITIVE, t as ATTR_FLAG_NAMES, tt as URL, u as ATTR_OPERATOR_DOLLAR_EQUAL, v as BLOCK, w as DECLARATION, x as COMMENT, y as CLASS_SELECTOR, z as NTH_SELECTOR } from "./css-node-Uj4oBgaw.js";
3
3
  import { c as str_starts_with, i as is_vendor_prefixed, o as str_equals, r as is_custom, s as str_index_of, t as parse_dimension } from "./parse-dimension-CCn_XRDe.js";
4
4
  import { parse_selector } from "./parse-selector.js";
5
5
  import { parse_atrule_prelude } from "./parse-atrule-prelude.js";
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { o as str_equals, s as str_index_of } from "./parse-dimension-CCn_XRDe.js";
4
4
  //#region src/parse-anplusb.ts
5
5
  /** @internal */
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { a as is_whitespace, l as strip_vendor_prefix, o as str_equals } from "./parse-dimension-CCn_XRDe.js";
4
4
  import { i as trim_boundaries, n as skip_whitespace_and_comments_forward } from "./parse-utils-DnsZRpfd.js";
5
5
  //#region src/parse-atrule-prelude.ts
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { i as is_vendor_prefixed } from "./parse-dimension-CCn_XRDe.js";
4
4
  import { i as trim_boundaries } from "./parse-utils-DnsZRpfd.js";
5
5
  import { ValueParser } from "./parse-value.js";
@@ -21,7 +21,9 @@ var DeclarationParser = class {
21
21
  return this.parse_declaration_with_lexer(lexer, end);
22
22
  }
23
23
  parse_declaration_with_lexer(lexer, end) {
24
+ const initial_saved = lexer.save_position();
24
25
  let has_browser_hack = false;
26
+ let has_delimiter_prefix = false;
25
27
  let browser_hack_start = 0;
26
28
  let browser_hack_line = 1;
27
29
  let browser_hack_column = 1;
@@ -51,8 +53,10 @@ var DeclarationParser = class {
51
53
  browser_hack_line = lexer.token_line;
52
54
  browser_hack_column = lexer.token_column;
53
55
  lexer.next_token_fast(true);
54
- if (lexer.token_type === 1) has_browser_hack = true;
55
- else lexer.restore_position(delim_saved);
56
+ if (lexer.token_type === 1) {
57
+ has_browser_hack = true;
58
+ has_delimiter_prefix = true;
59
+ } else lexer.restore_position(delim_saved);
56
60
  }
57
61
  if (lexer.token_type !== 1 && lexer.token_type !== 3 && lexer.token_type !== 4) return null;
58
62
  let prop_start = has_browser_hack ? browser_hack_start : lexer.token_start;
@@ -62,7 +66,7 @@ var DeclarationParser = class {
62
66
  const saved = lexer.save_position();
63
67
  lexer.next_token_fast(true);
64
68
  if (lexer.token_type !== 16) {
65
- lexer.restore_position(saved);
69
+ lexer.restore_position(has_delimiter_prefix ? initial_saved : saved);
66
70
  return null;
67
71
  }
68
72
  lexer.next_token_fast(true);
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { a as is_whitespace, n as is_combinator, o as str_equals } from "./parse-dimension-CCn_XRDe.js";
4
4
  import { n as skip_whitespace_and_comments_forward, r as skip_whitespace_forward, t as skip_whitespace_and_comments_backward } from "./parse-utils-DnsZRpfd.js";
5
5
  import { ANplusBParser } from "./parse-anplusb.js";
@@ -163,6 +163,7 @@ var SelectorParser = class {
163
163
  return node;
164
164
  }
165
165
  parse_type_or_namespace_selector(start, end) {
166
+ if (this.source.charCodeAt(start) === 45 && this.source.charCodeAt(start + 1) === 45) return null;
166
167
  const saved = this.lexer.save_position();
167
168
  this.skip_whitespace();
168
169
  if (this.lexer.pos < this.selector_end && this.source.charCodeAt(this.lexer.pos) === 124) {
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { a as is_whitespace, o as str_equals } from "./parse-dimension-CCn_XRDe.js";
4
4
  //#region src/parse-value.ts
5
5
  /** @internal */
package/dist/parse.d.ts CHANGED
@@ -32,7 +32,6 @@ declare class Parser {
32
32
  private parse_declaration;
33
33
  private parse_atrule;
34
34
  private atrule_has_declarations;
35
- private atrule_is_conditional;
36
35
  }
37
36
  /**
38
37
  * Parse CSS and return an AST
package/dist/parse.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as Lexer } from "./tokenize-BQFB1jXg.js";
2
- import { C as CSSDataArena, r as CSSNode } from "./css-node-2ejJUrIw.js";
1
+ import { t as Lexer } from "./tokenize-BSycRGm0.js";
2
+ import { C as CSSDataArena, r as CSSNode } from "./css-node-Uj4oBgaw.js";
3
3
  import { i as trim_boundaries } from "./parse-utils-DnsZRpfd.js";
4
4
  import { SelectorParser } from "./parse-selector.js";
5
5
  import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
@@ -16,16 +16,6 @@ let DECLARATION_AT_RULES = new Set([
16
16
  "position-try",
17
17
  "view-transition"
18
18
  ]);
19
- let CONDITIONAL_AT_RULES = new Set([
20
- "media",
21
- "supports",
22
- "container",
23
- "layer",
24
- "nest",
25
- "scope",
26
- "starting-style",
27
- "function"
28
- ]);
29
19
  /** @internal */
30
20
  var Parser = class {
31
21
  source;
@@ -184,15 +174,13 @@ var Parser = class {
184
174
  }
185
175
  let trimmed = trim_boundaries(this.source, prelude_start, prelude_end);
186
176
  let prelude_wrapper = null;
187
- if (trimmed) {
188
- this.arena.set_value_start_delta(at_rule, trimmed[0] - at_rule_start);
189
- this.arena.set_value_length(at_rule, trimmed[1] - trimmed[0]);
190
- if (this.prelude_parser) {
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) {
191
180
  prelude_wrapper = this.arena.create_node(40, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
192
- let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name, trimmed[0], trimmed[1], at_rule_line, at_rule_column);
193
- if (prelude_nodes.length > 0) this.arena.append_children(prelude_wrapper, prelude_nodes);
181
+ this.arena.append_children(prelude_wrapper, prelude_nodes);
194
182
  } else prelude_wrapper = this.arena.create_node(8, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
195
- }
183
+ } else prelude_wrapper = this.arena.create_node(8, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
196
184
  let last_end = this.lexer.token_end;
197
185
  if (this.peek_type() === 23) {
198
186
  let block_start = this.lexer.token_end;
@@ -202,7 +190,6 @@ var Parser = class {
202
190
  let block_column = this.lexer.token_column;
203
191
  let block_node = this.arena.create_node(7, block_start, 0, block_line, block_column);
204
192
  let has_declarations = this.atrule_has_declarations(at_rule_name);
205
- let is_conditional = this.atrule_is_conditional(at_rule_name);
206
193
  let block_children = [];
207
194
  if (has_declarations) while (!this.is_eof()) {
208
195
  if (this.peek_type() === 24) break;
@@ -210,7 +197,7 @@ var Parser = class {
210
197
  if (declaration !== null) block_children.push(declaration);
211
198
  else this.next_token();
212
199
  }
213
- else if (is_conditional) while (!this.is_eof()) {
200
+ else while (!this.is_eof()) {
214
201
  let token_type = this.peek_type();
215
202
  if (token_type === 24) break;
216
203
  if (token_type === 3) {
@@ -228,12 +215,6 @@ var Parser = class {
228
215
  if (nested_rule !== null) block_children.push(nested_rule);
229
216
  else this.next_token();
230
217
  }
231
- else while (!this.is_eof()) {
232
- if (this.peek_type() === 24) break;
233
- let rule = this.parse_rule();
234
- if (rule !== null) block_children.push(rule);
235
- else this.next_token();
236
- }
237
218
  if (this.peek_type() === 24) {
238
219
  let block_end = this.lexer.token_start;
239
220
  last_end = this.lexer.token_end;
@@ -260,9 +241,6 @@ var Parser = class {
260
241
  atrule_has_declarations(name) {
261
242
  return DECLARATION_AT_RULES.has(name.toLowerCase());
262
243
  }
263
- atrule_is_conditional(name) {
264
- return CONDITIONAL_AT_RULES.has(name.toLowerCase());
265
- }
266
244
  };
267
245
  /**
268
246
  * Parse CSS and return an AST
@@ -1,23 +1,26 @@
1
+ //#region src/char-types.ts
2
+ let CHAR_ALPHA = 1;
3
+ let CHAR_HEX = 4;
1
4
  let char_types = new Uint8Array(128);
2
5
  for (let i = 48; i <= 57; i++) char_types[i] = 2;
3
- for (let i = 48; i <= 57; i++) char_types[i] |= 4;
4
- for (let i = 65; i <= 70; i++) char_types[i] = 4;
5
- for (let i = 97; i <= 102; i++) char_types[i] = 4;
6
- for (let i = 65; i <= 90; i++) char_types[i] |= 1;
7
- for (let i = 97; i <= 122; i++) char_types[i] |= 1;
6
+ for (let i = 48; i <= 57; i++) char_types[i] |= CHAR_HEX;
7
+ for (let i = 65; i <= 70; i++) char_types[i] = CHAR_HEX;
8
+ for (let i = 97; i <= 102; i++) char_types[i] = CHAR_HEX;
9
+ for (let i = 65; i <= 90; i++) char_types[i] |= CHAR_ALPHA;
10
+ for (let i = 97; i <= 122; i++) char_types[i] |= CHAR_ALPHA;
8
11
  char_types[32] = 8;
9
12
  char_types[9] = 8;
10
13
  char_types[10] = 16;
11
14
  char_types[13] = 16;
12
15
  char_types[12] = 16;
13
- for (let i = 0; i < 128; i++) if (char_types[i] & 3) char_types[i] |= 32;
16
+ for (let i = 0; i < 128; i++) if (char_types[i] & (CHAR_ALPHA | 2)) char_types[i] |= 32;
14
17
  char_types[45] |= 32;
15
18
  char_types[95] |= 32;
16
19
  function is_hex_digit(ch) {
17
- return ch < 128 && (char_types[ch] & 4) !== 0;
20
+ return ch < 128 && (char_types[ch] & CHAR_HEX) !== 0;
18
21
  }
19
22
  function is_alpha(ch) {
20
- return ch < 128 && (char_types[ch] & 1) !== 0;
23
+ return ch < 128 && (char_types[ch] & CHAR_ALPHA) !== 0;
21
24
  }
22
25
  function is_whitespace(ch) {
23
26
  return ch < 128 && (char_types[ch] & 8) !== 0;
package/dist/tokenize.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as tokenize, t as Lexer } from "./tokenize-BQFB1jXg.js";
1
+ import { n as tokenize, t as Lexer } from "./tokenize-BSycRGm0.js";
2
2
  export { Lexer, tokenize };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectwallace/css-parser",
3
- "version": "0.13.6",
3
+ "version": "0.13.9",
4
4
  "description": "High-performance CSS lexer and parser, optimized for CSS inspection and analysis",
5
5
  "keywords": [
6
6
  "ast",
@@ -71,6 +71,7 @@
71
71
  "benchmark:memory": "npm run build && node --expose-gc benchmark/memory.ts",
72
72
  "lint": "oxlint --config .oxlintrc.json && oxfmt --check",
73
73
  "check": "tsc --noEmit",
74
+ "knip": "knip",
74
75
  "precommit": "npm run test -- --run; npm run lint; npm run check"
75
76
  },
76
77
  "devDependencies": {
@@ -80,12 +81,13 @@
80
81
  "@vitest/coverage-v8": "^4.0.8",
81
82
  "bootstrap": "^5.3.8",
82
83
  "css-tree": "^3.1.0",
83
- "oxfmt": "^0.36.0",
84
+ "knip": "^5.86.0",
85
+ "oxfmt": "^0.40.0",
84
86
  "oxlint": "^1.28.0",
85
87
  "postcss": "^8.5.6",
86
88
  "publint": "^0.3.18",
87
89
  "tailwindcss": "^2.2.8",
88
- "tinybench": "^2.9.0",
90
+ "tinybench": "^6.0.0",
89
91
  "tsdown": "^0.21.0",
90
92
  "typescript": "^5.9.3",
91
93
  "vitest": "^4.0.8"