@projectwallace/css-parser 0.18.12 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -107
- package/dist/{arena-DvT75bvK.d.ts → arena-7RLvyGPB.d.ts} +0 -1
- package/dist/{arena-Bsf96CQK.js → arena-CsJhQRUX.js} +0 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/{css-node-yoUdFtNg.js → css-node-BJnbanUS.js} +5 -54
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/{node-types-CY0JK9_a.d.ts → node-types-BZGPDESt.d.ts} +13 -30
- package/dist/node-types.d.ts +1 -1
- package/dist/node-types.js +1 -1
- package/dist/parse-anplusb.d.ts +2 -10
- package/dist/parse-anplusb.js +9 -17
- package/dist/parse-atrule-prelude.d.ts +3 -2
- package/dist/parse-atrule-prelude.js +68 -33
- package/dist/parse-declaration.d.ts +2 -2
- package/dist/parse-declaration.js +14 -14
- package/dist/parse-dimension.js +1 -1
- package/dist/{parse-selector-CqIpnBrQ.js → parse-selector-B59fV-Ya.js} +14 -14
- package/dist/parse-selector.d.ts +2 -2
- package/dist/parse-selector.js +1 -1
- package/dist/parse-value.d.ts +2 -2
- package/dist/parse-value.js +3 -3
- package/dist/parse.d.ts +2 -2
- package/dist/parse.js +5 -5
- package/dist/{string-helpers-BMWJduts.d.ts → string-helpers-t7UofIfp.d.ts} +5 -7
- package/dist/string-helpers.d.ts +1 -1
- package/dist/string-helpers.js +1 -1
- package/dist/{string-utils-DiRRd28d.js → string-utils-aEEsA2CS.js} +18 -14
- package/dist/{tokenize-Ccg58Z_k.js → tokenize-B2QSzdrM.js} +10 -45
- package/dist/tokenize.d.ts +1 -33
- package/dist/tokenize.js +1 -1
- package/dist/{value-node-parser-BBwBxFR_.js → value-node-parser-BBlVw-en.js} +54 -21
- package/dist/walk.d.ts +1 -1
- package/dist/walk.js +2 -2
- package/package.json +1 -1
package/dist/parse.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-B2QSzdrM.js";
|
|
2
2
|
import "./token-types.js";
|
|
3
|
-
import { l as CSSDataArena } from "./arena-
|
|
4
|
-
import { t as CSSNode } from "./css-node-
|
|
5
|
-
import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward, t as SelectorParser } from "./parse-selector-
|
|
3
|
+
import { l as CSSDataArena } from "./arena-CsJhQRUX.js";
|
|
4
|
+
import { t as CSSNode } from "./css-node-BJnbanUS.js";
|
|
5
|
+
import { a as skip_whitespace_and_comments_backward, o as skip_whitespace_and_comments_forward, t as SelectorParser } from "./parse-selector-B59fV-Ya.js";
|
|
6
6
|
import { AtRulePreludeParser } from "./parse-atrule-prelude.js";
|
|
7
7
|
import { DeclarationParser } from "./parse-declaration.js";
|
|
8
8
|
//#region src/parse.ts
|
|
@@ -68,7 +68,7 @@ var Parser = class {
|
|
|
68
68
|
return this.source;
|
|
69
69
|
}
|
|
70
70
|
next_token() {
|
|
71
|
-
this.lexer.
|
|
71
|
+
this.lexer.next_token(true);
|
|
72
72
|
}
|
|
73
73
|
peek_type() {
|
|
74
74
|
return this.lexer.token_type;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
//#region src/string-utils.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* @param a Base string, MUST be lowercase!
|
|
4
|
-
* @param b Compare string
|
|
5
|
-
*/
|
|
2
|
+
/** Case-insensitive ASCII equality without allocations. `a` MUST be lowercase. */
|
|
6
3
|
declare function str_equals(a: string, b: string): boolean;
|
|
7
4
|
/** Case-insensitive ASCII prefix check without allocations. `prefix` MUST be lowercase. */
|
|
8
|
-
declare function str_starts_with(
|
|
9
|
-
/** Case-insensitive substring search without allocations, or -1 if not found. `
|
|
10
|
-
declare function str_index_of(
|
|
5
|
+
declare function str_starts_with(prefix: string, str: string): boolean;
|
|
6
|
+
/** Case-insensitive substring search without allocations, or -1 if not found. `search_char` MUST be lowercase. */
|
|
7
|
+
declare function str_index_of(search_char: string, str: string): number;
|
|
11
8
|
/** True if the string/range is vendor-prefixed (-webkit-, -moz-, -ms-, -o-). `--custom-property` is not. */
|
|
12
9
|
declare function is_vendor_prefixed(text: string): boolean;
|
|
13
10
|
declare function is_vendor_prefixed(source: string, start: number, end: number): boolean;
|
|
14
11
|
/** True if the string is a CSS custom property (starts with `--`). */
|
|
15
12
|
declare function is_custom(str: string): boolean;
|
|
13
|
+
/** Strip a vendor prefix, e.g. `-webkit-keyframes` → `keyframes`. Returns the input unchanged if it has no prefix. */
|
|
16
14
|
declare function strip_vendor_prefix(str: string): string;
|
|
17
15
|
//#endregion
|
|
18
16
|
export { str_starts_with as a, str_index_of as i, is_vendor_prefixed as n, strip_vendor_prefix as o, str_equals as r, is_custom as t };
|
package/dist/string-helpers.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as str_starts_with, i as str_index_of, n as is_vendor_prefixed, o as strip_vendor_prefix, r as str_equals, t as is_custom } from "./string-helpers-
|
|
1
|
+
import { a as str_starts_with, i as str_index_of, n as is_vendor_prefixed, o as strip_vendor_prefix, r as str_equals, t as is_custom } from "./string-helpers-t7UofIfp.js";
|
|
2
2
|
export { is_custom, is_vendor_prefixed, str_equals, str_index_of, str_starts_with, strip_vendor_prefix };
|
package/dist/string-helpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { r as is_custom, a as is_vendor_prefixed, s as str_equals, l as str_index_of, u as str_starts_with, d as strip_vendor_prefix } from "./string-utils-
|
|
1
|
+
export { r as is_custom, a as is_vendor_prefixed, s as str_equals, l as str_index_of, u as str_starts_with, d as strip_vendor_prefix } from "./string-utils-aEEsA2CS.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** True if the character code is whitespace (space, tab, newline, CR, or FF). */
|
|
1
2
|
function is_whitespace(ch) {
|
|
2
3
|
return ch === 32 || ch === 9 || ch === 10 || ch === 13 || ch === 12;
|
|
3
4
|
}
|
|
@@ -8,10 +9,7 @@ function is_combinator(ch) {
|
|
|
8
9
|
function is_digit(ch) {
|
|
9
10
|
return ch >= 48 && ch <= 57;
|
|
10
11
|
}
|
|
11
|
-
/**
|
|
12
|
-
* @param a Base string, MUST be lowercase!
|
|
13
|
-
* @param b Compare string
|
|
14
|
-
*/
|
|
12
|
+
/** Case-insensitive ASCII equality without allocations. `a` MUST be lowercase. */
|
|
15
13
|
function str_equals(a, b) {
|
|
16
14
|
if (a.length !== b.length) return false;
|
|
17
15
|
for (let i = 0; i < a.length; i++) {
|
|
@@ -22,6 +20,10 @@ function str_equals(a, b) {
|
|
|
22
20
|
}
|
|
23
21
|
return true;
|
|
24
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Case-insensitive equality between `source[start, end)` and `literal`, without allocating a substring first.
|
|
25
|
+
* Same semantics as `str_equals(literal, source.substring(start, end))`. `literal` MUST be lowercase.
|
|
26
|
+
*/
|
|
25
27
|
function str_equals_range(source, start, end, literal) {
|
|
26
28
|
if (end - start !== literal.length) return false;
|
|
27
29
|
for (let i = 0; i < literal.length; i++) {
|
|
@@ -31,13 +33,14 @@ function str_equals_range(source, start, end, literal) {
|
|
|
31
33
|
}
|
|
32
34
|
return true;
|
|
33
35
|
}
|
|
36
|
+
/** True if `source[start, end)` is and/or/not (case-insensitive). */
|
|
34
37
|
function is_and_or_not_range(source, start, end) {
|
|
35
38
|
const length = end - start;
|
|
36
39
|
if (length === 3) return str_equals_range(source, start, end, "and") || str_equals_range(source, start, end, "not");
|
|
37
40
|
return length === 2 && str_equals_range(source, start, end, "or");
|
|
38
41
|
}
|
|
39
42
|
/** Case-insensitive ASCII prefix check without allocations. `prefix` MUST be lowercase. */
|
|
40
|
-
function str_starts_with(
|
|
43
|
+
function str_starts_with(prefix, str) {
|
|
41
44
|
if (str.length < prefix.length) return false;
|
|
42
45
|
for (let i = 0; i < prefix.length; i++) {
|
|
43
46
|
let ca = str.charCodeAt(i);
|
|
@@ -47,23 +50,23 @@ function str_starts_with(str, prefix) {
|
|
|
47
50
|
}
|
|
48
51
|
return true;
|
|
49
52
|
}
|
|
50
|
-
/** Case-insensitive substring search without allocations, or -1 if not found. `
|
|
51
|
-
function str_index_of(
|
|
52
|
-
if (
|
|
53
|
-
if (
|
|
54
|
-
const
|
|
53
|
+
/** Case-insensitive substring search without allocations, or -1 if not found. `search_char` MUST be lowercase. */
|
|
54
|
+
function str_index_of(search_char, str) {
|
|
55
|
+
if (search_char.length === 0) return -1;
|
|
56
|
+
if (search_char.length === 1) {
|
|
57
|
+
const search_code = search_char.charCodeAt(0);
|
|
55
58
|
for (let i = 0; i < str.length; i++) {
|
|
56
59
|
let ca = str.charCodeAt(i);
|
|
57
60
|
if (ca >= 65 && ca <= 90) ca |= 32;
|
|
58
|
-
if (ca ===
|
|
61
|
+
if (ca === search_code) return i;
|
|
59
62
|
}
|
|
60
63
|
return -1;
|
|
61
64
|
}
|
|
62
|
-
for (let i = 0; i <= str.length -
|
|
65
|
+
for (let i = 0; i <= str.length - search_char.length; i++) {
|
|
63
66
|
let match = true;
|
|
64
|
-
for (let j = 0; j <
|
|
67
|
+
for (let j = 0; j < search_char.length; j++) {
|
|
65
68
|
let ca = str.charCodeAt(i + j);
|
|
66
|
-
const cb =
|
|
69
|
+
const cb = search_char.charCodeAt(j);
|
|
67
70
|
if (ca >= 65 && ca <= 90) ca |= 32;
|
|
68
71
|
if (ca !== cb) {
|
|
69
72
|
match = false;
|
|
@@ -90,6 +93,7 @@ function is_custom(str) {
|
|
|
90
93
|
if (str.length < 3) return false;
|
|
91
94
|
return str.charCodeAt(0) === 45 && str.charCodeAt(1) === 45;
|
|
92
95
|
}
|
|
96
|
+
/** Strip a vendor prefix, e.g. `-webkit-keyframes` → `keyframes`. Returns the input unchanged if it has no prefix. */
|
|
93
97
|
function strip_vendor_prefix(str) {
|
|
94
98
|
if (!is_vendor_prefixed(str)) return str;
|
|
95
99
|
for (let i = 2; i < str.length; i++) if (str.charCodeAt(i) === 45) return str.substring(i + 1);
|
|
@@ -111,7 +111,7 @@ var Lexer = class {
|
|
|
111
111
|
this._line = line;
|
|
112
112
|
this._line_offset = pos - column + 1;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
next_token(skip_whitespace = false) {
|
|
115
115
|
const source = this.source;
|
|
116
116
|
const source_length = source.length;
|
|
117
117
|
while (true) {
|
|
@@ -257,18 +257,6 @@ var Lexer = class {
|
|
|
257
257
|
column: comment_column
|
|
258
258
|
});
|
|
259
259
|
}
|
|
260
|
-
/**
|
|
261
|
-
* Fast-forward to the next `target` char that isn't inside a string or comment, without
|
|
262
|
-
* fully tokenizing what's in between — used by callers that only need to know *where a
|
|
263
|
-
* construct ends* (e.g. a selector's `{`), since the sub-parser for that construct
|
|
264
|
-
* re-tokenizes the span properly afterward.
|
|
265
|
-
*
|
|
266
|
-
* Strings go through consume_string and comments through _skip_comment, so escapes and
|
|
267
|
-
* on_comment callbacks behave identically to real tokenization. Ordinary characters cost
|
|
268
|
-
* one SKIP_SCAN_INTERESTING lookup each, same as consume_ident_or_function's inner loop.
|
|
269
|
-
*
|
|
270
|
-
* Returns true with this.pos at target, or false with this.pos at source_length.
|
|
271
|
-
*/
|
|
272
260
|
skip_to_unquoted(target) {
|
|
273
261
|
const source = this.source;
|
|
274
262
|
const source_length = source.length;
|
|
@@ -305,13 +293,6 @@ var Lexer = class {
|
|
|
305
293
|
this.pos = pos;
|
|
306
294
|
return false;
|
|
307
295
|
}
|
|
308
|
-
/**
|
|
309
|
-
* Same approach as skip_to_unquoted, but stops at any of `; { } ( ) !` — the stop
|
|
310
|
-
* characters parse-declaration.ts's value scan needs (paren depth, statement end,
|
|
311
|
-
* !important). The caller decides what each one means; this only locates the next one.
|
|
312
|
-
*
|
|
313
|
-
* Returns the stop character's code (this.pos left at it), or 0 at `end` if none found.
|
|
314
|
-
*/
|
|
315
296
|
skip_to_declaration_stop(end) {
|
|
316
297
|
const source = this.source;
|
|
317
298
|
let pos = this.pos;
|
|
@@ -619,20 +600,6 @@ var Lexer = class {
|
|
|
619
600
|
this.token_column = column;
|
|
620
601
|
return type;
|
|
621
602
|
}
|
|
622
|
-
next_token(skip_whitespace = false) {
|
|
623
|
-
this.next_token_fast(skip_whitespace);
|
|
624
|
-
return {
|
|
625
|
-
type: this.token_type,
|
|
626
|
-
start: this.token_start,
|
|
627
|
-
end: this.token_end,
|
|
628
|
-
line: this.token_line,
|
|
629
|
-
column: this.token_column
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Save complete lexer state for backtracking
|
|
634
|
-
* @returns Object containing all lexer state
|
|
635
|
-
*/
|
|
636
603
|
save_position() {
|
|
637
604
|
return {
|
|
638
605
|
pos: this.pos,
|
|
@@ -658,10 +625,6 @@ var Lexer = class {
|
|
|
658
625
|
target.token_column = this.token_column;
|
|
659
626
|
return target;
|
|
660
627
|
}
|
|
661
|
-
/**
|
|
662
|
-
* Restore lexer state from saved position
|
|
663
|
-
* @param saved The saved position to restore
|
|
664
|
-
*/
|
|
665
628
|
restore_position(saved) {
|
|
666
629
|
this.pos = saved.pos;
|
|
667
630
|
this._line = saved.line;
|
|
@@ -672,10 +635,6 @@ var Lexer = class {
|
|
|
672
635
|
this.token_line = saved.token_line;
|
|
673
636
|
this.token_column = saved.token_column;
|
|
674
637
|
}
|
|
675
|
-
/**
|
|
676
|
-
* Skip whitespace and comments within a range, maintaining line/column tracking
|
|
677
|
-
* @param end The end boundary (exclusive)
|
|
678
|
-
*/
|
|
679
638
|
skip_whitespace_in_range(end) {
|
|
680
639
|
while (this.pos < end) {
|
|
681
640
|
const ch = this.source.charCodeAt(this.pos);
|
|
@@ -700,9 +659,15 @@ var Lexer = class {
|
|
|
700
659
|
function* tokenize(source, on_comment) {
|
|
701
660
|
const lexer = new Lexer(source, on_comment);
|
|
702
661
|
while (true) {
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
705
|
-
yield
|
|
662
|
+
const type = lexer.next_token();
|
|
663
|
+
if (type === 26) break;
|
|
664
|
+
yield {
|
|
665
|
+
type,
|
|
666
|
+
start: lexer.token_start,
|
|
667
|
+
end: lexer.token_end,
|
|
668
|
+
line: lexer.token_line,
|
|
669
|
+
column: lexer.token_column
|
|
670
|
+
};
|
|
706
671
|
}
|
|
707
672
|
}
|
|
708
673
|
//#endregion
|
package/dist/tokenize.d.ts
CHANGED
|
@@ -34,29 +34,10 @@ export declare class Lexer {
|
|
|
34
34
|
get line(): number;
|
|
35
35
|
get column(): number;
|
|
36
36
|
seek(pos: number, line: number, column?: number): void;
|
|
37
|
-
|
|
37
|
+
next_token(skip_whitespace?: boolean): TokenType;
|
|
38
38
|
private _scan_newlines;
|
|
39
39
|
private _skip_comment;
|
|
40
|
-
/**
|
|
41
|
-
* Fast-forward to the next `target` char that isn't inside a string or comment, without
|
|
42
|
-
* fully tokenizing what's in between — used by callers that only need to know *where a
|
|
43
|
-
* construct ends* (e.g. a selector's `{`), since the sub-parser for that construct
|
|
44
|
-
* re-tokenizes the span properly afterward.
|
|
45
|
-
*
|
|
46
|
-
* Strings go through consume_string and comments through _skip_comment, so escapes and
|
|
47
|
-
* on_comment callbacks behave identically to real tokenization. Ordinary characters cost
|
|
48
|
-
* one SKIP_SCAN_INTERESTING lookup each, same as consume_ident_or_function's inner loop.
|
|
49
|
-
*
|
|
50
|
-
* Returns true with this.pos at target, or false with this.pos at source_length.
|
|
51
|
-
*/
|
|
52
40
|
skip_to_unquoted(target: number): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Same approach as skip_to_unquoted, but stops at any of `; { } ( ) !` — the stop
|
|
55
|
-
* characters parse-declaration.ts's value scan needs (paren depth, statement end,
|
|
56
|
-
* !important). The caller decides what each one means; this only locates the next one.
|
|
57
|
-
*
|
|
58
|
-
* Returns the stop character's code (this.pos left at it), or 0 at `end` if none found.
|
|
59
|
-
*/
|
|
60
41
|
skip_to_declaration_stop(end: number): number;
|
|
61
42
|
consume_whitespace(start_line: number, start_column: number): TokenType;
|
|
62
43
|
consume_string(quote: number, start_line: number, start_column: number): TokenType;
|
|
@@ -69,22 +50,9 @@ export declare class Lexer {
|
|
|
69
50
|
advance(count?: number): void;
|
|
70
51
|
peek(offset?: number): number;
|
|
71
52
|
make_token(type: TokenType, start: number, end: number, line?: number, column?: number): TokenType;
|
|
72
|
-
next_token(skip_whitespace?: boolean): Token | null;
|
|
73
|
-
/**
|
|
74
|
-
* Save complete lexer state for backtracking
|
|
75
|
-
* @returns Object containing all lexer state
|
|
76
|
-
*/
|
|
77
53
|
save_position(): LexerPosition;
|
|
78
54
|
save_position_into(target: LexerPosition): LexerPosition;
|
|
79
|
-
/**
|
|
80
|
-
* Restore lexer state from saved position
|
|
81
|
-
* @param saved The saved position to restore
|
|
82
|
-
*/
|
|
83
55
|
restore_position(saved: LexerPosition): void;
|
|
84
|
-
/**
|
|
85
|
-
* Skip whitespace and comments within a range, maintaining line/column tracking
|
|
86
|
-
* @param end The end boundary (exclusive)
|
|
87
|
-
*/
|
|
88
56
|
skip_whitespace_in_range(end: number): void;
|
|
89
57
|
}
|
|
90
58
|
/**
|
package/dist/tokenize.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as Lexer, n as tokenize } from "./tokenize-
|
|
1
|
+
export { t as Lexer, n as tokenize } from "./tokenize-B2QSzdrM.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as Lexer } from "./tokenize-
|
|
1
|
+
import { t as Lexer } from "./tokenize-B2QSzdrM.js";
|
|
2
2
|
import "./token-types.js";
|
|
3
|
-
import "./arena-
|
|
4
|
-
import { c as str_equals_range, t as is_and_or_not_range } from "./string-utils-
|
|
5
|
-
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 "./arena-CsJhQRUX.js";
|
|
4
|
+
import { c as str_equals_range, t as is_and_or_not_range } from "./string-utils-aEEsA2CS.js";
|
|
5
|
+
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-B59fV-Ya.js";
|
|
6
6
|
//#region src/parse-condition.ts
|
|
7
7
|
var ConditionParser = class {
|
|
8
8
|
lexer;
|
|
@@ -29,19 +29,32 @@ var ConditionParser = class {
|
|
|
29
29
|
this.lexer.token_type = 26;
|
|
30
30
|
return 26;
|
|
31
31
|
}
|
|
32
|
-
return this.lexer.
|
|
32
|
+
return this.lexer.next_token(false);
|
|
33
33
|
}
|
|
34
34
|
paren_content_end = 0;
|
|
35
35
|
paren_close_end = 0;
|
|
36
|
+
unmatched_opens = null;
|
|
37
|
+
unmatched_opens_end = 0;
|
|
36
38
|
scan_matching_paren() {
|
|
37
39
|
let depth = 1;
|
|
38
40
|
let content_end = this.lexer.pos;
|
|
39
41
|
let close_end = this.lexer.token_end;
|
|
42
|
+
if (this.unmatched_opens !== null && this.unmatched_opens_end === this.end) {
|
|
43
|
+
if (this.unmatched_opens.has(this.lexer.token_start)) {
|
|
44
|
+
this.paren_content_end = content_end;
|
|
45
|
+
this.paren_close_end = close_end;
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const open_stack = [this.lexer.token_start];
|
|
40
50
|
while (this.lexer.pos < this.end && depth > 0) {
|
|
41
51
|
const token_type = this.next_token();
|
|
42
|
-
if (token_type === 21 || token_type === 2)
|
|
43
|
-
|
|
52
|
+
if (token_type === 21 || token_type === 2) {
|
|
53
|
+
depth++;
|
|
54
|
+
open_stack.push(this.lexer.token_start);
|
|
55
|
+
} else if (token_type === 22) {
|
|
44
56
|
depth--;
|
|
57
|
+
open_stack.pop();
|
|
45
58
|
if (depth === 0) {
|
|
46
59
|
content_end = this.lexer.token_start;
|
|
47
60
|
close_end = this.lexer.token_end;
|
|
@@ -50,7 +63,15 @@ var ConditionParser = class {
|
|
|
50
63
|
}
|
|
51
64
|
this.paren_content_end = content_end;
|
|
52
65
|
this.paren_close_end = close_end;
|
|
53
|
-
|
|
66
|
+
if (depth !== 0) {
|
|
67
|
+
if (this.unmatched_opens === null || this.unmatched_opens_end !== this.end) {
|
|
68
|
+
this.unmatched_opens = /* @__PURE__ */ new Set();
|
|
69
|
+
this.unmatched_opens_end = this.end;
|
|
70
|
+
}
|
|
71
|
+
for (const pos of open_stack) this.unmatched_opens.add(pos);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
54
75
|
}
|
|
55
76
|
parse_feature_value(start, end) {
|
|
56
77
|
return this.value_node_parser.parse_chain(start, end, this.lexer.line, this.lexer.column);
|
|
@@ -209,6 +230,8 @@ var ConditionParser = class {
|
|
|
209
230
|
const func_name_start = this.lexer.token_start;
|
|
210
231
|
const func_name_end = this.lexer.token_end - 1;
|
|
211
232
|
const content_start = this.lexer.token_end;
|
|
233
|
+
const content_line = this.lexer.line;
|
|
234
|
+
const content_column = this.lexer.column;
|
|
212
235
|
this.scan_matching_paren();
|
|
213
236
|
const content_end = this.paren_content_end;
|
|
214
237
|
const func_end = this.paren_close_end;
|
|
@@ -222,7 +245,8 @@ var ConditionParser = class {
|
|
|
222
245
|
if (selector_list !== null) this.arena.set_first_child(func_node, selector_list);
|
|
223
246
|
} else if (str_equals_range(this.source, func_name_start, func_name_end, "style")) {
|
|
224
247
|
const decl_child = this.parse_supports_declaration_content(content_start, content_end);
|
|
225
|
-
if (decl_child
|
|
248
|
+
if (decl_child === null) this.append_nested_condition(func_node, content_start, content_end, content_line, content_column);
|
|
249
|
+
else this.arena.set_first_child(func_node, decl_child);
|
|
226
250
|
}
|
|
227
251
|
return func_node;
|
|
228
252
|
}
|
|
@@ -231,6 +255,12 @@ var ConditionParser = class {
|
|
|
231
255
|
if (colon_pos === -1) return null;
|
|
232
256
|
return this.create_supports_declaration(content_start, content_end, colon_pos);
|
|
233
257
|
}
|
|
258
|
+
append_nested_condition(parent, start, end, line, column) {
|
|
259
|
+
const saved = this.lexer.save_position();
|
|
260
|
+
const children = this.parse_supports_condition(start, end, line, column);
|
|
261
|
+
this.lexer.restore_position(saved);
|
|
262
|
+
this.arena.append_children(parent, children);
|
|
263
|
+
}
|
|
234
264
|
parse_supports_condition(start, end, line, column) {
|
|
235
265
|
const saved_end = this.end;
|
|
236
266
|
this.end = end;
|
|
@@ -244,6 +274,8 @@ var ConditionParser = class {
|
|
|
244
274
|
if (token_type === 21) {
|
|
245
275
|
const feature_start = this.lexer.token_start;
|
|
246
276
|
const content_start = this.lexer.pos;
|
|
277
|
+
const content_line = this.lexer.line;
|
|
278
|
+
const content_column = this.lexer.column;
|
|
247
279
|
const matched = this.scan_matching_paren();
|
|
248
280
|
const content_end = this.paren_content_end;
|
|
249
281
|
const feature_end = this.paren_close_end;
|
|
@@ -254,7 +286,8 @@ var ConditionParser = class {
|
|
|
254
286
|
this.arena.set_value_start_delta(query, trimmed[0] - feature_start);
|
|
255
287
|
this.arena.set_value_length(query, trimmed[1] - trimmed[0]);
|
|
256
288
|
const decl_child = this.parse_supports_declaration_content(trimmed[0], trimmed[1]);
|
|
257
|
-
if (decl_child
|
|
289
|
+
if (decl_child === null) this.append_nested_condition(query, content_start, content_end, content_line, content_column);
|
|
290
|
+
else this.arena.set_first_child(query, decl_child);
|
|
258
291
|
}
|
|
259
292
|
nodes.push(query);
|
|
260
293
|
}
|
|
@@ -295,7 +328,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
295
328
|
let first_node = 0;
|
|
296
329
|
let last_node = 0;
|
|
297
330
|
while (this.lexer.pos < this.end) {
|
|
298
|
-
this.lexer.
|
|
331
|
+
this.lexer.next_token(true);
|
|
299
332
|
if (this.lexer.token_start >= this.end) break;
|
|
300
333
|
if (this.lexer.token_type === 26) break;
|
|
301
334
|
const node = this.parse_value_node();
|
|
@@ -346,7 +379,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
346
379
|
let content_end = this.lexer.pos;
|
|
347
380
|
let close_end = this.lexer.token_end;
|
|
348
381
|
while ((!bounded || this.lexer.pos < this.end) && depth > 0) {
|
|
349
|
-
this.lexer.
|
|
382
|
+
this.lexer.next_token(false);
|
|
350
383
|
const token_type = this.lexer.token_type;
|
|
351
384
|
if (token_type === 26) break;
|
|
352
385
|
if (bounded && this.lexer.token_start >= this.end) break;
|
|
@@ -372,8 +405,8 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
372
405
|
this.arena.set_content_length(node, name_end - start);
|
|
373
406
|
if (is_url || str_equals_range(this.source, start, name_end, "src")) {
|
|
374
407
|
const save_pos = this.lexer.save_position();
|
|
375
|
-
this.lexer.
|
|
376
|
-
while (this.lexer.token_type === 13 && this.lexer.pos < this.end) this.lexer.
|
|
408
|
+
this.lexer.next_token(false);
|
|
409
|
+
while (this.lexer.token_type === 13 && this.lexer.pos < this.end) this.lexer.next_token(false);
|
|
377
410
|
const first_token_type = this.lexer.token_type;
|
|
378
411
|
this.lexer.restore_position(save_pos);
|
|
379
412
|
if (first_token_type === 5) {} else {
|
|
@@ -400,7 +433,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
400
433
|
const content_start = end;
|
|
401
434
|
let content_end = end;
|
|
402
435
|
while (this.lexer.pos < this.end && paren_depth > 0) {
|
|
403
|
-
this.lexer.
|
|
436
|
+
this.lexer.next_token(true);
|
|
404
437
|
const token_type = this.lexer.token_type;
|
|
405
438
|
if (token_type === 26) break;
|
|
406
439
|
if (this.lexer.token_start >= this.end) break;
|
|
@@ -438,7 +471,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
438
471
|
let content_end = end;
|
|
439
472
|
let if_closed = false;
|
|
440
473
|
while (this.lexer.pos < this.end && !if_closed) {
|
|
441
|
-
this.lexer.
|
|
474
|
+
this.lexer.next_token(false);
|
|
442
475
|
const tt = this.lexer.token_type;
|
|
443
476
|
if (tt === 26) break;
|
|
444
477
|
if (this.lexer.token_start >= this.end) break;
|
|
@@ -456,7 +489,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
456
489
|
const condition_end_pos = this.arena.get_start_offset(condition_node) + this.arena.get_length(condition_node);
|
|
457
490
|
let colon_found = false;
|
|
458
491
|
while (this.lexer.pos < this.end) {
|
|
459
|
-
this.lexer.
|
|
492
|
+
this.lexer.next_token(false);
|
|
460
493
|
const t = this.lexer.token_type;
|
|
461
494
|
if (t === 26) break;
|
|
462
495
|
if (this.lexer.token_start >= this.end) break;
|
|
@@ -478,7 +511,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
478
511
|
let value_line = 0;
|
|
479
512
|
let value_col = 0;
|
|
480
513
|
if (colon_found && !if_closed) while (this.lexer.pos < this.end) {
|
|
481
|
-
this.lexer.
|
|
514
|
+
this.lexer.next_token(false);
|
|
482
515
|
const t = this.lexer.token_type;
|
|
483
516
|
if (t === 26) break;
|
|
484
517
|
if (this.lexer.token_start >= this.end) break;
|
|
@@ -528,7 +561,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
528
561
|
}
|
|
529
562
|
next_significant_token() {
|
|
530
563
|
while (this.lexer.pos < this.end) {
|
|
531
|
-
this.lexer.
|
|
564
|
+
this.lexer.next_token(false);
|
|
532
565
|
if (this.lexer.token_start >= this.end) return 26;
|
|
533
566
|
if (this.lexer.token_type === 13) continue;
|
|
534
567
|
return this.lexer.token_type;
|
|
@@ -627,7 +660,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
627
660
|
this.lexer.seek(start, this.lexer.line, this.lexer.column);
|
|
628
661
|
const nodes = [];
|
|
629
662
|
while (this.lexer.pos < this.end) {
|
|
630
|
-
this.lexer.
|
|
663
|
+
this.lexer.next_token(true);
|
|
631
664
|
if (this.lexer.token_start >= this.end) break;
|
|
632
665
|
if (this.lexer.token_type === 26) break;
|
|
633
666
|
const node = this.parse_value_node();
|
|
@@ -644,7 +677,7 @@ var ValueNodeParser = class ValueNodeParser {
|
|
|
644
677
|
let paren_depth = 1;
|
|
645
678
|
let paren_end = end;
|
|
646
679
|
while (this.lexer.pos < this.end && paren_depth > 0) {
|
|
647
|
-
this.lexer.
|
|
680
|
+
this.lexer.next_token(true);
|
|
648
681
|
const token_type = this.lexer.token_type;
|
|
649
682
|
if (token_type === 26) break;
|
|
650
683
|
if (this.lexer.token_start >= this.end) break;
|
package/dist/walk.d.ts
CHANGED
package/dist/walk.js
CHANGED