@projectwallace/css-parser 0.19.2 → 0.19.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.
Files changed (40) hide show
  1. package/README.md +15 -2
  2. package/dist/{arena-CsJhQRUX.js → arena-CaLnNKbP.js} +7 -4
  3. package/dist/{arena-7RLvyGPB.d.ts → arena-D689Bo6V.d.ts} +4 -3
  4. package/dist/constants.d.ts +46 -48
  5. package/dist/constants.js +2 -3
  6. package/dist/{css-node-BKcf0ZeS.js → css-node-CDTLvxo3.js} +3 -4
  7. package/dist/index.d.ts +6 -6
  8. package/dist/index.js +6 -6
  9. package/dist/{node-types-CD7A-d_c.d.ts → node-types-BF6bhAjo.d.ts} +56 -64
  10. package/dist/node-types.d.ts +1 -1
  11. package/dist/node-types.js +2 -3
  12. package/dist/parse-anplusb.d.ts +3 -5
  13. package/dist/parse-anplusb.js +5 -6
  14. package/dist/{value-node-parser-B568SwUx.js → parse-atrule-prelude-BMkgCZjw.js} +465 -15
  15. package/dist/parse-atrule-prelude.d.ts +13 -6
  16. package/dist/parse-atrule-prelude.js +1 -431
  17. package/dist/parse-declaration.d.ts +4 -6
  18. package/dist/parse-declaration.js +8 -9
  19. package/dist/parse-dimension.d.ts +1 -3
  20. package/dist/parse-dimension.js +2 -3
  21. package/dist/{parse-selector-DORsuJvq.js → parse-selector-CMKZgPmu.js} +6 -8
  22. package/dist/parse-selector.d.ts +3 -5
  23. package/dist/parse-selector.js +1 -1
  24. package/dist/parse-value.d.ts +4 -6
  25. package/dist/parse-value.js +6 -7
  26. package/dist/parse.d.ts +10 -5
  27. package/dist/parse.js +9 -10
  28. package/dist/{string-helpers-t7UofIfp.d.ts → string-helpers-CwNEcEhd.d.ts} +0 -2
  29. package/dist/string-helpers.d.ts +1 -1
  30. package/dist/string-helpers.js +1 -1
  31. package/dist/{string-utils-aEEsA2CS.js → string-utils-BYH1Oe8a.js} +0 -1
  32. package/dist/{token-types-Bqsf5FX-.d.ts → token-types-BhoXrORA.d.ts} +0 -2
  33. package/dist/token-types.d.ts +1 -1
  34. package/dist/token-types.js +1 -2
  35. package/dist/{tokenize-B2QSzdrM.js → tokenize-DC2Vb0J_.js} +20 -6
  36. package/dist/tokenize.d.ts +17 -5
  37. package/dist/tokenize.js +1 -1
  38. package/dist/walk.d.ts +1 -3
  39. package/dist/walk.js +3 -4
  40. package/package.json +3 -3
package/dist/parse.js CHANGED
@@ -1,11 +1,11 @@
1
- import { t as Lexer } from "./tokenize-B2QSzdrM.js";
1
+ import { t as Lexer } from "./tokenize-DC2Vb0J_.js";
2
2
  import "./token-types.js";
3
- import { l as CSSDataArena } from "./arena-CsJhQRUX.js";
4
- import { t as CSSNode } from "./css-node-BKcf0ZeS.js";
5
- import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward, t as SelectorParser } from "./parse-selector-DORsuJvq.js";
6
- import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
3
+ import { l as CSSDataArena } from "./arena-CaLnNKbP.js";
4
+ import { t as CSSNode } from "./css-node-CDTLvxo3.js";
5
+ import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward, t as SelectorParser } from "./parse-selector-CMKZgPmu.js";
6
+ import { t as AtRulePreludeParser } from "./parse-atrule-prelude-BMkgCZjw.js";
7
7
  import { DeclarationParser } from "./parse-declaration.js";
8
- //#region src/parse.ts
8
+ // src/parse.ts
9
9
  const DECLARATION_AT_RULES = /* @__PURE__ */ new Set([
10
10
  "font-face",
11
11
  "styleset",
@@ -55,11 +55,11 @@ var Parser = class {
55
55
  this.parse_selectors_enabled = opts.parse_selectors ?? true;
56
56
  this.parse_atrule_preludes_enabled = opts.parse_atrule_preludes ?? true;
57
57
  this.lexer = new Lexer(source, opts.on_comment);
58
- const capacity = CSSDataArena.capacity_for_source(source.length);
58
+ const capacity = CSSDataArena.capacity_for_source(source.length, this.parse_values_enabled, this.parse_selectors_enabled);
59
59
  this.arena = new CSSDataArena(capacity);
60
60
  this.selector_parser = this.parse_selectors_enabled ? new SelectorParser(this.arena, source) : null;
61
- this.prelude_parser = this.parse_atrule_preludes_enabled ? new AtRulePreludeParser(this.arena, source) : null;
62
- this.declaration_parser = new DeclarationParser(this.arena, source, this.parse_values_enabled);
61
+ this.prelude_parser = this.parse_atrule_preludes_enabled ? new AtRulePreludeParser(this.arena, source, opts.media_feature_range_name_as_child ?? false) : null;
62
+ this.declaration_parser = new DeclarationParser(this.arena, source, this.parse_values_enabled, opts.media_feature_range_name_as_child ?? false);
63
63
  }
64
64
  get_arena() {
65
65
  return this.arena;
@@ -266,5 +266,4 @@ var Parser = class {
266
266
  function parse(source, options) {
267
267
  return new Parser(source, options).parse();
268
268
  }
269
- //#endregion
270
269
  export { Parser, parse };
@@ -1,4 +1,3 @@
1
- //#region src/string-utils.d.ts
2
1
  /** Case-insensitive ASCII equality without allocations. `a` MUST be lowercase. */
3
2
  declare function str_equals(a: string, b: string): boolean;
4
3
  /** Case-insensitive ASCII prefix check without allocations. `prefix` MUST be lowercase. */
@@ -12,5 +11,4 @@ declare function is_vendor_prefixed(source: string, start: number, end: number):
12
11
  declare function is_custom(str: string): boolean;
13
12
  /** Strip a vendor prefix, e.g. `-webkit-keyframes` → `keyframes`. Returns the input unchanged if it has no prefix. */
14
13
  declare function strip_vendor_prefix(str: string): string;
15
- //#endregion
16
14
  export { str_starts_with as a, str_index_of as i, is_vendor_prefixed as n, strip_vendor_prefix as o, str_equals as r, is_custom as t };
@@ -1,2 +1,2 @@
1
- import { a as str_starts_with, i as str_index_of, n as is_vendor_prefixed, o as strip_vendor_prefix, r as str_equals, t as is_custom } from "./string-helpers-t7UofIfp.js";
1
+ import { a as str_starts_with, i as str_index_of, n as is_vendor_prefixed, o as strip_vendor_prefix, r as str_equals, t as is_custom } from "./string-helpers-CwNEcEhd.js";
2
2
  export { is_custom, is_vendor_prefixed, str_equals, str_index_of, str_starts_with, strip_vendor_prefix };
@@ -1 +1 @@
1
- export { r as is_custom, a as is_vendor_prefixed, s as str_equals, l as str_index_of, u as str_starts_with, d as strip_vendor_prefix } from "./string-utils-aEEsA2CS.js";
1
+ export { r as is_custom, a as is_vendor_prefixed, s as str_equals, l as str_index_of, u as str_starts_with, d as strip_vendor_prefix } from "./string-utils-BYH1Oe8a.js";
@@ -99,5 +99,4 @@ function strip_vendor_prefix(str) {
99
99
  for (let i = 2; i < str.length; i++) if (str.charCodeAt(i) === 45) return str.substring(i + 1);
100
100
  return str;
101
101
  }
102
- //#endregion
103
102
  export { is_vendor_prefixed as a, str_equals_range as c, strip_vendor_prefix as d, is_digit as i, str_index_of as l, is_combinator as n, is_whitespace as o, is_custom as r, str_equals as s, is_and_or_not_range as t, str_starts_with as u };
@@ -1,4 +1,3 @@
1
- //#region src/token-types.d.ts
2
1
  declare const TOKEN_IDENT = 1;
3
2
  declare const TOKEN_FUNCTION = 2;
4
3
  declare const TOKEN_AT_KEYWORD = 3;
@@ -34,5 +33,4 @@ type Token = {
34
33
  line: number;
35
34
  column: number;
36
35
  };
37
- //#endregion
38
36
  export { TOKEN_SEMICOLON as C, TOKEN_WHITESPACE as D, TOKEN_URL as E, Token as O, TOKEN_RIGHT_PAREN as S, TOKEN_UNICODE_RANGE as T, TOKEN_LEFT_PAREN as _, TOKEN_CDO as a, TOKEN_RIGHT_BRACE as b, TOKEN_COMMENT as c, TOKEN_EOF as d, TOKEN_FUNCTION as f, TOKEN_LEFT_BRACKET as g, TOKEN_LEFT_BRACE as h, TOKEN_CDC as i, TokenType as k, TOKEN_DELIM as l, TOKEN_IDENT as m, TOKEN_BAD_STRING as n, TOKEN_COLON as o, TOKEN_HASH as p, TOKEN_BAD_URL as r, TOKEN_COMMA as s, TOKEN_AT_KEYWORD as t, TOKEN_DIMENSION as u, TOKEN_NUMBER as v, TOKEN_STRING as w, TOKEN_RIGHT_BRACKET as x, TOKEN_PERCENTAGE as y };
@@ -1,2 +1,2 @@
1
- import { C as TOKEN_SEMICOLON, D as TOKEN_WHITESPACE, E as TOKEN_URL, O as Token, S as TOKEN_RIGHT_PAREN, T as TOKEN_UNICODE_RANGE, _ as TOKEN_LEFT_PAREN, a as TOKEN_CDO, b as TOKEN_RIGHT_BRACE, c as TOKEN_COMMENT, d as TOKEN_EOF, f as TOKEN_FUNCTION, g as TOKEN_LEFT_BRACKET, h as TOKEN_LEFT_BRACE, i as TOKEN_CDC, k as TokenType, l as TOKEN_DELIM, m as TOKEN_IDENT, n as TOKEN_BAD_STRING, o as TOKEN_COLON, p as TOKEN_HASH, r as TOKEN_BAD_URL, s as TOKEN_COMMA, t as TOKEN_AT_KEYWORD, u as TOKEN_DIMENSION, v as TOKEN_NUMBER, w as TOKEN_STRING, x as TOKEN_RIGHT_BRACKET, y as TOKEN_PERCENTAGE } from "./token-types-Bqsf5FX-.js";
1
+ import { C as TOKEN_SEMICOLON, D as TOKEN_WHITESPACE, E as TOKEN_URL, O as Token, S as TOKEN_RIGHT_PAREN, T as TOKEN_UNICODE_RANGE, _ as TOKEN_LEFT_PAREN, a as TOKEN_CDO, b as TOKEN_RIGHT_BRACE, c as TOKEN_COMMENT, d as TOKEN_EOF, f as TOKEN_FUNCTION, g as TOKEN_LEFT_BRACKET, h as TOKEN_LEFT_BRACE, i as TOKEN_CDC, k as TokenType, l as TOKEN_DELIM, m as TOKEN_IDENT, n as TOKEN_BAD_STRING, o as TOKEN_COLON, p as TOKEN_HASH, r as TOKEN_BAD_URL, s as TOKEN_COMMA, t as TOKEN_AT_KEYWORD, u as TOKEN_DIMENSION, v as TOKEN_NUMBER, w as TOKEN_STRING, x as TOKEN_RIGHT_BRACKET, y as TOKEN_PERCENTAGE } from "./token-types-BhoXrORA.js";
2
2
  export { TOKEN_AT_KEYWORD, TOKEN_BAD_STRING, TOKEN_BAD_URL, TOKEN_CDC, TOKEN_CDO, TOKEN_COLON, TOKEN_COMMA, TOKEN_COMMENT, TOKEN_DELIM, TOKEN_DIMENSION, TOKEN_EOF, TOKEN_FUNCTION, TOKEN_HASH, TOKEN_IDENT, TOKEN_LEFT_BRACE, TOKEN_LEFT_BRACKET, TOKEN_LEFT_PAREN, TOKEN_NUMBER, TOKEN_PERCENTAGE, TOKEN_RIGHT_BRACE, TOKEN_RIGHT_BRACKET, TOKEN_RIGHT_PAREN, TOKEN_SEMICOLON, TOKEN_STRING, TOKEN_UNICODE_RANGE, TOKEN_URL, TOKEN_WHITESPACE, Token, TokenType };
@@ -1,4 +1,4 @@
1
- //#region src/token-types.ts
1
+ // src/token-types.ts
2
2
  const TOKEN_IDENT = 1;
3
3
  const TOKEN_FUNCTION = 2;
4
4
  const TOKEN_AT_KEYWORD = 3;
@@ -26,5 +26,4 @@ const TOKEN_RIGHT_BRACE = 24;
26
26
  const TOKEN_COMMENT = 25;
27
27
  const TOKEN_EOF = 26;
28
28
  const TOKEN_UNICODE_RANGE = 27;
29
- //#endregion
30
29
  export { TOKEN_AT_KEYWORD, TOKEN_BAD_STRING, TOKEN_BAD_URL, TOKEN_CDC, TOKEN_CDO, TOKEN_COLON, TOKEN_COMMA, TOKEN_COMMENT, TOKEN_DELIM, TOKEN_DIMENSION, TOKEN_EOF, TOKEN_FUNCTION, TOKEN_HASH, TOKEN_IDENT, TOKEN_LEFT_BRACE, TOKEN_LEFT_BRACKET, TOKEN_LEFT_PAREN, TOKEN_NUMBER, TOKEN_PERCENTAGE, TOKEN_RIGHT_BRACE, TOKEN_RIGHT_BRACKET, TOKEN_RIGHT_PAREN, TOKEN_SEMICOLON, TOKEN_STRING, TOKEN_UNICODE_RANGE, TOKEN_URL, TOKEN_WHITESPACE };
@@ -1,5 +1,5 @@
1
1
  import "./token-types.js";
2
- //#region src/char-types.ts
2
+ // src/char-types.ts
3
3
  const CHAR_ALPHA = 1;
4
4
  const CHAR_HEX = 4;
5
5
  const CHAR_WHITESPACE = 8;
@@ -26,8 +26,7 @@ function is_hex_digit(ch) {
26
26
  function is_ident_start(ch) {
27
27
  return ch >= 128 || (char_types[ch] & 64) !== 0;
28
28
  }
29
- //#endregion
30
- //#region src/tokenize.ts
29
+ // src/tokenize.ts
31
30
  function is_newline(ch) {
32
31
  return ch < 128 && (char_types[ch] & 16) !== 0;
33
32
  }
@@ -83,13 +82,15 @@ var Lexer = class {
83
82
  _line;
84
83
  _line_offset;
85
84
  on_comment;
85
+ emit_comments;
86
86
  token_type;
87
87
  token_start;
88
88
  token_end;
89
89
  token_line;
90
90
  token_column;
91
- constructor(source, on_comment) {
91
+ constructor(source, on_comment, emit_comments = false) {
92
92
  this.source = source;
93
+ this.emit_comments = emit_comments;
93
94
  this.pos = 0;
94
95
  this._line = 1;
95
96
  this._line_offset = 0;
@@ -171,6 +172,7 @@ var Lexer = class {
171
172
  if ((ch_type & 24) !== 0) return this.consume_whitespace(start_line, start_column);
172
173
  if (ch === CHAR_FORWARD_SLASH && this.pos + 1 < source_length && source.charCodeAt(this.pos + 1) === CHAR_ASTERISK) {
173
174
  this._skip_comment();
175
+ if (this.emit_comments) return this.make_token(25, start, this.pos, start_line, start_column);
174
176
  continue;
175
177
  }
176
178
  if (ch >= 128 || (ch_type & 64) !== 0) return this.consume_ident_or_function(start_line, start_column);
@@ -651,10 +653,23 @@ var Lexer = class {
651
653
  }
652
654
  };
653
655
  /**
656
+ * Tokenize CSS source code, calling `on_token` for every token.
657
+ * Faster than the iterator-based `tokenize()` because it allocates no generator or token objects.
658
+ * @param source - The CSS source code to tokenize
659
+ * @param on_token - Called with `(type, start, end, line, column)` for each token
660
+ * @deprecated Renamed to `tokenize()` in 0.20.0, where the callback form replaces the iterator form.
661
+ */
662
+ function tokenize_cb(source, on_token) {
663
+ const lexer = new Lexer(source, void 0, true);
664
+ let type;
665
+ while ((type = lexer.next_token()) !== 26) on_token(type, lexer.token_start, lexer.token_end, lexer.token_line, lexer.token_column);
666
+ }
667
+ /**
654
668
  * Tokenize CSS source code
655
669
  * @param source - The CSS source code to tokenize
656
670
  * @param on_comment - Optional callback for comment tokens
657
671
  * @yields CSS tokens
672
+ * @deprecated The iterator form is replaced in 0.20.0 by a callback-based `tokenize(source, on_token)`. Use `tokenize_cb()` today for the same behavior.
658
673
  */
659
674
  function* tokenize(source, on_comment) {
660
675
  const lexer = new Lexer(source, on_comment);
@@ -670,5 +685,4 @@ function* tokenize(source, on_comment) {
670
685
  };
671
686
  }
672
687
  }
673
- //#endregion
674
- export { tokenize as n, Lexer as t };
688
+ export { tokenize as n, tokenize_cb as r, Lexer as t };
@@ -1,5 +1,4 @@
1
- import { O as Token, k as TokenType } from "./token-types-Bqsf5FX-.js";
2
- //#region src/tokenize.d.ts
1
+ import { O as Token, k as TokenType } from "./token-types-BhoXrORA.js";
3
2
  export interface LexerPosition {
4
3
  pos: number;
5
4
  line: number;
@@ -25,12 +24,13 @@ export declare class Lexer {
25
24
  private _line;
26
25
  private _line_offset;
27
26
  on_comment: ((info: CommentInfo) => void) | undefined;
27
+ emit_comments: boolean;
28
28
  token_type: TokenType;
29
29
  token_start: number;
30
30
  token_end: number;
31
31
  token_line: number;
32
32
  token_column: number;
33
- constructor(source: string, on_comment?: (info: CommentInfo) => void);
33
+ constructor(source: string, on_comment?: (info: CommentInfo) => void, emit_comments?: boolean);
34
34
  get line(): number;
35
35
  get column(): number;
36
36
  seek(pos: number, line: number, column?: number): void;
@@ -55,11 +55,23 @@ export declare class Lexer {
55
55
  restore_position(saved: LexerPosition): void;
56
56
  skip_whitespace_in_range(end: number): void;
57
57
  }
58
+ /**
59
+ * Called for every token, including whitespace and comments.
60
+ */
61
+ export type OnToken = (type: TokenType, start: number, end: number, line: number, column: number) => void;
62
+ /**
63
+ * Tokenize CSS source code, calling `on_token` for every token.
64
+ * Faster than the iterator-based `tokenize()` because it allocates no generator or token objects.
65
+ * @param source - The CSS source code to tokenize
66
+ * @param on_token - Called with `(type, start, end, line, column)` for each token
67
+ * @deprecated Renamed to `tokenize()` in 0.20.0, where the callback form replaces the iterator form.
68
+ */
69
+ export declare function tokenize_cb(source: string, on_token: OnToken): void;
58
70
  /**
59
71
  * Tokenize CSS source code
60
72
  * @param source - The CSS source code to tokenize
61
73
  * @param on_comment - Optional callback for comment tokens
62
74
  * @yields CSS tokens
75
+ * @deprecated The iterator form is replaced in 0.20.0 by a callback-based `tokenize(source, on_token)`. Use `tokenize_cb()` today for the same behavior.
63
76
  */
64
- export declare function tokenize(source: string, on_comment?: (info: CommentInfo) => void): Generator<Token, void, undefined>;
65
- //#endregion
77
+ export declare function tokenize(source: string, on_comment?: (info: CommentInfo) => void): Generator<Token, void, undefined>;
package/dist/tokenize.js CHANGED
@@ -1 +1 @@
1
- export { t as Lexer, n as tokenize } from "./tokenize-B2QSzdrM.js";
1
+ export { t as Lexer, n as tokenize, r as tokenize_cb } from "./tokenize-DC2Vb0J_.js";
package/dist/walk.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { s as CSSNode, t as AnyNode } from "./node-types-CD7A-d_c.js";
2
- //#region src/walk.d.ts
1
+ import { s as CSSNode, t as AnyNode } from "./node-types-BF6bhAjo.js";
3
2
  export declare const SKIP: unique symbol;
4
3
  export declare const BREAK: unique symbol;
5
4
  type WalkCallback = (node: AnyNode, depth: number) => void | typeof SKIP | typeof BREAK;
@@ -19,5 +18,4 @@ interface WalkEnterLeaveOptions {
19
18
  * SKIP in enter skips children (leave still runs); BREAK stops (leave doesn't run).
20
19
  */
21
20
  export declare function traverse(node: CSSNode, { enter, leave }?: WalkEnterLeaveOptions): boolean;
22
- //#endregion
23
21
  export {};
package/dist/walk.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./arena-CsJhQRUX.js";
2
- import { t as CSSNode } from "./css-node-BKcf0ZeS.js";
1
+ import "./arena-CaLnNKbP.js";
2
+ import { t as CSSNode } from "./css-node-CDTLvxo3.js";
3
3
  import "./constants.js";
4
- //#region src/walk.ts
4
+ // src/walk.ts
5
5
  const SKIP = Symbol("SKIP");
6
6
  const BREAK = Symbol("BREAK");
7
7
  /**
@@ -49,5 +49,4 @@ function _traverse(arena, source, index, enter, leave) {
49
49
  if (leave(node) === BREAK) return false;
50
50
  return true;
51
51
  }
52
- //#endregion
53
52
  export { BREAK, SKIP, traverse, walk };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectwallace/css-parser",
3
- "version": "0.19.2",
3
+ "version": "0.19.4",
4
4
  "description": "High-performance CSS lexer and parser, optimized for CSS inspection and analysis",
5
5
  "keywords": [
6
6
  "ast",
@@ -93,9 +93,9 @@
93
93
  "@vitest/coverage-v8": "^5.0.3",
94
94
  "css-tree": "^3.2.1",
95
95
  "knip": "^6.41.0",
96
- "oxfmt": "^0.72.0",
96
+ "oxfmt": "^0.74.0",
97
97
  "oxlint": "^1.87.0",
98
- "pkg-pr-new": "^0.0.91",
98
+ "pkg-pr-new": "^0.0.92",
99
99
  "postcss": "^8.5.29",
100
100
  "publint": "^0.3.25",
101
101
  "tinybench": "^6.2.1",