webpack 5.108.3 → 5.108.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Compilation.js +1 -4
- package/lib/FlagDependencyExportsPlugin.js +55 -8
- package/lib/LazyBarrel.js +30 -3
- package/lib/NormalModule.js +8 -12
- package/lib/config/defaults.js +3 -3
- package/lib/css/CssGenerator.js +33 -42
- package/lib/css/CssModulesPlugin.js +79 -53
- package/lib/css/CssParser.js +306 -96
- package/lib/css/syntax.js +451 -128
- package/lib/dependencies/CssIcssExportDependency.js +28 -16
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +23 -96
- package/lib/dependencies/HarmonyImportGuard.js +192 -20
- package/lib/dependencies/ImportParserPlugin.js +7 -9
- package/lib/html/HtmlGenerator.js +53 -76
- package/lib/html/HtmlModule.js +1 -0
- package/lib/html/HtmlModulesPlugin.js +24 -13
- package/lib/html/HtmlParser.js +240 -124
- package/lib/html/syntax.js +1362 -683
- package/lib/javascript/JavascriptParser.js +10 -0
- package/lib/url/URLParserPlugin.js +33 -7
- package/lib/util/LocConverter.js +9 -8
- package/lib/util/SourceProcessor.js +41 -28
- package/package.json +3 -3
- package/types.d.ts +79 -221
package/lib/css/syntax.js
CHANGED
|
@@ -297,6 +297,15 @@ const _isSpace = (cc) => cc === CC_SPACE || cc === CC_TAB;
|
|
|
297
297
|
// rarer tab / newline tests.
|
|
298
298
|
const _isWhiteSpace = (cc) => _isSpace(cc) || _isNewline(cc);
|
|
299
299
|
|
|
300
|
+
// Whitespace membership table for the run-consumption loop — one load instead
|
|
301
|
+
// of up to five compares per char. EOF (NaN) / non-ASCII index to undefined.
|
|
302
|
+
const _wsTable = new Uint8Array(128);
|
|
303
|
+
_wsTable[CC_SPACE] = 1;
|
|
304
|
+
_wsTable[CC_TAB] = 1;
|
|
305
|
+
_wsTable[CC_LINE_FEED] = 1;
|
|
306
|
+
_wsTable[CC_CARRIAGE_RETURN] = 1;
|
|
307
|
+
_wsTable[CC_FORM_FEED] = 1;
|
|
308
|
+
|
|
300
309
|
/**
|
|
301
310
|
* @param {number} cc char code
|
|
302
311
|
* @returns {boolean} true, if cc is a digit
|
|
@@ -612,7 +621,7 @@ const fill = (out, type, start, end) => {
|
|
|
612
621
|
*/
|
|
613
622
|
function consumeSpace(input, pos, out) {
|
|
614
623
|
const start = pos - 1;
|
|
615
|
-
while (
|
|
624
|
+
while (_wsTable[input.charCodeAt(pos)] === 1) pos++;
|
|
616
625
|
return fill(out, TT_WHITESPACE, start, pos);
|
|
617
626
|
}
|
|
618
627
|
|
|
@@ -1166,7 +1175,10 @@ const NodeType = {
|
|
|
1166
1175
|
Declaration: 23,
|
|
1167
1176
|
AtRule: 24,
|
|
1168
1177
|
QualifiedRule: 25,
|
|
1169
|
-
Stylesheet: 26
|
|
1178
|
+
Stylesheet: 26,
|
|
1179
|
+
// Comments are never tree nodes; this type exists only so a `NodeType.Comment`
|
|
1180
|
+
// visitor can be registered (fired during tokenization — see `grammar`).
|
|
1181
|
+
Comment: 27
|
|
1170
1182
|
};
|
|
1171
1183
|
const {
|
|
1172
1184
|
Ident: T_IDENT,
|
|
@@ -1194,7 +1206,8 @@ const {
|
|
|
1194
1206
|
Declaration: T_DECLARATION,
|
|
1195
1207
|
AtRule: T_AT_RULE,
|
|
1196
1208
|
QualifiedRule: T_QUALIFIED_RULE,
|
|
1197
|
-
Stylesheet: T_STYLESHEET
|
|
1209
|
+
Stylesheet: T_STYLESHEET,
|
|
1210
|
+
Comment: T_COMMENT
|
|
1198
1211
|
} = NodeType;
|
|
1199
1212
|
|
|
1200
1213
|
/**
|
|
@@ -1594,6 +1607,23 @@ _ttToNodeType[TT_CDC] = T_CDC;
|
|
|
1594
1607
|
// Current loc converter for the active parse (object backend reads it).
|
|
1595
1608
|
let _lc = /** @type {LocConverter} */ (/** @type {unknown} */ (null));
|
|
1596
1609
|
|
|
1610
|
+
// Active skip state (from `CssProcessOptions.skip`), applied by the grammar.
|
|
1611
|
+
// `_skipTypes` is indexed by `NodeType` (1 = skip): drop that component-value
|
|
1612
|
+
// leaf / container from declaration value and function-arg lists. The two
|
|
1613
|
+
// prelude flags scan a rule's prelude without materializing its tree (url tokens
|
|
1614
|
+
// / functions kept, so `url()` in a selector or `@import url(…)` still resolves).
|
|
1615
|
+
// A skipped node is still tokenized (positions stay correct) but never pushed,
|
|
1616
|
+
// so it is never walked or read — the caller must only skip what nothing reads.
|
|
1617
|
+
// `useObjectBackend` restores the defaults so `parseA*` build the full tree.
|
|
1618
|
+
const _NO_SKIP_TYPES = new Uint8Array(32);
|
|
1619
|
+
/** @type {Uint8Array} */
|
|
1620
|
+
let _skipTypes = _NO_SKIP_TYPES;
|
|
1621
|
+
// Fast-path flag: true only when a real skip set is active, so the (dominant)
|
|
1622
|
+
// no-skip parses pay one boolean test instead of a node-type lookup per value.
|
|
1623
|
+
let _skipActive = false;
|
|
1624
|
+
let _skipSelectorPrelude = false;
|
|
1625
|
+
let _skipAtRulePrelude = false;
|
|
1626
|
+
|
|
1597
1627
|
/** @type {(type: number, start: number, end: number) => Node} */
|
|
1598
1628
|
let _mkLeaf;
|
|
1599
1629
|
/** @type {(start: number, end: number, contentStart: number, contentEnd: number) => Node} */
|
|
@@ -1656,6 +1686,11 @@ const _objStylesheet = (start) => {
|
|
|
1656
1686
|
/** @param {LocConverter} lc loc converter for this parse */
|
|
1657
1687
|
const useObjectBackend = (lc) => {
|
|
1658
1688
|
_lc = lc;
|
|
1689
|
+
// `parseA*` return the full tree, so nothing is skipped.
|
|
1690
|
+
_skipTypes = _NO_SKIP_TYPES;
|
|
1691
|
+
_skipActive = false;
|
|
1692
|
+
_skipSelectorPrelude = false;
|
|
1693
|
+
_skipAtRulePrelude = false;
|
|
1659
1694
|
_mkLeaf = _objLeaf;
|
|
1660
1695
|
_mkUrl = _objUrl;
|
|
1661
1696
|
_mkContainer = _objContainer;
|
|
@@ -1773,18 +1808,26 @@ const _soaGrow = (need) => {
|
|
|
1773
1808
|
const _soaAlloc = (type, start, end) => {
|
|
1774
1809
|
// Ids are 1-based: a node ref is used in truthiness checks (`if (!parent)`),
|
|
1775
1810
|
// so 0 must stay reserved for "no node".
|
|
1811
|
+
// Leaves never read the flag / list slots — `_soaAllocContainer` clears
|
|
1812
|
+
// them instead, keeping the dominant leaf allocation at three writes.
|
|
1776
1813
|
const i = _soaN + 1;
|
|
1777
1814
|
if (i >= _soaCap) _soaGrow(i + 1);
|
|
1778
1815
|
_soaTy[i] = type;
|
|
1779
1816
|
_soaSt[i] = start;
|
|
1780
1817
|
_soaEn[i] = end;
|
|
1818
|
+
_soaN = i;
|
|
1819
|
+
return _ref(i);
|
|
1820
|
+
};
|
|
1821
|
+
/** @type {(type: number, start: number, end: number) => Node} */
|
|
1822
|
+
const _soaAllocContainer = (type, start, end) => {
|
|
1823
|
+
const r = _soaAlloc(type, start, end);
|
|
1824
|
+
const i = _ix(r);
|
|
1781
1825
|
_soaFl[i] = 0;
|
|
1782
1826
|
// Clear list slots so a reused id never exposes a previous node's children.
|
|
1783
1827
|
_soaL0[i] = null;
|
|
1784
1828
|
_soaL1[i] = null;
|
|
1785
1829
|
_soaL2[i] = null;
|
|
1786
|
-
|
|
1787
|
-
return _ref(i);
|
|
1830
|
+
return r;
|
|
1788
1831
|
};
|
|
1789
1832
|
// Raw token value (the lazy `Token.value` form): hash / at-keyword drop their
|
|
1790
1833
|
// one-char prefix, url uses its content range. Shared by the parser's
|
|
@@ -1816,8 +1859,8 @@ const useSoaBackend = (input, lc) => {
|
|
|
1816
1859
|
_soaA1[_ix(r)] = ce;
|
|
1817
1860
|
return r;
|
|
1818
1861
|
};
|
|
1819
|
-
_mkContainer = (type, start, end) =>
|
|
1820
|
-
_mkStylesheet = (start) =>
|
|
1862
|
+
_mkContainer = (type, start, end) => _soaAllocContainer(type, start, end);
|
|
1863
|
+
_mkStylesheet = (start) => _soaAllocContainer(T_STYLESHEET, start, start);
|
|
1821
1864
|
// name / nameStart are derived from start + nameEnd; only nameEnd is stored.
|
|
1822
1865
|
_setName = (r, v, ns, ne) => {
|
|
1823
1866
|
_soaA0[_ix(r)] = ne;
|
|
@@ -1918,12 +1961,12 @@ class TokenStream {
|
|
|
1918
1961
|
/** @type {number} */
|
|
1919
1962
|
this._commentHigh = pos;
|
|
1920
1963
|
// Single reused token the lexer writes into on the `next` path — see
|
|
1921
|
-
// `MutableToken`. `
|
|
1922
|
-
//
|
|
1964
|
+
// `MutableToken`. `_hasNext` marks it cached — a boolean instead of an
|
|
1965
|
+
// object slot, so caching a token never pays a GC write barrier.
|
|
1923
1966
|
/** @type {MutableToken} */
|
|
1924
1967
|
this._tok = createToken();
|
|
1925
|
-
/** @type {
|
|
1926
|
-
this.
|
|
1968
|
+
/** @type {boolean} whether `_tok` holds the (lazily tokenized) next token */
|
|
1969
|
+
this._hasNext = false;
|
|
1927
1970
|
/** @type {number[]} byte offsets to rewind to */
|
|
1928
1971
|
this._marks = [];
|
|
1929
1972
|
}
|
|
@@ -1937,14 +1980,14 @@ class TokenStream {
|
|
|
1937
1980
|
* @returns {MutableToken} the next token
|
|
1938
1981
|
*/
|
|
1939
1982
|
next() {
|
|
1940
|
-
if (this.
|
|
1983
|
+
if (!this._hasNext) {
|
|
1941
1984
|
const input = this.input;
|
|
1942
1985
|
const tok = this._tok;
|
|
1943
1986
|
let pos = this._pos;
|
|
1944
1987
|
for (;;) {
|
|
1945
1988
|
const t = readToken(input, pos, tok);
|
|
1946
1989
|
if (t === undefined) {
|
|
1947
|
-
|
|
1990
|
+
fill(tok, TT_EOF, input.length, input.length);
|
|
1948
1991
|
break;
|
|
1949
1992
|
}
|
|
1950
1993
|
if (t.type === TT_COMMENT) {
|
|
@@ -1955,11 +1998,11 @@ class TokenStream {
|
|
|
1955
1998
|
pos = t.end;
|
|
1956
1999
|
continue;
|
|
1957
2000
|
}
|
|
1958
|
-
this._next = t;
|
|
1959
2001
|
break;
|
|
1960
2002
|
}
|
|
2003
|
+
this._hasNext = true;
|
|
1961
2004
|
}
|
|
1962
|
-
return
|
|
2005
|
+
return this._tok;
|
|
1963
2006
|
}
|
|
1964
2007
|
|
|
1965
2008
|
/**
|
|
@@ -1972,7 +2015,7 @@ class TokenStream {
|
|
|
1972
2015
|
const t = this.next();
|
|
1973
2016
|
if (t.type !== TT_EOF) {
|
|
1974
2017
|
this._pos = t.end;
|
|
1975
|
-
this.
|
|
2018
|
+
this._hasNext = false;
|
|
1976
2019
|
}
|
|
1977
2020
|
return t;
|
|
1978
2021
|
}
|
|
@@ -1986,7 +2029,7 @@ class TokenStream {
|
|
|
1986
2029
|
const t = this.next();
|
|
1987
2030
|
if (t.type !== TT_EOF) {
|
|
1988
2031
|
this._pos = t.end;
|
|
1989
|
-
this.
|
|
2032
|
+
this._hasNext = false;
|
|
1990
2033
|
}
|
|
1991
2034
|
}
|
|
1992
2035
|
|
|
@@ -2006,7 +2049,7 @@ class TokenStream {
|
|
|
2006
2049
|
*/
|
|
2007
2050
|
restoreMark() {
|
|
2008
2051
|
this._pos = /** @type {number} */ (this._marks.pop());
|
|
2009
|
-
this.
|
|
2052
|
+
this._hasNext = false;
|
|
2010
2053
|
}
|
|
2011
2054
|
|
|
2012
2055
|
/**
|
|
@@ -2305,6 +2348,11 @@ const consumeAnAtRule = (ts, nested = false) => {
|
|
|
2305
2348
|
// declarations / childRules / blockStart (-1) / blockEnd (-1) keep their
|
|
2306
2349
|
// defaults (no block: the `;` / EOF / nested-`}` at-rule forms).
|
|
2307
2350
|
|
|
2351
|
+
// Like `consumeAQualifiedRule`: skip mode scans the prelude without
|
|
2352
|
+
// materializing it (url tokens / functions kept so `@import url(…)` still
|
|
2353
|
+
// resolves); the block boundary is found by scanning, not the prelude nodes.
|
|
2354
|
+
const skip = _skipAtRulePrelude;
|
|
2355
|
+
|
|
2308
2356
|
// Process input
|
|
2309
2357
|
for (;;) {
|
|
2310
2358
|
const t = ts.next();
|
|
@@ -2325,7 +2373,8 @@ const consumeAnAtRule = (ts, nested = false) => {
|
|
|
2325
2373
|
_setEnd(rule, t.start);
|
|
2326
2374
|
return rule;
|
|
2327
2375
|
}
|
|
2328
|
-
|
|
2376
|
+
const node = consumeATokenAsNode(ts);
|
|
2377
|
+
if (!skip) prelude.push(node);
|
|
2329
2378
|
continue;
|
|
2330
2379
|
}
|
|
2331
2380
|
// <{-token>
|
|
@@ -2340,7 +2389,12 @@ const consumeAnAtRule = (ts, nested = false) => {
|
|
|
2340
2389
|
|
|
2341
2390
|
// anything else
|
|
2342
2391
|
// Consume a component value from input and append the returned value to rule’s prelude.
|
|
2343
|
-
|
|
2392
|
+
const node = consumeAComponentValue(ts, t);
|
|
2393
|
+
if (!skip) {
|
|
2394
|
+
prelude.push(node);
|
|
2395
|
+
} else if (_nType(node) === T_FUNCTION || _nType(node) === T_URL) {
|
|
2396
|
+
prelude.push(node);
|
|
2397
|
+
}
|
|
2344
2398
|
}
|
|
2345
2399
|
};
|
|
2346
2400
|
|
|
@@ -2376,6 +2430,13 @@ const consumeAQualifiedRule = (ts, stopToken, nested = false) => {
|
|
|
2376
2430
|
// declarations / childRules / blockStart (-1) / blockEnd (-1) keep their
|
|
2377
2431
|
// defaults (no block until a `{` is reached).
|
|
2378
2432
|
|
|
2433
|
+
// Skip mode leaves `prelude` empty (selector text is recovered from the
|
|
2434
|
+
// rule's byte range, not its nodes); `first`/`second` still track the first
|
|
2435
|
+
// two non-whitespace tokens the `--foo: {` disambiguation below needs.
|
|
2436
|
+
const skip = _skipSelectorPrelude;
|
|
2437
|
+
let first = /** @type {Node} */ (/** @type {unknown} */ (0));
|
|
2438
|
+
let second = /** @type {Node} */ (/** @type {unknown} */ (0));
|
|
2439
|
+
|
|
2379
2440
|
// Process input
|
|
2380
2441
|
for (;;) {
|
|
2381
2442
|
const t = ts.next();
|
|
@@ -2389,7 +2450,13 @@ const consumeAQualifiedRule = (ts, stopToken, nested = false) => {
|
|
|
2389
2450
|
// This is a parse error. If nested is true, return nothing. Otherwise, consume a token and append the result to rule’s prelude.
|
|
2390
2451
|
else if (t.type === TT_RIGHT_CURLY_BRACKET) {
|
|
2391
2452
|
if (nested) return undefined;
|
|
2392
|
-
|
|
2453
|
+
const node = consumeATokenAsNode(ts);
|
|
2454
|
+
if (skip) {
|
|
2455
|
+
if (!first) first = node;
|
|
2456
|
+
else if (!second) second = node;
|
|
2457
|
+
} else {
|
|
2458
|
+
prelude.push(node);
|
|
2459
|
+
}
|
|
2393
2460
|
continue;
|
|
2394
2461
|
}
|
|
2395
2462
|
// <{-token>
|
|
@@ -2399,23 +2466,25 @@ const consumeAQualifiedRule = (ts, stopToken, nested = false) => {
|
|
|
2399
2466
|
// (This disambiguates custom-property declarations from nested qualified rules — `--foo: { … }` at top level of a block is a declaration, not a rule.)
|
|
2400
2467
|
// Otherwise, consume a block from input, and let child rules be the result.
|
|
2401
2468
|
else if (t.type === TT_LEFT_CURLY_BRACKET) {
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2469
|
+
if (!skip) {
|
|
2470
|
+
let firstIdx = 0;
|
|
2471
|
+
/* istanbul ignore next -- @preserve: leading whitespace is discarded before the rule, so the prelude never starts with it */
|
|
2472
|
+
while (
|
|
2473
|
+
firstIdx < prelude.length &&
|
|
2474
|
+
_nType(prelude[firstIdx]) === T_WHITESPACE
|
|
2475
|
+
) {
|
|
2476
|
+
firstIdx++;
|
|
2477
|
+
}
|
|
2478
|
+
let secondIdx = firstIdx + 1;
|
|
2479
|
+
while (
|
|
2480
|
+
secondIdx < prelude.length &&
|
|
2481
|
+
_nType(prelude[secondIdx]) === T_WHITESPACE
|
|
2482
|
+
) {
|
|
2483
|
+
secondIdx++;
|
|
2484
|
+
}
|
|
2485
|
+
first = prelude[firstIdx];
|
|
2486
|
+
second = prelude[secondIdx];
|
|
2416
2487
|
}
|
|
2417
|
-
const first = prelude[firstIdx];
|
|
2418
|
-
const second = prelude[secondIdx];
|
|
2419
2488
|
if (
|
|
2420
2489
|
first &&
|
|
2421
2490
|
_nType(first) === T_IDENT &&
|
|
@@ -2442,7 +2511,21 @@ const consumeAQualifiedRule = (ts, stopToken, nested = false) => {
|
|
|
2442
2511
|
|
|
2443
2512
|
// anything else
|
|
2444
2513
|
// Consume a component value from input and append the result to rule’s prelude.
|
|
2445
|
-
|
|
2514
|
+
const node = consumeAComponentValue(ts, t);
|
|
2515
|
+
if (skip) {
|
|
2516
|
+
// Keep only url-bearing nodes (url tokens, or functions that may hold a
|
|
2517
|
+
// url like `:unknown(url(x))`) so the url visitor still rewrites them;
|
|
2518
|
+
// other selector tokens have no non-modules consumer, so drop them.
|
|
2519
|
+
const ty = _nType(node);
|
|
2520
|
+
if (ty === T_FUNCTION || ty === T_URL) prelude.push(node);
|
|
2521
|
+
// Track the first two non-whitespace tokens for the disambiguation above.
|
|
2522
|
+
if (t.type !== TT_WHITESPACE) {
|
|
2523
|
+
if (!first) first = node;
|
|
2524
|
+
else if (!second) second = node;
|
|
2525
|
+
}
|
|
2526
|
+
} else {
|
|
2527
|
+
prelude.push(node);
|
|
2528
|
+
}
|
|
2446
2529
|
}
|
|
2447
2530
|
};
|
|
2448
2531
|
|
|
@@ -2466,7 +2549,8 @@ const consumeABlock = (ts) => {
|
|
|
2466
2549
|
};
|
|
2467
2550
|
|
|
2468
2551
|
/**
|
|
2469
|
-
* 2-token lookahead: is the next non-whitespace pair `<ident> <colon
|
|
2552
|
+
* 2-token lookahead: is the next non-whitespace pair `<ident> <colon>`?
|
|
2553
|
+
* Peeks raw code points without advancing; comments still fire `onComment` later.
|
|
2470
2554
|
* @param {TokenStream} ts token stream
|
|
2471
2555
|
* @returns {boolean} true if consume-a-declaration's step 1 + step 3 would both succeed on the current input
|
|
2472
2556
|
*/
|
|
@@ -2710,12 +2794,28 @@ const consumeAListOfComponentValues = (ts, stopToken, nested = false) => {
|
|
|
2710
2794
|
// Otherwise, this is a parse error. Consume a token from input and append the result to values.
|
|
2711
2795
|
if (t.type === TT_RIGHT_CURLY_BRACKET) {
|
|
2712
2796
|
if (nested) return values;
|
|
2713
|
-
|
|
2797
|
+
const closer = consumeATokenAsNode(ts);
|
|
2798
|
+
// Keep unless the type is explicitly marked skip (1); an out-of-range
|
|
2799
|
+
// lookup on a short `skip.types` yields `undefined`, which must not drop.
|
|
2800
|
+
if (!_skipActive || _skipTypes[_nType(closer)] !== 1) values.push(closer);
|
|
2714
2801
|
continue;
|
|
2715
2802
|
}
|
|
2716
2803
|
// anything else
|
|
2717
2804
|
// Consume a component value from input, and append the result to values.
|
|
2718
|
-
|
|
2805
|
+
// Skipped leaf types short-circuit before materializing: no SoA slot is
|
|
2806
|
+
// written and no node is built (blocks / functions never skip here).
|
|
2807
|
+
const tt = t.type;
|
|
2808
|
+
if (
|
|
2809
|
+
_skipActive &&
|
|
2810
|
+
tt !== TT_FUNCTION &&
|
|
2811
|
+
!(tt >= TT_LEFT_PARENTHESIS && tt <= TT_LEFT_CURLY_BRACKET) &&
|
|
2812
|
+
_skipTypes[_ttToNodeType[tt]] === 1
|
|
2813
|
+
) {
|
|
2814
|
+
ts.consume();
|
|
2815
|
+
continue;
|
|
2816
|
+
}
|
|
2817
|
+
const node = consumeAComponentValue(ts, t);
|
|
2818
|
+
if (!_skipActive || _skipTypes[_nType(node)] !== 1) values.push(node);
|
|
2719
2819
|
}
|
|
2720
2820
|
};
|
|
2721
2821
|
|
|
@@ -2821,7 +2921,19 @@ const consumeAFunction = (ts) => {
|
|
|
2821
2921
|
|
|
2822
2922
|
// anything else
|
|
2823
2923
|
// Consume a component value from input and append the result to function’s value.
|
|
2824
|
-
|
|
2924
|
+
// Same pre-materialization skip as `consumeAListOfComponentValues`.
|
|
2925
|
+
const tt = t.type;
|
|
2926
|
+
if (
|
|
2927
|
+
_skipActive &&
|
|
2928
|
+
tt !== TT_FUNCTION &&
|
|
2929
|
+
!(tt >= TT_LEFT_PARENTHESIS && tt <= TT_LEFT_CURLY_BRACKET) &&
|
|
2930
|
+
_skipTypes[_ttToNodeType[tt]] === 1
|
|
2931
|
+
) {
|
|
2932
|
+
ts.consume();
|
|
2933
|
+
continue;
|
|
2934
|
+
}
|
|
2935
|
+
const node = consumeAComponentValue(ts, t);
|
|
2936
|
+
if (!_skipActive || _skipTypes[_nType(node)] !== 1) val.push(node);
|
|
2825
2937
|
}
|
|
2826
2938
|
};
|
|
2827
2939
|
|
|
@@ -2999,11 +3111,10 @@ const unescapeIdentifier = makeCacheable(_unescapeIdentifier);
|
|
|
2999
3111
|
// CSS-typed views over the generic visitor machinery (`util/SourceProcessor`),
|
|
3000
3112
|
// re-exported so consumers keep importing them from this module.
|
|
3001
3113
|
/**
|
|
3002
|
-
* @typedef {import("../util/SourceProcessor").
|
|
3003
|
-
* @typedef {import("../util/SourceProcessor").
|
|
3004
|
-
* @typedef {import("../util/SourceProcessor").
|
|
3005
|
-
* @typedef {import("../util/SourceProcessor").
|
|
3006
|
-
* @typedef {import("../util/SourceProcessor").CompiledVisitorMap<Node>} CompiledVisitorMap
|
|
3114
|
+
* @typedef {import("../util/SourceProcessor").VisitorFn<CssPath>} VisitorFn
|
|
3115
|
+
* @typedef {import("../util/SourceProcessor").VisitorBucket<CssPath>} VisitorBucket
|
|
3116
|
+
* @typedef {import("../util/SourceProcessor").VisitorMap<CssPath>} VisitorMap
|
|
3117
|
+
* @typedef {import("../util/SourceProcessor").CompiledVisitorMap<CssPath>} CompiledVisitorMap
|
|
3007
3118
|
*/
|
|
3008
3119
|
|
|
3009
3120
|
/**
|
|
@@ -3027,9 +3138,17 @@ const TOP_LEVEL_CONSUMERS = {
|
|
|
3027
3138
|
/**
|
|
3028
3139
|
* @typedef {object} CssProcessOptions
|
|
3029
3140
|
* @property {LocConverter=} locConverter shared loc converter (default a fresh one over the input)
|
|
3030
|
-
* @property {((input: string, start: number, end: number) => number)=} comment comment-token callback
|
|
3031
3141
|
* @property {boolean=} recurseBlocks walk into block bodies' nested rules (default true)
|
|
3032
3142
|
* @property {("stylesheet" | "block-contents")=} as which top-level production to consume the source as (see `TOP_LEVEL_CONSUMERS`): `"stylesheet"` (default) or `"block-contents"` (a block's contents, e.g. an HTML `style` attribute)
|
|
3143
|
+
* @property {SkipOptions=} skip what the grammar may leave un-materialized to go faster — safe only for parts nothing reads in the active parse; default skip nothing
|
|
3144
|
+
*/
|
|
3145
|
+
|
|
3146
|
+
/**
|
|
3147
|
+
* `CssProcessOptions.skip`: two independent axes, so each reads unambiguously.
|
|
3148
|
+
* @typedef {object} SkipOptions
|
|
3149
|
+
* @property {Uint8Array=} types component-value node types to drop from declaration value / function-arg lists (indexed by `NodeType`, 1 = skip; build with `buildSkipSet`)
|
|
3150
|
+
* @property {boolean=} selectorPrelude drop qualified-rule (selector) preludes — the rule and its block are still produced (default false)
|
|
3151
|
+
* @property {boolean=} atRulePrelude drop at-rule preludes — the at-rule and its block are still produced (default false)
|
|
3033
3152
|
*/
|
|
3034
3153
|
|
|
3035
3154
|
/**
|
|
@@ -3043,18 +3162,36 @@ const TOP_LEVEL_CONSUMERS = {
|
|
|
3043
3162
|
* @param {CssProcessOptions} options process options
|
|
3044
3163
|
*/
|
|
3045
3164
|
const grammar = (input, visitors, options) => {
|
|
3046
|
-
const { comment } = options;
|
|
3047
3165
|
const locConverter = options.locConverter || new LocConverter(input);
|
|
3048
3166
|
useSoaBackend(input, locConverter);
|
|
3167
|
+
const skip = options.skip;
|
|
3168
|
+
_skipTypes = (skip && skip.types) || _NO_SKIP_TYPES;
|
|
3169
|
+
_skipActive = _skipTypes !== _NO_SKIP_TYPES;
|
|
3170
|
+
_skipSelectorPrelude = skip !== undefined && skip.selectorPrelude === true;
|
|
3171
|
+
_skipAtRulePrelude = skip !== undefined && skip.atRulePrelude === true;
|
|
3049
3172
|
const recurseBlocks = options.recurseBlocks !== false;
|
|
3050
3173
|
|
|
3051
|
-
//
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3174
|
+
// Comments reach the visitor map through `NodeType.Comment` instead of a
|
|
3175
|
+
// side callback. They fire during tokenization — in source order among
|
|
3176
|
+
// comments, not interleaved with the node walk — on a transient SoA node so
|
|
3177
|
+
// `A.start`/`end`/`loc`/`source` work. No comment visitor → no callback →
|
|
3178
|
+
// the tokenizer skips comments with zero overhead.
|
|
3179
|
+
const commentBucket = visitors[T_COMMENT];
|
|
3180
|
+
const onComment =
|
|
3181
|
+
commentBucket === undefined
|
|
3182
|
+
? undefined
|
|
3183
|
+
: /** @type {(input: string, start: number, end: number) => number} */ (
|
|
3184
|
+
(_input, start, end) => {
|
|
3185
|
+
const node = _soaAlloc(T_COMMENT, start, end);
|
|
3186
|
+
_curNode = node;
|
|
3187
|
+
_curParent = null;
|
|
3188
|
+
const e = commentBucket.enter;
|
|
3189
|
+
for (let i = 0; i < e.length; i++) e[i](A);
|
|
3190
|
+
const x = commentBucket.exit;
|
|
3191
|
+
for (let i = 0; i < x.length; i++) x[i](A);
|
|
3192
|
+
return end;
|
|
3193
|
+
}
|
|
3194
|
+
);
|
|
3058
3195
|
|
|
3059
3196
|
/**
|
|
3060
3197
|
* Walk a component-value subtree; children are already materialized. Fetches
|
|
@@ -3068,19 +3205,24 @@ const grammar = (input, visitors, options) => {
|
|
|
3068
3205
|
const b = visitors[ty];
|
|
3069
3206
|
let skip = false;
|
|
3070
3207
|
if (b !== undefined && b.enter.length !== 0) {
|
|
3071
|
-
|
|
3208
|
+
_walkSkip = false;
|
|
3209
|
+
_curNode = node;
|
|
3210
|
+
_curParent = parent;
|
|
3072
3211
|
const e = b.enter;
|
|
3073
|
-
for (let i = 0; i < e.length; i++) e[i](
|
|
3074
|
-
skip =
|
|
3075
|
-
|
|
3212
|
+
for (let i = 0; i < e.length; i++) e[i](A);
|
|
3213
|
+
skip = _walkSkip;
|
|
3214
|
+
_walkSkip = false;
|
|
3076
3215
|
}
|
|
3077
3216
|
if (!skip && (ty === T_FUNCTION || ty === T_SIMPLE_BLOCK)) {
|
|
3078
3217
|
const v = /** @type {Node[]} */ (_soaL0[_ix(node)]);
|
|
3079
3218
|
for (let i = 0; i < v.length; i++) walkValue(v[i], node);
|
|
3080
3219
|
}
|
|
3081
3220
|
if (b !== undefined) {
|
|
3221
|
+
// Rebind: descending into children moved the path.
|
|
3222
|
+
_curNode = node;
|
|
3223
|
+
_curParent = parent;
|
|
3082
3224
|
const x = b.exit;
|
|
3083
|
-
for (let i = 0; i < x.length; i++) x[i](
|
|
3225
|
+
for (let i = 0; i < x.length; i++) x[i](A);
|
|
3084
3226
|
}
|
|
3085
3227
|
};
|
|
3086
3228
|
|
|
@@ -3096,11 +3238,13 @@ const grammar = (input, visitors, options) => {
|
|
|
3096
3238
|
const b = visitors[ty];
|
|
3097
3239
|
let skip = false;
|
|
3098
3240
|
if (b !== undefined && b.enter.length !== 0) {
|
|
3099
|
-
|
|
3241
|
+
_walkSkip = false;
|
|
3242
|
+
_curNode = node;
|
|
3243
|
+
_curParent = parent;
|
|
3100
3244
|
const e = b.enter;
|
|
3101
|
-
for (let i = 0; i < e.length; i++) e[i](
|
|
3102
|
-
skip =
|
|
3103
|
-
|
|
3245
|
+
for (let i = 0; i < e.length; i++) e[i](A);
|
|
3246
|
+
skip = _walkSkip;
|
|
3247
|
+
_walkSkip = false;
|
|
3104
3248
|
}
|
|
3105
3249
|
if (!skip) {
|
|
3106
3250
|
if (ty === T_AT_RULE || ty === T_QUALIFIED_RULE) {
|
|
@@ -3121,22 +3265,35 @@ const grammar = (input, visitors, options) => {
|
|
|
3121
3265
|
}
|
|
3122
3266
|
}
|
|
3123
3267
|
if (b !== undefined) {
|
|
3268
|
+
// Rebind: descending into children moved the path.
|
|
3269
|
+
_curNode = node;
|
|
3270
|
+
_curParent = parent;
|
|
3124
3271
|
const x = b.exit;
|
|
3125
|
-
for (let i = 0; i < x.length; i++) x[i](
|
|
3272
|
+
for (let i = 0; i < x.length; i++) x[i](A);
|
|
3126
3273
|
}
|
|
3127
3274
|
};
|
|
3128
3275
|
|
|
3129
3276
|
// Stream each top-level node (selected by `as`) to the walker the moment it's
|
|
3130
3277
|
// consumed, rather than collecting them first — so the whole AST is never
|
|
3131
3278
|
// held at once; peak heap is ~one top-level node's subtree.
|
|
3132
|
-
const ts = new TokenStream(input, 0, locConverter,
|
|
3279
|
+
const ts = new TokenStream(input, 0, locConverter, onComment);
|
|
3133
3280
|
const consume =
|
|
3134
3281
|
TOP_LEVEL_CONSUMERS[options.as || "stylesheet"] ||
|
|
3135
3282
|
consumeAStylesheetsContents;
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3283
|
+
try {
|
|
3284
|
+
consume(ts, (node) => {
|
|
3285
|
+
walkRule(node, null);
|
|
3286
|
+
_soaN = 0;
|
|
3287
|
+
});
|
|
3288
|
+
} finally {
|
|
3289
|
+
// Drop the module-level SoA references so the last parsed source (and
|
|
3290
|
+
// its LocConverter / child lists) don't stay alive between parses.
|
|
3291
|
+
_soaInput = "";
|
|
3292
|
+
_soaLC = /** @type {LocConverter} */ (/** @type {unknown} */ (null));
|
|
3293
|
+
_soaL0.length = 0;
|
|
3294
|
+
_soaL1.length = 0;
|
|
3295
|
+
_soaL2.length = 0;
|
|
3296
|
+
}
|
|
3140
3297
|
};
|
|
3141
3298
|
|
|
3142
3299
|
/**
|
|
@@ -3144,17 +3301,55 @@ const grammar = (input, visitors, options) => {
|
|
|
3144
3301
|
* `grammar`. Babel-style usage:
|
|
3145
3302
|
*
|
|
3146
3303
|
* ```
|
|
3147
|
-
*
|
|
3148
|
-
* processor.process(source);
|
|
3304
|
+
* new SourceProcessor({ skip }).use({ [NodeType.AtRule]: (path) => {} }).process(source);
|
|
3149
3305
|
* ```
|
|
3150
|
-
* @extends {GenericSourceProcessor<
|
|
3306
|
+
* @extends {GenericSourceProcessor<CssPath, CssProcessOptions>}
|
|
3151
3307
|
*/
|
|
3152
3308
|
class SourceProcessor extends GenericSourceProcessor {
|
|
3153
|
-
|
|
3154
|
-
|
|
3309
|
+
/**
|
|
3310
|
+
* @param {CssProcessOptions=} options default process options (`skip`, `as`, …) for every `process` call
|
|
3311
|
+
*/
|
|
3312
|
+
constructor(options) {
|
|
3313
|
+
super(grammar, options);
|
|
3155
3314
|
}
|
|
3156
3315
|
}
|
|
3157
3316
|
|
|
3317
|
+
/**
|
|
3318
|
+
* Build a `SkipOptions.types` set (drop these component-value node types from
|
|
3319
|
+
* value / function-arg lists) from a list of `NodeType`s. Preludes are separate
|
|
3320
|
+
* (`SkipOptions.selectorPrelude` / `atRulePrelude`). The caller owns the safety
|
|
3321
|
+
* contract: only pass types nothing reads in the intended parse. Two
|
|
3322
|
+
* grammar-internal caveats beyond consumer needs: dropping both `Delim` and
|
|
3323
|
+
* `Ident` loses `!important` detection, and dropping `SimpleBlock` loses the
|
|
3324
|
+
* custom-property `{}`-value check (and its subtree). Precompute once per
|
|
3325
|
+
* configuration and reuse across parses.
|
|
3326
|
+
* @param {number[]} nodeTypes component-value node types to drop
|
|
3327
|
+
* @returns {Uint8Array} skip-types set indexed by `NodeType`
|
|
3328
|
+
*/
|
|
3329
|
+
const buildSkipSet = (nodeTypes) => {
|
|
3330
|
+
const set = new Uint8Array(32);
|
|
3331
|
+
for (let i = 0; i < nodeTypes.length; i++) set[nodeTypes[i]] = 1;
|
|
3332
|
+
return set;
|
|
3333
|
+
};
|
|
3334
|
+
|
|
3335
|
+
/* eslint-disable jsdoc/require-template -- `A` below is the accessor const, not a type parameter */
|
|
3336
|
+
/**
|
|
3337
|
+
* The CSS path (Babel's `path` shape): the AST accessor with the walk's
|
|
3338
|
+
* current position on it — the single argument every visitor receives.
|
|
3339
|
+
* @typedef {typeof A} CssPath
|
|
3340
|
+
*/
|
|
3341
|
+
/* eslint-enable jsdoc/require-template */
|
|
3342
|
+
|
|
3343
|
+
// Babel's `path.skip()`, children-only: set by `A.skipChildren()` during an
|
|
3344
|
+
// `enter` dispatch, consumed by the walk.
|
|
3345
|
+
let _walkSkip = false;
|
|
3346
|
+
// The walk's current position (`A.node` / `A.parent` read these; module-level
|
|
3347
|
+
// so the accessor methods' defaults avoid self-referential `this` typing).
|
|
3348
|
+
/** @type {Node} */
|
|
3349
|
+
let _curNode = /** @type {Node} */ (/** @type {unknown} */ (0));
|
|
3350
|
+
/** @type {Node | null} */
|
|
3351
|
+
let _curParent = null;
|
|
3352
|
+
|
|
3158
3353
|
// AST field-access seam. Every AST-node field read by `CssParser` goes through
|
|
3159
3354
|
// one of these accessors so the node representation can change underneath the
|
|
3160
3355
|
// consumer without touching it. Today they are backed by the `Node` / `Token` /
|
|
@@ -3163,19 +3358,58 @@ class SourceProcessor extends GenericSourceProcessor {
|
|
|
3163
3358
|
// consumer edit. `value` is the leaf-token string; container child lists are
|
|
3164
3359
|
// `children` / `prelude` / `declarations` / `childRules`.
|
|
3165
3360
|
const A = {
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3361
|
+
// === path position (rebound by the walk before every visitor call) ===
|
|
3362
|
+
/**
|
|
3363
|
+
* @returns {Node} current node — only valid during a visitor callback
|
|
3364
|
+
*/
|
|
3365
|
+
get node() {
|
|
3366
|
+
return _curNode;
|
|
3367
|
+
},
|
|
3368
|
+
/**
|
|
3369
|
+
* @returns {Node | null} enclosing node (null = a top-level node)
|
|
3370
|
+
*/
|
|
3371
|
+
get parent() {
|
|
3372
|
+
return _curParent;
|
|
3373
|
+
},
|
|
3374
|
+
/** Stop the walk descending into the current node (enter only). */
|
|
3375
|
+
skipChildren() {
|
|
3376
|
+
_walkSkip = true;
|
|
3377
|
+
},
|
|
3378
|
+
// === field reads — `n` defaults to the current node ===
|
|
3379
|
+
/**
|
|
3380
|
+
* @param {Node=} n node
|
|
3381
|
+
* @returns {number} node type
|
|
3382
|
+
*/
|
|
3383
|
+
type(n = _curNode) {
|
|
3384
|
+
return _soaTy[_ix(n)];
|
|
3385
|
+
},
|
|
3386
|
+
/**
|
|
3387
|
+
* @param {Node=} n node
|
|
3388
|
+
* @returns {number} start offset
|
|
3389
|
+
*/
|
|
3390
|
+
start(n = _curNode) {
|
|
3391
|
+
return _soaSt[_ix(n)];
|
|
3392
|
+
},
|
|
3393
|
+
/**
|
|
3394
|
+
* @param {Node=} n node
|
|
3395
|
+
* @returns {number} end offset
|
|
3396
|
+
*/
|
|
3397
|
+
end(n = _curNode) {
|
|
3398
|
+
return _soaEn[_ix(n)];
|
|
3399
|
+
},
|
|
3400
|
+
/**
|
|
3401
|
+
* @param {Node=} n node
|
|
3402
|
+
* @returns {[number, number]} start / end offsets
|
|
3403
|
+
*/
|
|
3404
|
+
range(n = _curNode) {
|
|
3174
3405
|
const i = _ix(n);
|
|
3175
3406
|
return [_soaSt[i], _soaEn[i]];
|
|
3176
3407
|
},
|
|
3177
|
-
/**
|
|
3178
|
-
|
|
3408
|
+
/**
|
|
3409
|
+
* @param {Node=} n node
|
|
3410
|
+
* @returns {{ start: { line: number, column: number }, end: { line: number, column: number } }} source location
|
|
3411
|
+
*/
|
|
3412
|
+
loc(n = _curNode) {
|
|
3179
3413
|
const i = _ix(n);
|
|
3180
3414
|
const lc = _soaLC;
|
|
3181
3415
|
const s = lc.get(_soaSt[i]);
|
|
@@ -3187,23 +3421,37 @@ const A = {
|
|
|
3187
3421
|
end: { line: e.line, column: e.column }
|
|
3188
3422
|
};
|
|
3189
3423
|
},
|
|
3190
|
-
/**
|
|
3191
|
-
|
|
3424
|
+
/**
|
|
3425
|
+
* @param {Node=} n node
|
|
3426
|
+
* @returns {string} raw source slice
|
|
3427
|
+
*/
|
|
3428
|
+
source(n = _curNode) {
|
|
3192
3429
|
const i = _ix(n);
|
|
3193
3430
|
return _soaInput.slice(_soaSt[i], _soaEn[i]);
|
|
3194
3431
|
},
|
|
3195
|
-
/**
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3432
|
+
/**
|
|
3433
|
+
* @param {Node=} n node
|
|
3434
|
+
* @returns {string} raw token value
|
|
3435
|
+
*/
|
|
3436
|
+
value(n = _curNode) {
|
|
3437
|
+
return _soaValueOf(_ix(n));
|
|
3438
|
+
},
|
|
3439
|
+
/**
|
|
3440
|
+
* @param {Node=} n node
|
|
3441
|
+
* @returns {string} unescaped token value
|
|
3442
|
+
*/
|
|
3443
|
+
unescaped(n = _curNode) {
|
|
3199
3444
|
const i = _ix(n);
|
|
3200
3445
|
const v = _soaValueOf(i);
|
|
3201
3446
|
return _soaTy[i] === T_STRING
|
|
3202
3447
|
? unescapeIdentifier(v.slice(1, -1))
|
|
3203
3448
|
: unescapeIdentifier(v);
|
|
3204
3449
|
},
|
|
3205
|
-
/**
|
|
3206
|
-
|
|
3450
|
+
/**
|
|
3451
|
+
* @param {Node=} n node
|
|
3452
|
+
* @returns {string} hash / numeric type flag
|
|
3453
|
+
*/
|
|
3454
|
+
typeFlag(n = _curNode) {
|
|
3207
3455
|
const i = _ix(n);
|
|
3208
3456
|
if (_soaTy[i] === T_HASH) {
|
|
3209
3457
|
const input = _soaInput;
|
|
@@ -3223,48 +3471,122 @@ const A = {
|
|
|
3223
3471
|
_soaTy[i] === T_DIMENSION ? v.slice(0, _consumeANumber(v, 0)) : v
|
|
3224
3472
|
);
|
|
3225
3473
|
},
|
|
3226
|
-
/**
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3474
|
+
/**
|
|
3475
|
+
* @param {Node=} n node
|
|
3476
|
+
* @returns {number} url content start offset
|
|
3477
|
+
*/
|
|
3478
|
+
contentStart(n = _curNode) {
|
|
3479
|
+
return _soaA0[_ix(n)];
|
|
3480
|
+
},
|
|
3481
|
+
/**
|
|
3482
|
+
* @param {Node=} n node
|
|
3483
|
+
* @returns {number} url content end offset
|
|
3484
|
+
*/
|
|
3485
|
+
contentEnd(n = _curNode) {
|
|
3486
|
+
return _soaA1[_ix(n)];
|
|
3487
|
+
},
|
|
3488
|
+
/**
|
|
3489
|
+
* @param {Node=} n node
|
|
3490
|
+
* @returns {string} rule / declaration / function name
|
|
3491
|
+
*/
|
|
3492
|
+
name(n = _curNode) {
|
|
3232
3493
|
const i = _ix(n);
|
|
3233
3494
|
return _soaTy[i] === T_AT_RULE
|
|
3234
3495
|
? _soaInput.slice(_soaSt[i] + 1, _soaA0[i])
|
|
3235
3496
|
: _soaInput.slice(_soaSt[i], _soaA0[i]);
|
|
3236
3497
|
},
|
|
3237
|
-
/**
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
/**
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3498
|
+
/**
|
|
3499
|
+
* @param {Node=} n node
|
|
3500
|
+
* @returns {number} name start offset
|
|
3501
|
+
*/
|
|
3502
|
+
nameStart(n = _curNode) {
|
|
3503
|
+
return _soaSt[_ix(n)];
|
|
3504
|
+
},
|
|
3505
|
+
/**
|
|
3506
|
+
* @param {Node=} n node
|
|
3507
|
+
* @returns {number} name end offset
|
|
3508
|
+
*/
|
|
3509
|
+
nameEnd(n = _curNode) {
|
|
3510
|
+
return _soaA0[_ix(n)];
|
|
3511
|
+
},
|
|
3512
|
+
/**
|
|
3513
|
+
* @param {Node=} n node
|
|
3514
|
+
* @returns {string} unescaped name
|
|
3515
|
+
*/
|
|
3516
|
+
unescapedName(n = _curNode) {
|
|
3517
|
+
return unescapeIdentifier(A.name(n));
|
|
3518
|
+
},
|
|
3519
|
+
/**
|
|
3520
|
+
* @param {Node=} n node
|
|
3521
|
+
* @returns {ComponentValue[]} function / block children
|
|
3522
|
+
*/
|
|
3523
|
+
children(n = _curNode) {
|
|
3524
|
+
return /** @type {ComponentValue[]} */ (_soaL0[_ix(n)]);
|
|
3525
|
+
},
|
|
3526
|
+
/**
|
|
3527
|
+
* @param {Node=} n node
|
|
3528
|
+
* @returns {ComponentValue[]} rule prelude
|
|
3529
|
+
*/
|
|
3530
|
+
prelude(n = _curNode) {
|
|
3531
|
+
return /** @type {ComponentValue[]} */ (_soaL0[_ix(n)]);
|
|
3532
|
+
},
|
|
3533
|
+
/**
|
|
3534
|
+
* @param {Node=} n node
|
|
3535
|
+
* @returns {Declaration[] | null} block declarations
|
|
3536
|
+
*/
|
|
3537
|
+
declarations(n = _curNode) {
|
|
3538
|
+
return /** @type {Declaration[] | null} */ (_soaL1[_ix(n)]);
|
|
3539
|
+
},
|
|
3540
|
+
/**
|
|
3541
|
+
* @param {Node=} n node
|
|
3542
|
+
* @returns {Rule[] | null} block child rules
|
|
3543
|
+
*/
|
|
3544
|
+
childRules(n = _curNode) {
|
|
3545
|
+
return /** @type {Rule[] | null} */ (_soaL2[_ix(n)]);
|
|
3546
|
+
},
|
|
3547
|
+
/**
|
|
3548
|
+
* @param {Node=} n node
|
|
3549
|
+
* @returns {number} block start offset
|
|
3550
|
+
*/
|
|
3551
|
+
blockStart(n = _curNode) {
|
|
3552
|
+
return _soaA1[_ix(n)];
|
|
3553
|
+
},
|
|
3554
|
+
/**
|
|
3555
|
+
* @param {Node=} n node
|
|
3556
|
+
* @returns {number} block end offset
|
|
3557
|
+
*/
|
|
3558
|
+
blockEnd(n = _curNode) {
|
|
3559
|
+
return _soaA2[_ix(n)];
|
|
3560
|
+
},
|
|
3561
|
+
/**
|
|
3562
|
+
* @param {Node=} n node
|
|
3563
|
+
* @returns {boolean} `!important` flag
|
|
3564
|
+
*/
|
|
3565
|
+
important(n = _curNode) {
|
|
3566
|
+
return (_soaFl[_ix(n)] & 1) !== 0;
|
|
3567
|
+
},
|
|
3568
|
+
/**
|
|
3569
|
+
* @param {Node=} n node
|
|
3570
|
+
* @returns {SimpleBlockToken} block opening token
|
|
3571
|
+
*/
|
|
3572
|
+
blockToken(n = _curNode) {
|
|
3573
|
+
return /** @type {SimpleBlockToken} */ (_soaInput[_soaSt[_ix(n)]]);
|
|
3574
|
+
},
|
|
3260
3575
|
// Writers — `CssParser` rewrites a rule's end / block-end when it folds an
|
|
3261
|
-
// inline ICSS `:import` / `:export` body into a single dependency.
|
|
3262
|
-
|
|
3263
|
-
|
|
3576
|
+
// inline ICSS `:import` / `:export` body into a single dependency. The
|
|
3577
|
+
// node stays explicit here: writes should never be implicit on position.
|
|
3578
|
+
/**
|
|
3579
|
+
* @param {Node} n node
|
|
3580
|
+
* @param {number} v new end offset
|
|
3581
|
+
*/
|
|
3582
|
+
setEnd(n, v) {
|
|
3264
3583
|
_soaEn[_ix(n)] = v;
|
|
3265
3584
|
},
|
|
3266
|
-
/**
|
|
3267
|
-
|
|
3585
|
+
/**
|
|
3586
|
+
* @param {Node} n node
|
|
3587
|
+
* @param {number} v new block end offset
|
|
3588
|
+
*/
|
|
3589
|
+
setBlockEnd(n, v) {
|
|
3268
3590
|
_soaA2[_ix(n)] = v;
|
|
3269
3591
|
}
|
|
3270
3592
|
};
|
|
@@ -3307,6 +3629,7 @@ module.exports.TT_URL = TT_URL;
|
|
|
3307
3629
|
module.exports.TT_WHITESPACE = TT_WHITESPACE;
|
|
3308
3630
|
module.exports.Token = Token;
|
|
3309
3631
|
module.exports.TokenStream = TokenStream;
|
|
3632
|
+
module.exports.buildSkipSet = buildSkipSet;
|
|
3310
3633
|
module.exports.equalsLowerCase = equalsLowerCase;
|
|
3311
3634
|
module.exports.escapeIdentifier = escapeIdentifier;
|
|
3312
3635
|
module.exports.parseABlocksContents = parseABlocksContents;
|