@projectwallace/css-parser 0.18.8 → 0.18.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.
- package/dist/{css-node-CH5HqF0J.js → css-node-DfJEsKN0.js} +1 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/parse-anplusb.js +3 -3
- package/dist/parse-atrule-prelude.d.ts +2 -1
- package/dist/parse-atrule-prelude.js +41 -37
- package/dist/parse-declaration.d.ts +2 -1
- package/dist/parse-declaration.js +16 -15
- package/dist/{parse-dimension-CQELWb5z.js → parse-dimension-CIaPOmBc.js} +6 -12
- package/dist/parse-dimension.js +1 -2
- package/dist/{parse-selector-PhqFezCi.js → parse-selector-rTXB4IN2.js} +3 -11
- package/dist/parse-selector.js +1 -2
- package/dist/parse-value.js +2 -2
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +10 -9
- package/dist/{tokenize-BYl6GvyV.js → tokenize-0ADWAELW.js} +12 -0
- package/dist/{tokenize-CDEnYcVG.d.ts → tokenize-CaWtrHw_.d.ts} +1 -0
- package/dist/tokenize.d.ts +1 -1
- package/dist/tokenize.js +1 -2
- package/dist/{value-node-parser-tjY982sG.js → value-node-parser-DizbcN1a.js} +48 -109
- package/dist/walk.js +1 -1
- package/package.json +13 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./arena-e9O_g2AN.js";
|
|
2
|
-
import {
|
|
2
|
+
import { c as str_equals, d as str_starts_with, o as is_vendor_prefixed, s as is_whitespace, t as dimension_number_end } from "./parse-dimension-CIaPOmBc.js";
|
|
3
3
|
//#region src/css-node.ts
|
|
4
4
|
const TYPE_NAMES = {
|
|
5
5
|
[1]: "StyleSheet",
|
|
@@ -114,18 +114,12 @@ var CSSNode = class CSSNode {
|
|
|
114
114
|
this.source = source;
|
|
115
115
|
this.index = index;
|
|
116
116
|
}
|
|
117
|
-
/**
|
|
118
|
-
* @internal
|
|
119
|
-
* Get the arena (for internal/advanced use only)
|
|
120
|
-
*/
|
|
121
117
|
__get_arena() {
|
|
122
118
|
return this.arena;
|
|
123
119
|
}
|
|
124
|
-
/** @internal */
|
|
125
120
|
__get_source() {
|
|
126
121
|
return this.source;
|
|
127
122
|
}
|
|
128
|
-
/** @internal */
|
|
129
123
|
__get_index() {
|
|
130
124
|
return this.index;
|
|
131
125
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { A as PARENTHESIS, B as STYLESHEET, C as MEDIA_QUERY, D as NTH_SELECTOR, E as NTH_OF_SELECTOR, F as RATIO, G as UNICODE_RANGE, H as SUPPORTS_DECLARATION, I as RAW, J as VALUE, K as UNIVERSAL_SELECTOR, L as SELECTOR, N as PSEUDO_CLASS_SELECTOR, O as NUMBER, P as PSEUDO_ELEMENT_SELECTOR, R as SELECTOR_LIST, S as MEDIA_FEATURE, T as NESTING_SELECTOR, U as SUPPORTS_QUERY, V as STYLE_RULE, W as TYPE_SELECTOR, _ as ID_SELECTOR, a as CLASS_SELECTOR, b as LANG_SELECTOR, c as CONTAINER_QUERY, d as DIMENSION, f as FEATURE_RANGE, g as IDENTIFIER, h as HASH, i as BLOCK, j as PRELUDE_OPERATOR, k as OPERATOR, m as FUNCTION, n as AT_RULE, o as COMBINATOR, p as FLAG_IMPORTANT, q as URL, r as AT_RULE_PRELUDE, s as COMMENT, t as ATTRIBUTE_SELECTOR, u as DECLARATION, v as IF_BRANCH, w as MEDIA_TYPE, x as LAYER_NAME, y as IF_CONDITION, z as STRING } from "./arena-BGvFdbj5.js";
|
|
2
2
|
import { NODE_TYPES } from "./constants.js";
|
|
3
|
-
import { A as TOKEN_URL, C as TOKEN_PERCENTAGE, D as TOKEN_SEMICOLON, E as TOKEN_RIGHT_PAREN, M as Token, N as TokenType, O as TOKEN_STRING, S as TOKEN_NUMBER, T as TOKEN_RIGHT_BRACKET, _ as TOKEN_HASH, a as TOKEN_AT_KEYWORD, b as TOKEN_LEFT_BRACKET, c as TOKEN_CDC, d as TOKEN_COMMA, f as TOKEN_COMMENT, g as TOKEN_FUNCTION, h as TOKEN_EOF, i as tokenize, j as TOKEN_WHITESPACE, k as TOKEN_UNICODE_RANGE, l as TOKEN_CDO, m as TOKEN_DIMENSION, o as TOKEN_BAD_STRING, p as TOKEN_DELIM, r as LexerPosition, s as TOKEN_BAD_URL, t as CommentInfo, u as TOKEN_COLON, v as TOKEN_IDENT, w as TOKEN_RIGHT_BRACE, x as TOKEN_LEFT_PAREN, y as TOKEN_LEFT_BRACE } from "./tokenize-
|
|
3
|
+
import { A as TOKEN_URL, C as TOKEN_PERCENTAGE, D as TOKEN_SEMICOLON, E as TOKEN_RIGHT_PAREN, M as Token, N as TokenType, O as TOKEN_STRING, S as TOKEN_NUMBER, T as TOKEN_RIGHT_BRACKET, _ as TOKEN_HASH, a as TOKEN_AT_KEYWORD, b as TOKEN_LEFT_BRACKET, c as TOKEN_CDC, d as TOKEN_COMMA, f as TOKEN_COMMENT, g as TOKEN_FUNCTION, h as TOKEN_EOF, i as tokenize, j as TOKEN_WHITESPACE, k as TOKEN_UNICODE_RANGE, l as TOKEN_CDO, m as TOKEN_DIMENSION, o as TOKEN_BAD_STRING, p as TOKEN_DELIM, r as LexerPosition, s as TOKEN_BAD_URL, t as CommentInfo, u as TOKEN_COLON, v as TOKEN_IDENT, w as TOKEN_RIGHT_BRACE, x as TOKEN_LEFT_PAREN, y as TOKEN_LEFT_BRACE } from "./tokenize-CaWtrHw_.js";
|
|
4
4
|
import { $ as is_atrule_prelude, A as Parenthesis, At as is_ratio, B as SelectorNode, Bt as is_unicode_range, C as MediaQuery, Ct as is_number, D as NthSelector, Dt as is_prelude_selectorlist, E as NthOfSelector, Et as is_prelude_operator, F as Ratio, Ft as is_string, G as ToPlain, Gt as PlainCSSNode, H as StyleSheet, Ht as is_url, I as Raw, It as is_stylesheet, J as UniversalSelector, K as TypeSelector, Kt as TYPE_NAMES, L as Rule, Lt as is_supports_declaration, M as PreludeSelectorList, Mt as is_rule, N as PseudoClassSelector, Nt as is_selector, O as Number, Ot as is_pseudo_class_selector, P as PseudoElementSelector, Pt as is_selector_list, Q as is_atrule, R as Selector, Rt as is_supports_query, S as MediaFeature, St as is_nth_selector, T as NestingSelector, Tt as is_parenthesis, U as SupportsDeclaration, Ut as is_value, V as String, Vt as is_universal_selector, W as SupportsQuery, Wt as CloneOptions, X as Value, Y as Url, Z as WithChildren, _ as Identifier, _t as is_media_feature, a as Block, at as is_container_query, b as LangSelector, bt as is_nesting_selector, c as Combinator, ct as is_feature_range, d as Declaration, dt as is_id_selector, et as is_attribute_selector, f as Dimension, ft as is_identifier, g as IdSelector, gt as is_layer_name, h as Hash, ht as is_lang_selector, i as AttributeSelector, it as is_comment, j as PreludeOperator, jt as is_raw, k as Operator, kt as is_pseudo_element_selector, l as Comment, lt as is_function, m as Function, mt as is_if_condition, n as Atrule, nt as is_class_selector, o as CSSNode, ot as is_declaration, p as FeatureRange, pt as is_if_branch, q as UnicodeRange, r as AtrulePrelude, rt as is_combinator, s as ClassSelector, st as is_dimension, t as AnyNode, tt as is_block, u as ContainerQuery, ut as is_hash, v as IfBranch, vt as is_media_query, w as MediaType, wt as is_operator, x as LayerName, xt as is_nth_of_selector, y as IfCondition, yt as is_media_type, z as SelectorList, zt as is_type_selector } from "./node-types-YnOKcNfU.js";
|
|
5
5
|
import { ParserOptions, parse } from "./parse.js";
|
|
6
6
|
import { parse_selector, parse_selector_list } from "./parse-selector.js";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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-
|
|
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-0ADWAELW.js";
|
|
2
2
|
import { A as PARENTHESIS, B as STYLE_RULE, C as MEDIA_QUERY, D as NTH_SELECTOR, E as NTH_OF_SELECTOR, F as RAW, G as UNIVERSAL_SELECTOR, H as SUPPORTS_QUERY, I as SELECTOR, K as URL, L as SELECTOR_LIST, M as PSEUDO_CLASS_SELECTOR, N as PSEUDO_ELEMENT_SELECTOR, O as NUMBER, P as RATIO, R as STRING, S as MEDIA_FEATURE, T as NESTING_SELECTOR, U as TYPE_SELECTOR, V as SUPPORTS_DECLARATION, W as UNICODE_RANGE, _ as ID_SELECTOR, a as CLASS_SELECTOR, b as LANG_SELECTOR, c as CONTAINER_QUERY, d as DIMENSION, f as FEATURE_RANGE, g as IDENTIFIER, h as HASH, i as BLOCK, j as PRELUDE_OPERATOR, k as OPERATOR, m as FUNCTION, n as AT_RULE, o as COMBINATOR, p as FLAG_IMPORTANT, q as VALUE, r as AT_RULE_PRELUDE, s as COMMENT, t as ATTRIBUTE_SELECTOR, u as DECLARATION, v as IF_BRANCH, w as MEDIA_TYPE, x as LAYER_NAME, y as IF_CONDITION, z as STYLESHEET } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import { a as
|
|
4
|
-
import { n as TYPE_NAMES } from "./css-node-
|
|
5
|
-
import { n as parse_selector, r as parse_selector_list } from "./parse-selector-
|
|
3
|
+
import { a as is_custom, c as str_equals, d as str_starts_with, n as parse_dimension, o as is_vendor_prefixed, u as str_index_of } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { n as TYPE_NAMES } from "./css-node-DfJEsKN0.js";
|
|
5
|
+
import { n as parse_selector, r as parse_selector_list } from "./parse-selector-rTXB4IN2.js";
|
|
6
6
|
import { parse_atrule_prelude } from "./parse-atrule-prelude.js";
|
|
7
7
|
import { parse_value } from "./parse-value.js";
|
|
8
8
|
import { parse_declaration } from "./parse-declaration.js";
|
package/dist/parse-anplusb.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
3
|
+
import { c as str_equals, u as str_index_of } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
5
5
|
//#region src/parse-anplusb.ts
|
|
6
6
|
/** @internal */
|
|
7
7
|
var ANplusBParser = class {
|
|
@@ -14,7 +14,8 @@ export declare class AtRulePreludeParser {
|
|
|
14
14
|
private parse_prelude_dispatch;
|
|
15
15
|
private parse_media_query_list;
|
|
16
16
|
private create_node;
|
|
17
|
-
private
|
|
17
|
+
private paren_content_end;
|
|
18
|
+
private paren_close_end;
|
|
18
19
|
private scan_matching_paren;
|
|
19
20
|
private parse_single_media_query;
|
|
20
21
|
private parse_container_query;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { s as trim_boundaries } from "./parse-selector-
|
|
6
|
-
import { n as ConditionParser, t as ValueNodeParser } from "./value-node-parser-
|
|
3
|
+
import { f as strip_vendor_prefix, l as str_equals_range, r as is_and_or_not_range } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
5
|
+
import { s as trim_boundaries } from "./parse-selector-rTXB4IN2.js";
|
|
6
|
+
import { n as ConditionParser, t as ValueNodeParser } from "./value-node-parser-DizbcN1a.js";
|
|
7
7
|
//#region src/parse-atrule-prelude.ts
|
|
8
8
|
/** @internal */
|
|
9
9
|
var AtRulePreludeParser = class {
|
|
@@ -66,9 +66,8 @@ var AtRulePreludeParser = class {
|
|
|
66
66
|
create_node(type, start, end) {
|
|
67
67
|
return this.arena.create_node(type, start, end - start, this.lexer.token_line, this.lexer.token_column);
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
69
|
+
paren_content_end = 0;
|
|
70
|
+
paren_close_end = 0;
|
|
72
71
|
scan_matching_paren() {
|
|
73
72
|
let depth = 1;
|
|
74
73
|
let content_end = this.lexer.pos;
|
|
@@ -84,11 +83,9 @@ var AtRulePreludeParser = class {
|
|
|
84
83
|
}
|
|
85
84
|
} else if (token_type === 26) break;
|
|
86
85
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
depth === 0
|
|
91
|
-
];
|
|
86
|
+
this.paren_content_end = content_end;
|
|
87
|
+
this.paren_close_end = close_end;
|
|
88
|
+
return depth === 0;
|
|
92
89
|
}
|
|
93
90
|
parse_single_media_query() {
|
|
94
91
|
let query_start = this.lexer.pos;
|
|
@@ -99,9 +96,11 @@ var AtRulePreludeParser = class {
|
|
|
99
96
|
const saved_token_start = this.lexer.save_position();
|
|
100
97
|
this.next_token();
|
|
101
98
|
if (this.lexer.token_type === 1) {
|
|
102
|
-
let
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
let source = this.source;
|
|
100
|
+
let token_start = this.lexer.token_start;
|
|
101
|
+
let token_end = this.lexer.token_end;
|
|
102
|
+
if (str_equals_range(source, token_start, token_end, "only") || str_equals_range(source, token_start, token_end, "not")) {
|
|
103
|
+
let modifier = this.create_node(38, token_start, token_end);
|
|
105
104
|
first_component = modifier;
|
|
106
105
|
last_component = modifier;
|
|
107
106
|
} else this.lexer.restore_position(saved_token_start);
|
|
@@ -115,11 +114,12 @@ var AtRulePreludeParser = class {
|
|
|
115
114
|
let component = null;
|
|
116
115
|
if (token_type === 21) {
|
|
117
116
|
component = this.condition_parser.parse_media_feature(this.lexer.token_start, this.prelude_end, this.lexer.token_line, this.lexer.token_column);
|
|
118
|
-
if (component !== null) this.
|
|
117
|
+
if (component !== null) this.condition_parser.seek_to_end(this.lexer);
|
|
119
118
|
} else if (token_type === 1) {
|
|
120
|
-
let
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
let token_start = this.lexer.token_start;
|
|
120
|
+
let token_end = this.lexer.token_end;
|
|
121
|
+
if (is_and_or_not_range(this.source, token_start, token_end)) component = this.create_node(38, token_start, token_end);
|
|
122
|
+
else component = this.create_node(34, token_start, token_end);
|
|
123
123
|
} else break;
|
|
124
124
|
if (component !== null) {
|
|
125
125
|
if (first_component === 0) first_component = component;
|
|
@@ -144,14 +144,15 @@ var AtRulePreludeParser = class {
|
|
|
144
144
|
let component = null;
|
|
145
145
|
if (token_type === 21) {
|
|
146
146
|
component = this.condition_parser.parse_media_feature(this.lexer.token_start, this.prelude_end, this.lexer.token_line, this.lexer.token_column);
|
|
147
|
-
if (component !== null) this.
|
|
147
|
+
if (component !== null) this.condition_parser.seek_to_end(this.lexer);
|
|
148
148
|
} else if (token_type === 2) {
|
|
149
149
|
component = this.condition_parser.parse_function_condition(this.lexer.token_start, this.prelude_end, this.lexer.token_line, this.lexer.token_column);
|
|
150
|
-
this.
|
|
150
|
+
this.condition_parser.seek_to_end(this.lexer);
|
|
151
151
|
} else if (token_type === 1) {
|
|
152
|
-
let
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
let token_start = this.lexer.token_start;
|
|
153
|
+
let token_end = this.lexer.token_end;
|
|
154
|
+
if (is_and_or_not_range(this.source, token_start, token_end)) component = this.create_node(38, token_start, token_end);
|
|
155
|
+
else component = this.create_node(10, token_start, token_end);
|
|
155
156
|
}
|
|
156
157
|
if (component !== null) {
|
|
157
158
|
if (first_component === 0) first_component = component;
|
|
@@ -249,8 +250,8 @@ var AtRulePreludeParser = class {
|
|
|
249
250
|
let url_start = this.lexer.token_start;
|
|
250
251
|
let url_end = this.lexer.token_end;
|
|
251
252
|
if (this.lexer.token_type === 2) {
|
|
252
|
-
|
|
253
|
-
url_end =
|
|
253
|
+
this.scan_matching_paren();
|
|
254
|
+
url_end = this.paren_close_end;
|
|
254
255
|
}
|
|
255
256
|
return this.create_node(18, url_start, url_end);
|
|
256
257
|
}
|
|
@@ -258,16 +259,17 @@ var AtRulePreludeParser = class {
|
|
|
258
259
|
const saved = this.lexer.save_position();
|
|
259
260
|
this.next_token();
|
|
260
261
|
if (this.lexer.token_type === 1 || this.lexer.token_type === 2) {
|
|
261
|
-
let
|
|
262
|
-
if (this.lexer.
|
|
263
|
-
if (str_equals("layer", text)) {
|
|
262
|
+
let name_end = this.lexer.token_type === 2 ? this.lexer.token_end - 1 : this.lexer.token_end;
|
|
263
|
+
if (str_equals_range(this.source, this.lexer.token_start, name_end, "layer")) {
|
|
264
264
|
let layer_start = this.lexer.token_start;
|
|
265
265
|
let layer_end = this.lexer.token_end;
|
|
266
266
|
let content_start = 0;
|
|
267
267
|
let content_length = 0;
|
|
268
268
|
if (this.lexer.token_type === 2) {
|
|
269
269
|
content_start = this.lexer.pos;
|
|
270
|
-
let
|
|
270
|
+
let matched = this.scan_matching_paren();
|
|
271
|
+
let content_end = this.paren_content_end;
|
|
272
|
+
let close_end = this.paren_close_end;
|
|
271
273
|
if (matched) {
|
|
272
274
|
content_length = content_end - content_start;
|
|
273
275
|
layer_end = close_end;
|
|
@@ -291,11 +293,12 @@ var AtRulePreludeParser = class {
|
|
|
291
293
|
const saved = this.lexer.save_position();
|
|
292
294
|
this.next_token();
|
|
293
295
|
if (this.lexer.token_type === 2) {
|
|
294
|
-
|
|
295
|
-
if (str_equals("supports", text)) {
|
|
296
|
+
if (str_equals_range(this.source, this.lexer.token_start, this.lexer.token_end - 1, "supports")) {
|
|
296
297
|
let supports_start = this.lexer.token_start;
|
|
297
298
|
let content_start = this.lexer.token_end;
|
|
298
|
-
|
|
299
|
+
this.scan_matching_paren();
|
|
300
|
+
let content_end = this.paren_content_end;
|
|
301
|
+
let supports_end = this.paren_close_end;
|
|
299
302
|
let supports_node = this.create_node(36, supports_start, supports_end);
|
|
300
303
|
let trimmed = trim_boundaries(this.source, content_start, content_end);
|
|
301
304
|
if (trimmed) {
|
|
@@ -351,7 +354,9 @@ var AtRulePreludeParser = class {
|
|
|
351
354
|
this.next_token();
|
|
352
355
|
let paren_start = this.lexer.token_start;
|
|
353
356
|
let content_start = this.lexer.pos;
|
|
354
|
-
|
|
357
|
+
this.scan_matching_paren();
|
|
358
|
+
let content_end = this.paren_content_end;
|
|
359
|
+
let paren_end = this.paren_close_end;
|
|
355
360
|
let scope_node = this.create_node(41, paren_start, paren_end);
|
|
356
361
|
let trimmed = trim_boundaries(this.source, content_start, content_end);
|
|
357
362
|
if (trimmed) {
|
|
@@ -361,8 +366,7 @@ var AtRulePreludeParser = class {
|
|
|
361
366
|
nodes.push(scope_node);
|
|
362
367
|
} else if (token_type === 1) {
|
|
363
368
|
this.next_token();
|
|
364
|
-
|
|
365
|
-
if (str_equals("to", text)) nodes.push(this.create_node(38, this.lexer.token_start, this.lexer.token_end));
|
|
369
|
+
if (str_equals_range(this.source, this.lexer.token_start, this.lexer.token_end, "to")) nodes.push(this.create_node(38, this.lexer.token_start, this.lexer.token_end));
|
|
366
370
|
} else this.next_token();
|
|
367
371
|
}
|
|
368
372
|
return nodes;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { l as CSSDataArena } from "./arena-BGvFdbj5.js";
|
|
2
|
-
import { n as Lexer } from "./tokenize-
|
|
2
|
+
import { n as Lexer } from "./tokenize-CaWtrHw_.js";
|
|
3
3
|
import { d as Declaration } from "./node-types-YnOKcNfU.js";
|
|
4
4
|
//#region src/parse-declaration.d.ts
|
|
5
5
|
/** @internal */
|
|
@@ -7,6 +7,7 @@ export declare class DeclarationParser {
|
|
|
7
7
|
private arena;
|
|
8
8
|
private source;
|
|
9
9
|
private value_parser;
|
|
10
|
+
private lookahead_position;
|
|
10
11
|
constructor(arena: CSSDataArena, source: string, parse_values?: boolean);
|
|
11
12
|
parse_declaration(start: number, end: number, line?: number, column?: number): number | null;
|
|
12
13
|
parse_declaration_with_lexer(lexer: Lexer, end: number): number | null;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { a as skip_whitespace_and_comments_backward,
|
|
3
|
+
import { o as is_vendor_prefixed } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
5
|
+
import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward } from "./parse-selector-rTXB4IN2.js";
|
|
6
6
|
import { ValueParser } from "./parse-value.js";
|
|
7
7
|
//#region src/parse-declaration.ts
|
|
8
8
|
/** @internal */
|
|
@@ -10,6 +10,7 @@ var DeclarationParser = class {
|
|
|
10
10
|
arena;
|
|
11
11
|
source;
|
|
12
12
|
value_parser;
|
|
13
|
+
lookahead_position = new Lexer("").save_position();
|
|
13
14
|
constructor(arena, source, parse_values = true) {
|
|
14
15
|
this.arena = arena;
|
|
15
16
|
this.source = source;
|
|
@@ -22,9 +23,8 @@ var DeclarationParser = class {
|
|
|
22
23
|
return this.parse_declaration_with_lexer(lexer, end);
|
|
23
24
|
}
|
|
24
25
|
parse_declaration_with_lexer(lexer, end) {
|
|
25
|
-
|
|
26
|
+
let initial_saved = null;
|
|
26
27
|
let has_browser_hack = false;
|
|
27
|
-
let has_delimiter_prefix = false;
|
|
28
28
|
let browser_hack_start = 0;
|
|
29
29
|
let browser_hack_line = 1;
|
|
30
30
|
let browser_hack_column = 1;
|
|
@@ -56,7 +56,7 @@ var DeclarationParser = class {
|
|
|
56
56
|
lexer.next_token_fast(true);
|
|
57
57
|
if (lexer.token_type === 1) {
|
|
58
58
|
has_browser_hack = true;
|
|
59
|
-
|
|
59
|
+
initial_saved = delim_saved;
|
|
60
60
|
} else lexer.restore_position(delim_saved);
|
|
61
61
|
}
|
|
62
62
|
if (lexer.token_type !== 1 && lexer.token_type !== 3 && lexer.token_type !== 4) return null;
|
|
@@ -64,10 +64,10 @@ var DeclarationParser = class {
|
|
|
64
64
|
let prop_end = lexer.token_end;
|
|
65
65
|
let decl_line = has_browser_hack ? browser_hack_line : lexer.token_line;
|
|
66
66
|
let decl_column = has_browser_hack ? browser_hack_column : lexer.token_column;
|
|
67
|
-
const saved = lexer.
|
|
67
|
+
const saved = lexer.save_position_into(this.lookahead_position);
|
|
68
68
|
lexer.next_token_fast(true);
|
|
69
69
|
if (lexer.token_type !== 16) {
|
|
70
|
-
lexer.restore_position(
|
|
70
|
+
lexer.restore_position(initial_saved ?? saved);
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
73
|
lexer.pos = lexer.token_end;
|
|
@@ -135,15 +135,16 @@ var DeclarationParser = class {
|
|
|
135
135
|
}
|
|
136
136
|
lexer.pos++;
|
|
137
137
|
}
|
|
138
|
-
let
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.arena.
|
|
138
|
+
let trimmed_start = skip_whitespace_and_comments_forward(this.source, value_start, value_end);
|
|
139
|
+
let trimmed_end = skip_whitespace_and_comments_backward(this.source, value_end, trimmed_start);
|
|
140
|
+
if (trimmed_start < trimmed_end) {
|
|
141
|
+
this.arena.set_value_start_delta(declaration, trimmed_start - prop_start);
|
|
142
|
+
this.arena.set_value_length(declaration, trimmed_end - trimmed_start);
|
|
142
143
|
if (this.value_parser) {
|
|
143
|
-
let valueNode = this.value_parser.parse_value(value_start,
|
|
144
|
+
let valueNode = this.value_parser.parse_value(value_start, trimmed_end, value_start_line, value_start_column);
|
|
144
145
|
this.arena.set_first_child(declaration, valueNode);
|
|
145
146
|
} else {
|
|
146
|
-
let rawNode = this.arena.create_node(8,
|
|
147
|
+
let rawNode = this.arena.create_node(8, trimmed_start, trimmed_end - trimmed_start, value_start_line, value_start_column);
|
|
147
148
|
this.arena.set_first_child(declaration, rawNode);
|
|
148
149
|
}
|
|
149
150
|
} else {
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if a character code is whitespace (space, tab, newline, CR, or FF)
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
1
|
function is_whitespace(ch) {
|
|
6
2
|
return ch === 32 || ch === 9 || ch === 10 || ch === 13 || ch === 12;
|
|
7
3
|
}
|
|
@@ -9,7 +5,6 @@ function is_whitespace(ch) {
|
|
|
9
5
|
function is_combinator(ch) {
|
|
10
6
|
return ch === 62 || ch === 43 || ch === 126;
|
|
11
7
|
}
|
|
12
|
-
/** @internal */
|
|
13
8
|
function is_digit(ch) {
|
|
14
9
|
return ch >= 48 && ch <= 57;
|
|
15
10
|
}
|
|
@@ -27,11 +22,6 @@ function str_equals(a, b) {
|
|
|
27
22
|
}
|
|
28
23
|
return true;
|
|
29
24
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Case-insensitive equality between `source[start, end)` and `literal`, without allocating
|
|
32
|
-
* a substring first. Same semantics as `str_equals(literal, source.substring(start, end))`.
|
|
33
|
-
* `literal` MUST be lowercase.
|
|
34
|
-
*/
|
|
35
25
|
function str_equals_range(source, start, end, literal) {
|
|
36
26
|
if (end - start !== literal.length) return false;
|
|
37
27
|
for (let i = 0; i < literal.length; i++) {
|
|
@@ -41,6 +31,11 @@ function str_equals_range(source, start, end, literal) {
|
|
|
41
31
|
}
|
|
42
32
|
return true;
|
|
43
33
|
}
|
|
34
|
+
function is_and_or_not_range(source, start, end) {
|
|
35
|
+
let length = end - start;
|
|
36
|
+
if (length === 3) return str_equals_range(source, start, end, "and") || str_equals_range(source, start, end, "not");
|
|
37
|
+
return length === 2 && str_equals_range(source, start, end, "or");
|
|
38
|
+
}
|
|
44
39
|
/** Case-insensitive ASCII prefix check without allocations. `prefix` MUST be lowercase. */
|
|
45
40
|
function str_starts_with(str, prefix) {
|
|
46
41
|
if (str.length < prefix.length) return false;
|
|
@@ -95,7 +90,6 @@ function is_custom(str) {
|
|
|
95
90
|
if (str.length < 3) return false;
|
|
96
91
|
return str.charCodeAt(0) === 45 && str.charCodeAt(1) === 45;
|
|
97
92
|
}
|
|
98
|
-
/** Strip a vendor prefix, e.g. `-webkit-keyframes` → `keyframes`. Returns the input unchanged if it has no prefix. */
|
|
99
93
|
function strip_vendor_prefix(str) {
|
|
100
94
|
if (!is_vendor_prefixed(str)) return str;
|
|
101
95
|
for (let i = 2; i < str.length; i++) if (str.charCodeAt(i) === 45) return str.substring(i + 1);
|
|
@@ -146,4 +140,4 @@ function parse_dimension(text) {
|
|
|
146
140
|
};
|
|
147
141
|
}
|
|
148
142
|
//#endregion
|
|
149
|
-
export {
|
|
143
|
+
export { is_custom as a, str_equals as c, str_starts_with as d, strip_vendor_prefix as f, is_combinator as i, str_equals_range as l, parse_dimension as n, is_vendor_prefixed as o, is_and_or_not_range as r, is_whitespace as s, dimension_number_end as t, str_index_of as u };
|
package/dist/parse-dimension.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { dimension_number_end, parse_dimension };
|
|
1
|
+
export { t as dimension_number_end, n as parse_dimension } from "./parse-dimension-CIaPOmBc.js";
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
3
|
+
import { i as is_combinator, l as str_equals_range, s as is_whitespace } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
5
5
|
import { ANplusBParser } from "./parse-anplusb.js";
|
|
6
6
|
//#region src/parse-utils.ts
|
|
7
|
-
/** @internal */
|
|
8
7
|
function skip_whitespace_forward(source, pos, end) {
|
|
9
8
|
while (pos < end && is_whitespace(source.charCodeAt(pos))) pos++;
|
|
10
9
|
return pos;
|
|
11
10
|
}
|
|
12
|
-
/** @internal */
|
|
13
11
|
function skip_whitespace_and_comments_forward(source, pos, end) {
|
|
14
12
|
while (pos < end) {
|
|
15
13
|
let ch = source.charCodeAt(pos);
|
|
@@ -32,7 +30,6 @@ function skip_whitespace_and_comments_forward(source, pos, end) {
|
|
|
32
30
|
}
|
|
33
31
|
return pos;
|
|
34
32
|
}
|
|
35
|
-
/** @internal */
|
|
36
33
|
function skip_whitespace_and_comments_backward(source, pos, start) {
|
|
37
34
|
while (pos > start) {
|
|
38
35
|
let ch = source.charCodeAt(pos - 1);
|
|
@@ -55,17 +52,12 @@ function skip_whitespace_and_comments_backward(source, pos, start) {
|
|
|
55
52
|
}
|
|
56
53
|
return pos;
|
|
57
54
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Trims whitespace and CSS comments from both ends; returns null if the range is only whitespace/comments.
|
|
60
|
-
* @internal
|
|
61
|
-
*/
|
|
62
55
|
function trim_boundaries(source, start, end) {
|
|
63
56
|
start = skip_whitespace_and_comments_forward(source, start, end);
|
|
64
57
|
end = skip_whitespace_and_comments_backward(source, end, start);
|
|
65
58
|
if (start >= end) return null;
|
|
66
59
|
return [start, end];
|
|
67
60
|
}
|
|
68
|
-
/** Find the position of the first ':' at parenthesis depth 0 in [start, end). Returns -1 if not found. @internal */
|
|
69
61
|
function find_colon_at_depth_zero(source, start, end) {
|
|
70
62
|
let depth = 0;
|
|
71
63
|
for (let i = start; i < end; i++) {
|
package/dist/parse-selector.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { SelectorParser, parse_selector, parse_selector_list };
|
|
1
|
+
export { t as SelectorParser, n as parse_selector, r as parse_selector_list } from "./parse-selector-rTXB4IN2.js";
|
package/dist/parse-value.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
2
|
-
import { t as CSSNode } from "./css-node-
|
|
3
|
-
import { t as ValueNodeParser } from "./value-node-parser-
|
|
2
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
3
|
+
import { t as ValueNodeParser } from "./value-node-parser-DizbcN1a.js";
|
|
4
4
|
//#region src/parse-value.ts
|
|
5
5
|
/** @internal */
|
|
6
6
|
var ValueParser = class {
|
package/dist/parse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { l as CSSDataArena } from "./arena-BGvFdbj5.js";
|
|
2
|
-
import { t as CommentInfo } from "./tokenize-
|
|
2
|
+
import { t as CommentInfo } from "./tokenize-CaWtrHw_.js";
|
|
3
3
|
import { H as StyleSheet } from "./node-types-YnOKcNfU.js";
|
|
4
4
|
//#region src/parse.d.ts
|
|
5
5
|
export interface ParserOptions {
|
package/dist/parse.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import { l as CSSDataArena } from "./arena-e9O_g2AN.js";
|
|
3
|
-
import { t as CSSNode } from "./css-node-
|
|
4
|
-
import { a as skip_whitespace_and_comments_backward,
|
|
3
|
+
import { t as CSSNode } from "./css-node-DfJEsKN0.js";
|
|
4
|
+
import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward, t as SelectorParser } from "./parse-selector-rTXB4IN2.js";
|
|
5
5
|
import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
|
|
6
6
|
import { DeclarationParser } from "./parse-declaration.js";
|
|
7
7
|
//#region src/parse.ts
|
|
@@ -187,16 +187,17 @@ var Parser = class {
|
|
|
187
187
|
prelude_end = this.lexer.token_end;
|
|
188
188
|
this.next_token();
|
|
189
189
|
}
|
|
190
|
-
let
|
|
190
|
+
let trimmed_start = skip_whitespace_and_comments_forward(this.source, prelude_start, prelude_end);
|
|
191
|
+
let trimmed_end = skip_whitespace_and_comments_backward(this.source, prelude_end, trimmed_start);
|
|
191
192
|
let prelude_wrapper = null;
|
|
192
|
-
if (
|
|
193
|
+
if (trimmed_start < trimmed_end) {
|
|
193
194
|
if (this.prelude_parser) {
|
|
194
|
-
let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name,
|
|
195
|
+
let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name, trimmed_start, trimmed_end, at_rule_line, at_rule_column);
|
|
195
196
|
if (prelude_nodes.length > 0) {
|
|
196
|
-
prelude_wrapper = this.arena.create_node(40,
|
|
197
|
+
prelude_wrapper = this.arena.create_node(40, trimmed_start, trimmed_end - trimmed_start, at_rule_line, at_rule_column);
|
|
197
198
|
this.arena.append_children(prelude_wrapper, prelude_nodes);
|
|
198
|
-
} else prelude_wrapper = this.arena.create_node(8,
|
|
199
|
-
} else prelude_wrapper = this.arena.create_node(8,
|
|
199
|
+
} else prelude_wrapper = this.arena.create_node(8, trimmed_start, trimmed_end - trimmed_start, at_rule_line, at_rule_column);
|
|
200
|
+
} else prelude_wrapper = this.arena.create_node(8, trimmed_start, trimmed_end - trimmed_start, at_rule_line, at_rule_column);
|
|
200
201
|
}
|
|
201
202
|
let last_end = this.lexer.token_end;
|
|
202
203
|
if (this.peek_type() === 23) {
|
|
@@ -675,6 +675,18 @@ var Lexer = class {
|
|
|
675
675
|
token_column: this.token_column
|
|
676
676
|
};
|
|
677
677
|
}
|
|
678
|
+
save_position_into(target) {
|
|
679
|
+
target.pos = this.pos;
|
|
680
|
+
target.line = this._line;
|
|
681
|
+
target.column = this.pos - this._line_offset + 1;
|
|
682
|
+
target._line_offset = this._line_offset;
|
|
683
|
+
target.token_type = this.token_type;
|
|
684
|
+
target.token_start = this.token_start;
|
|
685
|
+
target.token_end = this.token_end;
|
|
686
|
+
target.token_line = this.token_line;
|
|
687
|
+
target.token_column = this.token_column;
|
|
688
|
+
return target;
|
|
689
|
+
}
|
|
678
690
|
/**
|
|
679
691
|
* Restore lexer state from saved position
|
|
680
692
|
* @param saved The saved position to restore
|
|
@@ -111,6 +111,7 @@ declare class Lexer {
|
|
|
111
111
|
* @returns Object containing all lexer state
|
|
112
112
|
*/
|
|
113
113
|
save_position(): LexerPosition;
|
|
114
|
+
save_position_into(target: LexerPosition): LexerPosition;
|
|
114
115
|
/**
|
|
115
116
|
* Restore lexer state from saved position
|
|
116
117
|
* @param saved The saved position to restore
|
package/dist/tokenize.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as tokenize, n as Lexer, r as LexerPosition, t as CommentInfo } from "./tokenize-
|
|
1
|
+
import { i as tokenize, n as Lexer, r as LexerPosition, t as CommentInfo } from "./tokenize-CaWtrHw_.js";
|
|
2
2
|
export { CommentInfo, Lexer, LexerPosition, tokenize };
|
package/dist/tokenize.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { Lexer, tokenize };
|
|
1
|
+
export { t as Lexer, n as tokenize } from "./tokenize-0ADWAELW.js";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-0ADWAELW.js";
|
|
2
2
|
import "./arena-e9O_g2AN.js";
|
|
3
|
-
import {
|
|
4
|
-
import { i as find_colon_at_depth_zero, o as skip_whitespace_and_comments_forward, s as trim_boundaries, t as SelectorParser } from "./parse-selector-
|
|
3
|
+
import { l as str_equals_range, r as is_and_or_not_range } from "./parse-dimension-CIaPOmBc.js";
|
|
4
|
+
import { i as find_colon_at_depth_zero, o as skip_whitespace_and_comments_forward, s as trim_boundaries, t as SelectorParser } from "./parse-selector-rTXB4IN2.js";
|
|
5
5
|
//#region src/parse-condition.ts
|
|
6
|
-
/** @internal */
|
|
7
6
|
var ConditionParser = class {
|
|
8
7
|
lexer;
|
|
9
8
|
arena;
|
|
@@ -18,12 +17,8 @@ var ConditionParser = class {
|
|
|
18
17
|
this.value_node_parser = value_node_parser;
|
|
19
18
|
this.selector_parser = new SelectorParser(arena, source);
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.lexer.pos,
|
|
24
|
-
this.lexer.line,
|
|
25
|
-
this.lexer.column
|
|
26
|
-
];
|
|
20
|
+
seek_to_end(target) {
|
|
21
|
+
target.seek(this.lexer.pos, this.lexer.line, this.lexer.column);
|
|
27
22
|
}
|
|
28
23
|
create_node(type, start, end) {
|
|
29
24
|
return this.arena.create_node(type, start, end - start, this.lexer.token_line, this.lexer.token_column);
|
|
@@ -35,9 +30,8 @@ var ConditionParser = class {
|
|
|
35
30
|
}
|
|
36
31
|
return this.lexer.next_token_fast(false);
|
|
37
32
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
33
|
+
paren_content_end = 0;
|
|
34
|
+
paren_close_end = 0;
|
|
41
35
|
scan_matching_paren() {
|
|
42
36
|
let depth = 1;
|
|
43
37
|
let content_end = this.lexer.pos;
|
|
@@ -53,11 +47,9 @@ var ConditionParser = class {
|
|
|
53
47
|
}
|
|
54
48
|
} else if (token_type === 26) break;
|
|
55
49
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
depth === 0
|
|
60
|
-
];
|
|
50
|
+
this.paren_content_end = content_end;
|
|
51
|
+
this.paren_close_end = close_end;
|
|
52
|
+
return depth === 0;
|
|
61
53
|
}
|
|
62
54
|
parse_feature_value(start, end) {
|
|
63
55
|
return this.value_node_parser.parse_chain(start, end, this.lexer.line, this.lexer.column);
|
|
@@ -147,15 +139,6 @@ var ConditionParser = class {
|
|
|
147
139
|
if (first_child !== 0) this.arena.set_first_child(range_node, first_child);
|
|
148
140
|
return range_node;
|
|
149
141
|
}
|
|
150
|
-
/**
|
|
151
|
-
* Parse the content of a media feature — everything between its parentheses, already
|
|
152
|
-
* known by the caller as `[content_start, content_end)`. `feature_start`/`feature_end`
|
|
153
|
-
* are the span of the feature node itself: for a real `@media (min-width: 768px)` feature
|
|
154
|
-
* this includes the surrounding parens (`feature_start < content_start`); for if()'s
|
|
155
|
-
* `media(min-width: 768px)`, media()'s own parens already delimit the content, so callers
|
|
156
|
-
* pass `feature_start === content_start` and `feature_end === content_end`.
|
|
157
|
-
* Returns a MEDIA_FEATURE (name/boolean/name:value) or FEATURE_RANGE (comparison syntax) node.
|
|
158
|
-
*/
|
|
159
142
|
parse_media_feature_content(feature_start, feature_end, content_start, content_end) {
|
|
160
143
|
this.end = content_end;
|
|
161
144
|
let has_comparison = false;
|
|
@@ -209,7 +192,9 @@ var ConditionParser = class {
|
|
|
209
192
|
this.next_token();
|
|
210
193
|
let feature_start = this.lexer.token_start;
|
|
211
194
|
let content_start = this.lexer.pos;
|
|
212
|
-
let
|
|
195
|
+
let matched = this.scan_matching_paren();
|
|
196
|
+
let content_end = this.paren_content_end;
|
|
197
|
+
let feature_end = this.paren_close_end;
|
|
213
198
|
if (!matched) return null;
|
|
214
199
|
return this.parse_media_feature_content(feature_start, feature_end, content_start, content_end);
|
|
215
200
|
}
|
|
@@ -217,41 +202,31 @@ var ConditionParser = class {
|
|
|
217
202
|
this.end = end;
|
|
218
203
|
this.lexer.seek(func_start, line, column);
|
|
219
204
|
this.next_token();
|
|
220
|
-
let
|
|
205
|
+
let func_name_start = this.lexer.token_start;
|
|
206
|
+
let func_name_end = this.lexer.token_end - 1;
|
|
221
207
|
let content_start = this.lexer.token_end;
|
|
222
|
-
|
|
208
|
+
this.scan_matching_paren();
|
|
209
|
+
let content_end = this.paren_content_end;
|
|
210
|
+
let func_end = this.paren_close_end;
|
|
223
211
|
let func_node = this.create_node(15, func_start, func_end);
|
|
224
212
|
this.arena.set_content_start_delta(func_node, 0);
|
|
225
|
-
this.arena.set_content_length(func_node,
|
|
213
|
+
this.arena.set_content_length(func_node, func_name_end - func_name_start);
|
|
226
214
|
this.arena.set_value_start_delta(func_node, content_start - func_start);
|
|
227
215
|
this.arena.set_value_length(func_node, content_end - content_start);
|
|
228
|
-
if (
|
|
216
|
+
if (str_equals_range(this.source, func_name_start, func_name_end, "selector")) {
|
|
229
217
|
let selector_list = this.selector_parser.parse_selector(content_start, content_end, this.lexer.line, this.lexer.column);
|
|
230
218
|
if (selector_list !== null) this.arena.set_first_child(func_node, selector_list);
|
|
231
|
-
} else if (
|
|
219
|
+
} else if (str_equals_range(this.source, func_name_start, func_name_end, "style")) {
|
|
232
220
|
let decl_child = this.parse_supports_declaration_content(content_start, content_end);
|
|
233
221
|
if (decl_child !== null) this.arena.set_first_child(func_node, decl_child);
|
|
234
222
|
}
|
|
235
223
|
return func_node;
|
|
236
224
|
}
|
|
237
|
-
/**
|
|
238
|
-
* Parse a single `(property: value)` supports declaration from a content range — the
|
|
239
|
-
* `<style-feature>`/`<supports-feature>` grammar shared by `style()`, `@supports (…)`, and
|
|
240
|
-
* `@import … supports(…)`. Returns null if no top-level ':' is found.
|
|
241
|
-
*/
|
|
242
225
|
parse_supports_declaration_content(content_start, content_end) {
|
|
243
226
|
let colon_pos = find_colon_at_depth_zero(this.source, content_start, content_end);
|
|
244
227
|
if (colon_pos === -1) return null;
|
|
245
228
|
return this.create_supports_declaration(content_start, content_end, colon_pos);
|
|
246
229
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Parse a `<supports-condition>` — the compound and/or/not grammar shared by `@supports`
|
|
249
|
-
* preludes and if()'s `supports(...)` condition function: parenthesized `(property: value)`
|
|
250
|
-
* declarations, `and`/`or`/`not` logical operators, and nested function conditions
|
|
251
|
-
* (`selector()`, `style()`, etc.), chained as flat siblings.
|
|
252
|
-
* `start`/`end` bound the range to scan; the caller has already positioned nothing — this
|
|
253
|
-
* seeks its own lexer, so it's safe to call with any sub-range of the source.
|
|
254
|
-
*/
|
|
255
230
|
parse_supports_condition(start, end, line, column) {
|
|
256
231
|
let saved_end = this.end;
|
|
257
232
|
this.end = end;
|
|
@@ -265,7 +240,9 @@ var ConditionParser = class {
|
|
|
265
240
|
if (token_type === 21) {
|
|
266
241
|
let feature_start = this.lexer.token_start;
|
|
267
242
|
let content_start = this.lexer.pos;
|
|
268
|
-
let
|
|
243
|
+
let matched = this.scan_matching_paren();
|
|
244
|
+
let content_end = this.paren_content_end;
|
|
245
|
+
let feature_end = this.paren_close_end;
|
|
269
246
|
if (matched) {
|
|
270
247
|
let query = this.create_node(36, feature_start, feature_end);
|
|
271
248
|
let trimmed = trim_boundaries(this.source, content_start, content_end);
|
|
@@ -278,9 +255,10 @@ var ConditionParser = class {
|
|
|
278
255
|
nodes.push(query);
|
|
279
256
|
}
|
|
280
257
|
} else if (token_type === 1) {
|
|
281
|
-
let
|
|
282
|
-
|
|
283
|
-
|
|
258
|
+
let token_start = this.lexer.token_start;
|
|
259
|
+
let token_end = this.lexer.token_end;
|
|
260
|
+
if (is_and_or_not_range(this.source, token_start, token_end)) {
|
|
261
|
+
let op = this.create_node(38, token_start, token_end);
|
|
284
262
|
nodes.push(op);
|
|
285
263
|
}
|
|
286
264
|
} else if (token_type === 2) nodes.push(this.parse_function_condition(this.lexer.token_start, this.end, this.lexer.token_line, this.lexer.token_column));
|
|
@@ -291,7 +269,6 @@ var ConditionParser = class {
|
|
|
291
269
|
};
|
|
292
270
|
//#endregion
|
|
293
271
|
//#region src/value-node-parser.ts
|
|
294
|
-
/** @internal */
|
|
295
272
|
var ValueNodeParser = class ValueNodeParser {
|
|
296
273
|
lexer;
|
|
297
274
|
arena;
|
|
@@ -360,6 +337,8 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
360
337
|
if (ch === 43 || ch === 45 || ch === 42 || ch === 47) return this.create_node(16, start, end);
|
|
361
338
|
return null;
|
|
362
339
|
}
|
|
340
|
+
paren_content_end = 0;
|
|
341
|
+
paren_close_end = 0;
|
|
363
342
|
scan_matching_paren(bounded) {
|
|
364
343
|
let depth = 1;
|
|
365
344
|
let content_end = this.lexer.pos;
|
|
@@ -378,11 +357,9 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
378
357
|
}
|
|
379
358
|
}
|
|
380
359
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
depth === 0
|
|
385
|
-
];
|
|
360
|
+
this.paren_content_end = content_end;
|
|
361
|
+
this.paren_close_end = close_end;
|
|
362
|
+
return depth === 0;
|
|
386
363
|
}
|
|
387
364
|
parse_function_node(start, end) {
|
|
388
365
|
let name_end = end - 1;
|
|
@@ -401,7 +378,9 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
401
378
|
let func_end = end;
|
|
402
379
|
let content_start = end;
|
|
403
380
|
let content_end = end;
|
|
404
|
-
let
|
|
381
|
+
let matched = this.scan_matching_paren(false);
|
|
382
|
+
let scanned_content_end = this.paren_content_end;
|
|
383
|
+
let scanned_func_end = this.paren_close_end;
|
|
405
384
|
if (matched) {
|
|
406
385
|
content_end = scanned_content_end;
|
|
407
386
|
func_end = scanned_func_end;
|
|
@@ -445,17 +424,6 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
445
424
|
if (first_arg !== 0) this.arena.set_first_child(node, first_arg);
|
|
446
425
|
return node;
|
|
447
426
|
}
|
|
448
|
-
/**
|
|
449
|
-
* Parse an if() inline conditional function.
|
|
450
|
-
*
|
|
451
|
-
* Spec grammar (CSS Values Level 5):
|
|
452
|
-
* if( <if-branch>+ )
|
|
453
|
-
* <if-branch> = <if-condition> : <declaration-value>? ;?
|
|
454
|
-
* <if-condition> = style(…) | media(…) | supports(…) | else
|
|
455
|
-
*
|
|
456
|
-
* Each branch becomes an IF_BRANCH child (see the `IfBranch` type in node-types.ts
|
|
457
|
-
* for its shape). Colons/semicolons here are structural separators, not OPERATOR nodes.
|
|
458
|
-
*/
|
|
459
427
|
parse_if_function_node(start, end) {
|
|
460
428
|
let name_end = end - 1;
|
|
461
429
|
let save_line = this.lexer.token_line;
|
|
@@ -557,9 +525,6 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
557
525
|
this.arena.append_children(node, branches);
|
|
558
526
|
return node;
|
|
559
527
|
}
|
|
560
|
-
is_and_or_not(str) {
|
|
561
|
-
return str_equals("and", str) || str_equals("or", str) || str_equals("not", str);
|
|
562
|
-
}
|
|
563
528
|
next_significant_token() {
|
|
564
529
|
while (this.lexer.pos < this.end) {
|
|
565
530
|
this.lexer.next_token_fast(false);
|
|
@@ -569,22 +534,9 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
569
534
|
}
|
|
570
535
|
return 26;
|
|
571
536
|
}
|
|
572
|
-
/**
|
|
573
|
-
* Parse an if()-branch condition:
|
|
574
|
-
* <if-condition> = <boolean-expr[ <if-test> ]> | else
|
|
575
|
-
* <if-test> = style(…) | media(…) | supports(…)
|
|
576
|
-
* i.e. a single test function, the bare "else" identifier, or those test functions
|
|
577
|
-
* combined with not/and/or (e.g. "not style(--x: 1)", "style(--a: 1) and media(width > 600px)").
|
|
578
|
-
* Called with the lexer's current token already positioned at the condition's first token.
|
|
579
|
-
* A simple single-function/"else" condition returns that node directly, unwrapped (matching
|
|
580
|
-
* prior behavior); a compound not/and/or condition wraps the flat operator/function chain in
|
|
581
|
-
* an IF_CONDITION node so IfBranch.condition/.value (single first_child/next_sibling hops)
|
|
582
|
-
* still see exactly one node for "the condition".
|
|
583
|
-
*/
|
|
584
537
|
parse_if_condition() {
|
|
585
538
|
if (this.lexer.token_type === 1) {
|
|
586
|
-
|
|
587
|
-
if (str_equals("else", text)) return this.parse_value_node();
|
|
539
|
+
if (str_equals_range(this.source, this.lexer.token_start, this.lexer.token_end, "else")) return this.parse_value_node();
|
|
588
540
|
}
|
|
589
541
|
let first = 0;
|
|
590
542
|
let last = 0;
|
|
@@ -596,10 +548,11 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
596
548
|
let is_operator = false;
|
|
597
549
|
if (tt === 2) component = this.parse_if_condition_function(this.lexer.token_start, this.lexer.token_end);
|
|
598
550
|
else if (tt === 1) {
|
|
599
|
-
let
|
|
600
|
-
|
|
551
|
+
let token_start = this.lexer.token_start;
|
|
552
|
+
let token_end = this.lexer.token_end;
|
|
553
|
+
if (is_and_or_not_range(this.source, token_start, token_end)) {
|
|
601
554
|
is_operator = true;
|
|
602
|
-
component = this.arena.create_node(38,
|
|
555
|
+
component = this.arena.create_node(38, token_start, token_end - token_start, this.lexer.token_line, this.lexer.token_column);
|
|
603
556
|
} else component = this.parse_value_node();
|
|
604
557
|
} else component = this.parse_value_node();
|
|
605
558
|
if (component !== null) {
|
|
@@ -616,8 +569,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
616
569
|
continue;
|
|
617
570
|
}
|
|
618
571
|
if (next_tt === 1) {
|
|
619
|
-
|
|
620
|
-
if (this.is_and_or_not(text)) {
|
|
572
|
+
if (is_and_or_not_range(this.source, this.lexer.token_start, this.lexer.token_end)) {
|
|
621
573
|
compound = true;
|
|
622
574
|
continue;
|
|
623
575
|
}
|
|
@@ -634,28 +586,16 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
634
586
|
this.arena.set_first_child(wrapper, first);
|
|
635
587
|
return wrapper;
|
|
636
588
|
}
|
|
637
|
-
/**
|
|
638
|
-
* Parse a condition function inside if() — style(), supports(), or media(). Content parsing
|
|
639
|
-
* is delegated to the shared ConditionParser (see parse-condition.ts), so these produce the
|
|
640
|
-
* same node shapes real `@supports`/`@media` conditions do:
|
|
641
|
-
* style()/supports() → SUPPORTS_DECLARATION(s) — supports() gets the full compound
|
|
642
|
-
* <supports-condition> grammar (and/or/not, nested conditions), same as `@supports`.
|
|
643
|
-
* media() → a single MEDIA_FEATURE or FEATURE_RANGE (comparison syntax), same as `@media`.
|
|
644
|
-
* anything else → generic value nodes, as before.
|
|
645
|
-
*
|
|
646
|
-
* Called with the current token at TOKEN_FUNCTION (the '(' already consumed).
|
|
647
|
-
* @param func_start Offset of the function name's first char.
|
|
648
|
-
* @param token_end Offset right after '(' (== lexer.token_end here).
|
|
649
|
-
*/
|
|
650
589
|
parse_if_condition_function(func_start, token_end) {
|
|
651
590
|
let func_name_end = token_end - 1;
|
|
652
|
-
let func_name = this.source.substring(func_start, func_name_end);
|
|
653
591
|
let func_line = this.lexer.token_line;
|
|
654
592
|
let func_col = this.lexer.token_column;
|
|
655
593
|
let content_start = token_end;
|
|
656
594
|
let content_end = content_start;
|
|
657
595
|
let func_end = content_start;
|
|
658
|
-
let
|
|
596
|
+
let matched = this.scan_matching_paren(true);
|
|
597
|
+
let scanned_content_end = this.paren_content_end;
|
|
598
|
+
let scanned_func_end = this.paren_close_end;
|
|
659
599
|
if (matched) {
|
|
660
600
|
content_end = scanned_content_end;
|
|
661
601
|
func_end = scanned_func_end;
|
|
@@ -666,20 +606,19 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
666
606
|
this.arena.set_value_start_delta(func_node, content_start - func_start);
|
|
667
607
|
this.arena.set_value_length(func_node, content_end - content_start);
|
|
668
608
|
let child_nodes = [];
|
|
669
|
-
if (
|
|
609
|
+
if (str_equals_range(this.source, func_start, func_name_end, "style")) {
|
|
670
610
|
let decl = this.condition_parser.parse_supports_declaration_content(content_start, content_end);
|
|
671
611
|
if (decl === null) child_nodes = this.condition_parser.parse_supports_condition(content_start, content_end, func_line, func_col);
|
|
672
612
|
else child_nodes = [decl];
|
|
673
|
-
} else if (
|
|
613
|
+
} else if (str_equals_range(this.source, func_start, func_name_end, "supports")) {
|
|
674
614
|
let decl = this.condition_parser.parse_supports_declaration_content(content_start, content_end);
|
|
675
615
|
if (decl === null) child_nodes = this.condition_parser.parse_supports_condition(content_start, content_end, func_line, func_col);
|
|
676
616
|
else child_nodes = [decl];
|
|
677
|
-
} else if (
|
|
617
|
+
} else if (str_equals_range(this.source, func_start, func_name_end, "media")) child_nodes = [this.condition_parser.parse_media_feature_content(content_start, content_end, content_start, content_end)];
|
|
678
618
|
else child_nodes = this.parse_value_nodes_in_range(content_start, content_end);
|
|
679
619
|
this.arena.append_children(func_node, child_nodes);
|
|
680
620
|
return func_node;
|
|
681
621
|
}
|
|
682
|
-
/** Parse value tokens in a source sub-range using save/restore to protect lexer state. */
|
|
683
622
|
parse_value_nodes_in_range(start, end) {
|
|
684
623
|
let saved_end = this.end;
|
|
685
624
|
let saved_pos = this.lexer.save_position();
|
package/dist/walk.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projectwallace/css-parser",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.9",
|
|
4
4
|
"description": "High-performance CSS lexer and parser, optimized for CSS inspection and analysis",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
|
@@ -77,22 +77,20 @@
|
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@projectwallace/preset-oxlint": "^0.0.11",
|
|
80
|
-
"@types/node": "^26.
|
|
81
|
-
"@vitest/coverage-v8": "^5.0.
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"tailwindcss": "^2.2.8",
|
|
91
|
-
"tinybench": "^6.0.2",
|
|
80
|
+
"@types/node": "^26.6.5",
|
|
81
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
82
|
+
"css-tree": "^3.2.1",
|
|
83
|
+
"knip": "^6.41.0",
|
|
84
|
+
"oxfmt": "^0.72.0",
|
|
85
|
+
"oxlint": "^1.87.0",
|
|
86
|
+
"pkg-pr-new": "^0.0.91",
|
|
87
|
+
"postcss": "^8.5.29",
|
|
88
|
+
"publint": "^0.3.25",
|
|
89
|
+
"tinybench": "^6.2.1",
|
|
92
90
|
"tsdown": "^0.23.0",
|
|
93
91
|
"typescript": "^7.0.2",
|
|
94
|
-
"vite": "^8.
|
|
95
|
-
"vitest": "^5.0.
|
|
92
|
+
"vite": "^8.3.4",
|
|
93
|
+
"vitest": "^5.0.3"
|
|
96
94
|
},
|
|
97
95
|
"engines": {
|
|
98
96
|
"pnpm": ">=11.0.0"
|