@projectwallace/css-parser 0.6.0 → 0.6.2

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/dist/arena.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare const NODE_VALUE_STRING = 13;
12
12
  export declare const NODE_VALUE_COLOR = 14;
13
13
  export declare const NODE_VALUE_FUNCTION = 15;
14
14
  export declare const NODE_VALUE_OPERATOR = 16;
15
+ export declare const NODE_VALUE_PARENTHESIS = 17;
15
16
  export declare const NODE_SELECTOR_LIST = 20;
16
17
  export declare const NODE_SELECTOR_TYPE = 21;
17
18
  export declare const NODE_SELECTOR_CLASS = 22;
@@ -42,6 +43,7 @@ export declare const FLAG_LENGTH_OVERFLOW: number;
42
43
  export declare const FLAG_HAS_BLOCK: number;
43
44
  export declare const FLAG_VENDOR_PREFIXED: number;
44
45
  export declare const FLAG_HAS_DECLARATIONS: number;
46
+ export declare const FLAG_HAS_PARENS: number;
45
47
  export declare const ATTR_OPERATOR_NONE = 0;
46
48
  export declare const ATTR_OPERATOR_EQUAL = 1;
47
49
  export declare const ATTR_OPERATOR_TILDE_EQUAL = 2;
@@ -49,6 +51,9 @@ export declare const ATTR_OPERATOR_PIPE_EQUAL = 3;
49
51
  export declare const ATTR_OPERATOR_CARET_EQUAL = 4;
50
52
  export declare const ATTR_OPERATOR_DOLLAR_EQUAL = 5;
51
53
  export declare const ATTR_OPERATOR_STAR_EQUAL = 6;
54
+ export declare const ATTR_FLAG_NONE = 0;
55
+ export declare const ATTR_FLAG_CASE_INSENSITIVE = 1;
56
+ export declare const ATTR_FLAG_CASE_SENSITIVE = 2;
52
57
  export declare class CSSDataArena {
53
58
  private buffer;
54
59
  private view;
@@ -69,6 +74,7 @@ export declare class CSSDataArena {
69
74
  get_content_start(node_index: number): number;
70
75
  get_content_length(node_index: number): number;
71
76
  get_attr_operator(node_index: number): number;
77
+ get_attr_flags(node_index: number): number;
72
78
  get_first_child(node_index: number): number;
73
79
  get_last_child(node_index: number): number;
74
80
  get_next_sibling(node_index: number): number;
@@ -83,6 +89,7 @@ export declare class CSSDataArena {
83
89
  set_content_start(node_index: number, offset: number): void;
84
90
  set_content_length(node_index: number, length: number): void;
85
91
  set_attr_operator(node_index: number, operator: number): void;
92
+ set_attr_flags(node_index: number, flags: number): void;
86
93
  set_first_child(node_index: number, childIndex: number): void;
87
94
  set_last_child(node_index: number, childIndex: number): void;
88
95
  set_next_sibling(node_index: number, siblingIndex: number): void;
@@ -13,6 +13,7 @@ const NODE_VALUE_STRING = 13;
13
13
  const NODE_VALUE_COLOR = 14;
14
14
  const NODE_VALUE_FUNCTION = 15;
15
15
  const NODE_VALUE_OPERATOR = 16;
16
+ const NODE_VALUE_PARENTHESIS = 17;
16
17
  const NODE_SELECTOR_LIST = 20;
17
18
  const NODE_SELECTOR_TYPE = 21;
18
19
  const NODE_SELECTOR_CLASS = 22;
@@ -42,6 +43,7 @@ const FLAG_HAS_ERROR = 1 << 1;
42
43
  const FLAG_HAS_BLOCK = 1 << 3;
43
44
  const FLAG_VENDOR_PREFIXED = 1 << 4;
44
45
  const FLAG_HAS_DECLARATIONS = 1 << 5;
46
+ const FLAG_HAS_PARENS = 1 << 6;
45
47
  const ATTR_OPERATOR_NONE = 0;
46
48
  const ATTR_OPERATOR_EQUAL = 1;
47
49
  const ATTR_OPERATOR_TILDE_EQUAL = 2;
@@ -49,6 +51,9 @@ const ATTR_OPERATOR_PIPE_EQUAL = 3;
49
51
  const ATTR_OPERATOR_CARET_EQUAL = 4;
50
52
  const ATTR_OPERATOR_DOLLAR_EQUAL = 5;
51
53
  const ATTR_OPERATOR_STAR_EQUAL = 6;
54
+ const ATTR_FLAG_NONE = 0;
55
+ const ATTR_FLAG_CASE_INSENSITIVE = 1;
56
+ const ATTR_FLAG_CASE_SENSITIVE = 2;
52
57
  class CSSDataArena {
53
58
  buffer;
54
59
  view;
@@ -115,6 +120,10 @@ class CSSDataArena {
115
120
  get_attr_operator(node_index) {
116
121
  return this.view.getUint8(this.node_offset(node_index) + 2);
117
122
  }
123
+ // Read attribute flags (for NODE_SELECTOR_ATTRIBUTE)
124
+ get_attr_flags(node_index) {
125
+ return this.view.getUint8(this.node_offset(node_index) + 3);
126
+ }
118
127
  // Read first child index (0 = no children)
119
128
  get_first_child(node_index) {
120
129
  return this.view.getUint32(this.node_offset(node_index) + 20, true);
@@ -172,6 +181,10 @@ class CSSDataArena {
172
181
  set_attr_operator(node_index, operator) {
173
182
  this.view.setUint8(this.node_offset(node_index) + 2, operator);
174
183
  }
184
+ // Write attribute flags (for NODE_SELECTOR_ATTRIBUTE)
185
+ set_attr_flags(node_index, flags) {
186
+ this.view.setUint8(this.node_offset(node_index) + 3, flags);
187
+ }
175
188
  // Write first child index
176
189
  set_first_child(node_index, childIndex) {
177
190
  this.view.setUint32(this.node_offset(node_index) + 20, childIndex, true);
@@ -465,6 +478,11 @@ class CSSNode {
465
478
  get attr_operator() {
466
479
  return this.arena.get_attr_operator(this.index);
467
480
  }
481
+ // Get the attribute flags (for attribute selectors: i, s)
482
+ // Returns one of the ATTR_FLAG_* constants
483
+ get attr_flags() {
484
+ return this.arena.get_attr_flags(this.index);
485
+ }
468
486
  // Get the unit for dimension nodes (e.g., "px" from "100px", "%" from "50%")
469
487
  get unit() {
470
488
  if (this.type !== NODE_VALUE_DIMENSION) return null;
@@ -585,7 +603,14 @@ class CSSNode {
585
603
  return sibling_index !== 0;
586
604
  }
587
605
  // Check if this node has children
606
+ // For pseudo-class/pseudo-element functions, returns true if FLAG_HAS_PARENS is set
607
+ // This allows formatters to distinguish :lang() from :hover
588
608
  get has_children() {
609
+ if (this.type === NODE_SELECTOR_PSEUDO_CLASS || this.type === NODE_SELECTOR_PSEUDO_ELEMENT) {
610
+ if (this.arena.has_flag(this.index, FLAG_HAS_PARENS)) {
611
+ return true;
612
+ }
613
+ }
589
614
  return this.arena.has_children(this.index);
590
615
  }
591
616
  // Get all children as an array
@@ -641,4 +666,4 @@ class CSSNode {
641
666
  }
642
667
  }
643
668
 
644
- export { CHAR_GREATER_THAN as $, ATTR_OPERATOR_NONE as A, NODE_SELECTOR_UNIVERSAL as B, CSSNode as C, NODE_SELECTOR_NESTING as D, NODE_SELECTOR_NTH as E, NODE_SELECTOR_NTH_OF as F, NODE_PRELUDE_MEDIA_QUERY as G, NODE_PRELUDE_MEDIA_FEATURE as H, NODE_PRELUDE_MEDIA_TYPE as I, NODE_PRELUDE_CONTAINER_QUERY as J, NODE_PRELUDE_SUPPORTS_QUERY as K, NODE_PRELUDE_LAYER_NAME as L, NODE_PRELUDE_IDENTIFIER as M, NODE_STYLE_RULE as N, NODE_PRELUDE_OPERATOR as O, NODE_PRELUDE_IMPORT_URL as P, NODE_PRELUDE_IMPORT_LAYER as Q, NODE_PRELUDE_IMPORT_SUPPORTS as R, FLAG_IMPORTANT as S, CSSDataArena as T, FLAG_HAS_BLOCK as U, NODE_BLOCK as V, FLAG_HAS_DECLARATIONS as W, is_vendor_prefixed as X, FLAG_VENDOR_PREFIXED as Y, trim_boundaries as Z, NODE_SELECTOR_LANG as _, ATTR_OPERATOR_EQUAL as a, CHAR_PLUS as a0, CHAR_TILDE as a1, CHAR_PERIOD as a2, CHAR_ASTERISK as a3, CHAR_AMPERSAND as a4, is_whitespace as a5, is_combinator as a6, skip_whitespace_and_comments_forward as a7, skip_whitespace_and_comments_backward as a8, CHAR_EQUALS as a9, CHAR_PIPE as aa, CHAR_CARET as ab, CHAR_DOLLAR as ac, CHAR_SINGLE_QUOTE as ad, CHAR_DOUBLE_QUOTE as ae, CHAR_COLON as af, skip_whitespace_forward as ag, str_equals as ah, CHAR_MINUS_HYPHEN as ai, CHAR_FORWARD_SLASH as aj, 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, NODE_AT_RULE as g, NODE_COMMENT as h, NODE_DECLARATION as i, NODE_SELECTOR as j, NODE_STYLESHEET as k, NODE_VALUE_KEYWORD as l, NODE_VALUE_NUMBER as m, NODE_VALUE_DIMENSION as n, NODE_VALUE_STRING as o, NODE_VALUE_COLOR as p, NODE_VALUE_FUNCTION as q, NODE_VALUE_OPERATOR as r, NODE_SELECTOR_LIST as s, NODE_SELECTOR_TYPE as t, NODE_SELECTOR_CLASS as u, NODE_SELECTOR_ID as v, NODE_SELECTOR_ATTRIBUTE as w, NODE_SELECTOR_PSEUDO_CLASS as x, NODE_SELECTOR_PSEUDO_ELEMENT as y, NODE_SELECTOR_COMBINATOR 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, 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 };
@@ -1,6 +1,6 @@
1
1
  import type { CSSDataArena } from './arena';
2
- import { NODE_STYLESHEET, NODE_STYLE_RULE, NODE_AT_RULE, NODE_DECLARATION, NODE_SELECTOR, NODE_COMMENT, NODE_BLOCK, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_SELECTOR_LANG, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS } from './arena';
3
- export type CSSNodeType = typeof NODE_STYLESHEET | typeof NODE_STYLE_RULE | typeof NODE_AT_RULE | typeof NODE_DECLARATION | typeof NODE_SELECTOR | typeof NODE_COMMENT | typeof NODE_BLOCK | typeof NODE_VALUE_KEYWORD | typeof NODE_VALUE_NUMBER | typeof NODE_VALUE_DIMENSION | typeof NODE_VALUE_STRING | typeof NODE_VALUE_COLOR | typeof NODE_VALUE_FUNCTION | typeof NODE_VALUE_OPERATOR | typeof NODE_SELECTOR_LIST | typeof NODE_SELECTOR_TYPE | typeof NODE_SELECTOR_CLASS | typeof NODE_SELECTOR_ID | typeof NODE_SELECTOR_ATTRIBUTE | typeof NODE_SELECTOR_PSEUDO_CLASS | typeof NODE_SELECTOR_PSEUDO_ELEMENT | typeof NODE_SELECTOR_COMBINATOR | typeof NODE_SELECTOR_UNIVERSAL | typeof NODE_SELECTOR_NESTING | typeof NODE_SELECTOR_NTH | typeof NODE_SELECTOR_NTH_OF | typeof NODE_SELECTOR_LANG | typeof NODE_PRELUDE_MEDIA_QUERY | typeof NODE_PRELUDE_MEDIA_FEATURE | typeof NODE_PRELUDE_MEDIA_TYPE | typeof NODE_PRELUDE_CONTAINER_QUERY | typeof NODE_PRELUDE_SUPPORTS_QUERY | typeof NODE_PRELUDE_LAYER_NAME | typeof NODE_PRELUDE_IDENTIFIER | typeof NODE_PRELUDE_OPERATOR | typeof NODE_PRELUDE_IMPORT_URL | typeof NODE_PRELUDE_IMPORT_LAYER | typeof NODE_PRELUDE_IMPORT_SUPPORTS;
2
+ import { NODE_STYLESHEET, NODE_STYLE_RULE, NODE_AT_RULE, NODE_DECLARATION, NODE_SELECTOR, NODE_COMMENT, NODE_BLOCK, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_VALUE_PARENTHESIS, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_SELECTOR_LANG, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS } from './arena';
3
+ export type CSSNodeType = typeof NODE_STYLESHEET | typeof NODE_STYLE_RULE | typeof NODE_AT_RULE | typeof NODE_DECLARATION | typeof NODE_SELECTOR | typeof NODE_COMMENT | typeof NODE_BLOCK | typeof NODE_VALUE_KEYWORD | typeof NODE_VALUE_NUMBER | typeof NODE_VALUE_DIMENSION | typeof NODE_VALUE_STRING | typeof NODE_VALUE_COLOR | typeof NODE_VALUE_FUNCTION | typeof NODE_VALUE_OPERATOR | typeof NODE_VALUE_PARENTHESIS | typeof NODE_SELECTOR_LIST | typeof NODE_SELECTOR_TYPE | typeof NODE_SELECTOR_CLASS | typeof NODE_SELECTOR_ID | typeof NODE_SELECTOR_ATTRIBUTE | typeof NODE_SELECTOR_PSEUDO_CLASS | typeof NODE_SELECTOR_PSEUDO_ELEMENT | typeof NODE_SELECTOR_COMBINATOR | typeof NODE_SELECTOR_UNIVERSAL | typeof NODE_SELECTOR_NESTING | typeof NODE_SELECTOR_NTH | typeof NODE_SELECTOR_NTH_OF | typeof NODE_SELECTOR_LANG | typeof NODE_PRELUDE_MEDIA_QUERY | typeof NODE_PRELUDE_MEDIA_FEATURE | typeof NODE_PRELUDE_MEDIA_TYPE | typeof NODE_PRELUDE_CONTAINER_QUERY | typeof NODE_PRELUDE_SUPPORTS_QUERY | typeof NODE_PRELUDE_LAYER_NAME | typeof NODE_PRELUDE_IDENTIFIER | typeof NODE_PRELUDE_OPERATOR | typeof NODE_PRELUDE_IMPORT_URL | typeof NODE_PRELUDE_IMPORT_LAYER | typeof NODE_PRELUDE_IMPORT_SUPPORTS;
4
4
  export declare class CSSNode {
5
5
  private arena;
6
6
  private source;
@@ -14,6 +14,7 @@ export declare class CSSNode {
14
14
  get value(): string | number | null;
15
15
  get prelude(): string | null;
16
16
  get attr_operator(): number;
17
+ get attr_flags(): number;
17
18
  get unit(): string | null;
18
19
  get is_important(): boolean | null;
19
20
  get is_vendor_prefixed(): boolean;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,6 @@ export { walk, traverse } from './walk';
7
7
  export { type ParserOptions } from './parse';
8
8
  export { CSSNode, type CSSNodeType } from './css-node';
9
9
  export type { LexerPosition } from './lexer';
10
- export { ATTR_OPERATOR_NONE, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_STAR_EQUAL, } from './arena';
11
- export { NODE_STYLE_RULE, NODE_AT_RULE, NODE_COMMENT, NODE_DECLARATION, NODE_SELECTOR, NODE_STYLESHEET, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS, FLAG_IMPORTANT, } from './parse';
10
+ export { ATTR_OPERATOR_NONE, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_STAR_EQUAL, ATTR_FLAG_NONE, ATTR_FLAG_CASE_INSENSITIVE, ATTR_FLAG_CASE_SENSITIVE, } from './arena';
11
+ export { NODE_STYLE_RULE, NODE_AT_RULE, NODE_COMMENT, NODE_DECLARATION, NODE_SELECTOR, NODE_STYLESHEET, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_VALUE_PARENTHESIS, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_SELECTOR_LANG, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS, FLAG_IMPORTANT, } from './parse';
12
12
  export { TOKEN_IDENT, TOKEN_FUNCTION, TOKEN_AT_KEYWORD, TOKEN_HASH, TOKEN_STRING, TOKEN_BAD_STRING, TOKEN_URL, TOKEN_BAD_URL, TOKEN_DELIM, TOKEN_NUMBER, TOKEN_PERCENTAGE, TOKEN_DIMENSION, TOKEN_WHITESPACE, TOKEN_CDO, TOKEN_CDC, TOKEN_COLON, TOKEN_SEMICOLON, TOKEN_COMMA, TOKEN_LEFT_BRACKET, TOKEN_RIGHT_BRACKET, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_LEFT_BRACE, TOKEN_RIGHT_BRACE, TOKEN_COMMENT, TOKEN_EOF, type Token, type TokenType, } from './token-types';
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 { 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, S as FLAG_IMPORTANT, g as NODE_AT_RULE, h as NODE_COMMENT, i as NODE_DECLARATION, J as NODE_PRELUDE_CONTAINER_QUERY, M as NODE_PRELUDE_IDENTIFIER, Q as NODE_PRELUDE_IMPORT_LAYER, R as NODE_PRELUDE_IMPORT_SUPPORTS, P as NODE_PRELUDE_IMPORT_URL, L as NODE_PRELUDE_LAYER_NAME, H as NODE_PRELUDE_MEDIA_FEATURE, G as NODE_PRELUDE_MEDIA_QUERY, I as NODE_PRELUDE_MEDIA_TYPE, O as NODE_PRELUDE_OPERATOR, K as NODE_PRELUDE_SUPPORTS_QUERY, j as NODE_SELECTOR, w as NODE_SELECTOR_ATTRIBUTE, u as NODE_SELECTOR_CLASS, z as NODE_SELECTOR_COMBINATOR, v as NODE_SELECTOR_ID, s as NODE_SELECTOR_LIST, D as NODE_SELECTOR_NESTING, E as NODE_SELECTOR_NTH, F as NODE_SELECTOR_NTH_OF, x as NODE_SELECTOR_PSEUDO_CLASS, y as NODE_SELECTOR_PSEUDO_ELEMENT, t as NODE_SELECTOR_TYPE, B as NODE_SELECTOR_UNIVERSAL, k as NODE_STYLESHEET, N as NODE_STYLE_RULE, p as NODE_VALUE_COLOR, n as NODE_VALUE_DIMENSION, q as NODE_VALUE_FUNCTION, l as NODE_VALUE_KEYWORD, m as NODE_VALUE_NUMBER, r as NODE_VALUE_OPERATOR, o as NODE_VALUE_STRING } from './css-node-BzCSxoLM.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';
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 { ai as CHAR_MINUS_HYPHEN, a0 as CHAR_PLUS, ag as skip_whitespace_forward, E as NODE_SELECTOR_NTH, C as CSSNode, T as CSSDataArena } from './css-node-BzCSxoLM.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';
3
3
 
4
4
  class ANplusBParser {
5
5
  lexer;
@@ -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 { T as CSSDataArena, C as CSSNode, ah as str_equals, O as NODE_PRELUDE_OPERATOR, I as NODE_PRELUDE_MEDIA_TYPE, G as NODE_PRELUDE_MEDIA_QUERY, H as NODE_PRELUDE_MEDIA_FEATURE, Z as trim_boundaries, M as NODE_PRELUDE_IDENTIFIER, J as NODE_PRELUDE_CONTAINER_QUERY, K as NODE_PRELUDE_SUPPORTS_QUERY, L as NODE_PRELUDE_LAYER_NAME, P as NODE_PRELUDE_IMPORT_URL, Q as NODE_PRELUDE_IMPORT_LAYER, R as NODE_PRELUDE_IMPORT_SUPPORTS, ag as skip_whitespace_forward } from './css-node-BzCSxoLM.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';
3
3
 
4
4
  class AtRulePreludeParser {
5
5
  lexer;
@@ -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 { T as CSSDataArena, s as NODE_SELECTOR_LIST, C as CSSNode, j as NODE_SELECTOR, $ as CHAR_GREATER_THAN, a0 as CHAR_PLUS, a1 as CHAR_TILDE, a2 as CHAR_PERIOD, a3 as CHAR_ASTERISK, a4 as CHAR_AMPERSAND, a5 as is_whitespace, a6 as is_combinator, u as NODE_SELECTOR_CLASS, w as NODE_SELECTOR_ATTRIBUTE, a7 as skip_whitespace_and_comments_forward, a8 as skip_whitespace_and_comments_backward, a9 as CHAR_EQUALS, aa as CHAR_PIPE, ab as CHAR_CARET, ac as CHAR_DOLLAR, A as ATTR_OPERATOR_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, ad as CHAR_SINGLE_QUOTE, ae as CHAR_DOUBLE_QUOTE, af as CHAR_COLON, y as NODE_SELECTOR_PSEUDO_ELEMENT, x as NODE_SELECTOR_PSEUDO_CLASS, X as is_vendor_prefixed, Y as FLAG_VENDOR_PREFIXED, _ as NODE_SELECTOR_LANG, ag as skip_whitespace_forward, F as NODE_SELECTOR_NTH_OF, t as NODE_SELECTOR_TYPE, v as NODE_SELECTOR_ID, B as NODE_SELECTOR_UNIVERSAL, D as NODE_SELECTOR_NESTING, z as NODE_SELECTOR_COMBINATOR } from './css-node-BzCSxoLM.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';
3
3
  import { ANplusBParser } from './parse-anplusb.js';
4
4
 
5
5
  class SelectorParser {
@@ -15,7 +15,7 @@ class SelectorParser {
15
15
  }
16
16
  // Parse a selector range into selector nodes
17
17
  // Always returns a NODE_SELECTOR_LIST with selector components as children
18
- parse_selector(start, end, line = 1, column = 1, allow_relative = false) {
18
+ parse_selector(start, end, line = 1, column = 1, allow_relative = true) {
19
19
  this.selector_end = end;
20
20
  this.lexer.pos = start;
21
21
  this.lexer.line = line;
@@ -23,7 +23,7 @@ class SelectorParser {
23
23
  return this.parse_selector_list(allow_relative);
24
24
  }
25
25
  // Parse comma-separated selectors
26
- parse_selector_list(allow_relative = false) {
26
+ parse_selector_list(allow_relative = true) {
27
27
  let selectors = [];
28
28
  let list_start = this.lexer.pos;
29
29
  let list_line = this.lexer.line;
@@ -77,7 +77,8 @@ class SelectorParser {
77
77
  }
78
78
  // Parse a complex selector (with combinators)
79
79
  // e.g., "div.class > p + span"
80
- parse_complex_selector(allow_relative = false) {
80
+ // Also supports CSS Nesting relaxed syntax: "> a", "~ span", etc.
81
+ parse_complex_selector(allow_relative = true) {
81
82
  let components = [];
82
83
  this.skip_whitespace();
83
84
  if (allow_relative && this.lexer.pos < this.selector_end) {
@@ -297,6 +298,7 @@ class SelectorParser {
297
298
  let pos = skip_whitespace_and_comments_forward(this.source, name_end, end);
298
299
  if (pos >= end) {
299
300
  this.arena.set_attr_operator(node, ATTR_OPERATOR_NONE);
301
+ this.arena.set_attr_flags(node, ATTR_FLAG_NONE);
300
302
  return;
301
303
  }
302
304
  let ch1 = this.source.charCodeAt(pos);
@@ -320,10 +322,12 @@ class SelectorParser {
320
322
  this.arena.set_attr_operator(node, ATTR_OPERATOR_STAR_EQUAL);
321
323
  } else {
322
324
  this.arena.set_attr_operator(node, ATTR_OPERATOR_NONE);
325
+ this.arena.set_attr_flags(node, ATTR_FLAG_NONE);
323
326
  return;
324
327
  }
325
328
  pos = skip_whitespace_and_comments_forward(this.source, operator_end, end);
326
329
  if (pos >= end) {
330
+ this.arena.set_attr_flags(node, ATTR_FLAG_NONE);
327
331
  return;
328
332
  }
329
333
  value_start = pos;
@@ -359,6 +363,19 @@ class SelectorParser {
359
363
  this.arena.set_value_start(node, value_start);
360
364
  this.arena.set_value_length(node, value_end - value_start);
361
365
  }
366
+ pos = skip_whitespace_and_comments_forward(this.source, value_end, end);
367
+ if (pos < end) {
368
+ let flag_ch = this.source.charCodeAt(pos);
369
+ if (flag_ch === 105 || flag_ch === 73) {
370
+ this.arena.set_attr_flags(node, ATTR_FLAG_CASE_INSENSITIVE);
371
+ } else if (flag_ch === 115 || flag_ch === 83) {
372
+ this.arena.set_attr_flags(node, ATTR_FLAG_CASE_SENSITIVE);
373
+ } else {
374
+ this.arena.set_attr_flags(node, ATTR_FLAG_NONE);
375
+ }
376
+ } else {
377
+ this.arena.set_attr_flags(node, ATTR_FLAG_NONE);
378
+ }
362
379
  }
363
380
  // Parse pseudo-class or pseudo-element (:hover, ::before)
364
381
  parse_pseudo(start) {
@@ -423,6 +440,7 @@ class SelectorParser {
423
440
  this.arena.set_start_column(node, this.lexer.column);
424
441
  this.arena.set_content_start(node, func_name_start);
425
442
  this.arena.set_content_length(node, func_name_end - func_name_start);
443
+ this.arena.set_flag(node, FLAG_HAS_PARENS);
426
444
  if (is_vendor_prefixed(this.source, func_name_start, func_name_end)) {
427
445
  this.arena.set_flag(node, FLAG_VENDOR_PREFIXED);
428
446
  }
@@ -13,6 +13,7 @@ export declare class ValueParser {
13
13
  private create_operator_node;
14
14
  private parse_operator_node;
15
15
  private parse_function_node;
16
+ private parse_parenthesis_node;
16
17
  }
17
18
  /**
18
19
  * Parse a CSS declaration value string and return an array of value AST nodes
@@ -1,5 +1,5 @@
1
- import { L as Lexer, y as TOKEN_EOF, 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, t as TOKEN_LEFT_PAREN, u as TOKEN_RIGHT_PAREN } from './lexer-CtBKgfVv.js';
2
- import { T as CSSDataArena, C as CSSNode, a5 as is_whitespace, r as NODE_VALUE_OPERATOR, p as NODE_VALUE_COLOR, o as NODE_VALUE_STRING, n as NODE_VALUE_DIMENSION, m as NODE_VALUE_NUMBER, l as NODE_VALUE_KEYWORD, a0 as CHAR_PLUS, ai as CHAR_MINUS_HYPHEN, a3 as CHAR_ASTERISK, aj as CHAR_FORWARD_SLASH, q as NODE_VALUE_FUNCTION } from './css-node-BzCSxoLM.js';
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';
3
3
 
4
4
  class ValueParser {
5
5
  lexer;
@@ -68,6 +68,8 @@ class ValueParser {
68
68
  return this.parse_operator_node(start, end);
69
69
  case TOKEN_COMMA:
70
70
  return this.create_node(NODE_VALUE_OPERATOR, start, end);
71
+ case TOKEN_LEFT_PAREN:
72
+ return this.parse_parenthesis_node(start, end);
71
73
  default:
72
74
  return null;
73
75
  }
@@ -98,9 +100,46 @@ class ValueParser {
98
100
  let name_end = end - 1;
99
101
  this.arena.set_content_start(node, start);
100
102
  this.arena.set_content_length(node, name_end - start);
103
+ let func_name = this.source.substring(start, name_end).toLowerCase();
104
+ if (func_name === "url" || func_name === "src") {
105
+ let save_pos = this.lexer.save_position();
106
+ this.lexer.next_token_fast(false);
107
+ while (this.is_whitespace_token() && this.lexer.pos < this.value_end) {
108
+ this.lexer.next_token_fast(false);
109
+ }
110
+ let first_token_type = this.lexer.token_type;
111
+ this.lexer.restore_position(save_pos);
112
+ if (first_token_type === TOKEN_STRING) ; else {
113
+ let paren_depth2 = 1;
114
+ let func_end2 = end;
115
+ let content_start2 = end;
116
+ let content_end2 = end;
117
+ while (paren_depth2 > 0) {
118
+ this.lexer.next_token_fast(false);
119
+ let token_type = this.lexer.token_type;
120
+ if (token_type === TOKEN_EOF) break;
121
+ if (token_type === TOKEN_LEFT_PAREN || token_type === TOKEN_FUNCTION) {
122
+ paren_depth2++;
123
+ } else if (token_type === TOKEN_RIGHT_PAREN) {
124
+ paren_depth2--;
125
+ if (paren_depth2 === 0) {
126
+ content_end2 = this.lexer.token_start;
127
+ func_end2 = this.lexer.token_end;
128
+ break;
129
+ }
130
+ }
131
+ }
132
+ this.arena.set_length(node, func_end2 - start);
133
+ this.arena.set_value_start(node, content_start2);
134
+ this.arena.set_value_length(node, content_end2 - content_start2);
135
+ return node;
136
+ }
137
+ }
101
138
  let args = [];
102
139
  let paren_depth = 1;
103
140
  let func_end = end;
141
+ let content_start = end;
142
+ let content_end = end;
104
143
  while (this.lexer.pos < this.value_end && paren_depth > 0) {
105
144
  this.lexer.next_token_fast(false);
106
145
  let token_type = this.lexer.token_type;
@@ -111,6 +150,7 @@ class ValueParser {
111
150
  } else if (token_type === TOKEN_RIGHT_PAREN) {
112
151
  paren_depth--;
113
152
  if (paren_depth === 0) {
153
+ content_end = this.lexer.token_start;
114
154
  func_end = this.lexer.token_end;
115
155
  break;
116
156
  }
@@ -122,6 +162,8 @@ class ValueParser {
122
162
  }
123
163
  }
124
164
  this.arena.set_length(node, func_end - start);
165
+ this.arena.set_value_start(node, content_start);
166
+ this.arena.set_value_length(node, content_end - content_start);
125
167
  if (args.length > 0) {
126
168
  this.arena.set_first_child(node, args[0]);
127
169
  this.arena.set_last_child(node, args[args.length - 1]);
@@ -131,6 +173,41 @@ class ValueParser {
131
173
  }
132
174
  return node;
133
175
  }
176
+ parse_parenthesis_node(start, end) {
177
+ let node = this.arena.create_node();
178
+ this.arena.set_type(node, NODE_VALUE_PARENTHESIS);
179
+ this.arena.set_start_offset(node, start);
180
+ let children = [];
181
+ let paren_depth = 1;
182
+ let paren_end = end;
183
+ while (this.lexer.pos < this.value_end && paren_depth > 0) {
184
+ this.lexer.next_token_fast(false);
185
+ let token_type = this.lexer.token_type;
186
+ if (token_type === TOKEN_EOF) break;
187
+ if (this.lexer.token_start >= this.value_end) break;
188
+ if (token_type === TOKEN_RIGHT_PAREN) {
189
+ paren_depth--;
190
+ if (paren_depth === 0) {
191
+ paren_end = this.lexer.token_end;
192
+ break;
193
+ }
194
+ }
195
+ if (this.is_whitespace_token()) continue;
196
+ let child_node = this.parse_value_node();
197
+ if (child_node !== null) {
198
+ children.push(child_node);
199
+ }
200
+ }
201
+ this.arena.set_length(node, paren_end - start);
202
+ if (children.length > 0) {
203
+ this.arena.set_first_child(node, children[0]);
204
+ this.arena.set_last_child(node, children[children.length - 1]);
205
+ for (let i = 0; i < children.length - 1; i++) {
206
+ this.arena.set_next_sibling(children[i], children[i + 1]);
207
+ }
208
+ }
209
+ return node;
210
+ }
134
211
  }
135
212
  function parse_value(value_string) {
136
213
  const arena = new CSSDataArena(CSSDataArena.capacity_for_source(value_string.length));
package/dist/parse.d.ts CHANGED
@@ -38,4 +38,4 @@ export declare class Parser {
38
38
  * @returns The root CSSNode of the AST
39
39
  */
40
40
  export declare function parse(source: string, options?: ParserOptions): CSSNode;
41
- export { NODE_STYLESHEET, NODE_STYLE_RULE, NODE_AT_RULE, NODE_DECLARATION, NODE_SELECTOR, NODE_COMMENT, NODE_BLOCK, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_SELECTOR_LANG, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS, FLAG_IMPORTANT, } from './arena';
41
+ export { NODE_STYLESHEET, NODE_STYLE_RULE, NODE_AT_RULE, NODE_DECLARATION, NODE_SELECTOR, NODE_COMMENT, NODE_BLOCK, NODE_VALUE_KEYWORD, NODE_VALUE_NUMBER, NODE_VALUE_DIMENSION, NODE_VALUE_STRING, NODE_VALUE_COLOR, NODE_VALUE_FUNCTION, NODE_VALUE_OPERATOR, NODE_VALUE_PARENTHESIS, NODE_SELECTOR_LIST, NODE_SELECTOR_TYPE, NODE_SELECTOR_CLASS, NODE_SELECTOR_ID, NODE_SELECTOR_ATTRIBUTE, NODE_SELECTOR_PSEUDO_CLASS, NODE_SELECTOR_PSEUDO_ELEMENT, NODE_SELECTOR_COMBINATOR, NODE_SELECTOR_UNIVERSAL, NODE_SELECTOR_NESTING, NODE_SELECTOR_NTH, NODE_SELECTOR_NTH_OF, NODE_SELECTOR_LANG, NODE_PRELUDE_MEDIA_QUERY, NODE_PRELUDE_MEDIA_FEATURE, NODE_PRELUDE_MEDIA_TYPE, NODE_PRELUDE_CONTAINER_QUERY, NODE_PRELUDE_SUPPORTS_QUERY, NODE_PRELUDE_LAYER_NAME, NODE_PRELUDE_IDENTIFIER, NODE_PRELUDE_OPERATOR, NODE_PRELUDE_IMPORT_URL, NODE_PRELUDE_IMPORT_LAYER, NODE_PRELUDE_IMPORT_SUPPORTS, FLAG_IMPORTANT, } from './arena';
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 { T as CSSDataArena, k as NODE_STYLESHEET, C as CSSNode, N as NODE_STYLE_RULE, U as FLAG_HAS_BLOCK, V as NODE_BLOCK, W as FLAG_HAS_DECLARATIONS, s as NODE_SELECTOR_LIST, i as NODE_DECLARATION, X as is_vendor_prefixed, Y as FLAG_VENDOR_PREFIXED, Z as trim_boundaries, S as FLAG_IMPORTANT, g as NODE_AT_RULE } from './css-node-BzCSxoLM.js';
3
- export { h as NODE_COMMENT, J as NODE_PRELUDE_CONTAINER_QUERY, M as NODE_PRELUDE_IDENTIFIER, Q as NODE_PRELUDE_IMPORT_LAYER, R as NODE_PRELUDE_IMPORT_SUPPORTS, P as NODE_PRELUDE_IMPORT_URL, L as NODE_PRELUDE_LAYER_NAME, H as NODE_PRELUDE_MEDIA_FEATURE, G as NODE_PRELUDE_MEDIA_QUERY, I as NODE_PRELUDE_MEDIA_TYPE, O as NODE_PRELUDE_OPERATOR, K as NODE_PRELUDE_SUPPORTS_QUERY, j as NODE_SELECTOR, w as NODE_SELECTOR_ATTRIBUTE, u as NODE_SELECTOR_CLASS, z as NODE_SELECTOR_COMBINATOR, v as NODE_SELECTOR_ID, _ as NODE_SELECTOR_LANG, D as NODE_SELECTOR_NESTING, E as NODE_SELECTOR_NTH, F as NODE_SELECTOR_NTH_OF, x as NODE_SELECTOR_PSEUDO_CLASS, y as NODE_SELECTOR_PSEUDO_ELEMENT, t as NODE_SELECTOR_TYPE, B as NODE_SELECTOR_UNIVERSAL, p as NODE_VALUE_COLOR, n as NODE_VALUE_DIMENSION, q as NODE_VALUE_FUNCTION, l as NODE_VALUE_KEYWORD, m as NODE_VALUE_NUMBER, r as NODE_VALUE_OPERATOR, o as NODE_VALUE_STRING } from './css-node-BzCSxoLM.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';
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.0",
3
+ "version": "0.6.2",
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",