webpack 5.108.1 → 5.108.3
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/CleanPlugin.js +8 -25
- package/lib/Compilation.js +0 -1
- package/lib/DefinePlugin.js +8 -19
- package/lib/ExternalModule.js +64 -19
- package/lib/ExternalModuleFactoryPlugin.js +37 -1
- package/lib/LazyBarrel.js +4 -3
- package/lib/NormalModule.js +49 -59
- package/lib/bun/BunTargetPlugin.js +1 -7
- package/lib/container/ModuleFederationPlugin.js +9 -25
- package/lib/css/CssInjectStyleRuntimeModule.js +9 -24
- package/lib/css/CssLoadingRuntimeModule.js +12 -27
- package/lib/css/CssModulesPlugin.js +15 -31
- package/lib/css/CssParser.js +421 -381
- package/lib/css/syntax.js +768 -305
- package/lib/deno/DenoTargetPlugin.js +1 -7
- package/lib/dependencies/HarmonyAcceptDependency.js +8 -16
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +22 -0
- package/lib/dependencies/HarmonyImportDependency.js +2 -0
- package/lib/dependencies/ImportMetaPlugin.js +9 -25
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +10 -26
- package/lib/javascript/JavascriptModulesPlugin.js +38 -54
- package/lib/node/NodeTargetPlugin.js +1 -62
- package/lib/node/nodeBuiltins.js +80 -0
- package/lib/optimize/ConcatenatedModule.js +17 -27
- package/lib/optimize/RealContentHashPlugin.js +8 -24
- package/lib/runtime/LoadScriptRuntimeModule.js +9 -24
- package/lib/util/createHooksRegistry.js +35 -0
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +12 -29
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +10 -25
- package/package.json +1 -1
- package/types.d.ts +84 -71
package/lib/css/CssParser.js
CHANGED
|
@@ -29,6 +29,7 @@ const {
|
|
|
29
29
|
} = require("../util/magicComment");
|
|
30
30
|
const topologicalSort = require("../util/topologicalSort");
|
|
31
31
|
const {
|
|
32
|
+
A,
|
|
32
33
|
NodeType,
|
|
33
34
|
SourceProcessor,
|
|
34
35
|
equalsLowerCase,
|
|
@@ -65,6 +66,7 @@ const {
|
|
|
65
66
|
/** @typedef {{ localName: string, value: string }} ValueAtRuleValue */
|
|
66
67
|
|
|
67
68
|
const CC_COLON = ":".charCodeAt(0);
|
|
69
|
+
const CC_HYPHEN_MINUS = "-".charCodeAt(0);
|
|
68
70
|
const CC_SEMICOLON = ";".charCodeAt(0);
|
|
69
71
|
const CC_TAB = "\t".charCodeAt(0);
|
|
70
72
|
const CC_SPACE = " ".charCodeAt(0);
|
|
@@ -577,26 +579,27 @@ const isPureBodyAtRule = (name) =>
|
|
|
577
579
|
|
|
578
580
|
/**
|
|
579
581
|
* Scan a rule body once: does it hold a direct declaration counted against the enclosing rule (a declaration, or one in a transparent conditional-group at-rule like `@media`/`@supports`/…) and does it hold a nested block (qualified rule or any block-bearing at-rule)?
|
|
580
|
-
* @param {
|
|
582
|
+
* @param {Declaration[] | null} declarations rule-body declarations
|
|
583
|
+
* @param {Rule[] | null} childRules rule-body child rules
|
|
581
584
|
* @returns {{ hasDirectDecl: boolean, hasNestedBlock: boolean }} scan result
|
|
582
585
|
*/
|
|
583
|
-
const scanRuleBody = (
|
|
584
|
-
let hasDirectDecl = Boolean(
|
|
585
|
-
body.declarations && body.declarations.length > 0
|
|
586
|
-
);
|
|
586
|
+
const scanRuleBody = (declarations, childRules) => {
|
|
587
|
+
let hasDirectDecl = Boolean(declarations && declarations.length > 0);
|
|
587
588
|
let hasNestedBlock = false;
|
|
588
|
-
if (
|
|
589
|
-
for (const child of
|
|
590
|
-
|
|
589
|
+
if (childRules) {
|
|
590
|
+
for (const child of childRules) {
|
|
591
|
+
const t = A.type(child);
|
|
592
|
+
if (t === NodeType.QualifiedRule) {
|
|
591
593
|
hasNestedBlock = true;
|
|
592
|
-
} else if (
|
|
593
|
-
const
|
|
594
|
-
|
|
594
|
+
} else if (t === NodeType.AtRule) {
|
|
595
|
+
const atDecls = A.declarations(child);
|
|
596
|
+
const atChildRules = A.childRules(child);
|
|
597
|
+
if (!atDecls && !atChildRules) continue;
|
|
595
598
|
hasNestedBlock = true;
|
|
596
599
|
if (
|
|
597
600
|
!hasDirectDecl &&
|
|
598
|
-
!isPureBodyAtRule(`@${
|
|
599
|
-
scanRuleBody(
|
|
601
|
+
!isPureBodyAtRule(`@${A.name(child).toLowerCase()}`) &&
|
|
602
|
+
scanRuleBody(atDecls, atChildRules).hasDirectDecl
|
|
600
603
|
) {
|
|
601
604
|
hasDirectDecl = true;
|
|
602
605
|
}
|
|
@@ -686,7 +689,7 @@ const parseValueAtRuleParams = (str) => {
|
|
|
686
689
|
*/
|
|
687
690
|
const nextNonWhitespace = (nodes, from) => {
|
|
688
691
|
let i = from;
|
|
689
|
-
while (i < nodes.length && nodes[i]
|
|
692
|
+
while (i < nodes.length && A.type(nodes[i]) === NodeType.Whitespace) i++;
|
|
690
693
|
return i;
|
|
691
694
|
};
|
|
692
695
|
|
|
@@ -706,21 +709,22 @@ const parseImportPrelude = (prelude) => {
|
|
|
706
709
|
let supportsNode;
|
|
707
710
|
|
|
708
711
|
for (const cv of prelude) {
|
|
709
|
-
|
|
712
|
+
const t = A.type(cv);
|
|
713
|
+
if (t === NodeType.Whitespace) continue;
|
|
710
714
|
|
|
711
715
|
if (!urlNode) {
|
|
712
|
-
if (
|
|
716
|
+
if (t === NodeType.Url || t === NodeType.String) {
|
|
713
717
|
urlNode = cv;
|
|
714
718
|
continue;
|
|
715
719
|
}
|
|
716
720
|
if (
|
|
717
|
-
|
|
718
|
-
equalsLowerCase(
|
|
721
|
+
t === NodeType.Function &&
|
|
722
|
+
equalsLowerCase(A.unescapedName(cv), "url")
|
|
719
723
|
) {
|
|
720
724
|
urlNode = cv;
|
|
721
725
|
continue;
|
|
722
726
|
}
|
|
723
|
-
if (
|
|
727
|
+
if (t === NodeType.Ident) {
|
|
724
728
|
// CSS Modules: bare ident is a `@value` reference.
|
|
725
729
|
urlNode = cv;
|
|
726
730
|
continue;
|
|
@@ -729,14 +733,14 @@ const parseImportPrelude = (prelude) => {
|
|
|
729
733
|
}
|
|
730
734
|
|
|
731
735
|
if (!layerNode && !supportsNode) {
|
|
732
|
-
if (
|
|
733
|
-
if (equalsLowerCase(
|
|
736
|
+
if (t === NodeType.Ident) {
|
|
737
|
+
if (equalsLowerCase(A.unescaped(cv), "layer")) {
|
|
734
738
|
layerNode = cv;
|
|
735
739
|
continue;
|
|
736
740
|
}
|
|
737
741
|
} else if (
|
|
738
|
-
|
|
739
|
-
equalsLowerCase(
|
|
742
|
+
t === NodeType.Function &&
|
|
743
|
+
equalsLowerCase(A.unescapedName(cv), "layer")
|
|
740
744
|
) {
|
|
741
745
|
layerNode = cv;
|
|
742
746
|
continue;
|
|
@@ -745,11 +749,8 @@ const parseImportPrelude = (prelude) => {
|
|
|
745
749
|
|
|
746
750
|
if (
|
|
747
751
|
!supportsNode &&
|
|
748
|
-
|
|
749
|
-
equalsLowerCase(
|
|
750
|
-
/** @type {FunctionNode} */ (cv).unescapedName,
|
|
751
|
-
"supports"
|
|
752
|
-
)
|
|
752
|
+
t === NodeType.Function &&
|
|
753
|
+
equalsLowerCase(A.unescapedName(cv), "supports")
|
|
753
754
|
) {
|
|
754
755
|
supportsNode = /** @type {FunctionNode} */ (cv);
|
|
755
756
|
continue;
|
|
@@ -772,31 +773,28 @@ const parseImportPrelude = (prelude) => {
|
|
|
772
773
|
const parseIcssImportRequest = (second, rule, source) => {
|
|
773
774
|
/** @type {AstNode[] | undefined} */
|
|
774
775
|
let args;
|
|
775
|
-
if (
|
|
776
|
-
args =
|
|
776
|
+
if (A.type(second) === NodeType.Function) {
|
|
777
|
+
args = A.children(second);
|
|
777
778
|
} else {
|
|
778
|
-
for (const p of
|
|
779
|
-
if (
|
|
780
|
-
|
|
781
|
-
/** @type {SimpleBlock} */ (p).token === "("
|
|
782
|
-
) {
|
|
783
|
-
args = /** @type {SimpleBlock} */ (p).value;
|
|
779
|
+
for (const p of A.prelude(rule)) {
|
|
780
|
+
if (A.type(p) === NodeType.SimpleBlock && A.blockToken(p) === "(") {
|
|
781
|
+
args = A.children(p);
|
|
784
782
|
break;
|
|
785
783
|
}
|
|
786
784
|
}
|
|
787
785
|
}
|
|
788
786
|
// The first non-whitespace value inside `(...)` must be a string.
|
|
789
787
|
const innerStrToken =
|
|
790
|
-
args && args.find((v) =>
|
|
791
|
-
if (!innerStrToken ||
|
|
788
|
+
args && args.find((v) => A.type(v) !== NodeType.Whitespace);
|
|
789
|
+
if (!innerStrToken || A.type(innerStrToken) !== NodeType.String) {
|
|
792
790
|
const errorPos =
|
|
793
|
-
|
|
794
|
-
?
|
|
795
|
-
:
|
|
791
|
+
A.type(second) === NodeType.Function
|
|
792
|
+
? A.nameEnd(second) + 1
|
|
793
|
+
: A.end(second);
|
|
796
794
|
return { errorPos };
|
|
797
795
|
}
|
|
798
796
|
return {
|
|
799
|
-
request: source.slice(
|
|
797
|
+
request: source.slice(A.start(innerStrToken) + 1, A.end(innerStrToken) - 1)
|
|
800
798
|
};
|
|
801
799
|
};
|
|
802
800
|
|
|
@@ -1054,7 +1052,7 @@ class CssParser extends Parser {
|
|
|
1054
1052
|
/**
|
|
1055
1053
|
* Unescape a CSS identifier from a source byte range — for value spans not
|
|
1056
1054
|
* backed by a single token (string contents, `--` dashed-ident bodies,
|
|
1057
|
-
* composed names). Token-backed names use `
|
|
1055
|
+
* composed names). Token-backed names use `A.unescaped(node)` instead.
|
|
1058
1056
|
* @param {number} start start offset
|
|
1059
1057
|
* @param {number} end end offset
|
|
1060
1058
|
* @returns {string} the unescaped identifier
|
|
@@ -1170,10 +1168,10 @@ class CssParser extends Parser {
|
|
|
1170
1168
|
const hasBody = Boolean(declarations || childRules);
|
|
1171
1169
|
let leaf = treatAsLeaf || !hasBody;
|
|
1172
1170
|
if (!leaf && hasBody) {
|
|
1173
|
-
const { hasDirectDecl, hasNestedBlock } = scanRuleBody(
|
|
1171
|
+
const { hasDirectDecl, hasNestedBlock } = scanRuleBody(
|
|
1174
1172
|
declarations,
|
|
1175
1173
|
childRules
|
|
1176
|
-
|
|
1174
|
+
);
|
|
1177
1175
|
leaf = hasDirectDecl || !hasNestedBlock;
|
|
1178
1176
|
}
|
|
1179
1177
|
if (leaf) this.report(preludeStart, preludeEnd);
|
|
@@ -1457,21 +1455,22 @@ class CssParser extends Parser {
|
|
|
1457
1455
|
};
|
|
1458
1456
|
|
|
1459
1457
|
// Body `{ name: value; … }` is parsed eagerly (§5.4.4) — emit a dep per declaration.
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1458
|
+
const ruleDecls = A.declarations(rule);
|
|
1459
|
+
if (!ruleDecls || A.blockStart(rule) === -1) return A.end(second);
|
|
1460
|
+
for (const decl of ruleDecls) {
|
|
1461
|
+
const vals = A.children(decl);
|
|
1463
1462
|
if (vals.length === 0) continue;
|
|
1464
|
-
const rawStart = vals[0]
|
|
1465
|
-
const rawEnd = vals[vals.length - 1]
|
|
1463
|
+
const rawStart = A.start(vals[0]);
|
|
1464
|
+
const rawEnd = A.end(vals[vals.length - 1]);
|
|
1466
1465
|
createDep(
|
|
1467
|
-
source.slice(
|
|
1466
|
+
source.slice(A.nameStart(decl), A.nameEnd(decl)),
|
|
1468
1467
|
source.slice(rawStart, rawEnd),
|
|
1469
|
-
|
|
1468
|
+
A.nameEnd(decl),
|
|
1470
1469
|
rawEnd
|
|
1471
1470
|
);
|
|
1472
1471
|
}
|
|
1473
1472
|
|
|
1474
|
-
return skipWhiteLine(source,
|
|
1473
|
+
return skipWhiteLine(source, A.blockEnd(rule));
|
|
1475
1474
|
};
|
|
1476
1475
|
|
|
1477
1476
|
/**
|
|
@@ -1506,20 +1505,21 @@ class CssParser extends Parser {
|
|
|
1506
1505
|
*/
|
|
1507
1506
|
const processLocalOrGlobalFunction = (fn, type) => {
|
|
1508
1507
|
// Replace `local(` / `global(` (and a leading `:` for the `:local(`/`:global(` selector form) with empty.
|
|
1509
|
-
const
|
|
1510
|
-
const
|
|
1508
|
+
const fnStart = A.start(fn);
|
|
1509
|
+
const isColon = input.charCodeAt(fnStart - 1) === CC_COLON;
|
|
1510
|
+
const openEnd = A.nameEnd(fn) + 1;
|
|
1511
1511
|
module.addPresentationalDependency(
|
|
1512
|
-
new ConstDependency("", [isColon ?
|
|
1512
|
+
new ConstDependency("", [isColon ? fnStart - 1 : fnStart, openEnd])
|
|
1513
1513
|
);
|
|
1514
1514
|
|
|
1515
1515
|
if (type === 1) {
|
|
1516
|
-
for (const cv of fn
|
|
1517
|
-
if (
|
|
1518
|
-
let identifier =
|
|
1516
|
+
for (const cv of A.children(fn)) {
|
|
1517
|
+
if (A.type(cv) !== NodeType.Ident) continue;
|
|
1518
|
+
let identifier = A.unescaped(cv);
|
|
1519
1519
|
const {
|
|
1520
1520
|
start: { line: sl, column: sc },
|
|
1521
1521
|
end: { line: el, column: ec }
|
|
1522
|
-
} =
|
|
1522
|
+
} = A.loc(cv);
|
|
1523
1523
|
const isDashedIdent = isDashedIdentifier(identifier);
|
|
1524
1524
|
if (isDashedIdent) identifier = identifier.slice(2);
|
|
1525
1525
|
addCssExport(
|
|
@@ -1529,7 +1529,7 @@ class CssParser extends Parser {
|
|
|
1529
1529
|
ec,
|
|
1530
1530
|
identifier,
|
|
1531
1531
|
getReexport(identifier),
|
|
1532
|
-
[
|
|
1532
|
+
[A.start(cv), A.end(cv)],
|
|
1533
1533
|
true,
|
|
1534
1534
|
CssIcssExportDependency.EXPORT_MODE.ONCE,
|
|
1535
1535
|
isDashedIdent
|
|
@@ -1541,7 +1541,7 @@ class CssParser extends Parser {
|
|
|
1541
1541
|
|
|
1542
1542
|
// Replace the closing `)`.
|
|
1543
1543
|
module.addPresentationalDependency(
|
|
1544
|
-
new ConstDependency("", [
|
|
1544
|
+
new ConstDependency("", [A.end(fn) - 1, A.end(fn)])
|
|
1545
1545
|
);
|
|
1546
1546
|
};
|
|
1547
1547
|
|
|
@@ -1553,16 +1553,17 @@ class CssParser extends Parser {
|
|
|
1553
1553
|
*/
|
|
1554
1554
|
const processLocalAtRule = (atRule, options) => {
|
|
1555
1555
|
let found = false;
|
|
1556
|
-
for (const cv of
|
|
1557
|
-
|
|
1556
|
+
for (const cv of A.prelude(atRule)) {
|
|
1557
|
+
const cvType = A.type(cv);
|
|
1558
|
+
if (cvType === NodeType.Whitespace) continue;
|
|
1558
1559
|
|
|
1559
|
-
if (
|
|
1560
|
+
if (cvType === NodeType.String) {
|
|
1560
1561
|
if (!found && options.string) {
|
|
1561
|
-
const value =
|
|
1562
|
+
const value = A.unescaped(cv);
|
|
1562
1563
|
const {
|
|
1563
1564
|
start: { line: sl, column: sc },
|
|
1564
1565
|
end: { line: el, column: ec }
|
|
1565
|
-
} =
|
|
1566
|
+
} = A.loc(cv);
|
|
1566
1567
|
addCssExport(
|
|
1567
1568
|
sl,
|
|
1568
1569
|
sc,
|
|
@@ -1570,7 +1571,7 @@ class CssParser extends Parser {
|
|
|
1570
1571
|
ec,
|
|
1571
1572
|
value,
|
|
1572
1573
|
value,
|
|
1573
|
-
[
|
|
1574
|
+
[A.start(cv), A.end(cv)],
|
|
1574
1575
|
true,
|
|
1575
1576
|
CssIcssExportDependency.EXPORT_MODE.ONCE
|
|
1576
1577
|
);
|
|
@@ -1580,9 +1581,9 @@ class CssParser extends Parser {
|
|
|
1580
1581
|
continue;
|
|
1581
1582
|
}
|
|
1582
1583
|
|
|
1583
|
-
if (
|
|
1584
|
+
if (cvType === NodeType.Ident) {
|
|
1584
1585
|
if (!found && options.identifier) {
|
|
1585
|
-
const identifier =
|
|
1586
|
+
const identifier = A.unescaped(cv);
|
|
1586
1587
|
if (
|
|
1587
1588
|
options.identifier instanceof RegExp &&
|
|
1588
1589
|
options.identifier.test(identifier)
|
|
@@ -1592,7 +1593,7 @@ class CssParser extends Parser {
|
|
|
1592
1593
|
const {
|
|
1593
1594
|
start: { line: sl, column: sc },
|
|
1594
1595
|
end: { line: el, column: ec }
|
|
1595
|
-
} =
|
|
1596
|
+
} = A.loc(cv);
|
|
1596
1597
|
addCssExport(
|
|
1597
1598
|
sl,
|
|
1598
1599
|
sc,
|
|
@@ -1600,7 +1601,7 @@ class CssParser extends Parser {
|
|
|
1600
1601
|
ec,
|
|
1601
1602
|
identifier,
|
|
1602
1603
|
getReexport(identifier),
|
|
1603
|
-
[
|
|
1604
|
+
[A.start(cv), A.end(cv)],
|
|
1604
1605
|
true,
|
|
1605
1606
|
CssIcssExportDependency.EXPORT_MODE.ONCE,
|
|
1606
1607
|
CssIcssExportDependency.EXPORT_TYPE.NORMAL
|
|
@@ -1611,9 +1612,9 @@ class CssParser extends Parser {
|
|
|
1611
1612
|
continue;
|
|
1612
1613
|
}
|
|
1613
1614
|
|
|
1614
|
-
if (
|
|
1615
|
+
if (cvType === NodeType.Function) {
|
|
1615
1616
|
const fn = /** @type {FunctionNode} */ (cv);
|
|
1616
|
-
const fname =
|
|
1617
|
+
const fname = A.unescapedName(fn).toLowerCase();
|
|
1617
1618
|
const type =
|
|
1618
1619
|
fname === "local" ? 1 : fname === "global" ? 2 : undefined;
|
|
1619
1620
|
if (!found && type) {
|
|
@@ -1631,7 +1632,7 @@ class CssParser extends Parser {
|
|
|
1631
1632
|
}
|
|
1632
1633
|
}
|
|
1633
1634
|
}
|
|
1634
|
-
return
|
|
1635
|
+
return A.end(atRule);
|
|
1635
1636
|
};
|
|
1636
1637
|
/**
|
|
1637
1638
|
* Emit the ICSS export declaring this module exports the given custom property.
|
|
@@ -1724,56 +1725,64 @@ class CssParser extends Parser {
|
|
|
1724
1725
|
/** @type {Token | undefined} */
|
|
1725
1726
|
let identNode;
|
|
1726
1727
|
let identIdx = -1;
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
if (
|
|
1728
|
+
const fv = A.children(fn);
|
|
1729
|
+
for (let i = 0; i < fv.length; i++) {
|
|
1730
|
+
const cv = fv[i];
|
|
1731
|
+
if (A.type(cv) === NodeType.Whitespace) continue;
|
|
1732
|
+
if (A.type(cv) === NodeType.Ident) {
|
|
1731
1733
|
identNode = /** @type {Token} */ (cv);
|
|
1732
1734
|
identIdx = i;
|
|
1733
1735
|
}
|
|
1734
1736
|
break;
|
|
1735
1737
|
}
|
|
1736
|
-
if (!identNode
|
|
1738
|
+
if (!identNode) return;
|
|
1737
1739
|
|
|
1738
|
-
const identStart =
|
|
1739
|
-
const identEnd =
|
|
1740
|
+
const identStart = A.start(identNode);
|
|
1741
|
+
const identEnd = A.end(identNode);
|
|
1742
|
+
// `isDashedIdentifier` on the value without slicing it: a literal `--`
|
|
1743
|
+
// prefix of length >= 3 (escaped dashes don't match, same as the string
|
|
1744
|
+
// form, since the raw bytes aren't `--`).
|
|
1745
|
+
if (
|
|
1746
|
+
identEnd - identStart < 3 ||
|
|
1747
|
+
input.charCodeAt(identStart) !== CC_HYPHEN_MINUS ||
|
|
1748
|
+
input.charCodeAt(identStart + 1) !== CC_HYPHEN_MINUS
|
|
1749
|
+
) {
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1740
1752
|
|
|
1741
1753
|
let j = identIdx + 1;
|
|
1742
|
-
while (j <
|
|
1754
|
+
while (j < fv.length && A.type(fv[j]) === NodeType.Whitespace) {
|
|
1743
1755
|
j++;
|
|
1744
1756
|
}
|
|
1745
1757
|
|
|
1746
1758
|
if (
|
|
1747
|
-
j >=
|
|
1748
|
-
|
|
1749
|
-
!equalsLowerCase(
|
|
1759
|
+
j >= fv.length ||
|
|
1760
|
+
A.type(fv[j]) !== NodeType.Ident ||
|
|
1761
|
+
!equalsLowerCase(A.value(fv[j]), "from")
|
|
1750
1762
|
) {
|
|
1751
1763
|
emitDashedIdentExport(identStart, identEnd);
|
|
1752
1764
|
return;
|
|
1753
1765
|
}
|
|
1754
1766
|
|
|
1755
|
-
const fromIdent =
|
|
1767
|
+
const fromIdent = fv[j];
|
|
1756
1768
|
j++;
|
|
1757
|
-
while (j <
|
|
1769
|
+
while (j < fv.length && A.type(fv[j]) === NodeType.Whitespace) {
|
|
1758
1770
|
j++;
|
|
1759
1771
|
}
|
|
1760
|
-
if (j >=
|
|
1772
|
+
if (j >= fv.length) return;
|
|
1761
1773
|
|
|
1762
|
-
const
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
/** @type {Token} */ (source).value === "global"
|
|
1766
|
-
) {
|
|
1767
|
-
emitDashedIdentFromGlobal(identEnd, source.end);
|
|
1774
|
+
const src = fv[j];
|
|
1775
|
+
if (A.type(src) === NodeType.Ident && A.value(src) === "global") {
|
|
1776
|
+
emitDashedIdentFromGlobal(identEnd, A.end(src));
|
|
1768
1777
|
return;
|
|
1769
1778
|
}
|
|
1770
|
-
if (
|
|
1779
|
+
if (A.type(src) === NodeType.String) {
|
|
1771
1780
|
emitDashedIdentImport(
|
|
1772
1781
|
identStart,
|
|
1773
1782
|
identEnd,
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
input.slice(
|
|
1783
|
+
A.start(fromIdent),
|
|
1784
|
+
A.end(src),
|
|
1785
|
+
input.slice(A.start(src) + 1, A.end(src) - 1)
|
|
1777
1786
|
);
|
|
1778
1787
|
}
|
|
1779
1788
|
};
|
|
@@ -1785,16 +1794,14 @@ class CssParser extends Parser {
|
|
|
1785
1794
|
*/
|
|
1786
1795
|
const childrenOf = (parent) => {
|
|
1787
1796
|
if (!parent) return undefined;
|
|
1788
|
-
switch (
|
|
1797
|
+
switch (A.type(parent)) {
|
|
1789
1798
|
case NodeType.Function:
|
|
1790
|
-
return /** @type {FunctionNode} */ (parent).value;
|
|
1791
1799
|
case NodeType.SimpleBlock:
|
|
1792
|
-
return /** @type {SimpleBlock} */ (parent).value;
|
|
1793
1800
|
case NodeType.Declaration:
|
|
1794
|
-
return
|
|
1801
|
+
return A.children(parent);
|
|
1795
1802
|
case NodeType.AtRule:
|
|
1796
1803
|
case NodeType.QualifiedRule:
|
|
1797
|
-
return
|
|
1804
|
+
return A.prelude(parent);
|
|
1798
1805
|
default:
|
|
1799
1806
|
return undefined;
|
|
1800
1807
|
}
|
|
@@ -1833,6 +1840,8 @@ class CssParser extends Parser {
|
|
|
1833
1840
|
let currentStructural;
|
|
1834
1841
|
// Cached on each structural enter and read per value token, so the hot Function / Ident / Url visitors don't re-derive the property / at-rule name on every visit.
|
|
1835
1842
|
let currentAtRuleName = "";
|
|
1843
|
+
// Set by `handleImportAtRule` for a malformed `@import` so its prelude still emits orphan url() deps; read by `urlActive`. Reset per at-rule enter (replaces an ad-hoc property on the node).
|
|
1844
|
+
let currentUrlRecovery = false;
|
|
1836
1845
|
/** Whether the current Declaration's property is a localizable known property. */
|
|
1837
1846
|
let currentDeclIsKnownProperty = false;
|
|
1838
1847
|
/** Whether the current `composes:` declaration owns the whole value (suppresses value rewrites). */
|
|
@@ -1853,13 +1862,16 @@ class CssParser extends Parser {
|
|
|
1853
1862
|
*/
|
|
1854
1863
|
const stripBareMarker = (colon, ident, after) => {
|
|
1855
1864
|
const afterIsWhitespace = Boolean(
|
|
1856
|
-
after &&
|
|
1865
|
+
after && A.type(after) === NodeType.Whitespace
|
|
1857
1866
|
);
|
|
1867
|
+
const identEnd = A.end(ident);
|
|
1858
1868
|
const stripEnd =
|
|
1859
|
-
afterIsWhitespace &&
|
|
1869
|
+
afterIsWhitespace && A.start(after) === identEnd
|
|
1870
|
+
? A.end(after)
|
|
1871
|
+
: identEnd;
|
|
1860
1872
|
if (isModules) {
|
|
1861
1873
|
module.addPresentationalDependency(
|
|
1862
|
-
new ConstDependency("", [
|
|
1874
|
+
new ConstDependency("", [A.start(colon), stripEnd])
|
|
1863
1875
|
);
|
|
1864
1876
|
}
|
|
1865
1877
|
return afterIsWhitespace;
|
|
@@ -1874,17 +1886,18 @@ class CssParser extends Parser {
|
|
|
1874
1886
|
*/
|
|
1875
1887
|
const stripFunctionMarker = (colon, fn, isLocal) => {
|
|
1876
1888
|
if (!isModules) return;
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1889
|
+
const fnEnd = A.end(fn);
|
|
1890
|
+
let stripLeadEnd = fnEnd - 1;
|
|
1891
|
+
for (const arg of A.children(fn)) {
|
|
1892
|
+
if (A.type(arg) !== NodeType.Whitespace) {
|
|
1893
|
+
stripLeadEnd = A.start(arg);
|
|
1881
1894
|
break;
|
|
1882
1895
|
}
|
|
1883
1896
|
}
|
|
1884
1897
|
module.addPresentationalDependency(
|
|
1885
|
-
new ConstDependency("", [
|
|
1898
|
+
new ConstDependency("", [A.start(colon), stripLeadEnd])
|
|
1886
1899
|
);
|
|
1887
|
-
let trailStart =
|
|
1900
|
+
let trailStart = fnEnd - 1; // position of `)`
|
|
1888
1901
|
if (isLocal) {
|
|
1889
1902
|
while (
|
|
1890
1903
|
trailStart > 0 &&
|
|
@@ -1894,7 +1907,7 @@ class CssParser extends Parser {
|
|
|
1894
1907
|
}
|
|
1895
1908
|
}
|
|
1896
1909
|
module.addPresentationalDependency(
|
|
1897
|
-
new ConstDependency("", [trailStart,
|
|
1910
|
+
new ConstDependency("", [trailStart, fnEnd])
|
|
1898
1911
|
);
|
|
1899
1912
|
};
|
|
1900
1913
|
|
|
@@ -1904,37 +1917,33 @@ class CssParser extends Parser {
|
|
|
1904
1917
|
* @returns {void}
|
|
1905
1918
|
*/
|
|
1906
1919
|
const handleAttributeSelector = (block) => {
|
|
1907
|
-
const attrParts = block
|
|
1920
|
+
const attrParts = A.children(block);
|
|
1908
1921
|
let ai = 0;
|
|
1909
1922
|
while (
|
|
1910
1923
|
ai < attrParts.length &&
|
|
1911
|
-
attrParts[ai]
|
|
1924
|
+
A.type(attrParts[ai]) === NodeType.Whitespace
|
|
1912
1925
|
) {
|
|
1913
1926
|
ai++;
|
|
1914
1927
|
}
|
|
1915
1928
|
const attrNameNode = attrParts[ai];
|
|
1916
|
-
if (!attrNameNode ||
|
|
1917
|
-
const attrName =
|
|
1929
|
+
if (!attrNameNode || A.type(attrNameNode) !== NodeType.Ident) return;
|
|
1930
|
+
const attrName = A.unescaped(attrNameNode);
|
|
1918
1931
|
if (!equalsLowerCase(attrName, "class")) return;
|
|
1919
1932
|
ai++;
|
|
1920
1933
|
while (
|
|
1921
1934
|
ai < attrParts.length &&
|
|
1922
|
-
attrParts[ai]
|
|
1935
|
+
A.type(attrParts[ai]) === NodeType.Whitespace
|
|
1923
1936
|
) {
|
|
1924
1937
|
ai++;
|
|
1925
1938
|
}
|
|
1926
1939
|
// `=` or `~=` (two `Delim` tokens for the latter).
|
|
1927
1940
|
const op1 = attrParts[ai];
|
|
1928
|
-
if (!op1 ||
|
|
1929
|
-
const op1v =
|
|
1941
|
+
if (!op1 || A.type(op1) !== NodeType.Delim) return;
|
|
1942
|
+
const op1v = A.value(op1);
|
|
1930
1943
|
if (op1v === "~") {
|
|
1931
1944
|
ai++;
|
|
1932
1945
|
const op2 = attrParts[ai];
|
|
1933
|
-
if (
|
|
1934
|
-
!op2 ||
|
|
1935
|
-
op2.type !== NodeType.Delim ||
|
|
1936
|
-
/** @type {Token} */ (op2).value !== "="
|
|
1937
|
-
) {
|
|
1946
|
+
if (!op2 || A.type(op2) !== NodeType.Delim || A.value(op2) !== "=") {
|
|
1938
1947
|
return;
|
|
1939
1948
|
}
|
|
1940
1949
|
} else if (op1v !== "=") {
|
|
@@ -1943,7 +1952,7 @@ class CssParser extends Parser {
|
|
|
1943
1952
|
ai++;
|
|
1944
1953
|
while (
|
|
1945
1954
|
ai < attrParts.length &&
|
|
1946
|
-
attrParts[ai]
|
|
1955
|
+
A.type(attrParts[ai]) === NodeType.Whitespace
|
|
1947
1956
|
) {
|
|
1948
1957
|
ai++;
|
|
1949
1958
|
}
|
|
@@ -1953,12 +1962,12 @@ class CssParser extends Parser {
|
|
|
1953
1962
|
let classNameStart;
|
|
1954
1963
|
/** @type {number} */
|
|
1955
1964
|
let classNameEnd;
|
|
1956
|
-
if (
|
|
1957
|
-
classNameStart =
|
|
1958
|
-
classNameEnd =
|
|
1959
|
-
} else if (
|
|
1960
|
-
classNameStart =
|
|
1961
|
-
classNameEnd =
|
|
1965
|
+
if (A.type(attrValueNode) === NodeType.String) {
|
|
1966
|
+
classNameStart = A.start(attrValueNode) + 1;
|
|
1967
|
+
classNameEnd = A.end(attrValueNode) - 1;
|
|
1968
|
+
} else if (A.type(attrValueNode) === NodeType.Ident) {
|
|
1969
|
+
classNameStart = A.start(attrValueNode);
|
|
1970
|
+
classNameEnd = A.end(attrValueNode);
|
|
1962
1971
|
} else {
|
|
1963
1972
|
return;
|
|
1964
1973
|
}
|
|
@@ -1998,7 +2007,7 @@ class CssParser extends Parser {
|
|
|
1998
2007
|
}
|
|
1999
2008
|
for (let i = 0; i < values.length; i++) {
|
|
2000
2009
|
const v = values[i];
|
|
2001
|
-
switch (
|
|
2010
|
+
switch (A.type(v)) {
|
|
2002
2011
|
case NodeType.Whitespace:
|
|
2003
2012
|
break;
|
|
2004
2013
|
case NodeType.Comma:
|
|
@@ -2013,8 +2022,9 @@ class CssParser extends Parser {
|
|
|
2013
2022
|
// Look ahead for `:local` / `:global` markers; other pseudos fall through.
|
|
2014
2023
|
const next = values[i + 1];
|
|
2015
2024
|
if (!next) break;
|
|
2016
|
-
|
|
2017
|
-
|
|
2025
|
+
const nextType = A.type(next);
|
|
2026
|
+
if (nextType === NodeType.Ident) {
|
|
2027
|
+
const raw = A.value(next);
|
|
2018
2028
|
const isLocal = equalsLowerCase(raw, "local");
|
|
2019
2029
|
if (isLocal || equalsLowerCase(raw, "global")) {
|
|
2020
2030
|
const id = isLocal ? "local" : "global";
|
|
@@ -2029,12 +2039,12 @@ class CssParser extends Parser {
|
|
|
2029
2039
|
this._emitWarning(
|
|
2030
2040
|
state,
|
|
2031
2041
|
`Missing whitespace after ':${id}' in '${source.slice(
|
|
2032
|
-
|
|
2033
|
-
findLeftCurly(source,
|
|
2042
|
+
A.start(v),
|
|
2043
|
+
findLeftCurly(source, A.end(next)) + 1
|
|
2034
2044
|
)}'`,
|
|
2035
2045
|
locConverter,
|
|
2036
|
-
|
|
2037
|
-
|
|
2046
|
+
A.start(v),
|
|
2047
|
+
A.end(next)
|
|
2038
2048
|
);
|
|
2039
2049
|
}
|
|
2040
2050
|
segmentMode = id;
|
|
@@ -2042,14 +2052,18 @@ class CssParser extends Parser {
|
|
|
2042
2052
|
// Skip past the colon + ident.
|
|
2043
2053
|
i += 1;
|
|
2044
2054
|
}
|
|
2045
|
-
} else if (
|
|
2055
|
+
} else if (nextType === NodeType.Function) {
|
|
2046
2056
|
const fn = /** @type {FunctionNode} */ (next);
|
|
2047
|
-
const rawName =
|
|
2057
|
+
const rawName = A.unescapedName(fn);
|
|
2048
2058
|
const isLocal = equalsLowerCase(rawName, "local");
|
|
2049
2059
|
if (isLocal || equalsLowerCase(rawName, "global")) {
|
|
2050
2060
|
// `:local(…)` / `:global(…)`: scope mode to the args and strip the `:name(` … `)` wrapper.
|
|
2051
2061
|
stripFunctionMarker(v, fn, isLocal);
|
|
2052
|
-
walkSelectorList(
|
|
2062
|
+
walkSelectorList(
|
|
2063
|
+
A.children(fn),
|
|
2064
|
+
isLocal ? "local" : "global",
|
|
2065
|
+
false
|
|
2066
|
+
);
|
|
2053
2067
|
// Skip past the colon + function.
|
|
2054
2068
|
i += 1;
|
|
2055
2069
|
}
|
|
@@ -2058,26 +2072,19 @@ class CssParser extends Parser {
|
|
|
2058
2072
|
}
|
|
2059
2073
|
case NodeType.Function:
|
|
2060
2074
|
// Any other function (`:not(…)`, `:is(…)`, …): recurse with the segment mode preserved (only `:local(…)` / `:global(…)`, handled above, switch mode).
|
|
2061
|
-
walkSelectorList(
|
|
2062
|
-
/** @type {FunctionNode} */ (v).value,
|
|
2063
|
-
segmentMode,
|
|
2064
|
-
false
|
|
2065
|
-
);
|
|
2075
|
+
walkSelectorList(A.children(v), segmentMode, false);
|
|
2066
2076
|
break;
|
|
2067
2077
|
case NodeType.Hash: {
|
|
2068
|
-
if (
|
|
2069
|
-
/** @type {HashToken} */ (v).typeFlag !== "id" ||
|
|
2070
|
-
segmentMode !== "local"
|
|
2071
|
-
) {
|
|
2078
|
+
if (A.typeFlag(v) !== "id" || segmentMode !== "local") {
|
|
2072
2079
|
break;
|
|
2073
2080
|
}
|
|
2074
2081
|
// ID selectors emit the ICSS export but aren't a `composes:` anchor.
|
|
2075
|
-
const idValueStart =
|
|
2076
|
-
const idName =
|
|
2082
|
+
const idValueStart = A.start(v) + 1;
|
|
2083
|
+
const idName = A.unescaped(v);
|
|
2077
2084
|
const {
|
|
2078
2085
|
start: { line: idSl, column: idSc },
|
|
2079
2086
|
end: { line: idEl, column: idEc }
|
|
2080
|
-
} =
|
|
2087
|
+
} = A.loc(v);
|
|
2081
2088
|
addCssExport(
|
|
2082
2089
|
idSl,
|
|
2083
2090
|
idSc,
|
|
@@ -2085,7 +2092,7 @@ class CssParser extends Parser {
|
|
|
2085
2092
|
idEc,
|
|
2086
2093
|
idName,
|
|
2087
2094
|
getReexport(idName),
|
|
2088
|
-
[idValueStart,
|
|
2095
|
+
[idValueStart, A.end(v)],
|
|
2089
2096
|
true,
|
|
2090
2097
|
CssIcssExportDependency.EXPORT_MODE.ONCE
|
|
2091
2098
|
);
|
|
@@ -2094,17 +2101,18 @@ class CssParser extends Parser {
|
|
|
2094
2101
|
}
|
|
2095
2102
|
case NodeType.SimpleBlock: {
|
|
2096
2103
|
const block = /** @type {SimpleBlock} */ (v);
|
|
2097
|
-
|
|
2104
|
+
const bt = A.blockToken(block);
|
|
2105
|
+
if (bt === "[") {
|
|
2098
2106
|
// Attribute selectors `[class="foo"]` localize only in local mode.
|
|
2099
2107
|
if (segmentMode === "local") handleAttributeSelector(block);
|
|
2100
|
-
} else if (
|
|
2108
|
+
} else if (bt === "(") {
|
|
2101
2109
|
// `@scope (.foo)` and other parenthesised selector wrappers — recurse into the `(…)` block.
|
|
2102
|
-
walkSelectorList(block
|
|
2110
|
+
walkSelectorList(A.children(block), segmentMode, false);
|
|
2103
2111
|
}
|
|
2104
2112
|
break;
|
|
2105
2113
|
}
|
|
2106
2114
|
case NodeType.Delim: {
|
|
2107
|
-
const delim =
|
|
2115
|
+
const delim = A.value(v);
|
|
2108
2116
|
if (delim === "&") {
|
|
2109
2117
|
// Pure-mode: a nesting `&` inherits a pure ancestor's purity.
|
|
2110
2118
|
if (topLevel && pure.ancestorHadLocal()) pure.markLocal();
|
|
@@ -2112,14 +2120,14 @@ class CssParser extends Parser {
|
|
|
2112
2120
|
}
|
|
2113
2121
|
if (delim !== ".") break;
|
|
2114
2122
|
const next = values[i + 1];
|
|
2115
|
-
if (!next ||
|
|
2123
|
+
if (!next || A.type(next) !== NodeType.Ident) break;
|
|
2116
2124
|
if (segmentMode === "local") {
|
|
2117
2125
|
// `.<ident>` in local mode is a class selector (dep covers the ident bytes only).
|
|
2118
|
-
const name =
|
|
2126
|
+
const name = A.unescaped(next);
|
|
2119
2127
|
const {
|
|
2120
2128
|
start: { line: sl, column: sc },
|
|
2121
2129
|
end: { line: el, column: ec }
|
|
2122
|
-
} =
|
|
2130
|
+
} = A.loc(next);
|
|
2123
2131
|
addCssExport(
|
|
2124
2132
|
sl,
|
|
2125
2133
|
sc,
|
|
@@ -2127,7 +2135,7 @@ class CssParser extends Parser {
|
|
|
2127
2135
|
ec,
|
|
2128
2136
|
name,
|
|
2129
2137
|
getReexport(name),
|
|
2130
|
-
[
|
|
2138
|
+
[A.start(next), A.end(next)],
|
|
2131
2139
|
true,
|
|
2132
2140
|
CssIcssExportDependency.EXPORT_MODE.ONCE
|
|
2133
2141
|
);
|
|
@@ -2136,9 +2144,9 @@ class CssParser extends Parser {
|
|
|
2136
2144
|
pure.markLocal();
|
|
2137
2145
|
} else {
|
|
2138
2146
|
// `.<ident>` in global mode: not localized, but the ident may be `@value`-defined and need ICSS rewrite.
|
|
2139
|
-
const ident =
|
|
2147
|
+
const ident = A.value(next);
|
|
2140
2148
|
if (!isDashedIdentifier(ident) && icssDefinitions.has(ident)) {
|
|
2141
|
-
emitICSSSymbol(ident,
|
|
2149
|
+
emitICSSSymbol(ident, A.start(next), A.end(next));
|
|
2142
2150
|
}
|
|
2143
2151
|
}
|
|
2144
2152
|
// Skip the consumed ident.
|
|
@@ -2147,9 +2155,9 @@ class CssParser extends Parser {
|
|
|
2147
2155
|
}
|
|
2148
2156
|
case NodeType.Ident: {
|
|
2149
2157
|
// ICSS rewrite for a bare `@value`-defined ident used as a type-style selector.
|
|
2150
|
-
const ident =
|
|
2158
|
+
const ident = A.value(v);
|
|
2151
2159
|
if (!isDashedIdentifier(ident) && icssDefinitions.has(ident)) {
|
|
2152
|
-
emitICSSSymbol(ident,
|
|
2160
|
+
emitICSSSymbol(ident, A.start(v), A.end(v));
|
|
2153
2161
|
}
|
|
2154
2162
|
break;
|
|
2155
2163
|
}
|
|
@@ -2172,11 +2180,11 @@ class CssParser extends Parser {
|
|
|
2172
2180
|
*/
|
|
2173
2181
|
const urlActive = () => {
|
|
2174
2182
|
if (!this.options.url || !currentStructural) return false;
|
|
2175
|
-
if (
|
|
2176
|
-
|
|
2177
|
-
currentStructural
|
|
2183
|
+
if (A.type(currentStructural) === NodeType.AtRule) {
|
|
2184
|
+
return (
|
|
2185
|
+
!equalsLowerCase(A.name(currentStructural), "import") ||
|
|
2186
|
+
currentUrlRecovery
|
|
2178
2187
|
);
|
|
2179
|
-
return !equalsLowerCase(at.name, "import") || Boolean(at.urlRecovery);
|
|
2180
2188
|
}
|
|
2181
2189
|
return true;
|
|
2182
2190
|
};
|
|
@@ -2204,10 +2212,11 @@ class CssParser extends Parser {
|
|
|
2204
2212
|
*/
|
|
2205
2213
|
const localGlobalActive = () => {
|
|
2206
2214
|
if (!isModules || !currentStructural) return false;
|
|
2207
|
-
|
|
2215
|
+
const t = A.type(currentStructural);
|
|
2216
|
+
if (t === NodeType.AtRule) {
|
|
2208
2217
|
return !isLocalHandledAtRule(currentAtRuleName);
|
|
2209
2218
|
}
|
|
2210
|
-
if (
|
|
2219
|
+
if (t === NodeType.Declaration) {
|
|
2211
2220
|
return !currentDeclComposesSkip;
|
|
2212
2221
|
}
|
|
2213
2222
|
return false;
|
|
@@ -2219,12 +2228,13 @@ class CssParser extends Parser {
|
|
|
2219
2228
|
*/
|
|
2220
2229
|
const icssActive = () => {
|
|
2221
2230
|
if (!isModules || !currentStructural) return false;
|
|
2222
|
-
|
|
2231
|
+
const t = A.type(currentStructural);
|
|
2232
|
+
if (t === NodeType.AtRule) {
|
|
2223
2233
|
return (
|
|
2224
2234
|
currentAtRuleName !== "@value" && currentAtRuleName !== "@import"
|
|
2225
2235
|
);
|
|
2226
2236
|
}
|
|
2227
|
-
if (
|
|
2237
|
+
if (t === NodeType.Declaration) {
|
|
2228
2238
|
return !currentDeclComposesSkip && !currentDeclIsKnownProperty;
|
|
2229
2239
|
}
|
|
2230
2240
|
return false;
|
|
@@ -2237,8 +2247,7 @@ class CssParser extends Parser {
|
|
|
2237
2247
|
* @returns {void}
|
|
2238
2248
|
*/
|
|
2239
2249
|
const finishTopLevelRule = (node, blockBearing) => {
|
|
2240
|
-
|
|
2241
|
-
if (!blockBearing || at.declarations || at.childRules) {
|
|
2250
|
+
if (!blockBearing || A.declarations(node) || A.childRules(node)) {
|
|
2242
2251
|
allowImport = false;
|
|
2243
2252
|
}
|
|
2244
2253
|
pure.markSeenTopLevelRule();
|
|
@@ -2383,8 +2392,8 @@ class CssParser extends Parser {
|
|
|
2383
2392
|
'", "'
|
|
2384
2393
|
)}"`,
|
|
2385
2394
|
locConverter,
|
|
2386
|
-
|
|
2387
|
-
|
|
2395
|
+
A.start(decl),
|
|
2396
|
+
A.end(decl)
|
|
2388
2397
|
);
|
|
2389
2398
|
return;
|
|
2390
2399
|
}
|
|
@@ -2395,8 +2404,8 @@ class CssParser extends Parser {
|
|
|
2395
2404
|
const groups = [];
|
|
2396
2405
|
/** @type {AstNode[]} */
|
|
2397
2406
|
let currentGroup = [];
|
|
2398
|
-
for (const cv of decl
|
|
2399
|
-
if (
|
|
2407
|
+
for (const cv of A.children(decl)) {
|
|
2408
|
+
if (A.type(cv) === NodeType.Comma) {
|
|
2400
2409
|
groups.push(currentGroup);
|
|
2401
2410
|
currentGroup = [];
|
|
2402
2411
|
} else {
|
|
@@ -2419,20 +2428,20 @@ class CssParser extends Parser {
|
|
|
2419
2428
|
|
|
2420
2429
|
for (let i = 0; i < group.length; i++) {
|
|
2421
2430
|
const cv = group[i];
|
|
2422
|
-
if (
|
|
2431
|
+
if (A.type(cv) === NodeType.Whitespace) continue;
|
|
2423
2432
|
|
|
2424
2433
|
if (phase === "expecting-source") {
|
|
2425
|
-
if (
|
|
2434
|
+
if (A.type(cv) === NodeType.String) {
|
|
2426
2435
|
fromSource = {
|
|
2427
2436
|
kind: "string",
|
|
2428
|
-
path: source.slice(
|
|
2437
|
+
path: source.slice(A.start(cv) + 1, A.end(cv) - 1)
|
|
2429
2438
|
};
|
|
2430
2439
|
phase = "done";
|
|
2431
2440
|
continue;
|
|
2432
2441
|
}
|
|
2433
2442
|
if (
|
|
2434
|
-
|
|
2435
|
-
equalsLowerCase(
|
|
2443
|
+
A.type(cv) === NodeType.Ident &&
|
|
2444
|
+
equalsLowerCase(A.value(cv), "global")
|
|
2436
2445
|
) {
|
|
2437
2446
|
fromSource = { kind: "global" };
|
|
2438
2447
|
phase = "done";
|
|
@@ -2448,8 +2457,8 @@ class CssParser extends Parser {
|
|
|
2448
2457
|
continue;
|
|
2449
2458
|
}
|
|
2450
2459
|
|
|
2451
|
-
if (
|
|
2452
|
-
const identValue =
|
|
2460
|
+
if (A.type(cv) === NodeType.Ident) {
|
|
2461
|
+
const identValue = A.value(cv);
|
|
2453
2462
|
if (
|
|
2454
2463
|
equalsLowerCase(identValue, "from") &&
|
|
2455
2464
|
classNames.length > 0 &&
|
|
@@ -2459,21 +2468,21 @@ class CssParser extends Parser {
|
|
|
2459
2468
|
continue;
|
|
2460
2469
|
}
|
|
2461
2470
|
classNames.push({
|
|
2462
|
-
start:
|
|
2463
|
-
end:
|
|
2471
|
+
start: A.start(cv),
|
|
2472
|
+
end: A.end(cv),
|
|
2464
2473
|
isGlobal: false
|
|
2465
2474
|
});
|
|
2466
2475
|
continue;
|
|
2467
2476
|
}
|
|
2468
2477
|
|
|
2469
|
-
if (
|
|
2478
|
+
if (A.type(cv) === NodeType.Function) {
|
|
2470
2479
|
const fn = /** @type {FunctionNode} */ (cv);
|
|
2471
|
-
const isGlobal = equalsLowerCase(
|
|
2472
|
-
for (const inner of fn
|
|
2473
|
-
if (
|
|
2480
|
+
const isGlobal = equalsLowerCase(A.unescapedName(fn), "global");
|
|
2481
|
+
for (const inner of A.children(fn)) {
|
|
2482
|
+
if (A.type(inner) === NodeType.Ident) {
|
|
2474
2483
|
classNames.push({
|
|
2475
|
-
start:
|
|
2476
|
-
end:
|
|
2484
|
+
start: A.start(inner),
|
|
2485
|
+
end: A.end(inner),
|
|
2477
2486
|
isGlobal
|
|
2478
2487
|
});
|
|
2479
2488
|
break;
|
|
@@ -2500,8 +2509,8 @@ class CssParser extends Parser {
|
|
|
2500
2509
|
state,
|
|
2501
2510
|
errorMessage,
|
|
2502
2511
|
locConverter,
|
|
2503
|
-
|
|
2504
|
-
|
|
2512
|
+
A.start(errorToken),
|
|
2513
|
+
A.end(errorToken)
|
|
2505
2514
|
);
|
|
2506
2515
|
return;
|
|
2507
2516
|
}
|
|
@@ -2512,13 +2521,13 @@ class CssParser extends Parser {
|
|
|
2512
2521
|
}
|
|
2513
2522
|
|
|
2514
2523
|
// Strip the whole `composes: …;` (property name included) plus trailing same-line whitespace. The `;` and that whitespace aren't AST nodes (a block's contents drop them), so scan the source here.
|
|
2515
|
-
let resumeAt =
|
|
2516
|
-
if (source.charCodeAt(
|
|
2517
|
-
resumeAt =
|
|
2524
|
+
let resumeAt = A.end(decl);
|
|
2525
|
+
if (source.charCodeAt(A.end(decl)) === CC_SEMICOLON) {
|
|
2526
|
+
resumeAt = A.end(decl) + 1;
|
|
2518
2527
|
while (isCssWhitespace(source.charCodeAt(resumeAt))) resumeAt++;
|
|
2519
2528
|
}
|
|
2520
2529
|
module.addPresentationalDependency(
|
|
2521
|
-
new ConstDependency("", [
|
|
2530
|
+
new ConstDependency("", [A.nameStart(decl), resumeAt])
|
|
2522
2531
|
);
|
|
2523
2532
|
};
|
|
2524
2533
|
|
|
@@ -2530,63 +2539,69 @@ class CssParser extends Parser {
|
|
|
2530
2539
|
const emitUrlFunction = (fn, fname) => {
|
|
2531
2540
|
if (fname === "url" || fname === "src") {
|
|
2532
2541
|
// Quoted `url("…")` / `src("…")`: first non-whitespace value must be the string token.
|
|
2533
|
-
const first = fn
|
|
2534
|
-
if (!first ||
|
|
2542
|
+
const first = A.children(fn)[nextNonWhitespace(A.children(fn), 0)];
|
|
2543
|
+
if (!first || A.type(first) !== NodeType.String) return;
|
|
2535
2544
|
const string = /** @type {Token} */ (first);
|
|
2536
2545
|
if (
|
|
2537
2546
|
webpackIgnored(
|
|
2538
|
-
[lastTokenEndForComments,
|
|
2539
|
-
|
|
2540
|
-
|
|
2547
|
+
[lastTokenEndForComments, A.start(fn)],
|
|
2548
|
+
A.start(string),
|
|
2549
|
+
A.end(string)
|
|
2541
2550
|
)
|
|
2542
2551
|
) {
|
|
2543
2552
|
return;
|
|
2544
2553
|
}
|
|
2545
2554
|
const value = normalizeUrl(
|
|
2546
|
-
input.slice(
|
|
2555
|
+
input.slice(A.start(string) + 1, A.end(string) - 1),
|
|
2547
2556
|
true
|
|
2548
2557
|
);
|
|
2549
2558
|
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
|
2550
2559
|
if (value.length === 0) return;
|
|
2551
2560
|
const dep = new CssUrlDependency(
|
|
2552
2561
|
value,
|
|
2553
|
-
[
|
|
2562
|
+
[A.start(string), A.end(string)],
|
|
2554
2563
|
"string"
|
|
2555
2564
|
);
|
|
2556
|
-
setDepLoc(dep,
|
|
2565
|
+
setDepLoc(dep, A.start(string), A.end(string));
|
|
2557
2566
|
module.addDependency(dep);
|
|
2558
2567
|
module.addCodeGenerationDependency(dep);
|
|
2559
2568
|
} else if (IMAGE_SET_FUNCTION.test(fname)) {
|
|
2560
2569
|
// `image-set(…)`: each comma segment's first string is the URL; advance the magic-comment fence per string.
|
|
2561
|
-
lastTokenEndForComments =
|
|
2562
|
-
let prevStringEnd =
|
|
2570
|
+
lastTokenEndForComments = A.nameEnd(fn) + 1;
|
|
2571
|
+
let prevStringEnd = A.start(fn);
|
|
2563
2572
|
let firstInSegment = true;
|
|
2564
|
-
for (const cv of fn
|
|
2565
|
-
if (
|
|
2573
|
+
for (const cv of A.children(fn)) {
|
|
2574
|
+
if (A.type(cv) === NodeType.Comma) {
|
|
2566
2575
|
firstInSegment = true;
|
|
2567
2576
|
continue;
|
|
2568
2577
|
}
|
|
2569
|
-
if (
|
|
2578
|
+
if (A.type(cv) === NodeType.Whitespace) continue;
|
|
2570
2579
|
const wasFirst = firstInSegment;
|
|
2571
2580
|
firstInSegment = false;
|
|
2572
|
-
if (!wasFirst ||
|
|
2581
|
+
if (!wasFirst || A.type(cv) !== NodeType.String) continue;
|
|
2573
2582
|
const string = /** @type {Token} */ (cv);
|
|
2574
2583
|
const start = prevStringEnd;
|
|
2575
|
-
prevStringEnd =
|
|
2584
|
+
prevStringEnd = A.end(string);
|
|
2576
2585
|
const value = normalizeUrl(
|
|
2577
|
-
input.slice(
|
|
2586
|
+
input.slice(A.start(string) + 1, A.end(string) - 1),
|
|
2578
2587
|
true
|
|
2579
2588
|
);
|
|
2580
2589
|
if (value.length === 0) continue;
|
|
2581
|
-
if (
|
|
2590
|
+
if (
|
|
2591
|
+
webpackIgnored(
|
|
2592
|
+
[start, A.end(string)],
|
|
2593
|
+
A.start(string),
|
|
2594
|
+
A.end(string)
|
|
2595
|
+
)
|
|
2596
|
+
) {
|
|
2582
2597
|
continue;
|
|
2583
2598
|
}
|
|
2584
2599
|
const dep = new CssUrlDependency(
|
|
2585
2600
|
value,
|
|
2586
|
-
[
|
|
2601
|
+
[A.start(string), A.end(string)],
|
|
2587
2602
|
"url"
|
|
2588
2603
|
);
|
|
2589
|
-
setDepLoc(dep,
|
|
2604
|
+
setDepLoc(dep, A.start(string), A.end(string));
|
|
2590
2605
|
module.addDependency(dep);
|
|
2591
2606
|
module.addCodeGenerationDependency(dep);
|
|
2592
2607
|
}
|
|
@@ -2605,24 +2620,24 @@ class CssParser extends Parser {
|
|
|
2605
2620
|
state,
|
|
2606
2621
|
"Any '@import' rules must precede all other rules",
|
|
2607
2622
|
locConverter,
|
|
2608
|
-
|
|
2609
|
-
|
|
2623
|
+
A.start(at),
|
|
2624
|
+
A.nameEnd(at)
|
|
2610
2625
|
);
|
|
2611
2626
|
return;
|
|
2612
2627
|
}
|
|
2613
|
-
const importStart =
|
|
2614
|
-
const importNameEnd =
|
|
2628
|
+
const importStart = A.start(at);
|
|
2629
|
+
const importNameEnd = A.nameEnd(at);
|
|
2615
2630
|
// We only accept `;`-terminated @import; block / EOF / `}` ends are silent bails.
|
|
2616
|
-
if (source.charCodeAt(
|
|
2631
|
+
if (source.charCodeAt(A.end(at)) !== CC_SEMICOLON) return;
|
|
2617
2632
|
|
|
2618
2633
|
// Walk the prelude in spec order (URL → layer? → supports? → media query); anything else joins the media query.
|
|
2619
2634
|
const { urlNode, layerNode, supportsNode } = parseImportPrelude(
|
|
2620
|
-
|
|
2635
|
+
A.prelude(at)
|
|
2621
2636
|
);
|
|
2622
2637
|
|
|
2623
|
-
const semi =
|
|
2638
|
+
const semi = A.end(at) + 1; // position past `;`
|
|
2624
2639
|
|
|
2625
|
-
if (!urlNode || (
|
|
2640
|
+
if (!urlNode || (A.type(urlNode) === NodeType.Ident && !isModules)) {
|
|
2626
2641
|
this._emitWarning(
|
|
2627
2642
|
state,
|
|
2628
2643
|
`Expected URL in '${input.slice(importStart, semi)}'`,
|
|
@@ -2630,17 +2645,16 @@ class CssParser extends Parser {
|
|
|
2630
2645
|
importStart,
|
|
2631
2646
|
semi
|
|
2632
2647
|
);
|
|
2633
|
-
// A malformed `@import` still emits orphan url() deps from its prelude — flag
|
|
2634
|
-
|
|
2635
|
-
true;
|
|
2648
|
+
// A malformed `@import` still emits orphan url() deps from its prelude — flag it so the value visitors enable url().
|
|
2649
|
+
currentUrlRecovery = true;
|
|
2636
2650
|
return;
|
|
2637
2651
|
}
|
|
2638
2652
|
|
|
2639
2653
|
/** @type {string} */
|
|
2640
2654
|
let url;
|
|
2641
|
-
if (
|
|
2655
|
+
if (A.type(urlNode) === NodeType.Ident) {
|
|
2642
2656
|
// URL given as identifier — resolve via CSS Modules `@value`.
|
|
2643
|
-
const identName =
|
|
2657
|
+
const identName = A.value(urlNode);
|
|
2644
2658
|
const def = icssDefinitions.get(identName);
|
|
2645
2659
|
if (!def) {
|
|
2646
2660
|
this._emitWarning(
|
|
@@ -2676,21 +2690,24 @@ class CssParser extends Parser {
|
|
|
2676
2690
|
(raw.startsWith("'") && raw.endsWith("'"))
|
|
2677
2691
|
? normalizeUrl(raw.slice(1, -1), true)
|
|
2678
2692
|
: normalizeUrl(raw, false);
|
|
2679
|
-
} else if (
|
|
2693
|
+
} else if (A.type(urlNode) === NodeType.Url) {
|
|
2680
2694
|
const ut = /** @type {UrlToken} */ (urlNode);
|
|
2681
|
-
url = normalizeUrl(input.slice(ut.contentStart, ut.contentEnd), false);
|
|
2682
|
-
} else if (urlNode.type === NodeType.String) {
|
|
2683
2695
|
url = normalizeUrl(
|
|
2684
|
-
input.slice(
|
|
2696
|
+
input.slice(A.contentStart(ut), A.contentEnd(ut)),
|
|
2697
|
+
false
|
|
2698
|
+
);
|
|
2699
|
+
} else if (A.type(urlNode) === NodeType.String) {
|
|
2700
|
+
url = normalizeUrl(
|
|
2701
|
+
input.slice(A.start(urlNode) + 1, A.end(urlNode) - 1),
|
|
2685
2702
|
true
|
|
2686
2703
|
);
|
|
2687
2704
|
} else {
|
|
2688
2705
|
// url(...) function — first non-whitespace child is the string.
|
|
2689
2706
|
/** @type {Token | undefined} */
|
|
2690
2707
|
let string;
|
|
2691
|
-
for (const inner of
|
|
2692
|
-
if (
|
|
2693
|
-
if (
|
|
2708
|
+
for (const inner of A.children(urlNode)) {
|
|
2709
|
+
if (A.type(inner) === NodeType.Whitespace) continue;
|
|
2710
|
+
if (A.type(inner) === NodeType.String) {
|
|
2694
2711
|
string = /** @type {Token} */ (inner);
|
|
2695
2712
|
}
|
|
2696
2713
|
break;
|
|
@@ -2705,11 +2722,16 @@ class CssParser extends Parser {
|
|
|
2705
2722
|
);
|
|
2706
2723
|
return;
|
|
2707
2724
|
}
|
|
2708
|
-
url = normalizeUrl(
|
|
2725
|
+
url = normalizeUrl(
|
|
2726
|
+
input.slice(A.start(string) + 1, A.end(string) - 1),
|
|
2727
|
+
true
|
|
2728
|
+
);
|
|
2709
2729
|
}
|
|
2710
2730
|
|
|
2711
2731
|
const newline = skipWhiteLine(input, semi);
|
|
2712
|
-
if (
|
|
2732
|
+
if (
|
|
2733
|
+
webpackIgnored([importNameEnd, A.end(urlNode)], importStart, newline)
|
|
2734
|
+
) {
|
|
2713
2735
|
return;
|
|
2714
2736
|
}
|
|
2715
2737
|
if (url.length === 0) {
|
|
@@ -2723,10 +2745,10 @@ class CssParser extends Parser {
|
|
|
2723
2745
|
/** @type {undefined | string} */
|
|
2724
2746
|
let layer;
|
|
2725
2747
|
if (layerNode) {
|
|
2726
|
-
if (
|
|
2748
|
+
if (A.type(layerNode) === NodeType.Function) {
|
|
2727
2749
|
// `layer(<ident>)` — extract content between `(` and `)`.
|
|
2728
2750
|
const fn = /** @type {FunctionNode} */ (layerNode);
|
|
2729
|
-
layer = input.slice(
|
|
2751
|
+
layer = input.slice(A.nameEnd(fn) + 1, A.end(fn) - 1).trim();
|
|
2730
2752
|
} else {
|
|
2731
2753
|
// Bare `layer` ident — anonymous layer.
|
|
2732
2754
|
layer = "";
|
|
@@ -2737,21 +2759,23 @@ class CssParser extends Parser {
|
|
|
2737
2759
|
let supports;
|
|
2738
2760
|
if (supportsNode) {
|
|
2739
2761
|
supports = input
|
|
2740
|
-
.slice(
|
|
2762
|
+
.slice(A.nameEnd(supportsNode) + 1, A.end(supportsNode) - 1)
|
|
2741
2763
|
.trim();
|
|
2742
2764
|
}
|
|
2743
2765
|
|
|
2744
2766
|
// Media query = whatever sits between the last url/layer/supports part and the closing `;`, trimmed. Start at the next non-whitespace prelude node (skips the gap, comments included).
|
|
2745
2767
|
const lastPrefixPart = supportsNode || layerNode || urlNode;
|
|
2746
2768
|
const afterIdx =
|
|
2747
|
-
/** @type {AstNode[]} */ (
|
|
2748
|
-
const nextIdx = nextNonWhitespace(
|
|
2769
|
+
/** @type {AstNode[]} */ (A.prelude(at)).indexOf(lastPrefixPart) + 1;
|
|
2770
|
+
const nextIdx = nextNonWhitespace(A.prelude(at), afterIdx);
|
|
2749
2771
|
const mediaStart =
|
|
2750
|
-
nextIdx <
|
|
2772
|
+
nextIdx < A.prelude(at).length
|
|
2773
|
+
? A.start(A.prelude(at)[nextIdx])
|
|
2774
|
+
: A.end(at);
|
|
2751
2775
|
/** @type {undefined | string} */
|
|
2752
2776
|
let media;
|
|
2753
|
-
if (mediaStart !==
|
|
2754
|
-
media = input.slice(mediaStart,
|
|
2777
|
+
if (mediaStart !== A.end(at)) {
|
|
2778
|
+
media = input.slice(mediaStart, A.end(at)).trim();
|
|
2755
2779
|
}
|
|
2756
2780
|
|
|
2757
2781
|
const { line: sl, column: sc } = locConverter.get(importStart);
|
|
@@ -2793,9 +2817,9 @@ class CssParser extends Parser {
|
|
|
2793
2817
|
* @param {AtRule} at the `@value` at-rule
|
|
2794
2818
|
*/
|
|
2795
2819
|
const handleValueAtRule = (at) => {
|
|
2796
|
-
const start =
|
|
2797
|
-
const nameEnd =
|
|
2798
|
-
const semi =
|
|
2820
|
+
const start = A.start(at);
|
|
2821
|
+
const nameEnd = A.nameEnd(at);
|
|
2822
|
+
const semi = A.end(at);
|
|
2799
2823
|
const atRuleEnd =
|
|
2800
2824
|
source.charCodeAt(semi) === CC_SEMICOLON ? semi + 1 : semi;
|
|
2801
2825
|
const params = input.slice(nameEnd, semi);
|
|
@@ -2956,12 +2980,12 @@ class CssParser extends Parser {
|
|
|
2956
2980
|
/** @type {(cvs: AstNode[]) => void} */
|
|
2957
2981
|
const walkExports = (cvs) => {
|
|
2958
2982
|
for (const cv of cvs) {
|
|
2959
|
-
switch (
|
|
2983
|
+
switch (A.type(cv)) {
|
|
2960
2984
|
case NodeType.Comma:
|
|
2961
2985
|
parsedKeywords = Object.create(null);
|
|
2962
2986
|
break;
|
|
2963
2987
|
case NodeType.Delim:
|
|
2964
|
-
afterExclamation =
|
|
2988
|
+
afterExclamation = A.value(cv) === "!";
|
|
2965
2989
|
break;
|
|
2966
2990
|
case NodeType.Ident: {
|
|
2967
2991
|
if (isGridTemplate) break;
|
|
@@ -2969,7 +2993,7 @@ class CssParser extends Parser {
|
|
|
2969
2993
|
afterExclamation = false;
|
|
2970
2994
|
break;
|
|
2971
2995
|
}
|
|
2972
|
-
const identifier =
|
|
2996
|
+
const identifier = A.value(cv);
|
|
2973
2997
|
const keyword = identifier.toLowerCase();
|
|
2974
2998
|
parsedKeywords[keyword] =
|
|
2975
2999
|
typeof parsedKeywords[keyword] !== "undefined"
|
|
@@ -2981,7 +3005,7 @@ class CssParser extends Parser {
|
|
|
2981
3005
|
) {
|
|
2982
3006
|
break;
|
|
2983
3007
|
}
|
|
2984
|
-
emit(
|
|
3008
|
+
emit(A.start(cv), A.end(cv));
|
|
2985
3009
|
break;
|
|
2986
3010
|
}
|
|
2987
3011
|
case NodeType.String: {
|
|
@@ -2989,17 +3013,17 @@ class CssParser extends Parser {
|
|
|
2989
3013
|
declPropertyName === "animation" ||
|
|
2990
3014
|
declPropertyName === "animation-name"
|
|
2991
3015
|
) {
|
|
2992
|
-
emit(
|
|
3016
|
+
emit(A.start(cv), A.end(cv), true);
|
|
2993
3017
|
}
|
|
2994
3018
|
if (
|
|
2995
3019
|
declPropertyName === "grid" ||
|
|
2996
3020
|
declPropertyName === "grid-template" ||
|
|
2997
3021
|
declPropertyName === "grid-template-areas"
|
|
2998
3022
|
) {
|
|
2999
|
-
const areas =
|
|
3023
|
+
const areas = A.unescaped(cv);
|
|
3000
3024
|
const matches = matchAll(/\b\w+\b/g, areas);
|
|
3001
3025
|
for (const match of matches) {
|
|
3002
|
-
const areaStart =
|
|
3026
|
+
const areaStart = A.start(cv) + 1 + match.index;
|
|
3003
3027
|
emit(areaStart, areaStart + match[0].length, false);
|
|
3004
3028
|
}
|
|
3005
3029
|
}
|
|
@@ -3007,28 +3031,28 @@ class CssParser extends Parser {
|
|
|
3007
3031
|
}
|
|
3008
3032
|
case NodeType.SimpleBlock: {
|
|
3009
3033
|
const block = /** @type {SimpleBlock} */ (cv);
|
|
3010
|
-
if (block
|
|
3034
|
+
if (A.blockToken(block) === "[") {
|
|
3011
3035
|
// Collect identifiers until the first non-ident token (`<line-names> = '[' <custom-ident>* ']'`).
|
|
3012
|
-
for (const inner of block
|
|
3013
|
-
if (
|
|
3014
|
-
if (
|
|
3015
|
-
emit(
|
|
3036
|
+
for (const inner of A.children(block)) {
|
|
3037
|
+
if (A.type(inner) === NodeType.Whitespace) continue;
|
|
3038
|
+
if (A.type(inner) !== NodeType.Ident) break;
|
|
3039
|
+
emit(A.start(inner), A.end(inner));
|
|
3016
3040
|
}
|
|
3017
3041
|
} else if (isGridTemplate) {
|
|
3018
|
-
walkExports(block
|
|
3042
|
+
walkExports(A.children(block));
|
|
3019
3043
|
}
|
|
3020
3044
|
break;
|
|
3021
3045
|
}
|
|
3022
3046
|
case NodeType.Function:
|
|
3023
3047
|
if (isGridTemplate) {
|
|
3024
|
-
walkExports(
|
|
3048
|
+
walkExports(A.children(cv));
|
|
3025
3049
|
}
|
|
3026
3050
|
break;
|
|
3027
3051
|
// Other types carry no ICSS-export information.
|
|
3028
3052
|
}
|
|
3029
3053
|
}
|
|
3030
3054
|
};
|
|
3031
|
-
walkExports(decl
|
|
3055
|
+
walkExports(A.children(decl));
|
|
3032
3056
|
};
|
|
3033
3057
|
|
|
3034
3058
|
/**
|
|
@@ -3047,27 +3071,26 @@ class CssParser extends Parser {
|
|
|
3047
3071
|
) => {
|
|
3048
3072
|
const acceptIdent = isKeyframes || isCounterStyle || isContainer;
|
|
3049
3073
|
const acceptString = isKeyframes;
|
|
3050
|
-
for (const cv of
|
|
3051
|
-
|
|
3052
|
-
if (
|
|
3074
|
+
for (const cv of A.prelude(at)) {
|
|
3075
|
+
const cvType = A.type(cv);
|
|
3076
|
+
if (cvType === NodeType.Whitespace) continue;
|
|
3077
|
+
if (cvType === NodeType.String) {
|
|
3053
3078
|
if (acceptString) pure.markLocal();
|
|
3054
3079
|
break;
|
|
3055
3080
|
}
|
|
3056
|
-
if (
|
|
3081
|
+
if (cvType === NodeType.Ident) {
|
|
3057
3082
|
if (!acceptIdent) break;
|
|
3058
|
-
if (
|
|
3083
|
+
if (
|
|
3084
|
+
isContainer &&
|
|
3085
|
+
isContainerKeyword(source, A.start(cv), A.end(cv))
|
|
3086
|
+
) {
|
|
3059
3087
|
continue;
|
|
3060
3088
|
}
|
|
3061
3089
|
pure.markLocal();
|
|
3062
3090
|
break;
|
|
3063
3091
|
}
|
|
3064
|
-
if (
|
|
3065
|
-
if (
|
|
3066
|
-
equalsLowerCase(
|
|
3067
|
-
/** @type {FunctionNode} */ (cv).unescapedName,
|
|
3068
|
-
"local"
|
|
3069
|
-
)
|
|
3070
|
-
) {
|
|
3092
|
+
if (cvType === NodeType.Function) {
|
|
3093
|
+
if (equalsLowerCase(A.unescapedName(cv), "local")) {
|
|
3071
3094
|
pure.markLocal();
|
|
3072
3095
|
}
|
|
3073
3096
|
break;
|
|
@@ -3083,7 +3106,8 @@ class CssParser extends Parser {
|
|
|
3083
3106
|
enter: (node, parent) => {
|
|
3084
3107
|
const at = /** @type {AtRule} */ (node);
|
|
3085
3108
|
const topLevel = parent === null;
|
|
3086
|
-
|
|
3109
|
+
currentUrlRecovery = false;
|
|
3110
|
+
advanceCommentCursor(A.start(at));
|
|
3087
3111
|
const savedAnchor = currentRule.hasLocalAnchor;
|
|
3088
3112
|
const savedLocalIdentifiers = currentRule.localIdentifiers;
|
|
3089
3113
|
// Only modules-mode walks mutate `localIdentifiers`; otherwise share
|
|
@@ -3091,33 +3115,32 @@ class CssParser extends Parser {
|
|
|
3091
3115
|
currentRule.localIdentifiers = isModules
|
|
3092
3116
|
? [...savedLocalIdentifiers]
|
|
3093
3117
|
: savedLocalIdentifiers;
|
|
3094
|
-
const name = `@${
|
|
3118
|
+
const name = `@${A.name(at).toLowerCase()}`;
|
|
3095
3119
|
switch (name) {
|
|
3096
3120
|
case "@namespace": {
|
|
3097
3121
|
this._emitWarning(
|
|
3098
3122
|
state,
|
|
3099
3123
|
"'@namespace' is not supported in bundled CSS",
|
|
3100
3124
|
locConverter,
|
|
3101
|
-
|
|
3102
|
-
|
|
3125
|
+
A.start(at),
|
|
3126
|
+
A.nameEnd(at)
|
|
3103
3127
|
);
|
|
3104
3128
|
break;
|
|
3105
3129
|
}
|
|
3106
3130
|
case "@charset": {
|
|
3107
3131
|
if (/** @type {CssModule} */ (module).exportType !== "style") {
|
|
3132
|
+
const atEnd = A.end(at);
|
|
3108
3133
|
const atRuleEnd =
|
|
3109
|
-
source.charCodeAt(
|
|
3110
|
-
|
|
3111
|
-
: at.end;
|
|
3112
|
-
const dep = new ConstDependency("", [at.start, atRuleEnd]);
|
|
3134
|
+
source.charCodeAt(atEnd) === CC_SEMICOLON ? atEnd + 1 : atEnd;
|
|
3135
|
+
const dep = new ConstDependency("", [A.start(at), atRuleEnd]);
|
|
3113
3136
|
module.addPresentationalDependency(dep);
|
|
3114
|
-
const string =
|
|
3115
|
-
(v) =>
|
|
3137
|
+
const string = A.prelude(at).find(
|
|
3138
|
+
(v) => A.type(v) !== NodeType.Whitespace
|
|
3116
3139
|
);
|
|
3117
|
-
if (string &&
|
|
3140
|
+
if (string && A.type(string) === NodeType.String) {
|
|
3118
3141
|
/** @type {CssModuleBuildInfo} */
|
|
3119
3142
|
(module.buildInfo).charset = source
|
|
3120
|
-
.slice(
|
|
3143
|
+
.slice(A.start(string) + 1, A.end(string) - 1)
|
|
3121
3144
|
.toUpperCase();
|
|
3122
3145
|
}
|
|
3123
3146
|
}
|
|
@@ -3158,11 +3181,11 @@ class CssParser extends Parser {
|
|
|
3158
3181
|
// `@scope (.x) to (.y)` — walk the prelude as a selector list.
|
|
3159
3182
|
if (
|
|
3160
3183
|
isModules &&
|
|
3161
|
-
equalsLowerCase(
|
|
3162
|
-
|
|
3184
|
+
equalsLowerCase(A.name(at), "scope") &&
|
|
3185
|
+
A.prelude(at).length > 0
|
|
3163
3186
|
) {
|
|
3164
3187
|
walkSelectorList(
|
|
3165
|
-
|
|
3188
|
+
A.prelude(at),
|
|
3166
3189
|
/** @type {"local" | "global"} */ (
|
|
3167
3190
|
mode === "local" ? "local" : "global"
|
|
3168
3191
|
)
|
|
@@ -3175,14 +3198,9 @@ class CssParser extends Parser {
|
|
|
3175
3198
|
currentStructural = at;
|
|
3176
3199
|
currentAtRuleName = name;
|
|
3177
3200
|
dashed.active = false;
|
|
3178
|
-
// `@import` url() is the import target — only walk its prelude for url deps on malformed-import recovery
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
if (
|
|
3182
|
-
this.options.url &&
|
|
3183
|
-
(name !== "@import" || atWithRecovery.urlRecovery)
|
|
3184
|
-
) {
|
|
3185
|
-
lastTokenEndForComments = at.nameEnd;
|
|
3201
|
+
// `@import` url() is the import target — only walk its prelude for url deps on malformed-import recovery.
|
|
3202
|
+
if (this.options.url && (name !== "@import" || currentUrlRecovery)) {
|
|
3203
|
+
lastTokenEndForComments = A.nameEnd(at);
|
|
3186
3204
|
}
|
|
3187
3205
|
// Dashed-ident scoping over the prelude (the Ident / Function visitors emit).
|
|
3188
3206
|
dashed.active = Boolean(
|
|
@@ -3219,18 +3237,21 @@ class CssParser extends Parser {
|
|
|
3219
3237
|
}
|
|
3220
3238
|
|
|
3221
3239
|
// pure.stack push for block-bearing at-rules.
|
|
3222
|
-
const
|
|
3223
|
-
|
|
3240
|
+
const atDecls = A.declarations(at);
|
|
3241
|
+
const atChildRules = A.childRules(at);
|
|
3242
|
+
const atHasBlock = Boolean(atDecls || atChildRules);
|
|
3243
|
+
const atBlockStart = A.blockStart(at);
|
|
3244
|
+
if (atHasBlock && atBlockStart !== -1) {
|
|
3224
3245
|
const isAtRulePrelude = isPureBodyAtRule(name);
|
|
3225
3246
|
if (isAtRulePrelude) pure.finalizeSelector();
|
|
3226
3247
|
pure.enterBlock({
|
|
3227
3248
|
isRulePrelude: isAtRulePrelude,
|
|
3228
3249
|
treatAsLeaf: atTreatAsLeaf,
|
|
3229
3250
|
ownSkip: atSkipChildren,
|
|
3230
|
-
declarations:
|
|
3231
|
-
childRules:
|
|
3232
|
-
preludeStart:
|
|
3233
|
-
preludeEnd:
|
|
3251
|
+
declarations: atDecls,
|
|
3252
|
+
childRules: atChildRules,
|
|
3253
|
+
preludeStart: A.start(at),
|
|
3254
|
+
preludeEnd: atBlockStart
|
|
3234
3255
|
});
|
|
3235
3256
|
}
|
|
3236
3257
|
|
|
@@ -3239,7 +3260,7 @@ class CssParser extends Parser {
|
|
|
3239
3260
|
savedLocalIdentifiers,
|
|
3240
3261
|
name,
|
|
3241
3262
|
hasBlock: atHasBlock,
|
|
3242
|
-
endsWithSemicolon: source.charCodeAt(
|
|
3263
|
+
endsWithSemicolon: source.charCodeAt(A.end(at)) === CC_SEMICOLON
|
|
3243
3264
|
});
|
|
3244
3265
|
},
|
|
3245
3266
|
// At-rule exit: pure-frame finalization, `suppressNextRulePrelude`, scope restore, top-level reset.
|
|
@@ -3266,25 +3287,27 @@ class CssParser extends Parser {
|
|
|
3266
3287
|
enter: (node, parent, ctx) => {
|
|
3267
3288
|
const rule = /** @type {QualifiedRule} */ (node);
|
|
3268
3289
|
const topLevel = parent === null;
|
|
3269
|
-
advanceCommentCursor(
|
|
3290
|
+
advanceCommentCursor(A.start(rule));
|
|
3270
3291
|
// `:import(…) { … }` / `:export { … }` ICSS pseudo-rules are processed inline at top level; nested ones bail out.
|
|
3271
3292
|
if (isModules) {
|
|
3272
|
-
const
|
|
3293
|
+
const rulePrelude = A.prelude(rule);
|
|
3294
|
+
const firstIdx = nextNonWhitespace(rulePrelude, 0);
|
|
3273
3295
|
if (
|
|
3274
|
-
firstIdx + 1 <
|
|
3275
|
-
|
|
3296
|
+
firstIdx + 1 < rulePrelude.length &&
|
|
3297
|
+
A.type(rulePrelude[firstIdx]) === NodeType.Colon
|
|
3276
3298
|
) {
|
|
3277
|
-
const second =
|
|
3299
|
+
const second = rulePrelude[firstIdx + 1];
|
|
3300
|
+
const secondType = A.type(second);
|
|
3278
3301
|
const rawName =
|
|
3279
|
-
|
|
3280
|
-
?
|
|
3281
|
-
:
|
|
3282
|
-
?
|
|
3302
|
+
secondType === NodeType.Ident
|
|
3303
|
+
? A.value(second)
|
|
3304
|
+
: secondType === NodeType.Function
|
|
3305
|
+
? A.name(second)
|
|
3283
3306
|
: "";
|
|
3284
3307
|
const isImport = equalsLowerCase(rawName, "import");
|
|
3285
3308
|
if (isImport || equalsLowerCase(rawName, "export")) {
|
|
3286
3309
|
if (topLevel) {
|
|
3287
|
-
const startColon =
|
|
3310
|
+
const startColon = A.start(rulePrelude[firstIdx]);
|
|
3288
3311
|
const endAfterBody = processImportOrExport(
|
|
3289
3312
|
isImport ? 0 : 1,
|
|
3290
3313
|
second,
|
|
@@ -3293,11 +3316,13 @@ class CssParser extends Parser {
|
|
|
3293
3316
|
module.addPresentationalDependency(
|
|
3294
3317
|
new ConstDependency("", [startColon, endAfterBody])
|
|
3295
3318
|
);
|
|
3296
|
-
if (
|
|
3297
|
-
|
|
3298
|
-
|
|
3319
|
+
if (A.blockStart(rule) !== -1) {
|
|
3320
|
+
A.setBlockEnd(rule, endAfterBody);
|
|
3321
|
+
}
|
|
3322
|
+
A.setEnd(rule, endAfterBody);
|
|
3323
|
+
} else if (A.blockStart(rule) !== -1) {
|
|
3299
3324
|
// Nested `:import` / `:export` — leave the body alone.
|
|
3300
|
-
rule
|
|
3325
|
+
A.setEnd(rule, A.blockEnd(rule));
|
|
3301
3326
|
}
|
|
3302
3327
|
// Don't recurse into the body — handled inline above.
|
|
3303
3328
|
if (ctx) ctx.skipChildren();
|
|
@@ -3327,9 +3352,10 @@ class CssParser extends Parser {
|
|
|
3327
3352
|
savedComposesFiles
|
|
3328
3353
|
});
|
|
3329
3354
|
// Selectors are only CSS-Modules-relevant when `isModules` holds.
|
|
3355
|
+
const rulePrelude = A.prelude(rule);
|
|
3330
3356
|
if (isModules) {
|
|
3331
3357
|
walkSelectorList(
|
|
3332
|
-
|
|
3358
|
+
rulePrelude,
|
|
3333
3359
|
/** @type {"local" | "global"} */ (
|
|
3334
3360
|
mode === "local" ? "local" : "global"
|
|
3335
3361
|
)
|
|
@@ -3339,20 +3365,20 @@ class CssParser extends Parser {
|
|
|
3339
3365
|
currentStructural = rule;
|
|
3340
3366
|
dashed.active = false;
|
|
3341
3367
|
dashed.emit = false;
|
|
3342
|
-
if (this.options.url &&
|
|
3343
|
-
lastTokenEndForComments =
|
|
3368
|
+
if (this.options.url && rulePrelude.length > 0) {
|
|
3369
|
+
lastTokenEndForComments = A.start(rulePrelude[0]);
|
|
3344
3370
|
}
|
|
3345
3371
|
// Dashed-ident scoping for the deprecated `--foo: { … }` custom-property-set syntax (prelude starts with a dashed-ident).
|
|
3346
3372
|
if (
|
|
3347
3373
|
this.options.dashedIdents &&
|
|
3348
3374
|
isModules &&
|
|
3349
|
-
|
|
3375
|
+
rulePrelude.length > 0
|
|
3350
3376
|
) {
|
|
3351
|
-
const first =
|
|
3377
|
+
const first = rulePrelude[nextNonWhitespace(rulePrelude, 0)];
|
|
3352
3378
|
if (
|
|
3353
3379
|
first &&
|
|
3354
|
-
|
|
3355
|
-
isDashedIdentifier(
|
|
3380
|
+
A.type(first) === NodeType.Ident &&
|
|
3381
|
+
isDashedIdentifier(A.value(first))
|
|
3356
3382
|
) {
|
|
3357
3383
|
const effectiveLocalMode = isEffectivelyLocal();
|
|
3358
3384
|
if (effectiveLocalMode) {
|
|
@@ -3362,14 +3388,15 @@ class CssParser extends Parser {
|
|
|
3362
3388
|
}
|
|
3363
3389
|
}
|
|
3364
3390
|
// Pure-mode: report an impure prelude (if leaf-ish) and push the inherited-context frame before walking the body.
|
|
3391
|
+
const ruleBlockStart = A.blockStart(rule);
|
|
3365
3392
|
pure.enterBlock({
|
|
3366
3393
|
isRulePrelude: true,
|
|
3367
3394
|
treatAsLeaf: false,
|
|
3368
3395
|
ownSkip: false,
|
|
3369
|
-
declarations:
|
|
3370
|
-
childRules:
|
|
3371
|
-
preludeStart:
|
|
3372
|
-
preludeEnd:
|
|
3396
|
+
declarations: A.declarations(rule),
|
|
3397
|
+
childRules: A.childRules(rule),
|
|
3398
|
+
preludeStart: A.start(rule),
|
|
3399
|
+
preludeEnd: ruleBlockStart !== -1 ? ruleBlockStart : A.end(rule)
|
|
3373
3400
|
});
|
|
3374
3401
|
},
|
|
3375
3402
|
// Qualified-rule exit: pure-frame finalization, scope restore, top-level reset; no-op for bailed ICSS.
|
|
@@ -3391,13 +3418,8 @@ class CssParser extends Parser {
|
|
|
3391
3418
|
currentStructural = decl;
|
|
3392
3419
|
dashed.active = false;
|
|
3393
3420
|
dashed.emit = false;
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
.toLowerCase();
|
|
3397
|
-
// Cache the known-property flag so the per-token value visitors don't recompute it.
|
|
3398
|
-
currentDeclIsKnownProperty = knownProperties.has(declPropertyName);
|
|
3399
|
-
// Position `lastTokenEndForComments` just past the `:` so a magic comment before the url() is found.
|
|
3400
|
-
let colonPos = decl.nameEnd;
|
|
3421
|
+
// Position `lastTokenEndForComments` just past the `:` so a magic comment before a url() is found (every mode).
|
|
3422
|
+
let colonPos = A.nameEnd(decl);
|
|
3401
3423
|
while (
|
|
3402
3424
|
colonPos < source.length &&
|
|
3403
3425
|
source.charCodeAt(colonPos) !== CC_COLON
|
|
@@ -3405,6 +3427,15 @@ class CssParser extends Parser {
|
|
|
3405
3427
|
colonPos++;
|
|
3406
3428
|
}
|
|
3407
3429
|
lastTokenEndForComments = colonPos + 1;
|
|
3430
|
+
currentDeclIsKnownProperty = false;
|
|
3431
|
+
currentDeclComposesSkip = false;
|
|
3432
|
+
// Property-name analysis and value exports are CSS-Modules-only; a plain
|
|
3433
|
+
// stylesheet's declarations need no per-decl name slice / known-property lookup.
|
|
3434
|
+
if (!isModules) return;
|
|
3435
|
+
const declName = A.name(decl);
|
|
3436
|
+
const declPropertyName = declName.replace(/^(-\w+-)/, "").toLowerCase();
|
|
3437
|
+
// Cache the known-property flag so the per-token value visitors don't recompute it.
|
|
3438
|
+
currentDeclIsKnownProperty = knownProperties.has(declPropertyName);
|
|
3408
3439
|
const effectiveLocalMode = isEffectivelyLocal();
|
|
3409
3440
|
// `composes:` with a local anchor: its strip-dep covers the whole declaration, so suppress the value's local/global/dashed/ICSS rewrites.
|
|
3410
3441
|
currentDeclComposesSkip =
|
|
@@ -3413,31 +3444,29 @@ class CssParser extends Parser {
|
|
|
3413
3444
|
if (currentDeclComposesSkip) emitComposesWithAnchor(decl);
|
|
3414
3445
|
const skipForComposes = currentDeclComposesSkip;
|
|
3415
3446
|
// Known-property value localization (`animation-name: foo` exports `foo`).
|
|
3416
|
-
if (
|
|
3447
|
+
if (effectiveLocalMode && currentDeclIsKnownProperty) {
|
|
3417
3448
|
emitKnownPropertyExports(decl, declPropertyName);
|
|
3418
3449
|
}
|
|
3419
3450
|
// Dashed-ident (custom-property) export of the property name; the value's dashed idents are scoped by the Ident / Function visitors (top-level only for unknown properties).
|
|
3420
3451
|
if (
|
|
3421
3452
|
this.options.dashedIdents &&
|
|
3422
|
-
isModules &&
|
|
3423
3453
|
effectiveLocalMode &&
|
|
3424
3454
|
!skipForComposes
|
|
3425
3455
|
) {
|
|
3426
|
-
if (isDashedIdentifier(
|
|
3427
|
-
emitDashedIdentExport(
|
|
3456
|
+
if (isDashedIdentifier(declName)) {
|
|
3457
|
+
emitDashedIdentExport(A.nameStart(decl), A.nameEnd(decl));
|
|
3428
3458
|
}
|
|
3429
3459
|
dashed.active = true;
|
|
3430
3460
|
dashed.emit = !currentDeclIsKnownProperty;
|
|
3431
3461
|
}
|
|
3432
3462
|
// ICSS-symbol rewrite (`color: foo` when `foo` is `@value`-defined), skipping known properties, the composes anchor, and dashed idents (handled above).
|
|
3433
3463
|
if (
|
|
3434
|
-
isModules &&
|
|
3435
3464
|
!skipForComposes &&
|
|
3436
3465
|
!currentDeclIsKnownProperty &&
|
|
3437
|
-
!(dashed.active && isDashedIdentifier(
|
|
3438
|
-
icssDefinitions.has(
|
|
3466
|
+
!(dashed.active && isDashedIdentifier(declName)) &&
|
|
3467
|
+
icssDefinitions.has(declName)
|
|
3439
3468
|
) {
|
|
3440
|
-
emitICSSSymbol(
|
|
3469
|
+
emitICSSSymbol(declName, A.nameStart(decl), A.nameEnd(decl));
|
|
3441
3470
|
}
|
|
3442
3471
|
},
|
|
3443
3472
|
// Value-level visitors decide handling from the enclosing node via `urlActive()` / `localGlobalActive()` / `icssActive()`.
|
|
@@ -3447,7 +3476,7 @@ class CssParser extends Parser {
|
|
|
3447
3476
|
// Skip bare url-tokens for a known property in CSS-Modules local mode.
|
|
3448
3477
|
if (
|
|
3449
3478
|
currentStructural &&
|
|
3450
|
-
|
|
3479
|
+
A.type(currentStructural) === NodeType.Declaration &&
|
|
3451
3480
|
isModules &&
|
|
3452
3481
|
currentDeclIsKnownProperty &&
|
|
3453
3482
|
isEffectivelyLocal()
|
|
@@ -3456,15 +3485,15 @@ class CssParser extends Parser {
|
|
|
3456
3485
|
}
|
|
3457
3486
|
if (
|
|
3458
3487
|
webpackIgnored(
|
|
3459
|
-
[lastTokenEndForComments,
|
|
3488
|
+
[lastTokenEndForComments, A.end(node)],
|
|
3460
3489
|
lastTokenEndForComments,
|
|
3461
|
-
|
|
3490
|
+
A.end(node)
|
|
3462
3491
|
)
|
|
3463
3492
|
) {
|
|
3464
3493
|
return;
|
|
3465
3494
|
}
|
|
3466
3495
|
let value = normalizeUrl(
|
|
3467
|
-
input.slice(
|
|
3496
|
+
input.slice(A.contentStart(url), A.contentEnd(url)),
|
|
3468
3497
|
false
|
|
3469
3498
|
);
|
|
3470
3499
|
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
|
@@ -3485,25 +3514,29 @@ class CssParser extends Parser {
|
|
|
3485
3514
|
state,
|
|
3486
3515
|
`'@value' identifier '${value}' was imported from another module and cannot be used inside 'url()' — only locally defined values are supported here`,
|
|
3487
3516
|
locConverter,
|
|
3488
|
-
|
|
3489
|
-
|
|
3517
|
+
A.start(node),
|
|
3518
|
+
A.end(node)
|
|
3490
3519
|
);
|
|
3491
3520
|
return;
|
|
3492
3521
|
}
|
|
3493
3522
|
}
|
|
3494
3523
|
}
|
|
3495
|
-
const dep = new CssUrlDependency(
|
|
3496
|
-
|
|
3524
|
+
const dep = new CssUrlDependency(
|
|
3525
|
+
value,
|
|
3526
|
+
[A.start(node), A.end(node)],
|
|
3527
|
+
"url"
|
|
3528
|
+
);
|
|
3529
|
+
setDepLoc(dep, A.start(node), A.end(node));
|
|
3497
3530
|
module.addDependency(dep);
|
|
3498
3531
|
module.addCodeGenerationDependency(dep);
|
|
3499
3532
|
},
|
|
3500
3533
|
[NodeType.Comma](node) {
|
|
3501
|
-
if (urlActive()) lastTokenEndForComments =
|
|
3534
|
+
if (urlActive()) lastTokenEndForComments = A.start(node);
|
|
3502
3535
|
},
|
|
3503
3536
|
[NodeType.Function]: {
|
|
3504
3537
|
enter: (node) => {
|
|
3505
3538
|
const fn = /** @type {FunctionNode} */ (node);
|
|
3506
|
-
const fnameRaw =
|
|
3539
|
+
const fnameRaw = A.unescapedName(fn);
|
|
3507
3540
|
const fname = fnameRaw.toLowerCase();
|
|
3508
3541
|
if (urlActive()) emitUrlFunction(fn, fname);
|
|
3509
3542
|
if (
|
|
@@ -3519,7 +3552,7 @@ class CssParser extends Parser {
|
|
|
3519
3552
|
!(dashed.active && isDashedIdentifier(fnameRaw)) &&
|
|
3520
3553
|
icssDefinitions.has(fnameRaw)
|
|
3521
3554
|
) {
|
|
3522
|
-
emitICSSSymbol(fnameRaw,
|
|
3555
|
+
emitICSSSymbol(fnameRaw, A.nameStart(fn), A.nameEnd(fn));
|
|
3523
3556
|
}
|
|
3524
3557
|
// Dashed-ident scoping: handle this function, then set the child nesting level's state for the walk.
|
|
3525
3558
|
dashed.push();
|
|
@@ -3531,9 +3564,9 @@ class CssParser extends Parser {
|
|
|
3531
3564
|
// `var(--foo, …)` / `style(--foo, …)`: emit the first ident; the fallback doesn't self-emit.
|
|
3532
3565
|
processDashedIdentInVarFunction(fn);
|
|
3533
3566
|
dashed.emit = false;
|
|
3534
|
-
} else if (dashed.emit && isDashedIdentifier(
|
|
3567
|
+
} else if (dashed.emit && isDashedIdentifier(A.name(fn))) {
|
|
3535
3568
|
// Custom-function call `--my-func(args)` — the name is the exported dashed-ident.
|
|
3536
|
-
emitDashedIdentExport(
|
|
3569
|
+
emitDashedIdentExport(A.nameStart(fn), A.nameEnd(fn));
|
|
3537
3570
|
}
|
|
3538
3571
|
}
|
|
3539
3572
|
},
|
|
@@ -3542,8 +3575,15 @@ class CssParser extends Parser {
|
|
|
3542
3575
|
}
|
|
3543
3576
|
},
|
|
3544
3577
|
[NodeType.Ident](node, parent) {
|
|
3545
|
-
|
|
3546
|
-
|
|
3578
|
+
// Fast exit before slicing the ident value: outside dashed-ident scoping
|
|
3579
|
+
// and ICSS context (any non-CSS-Modules stylesheet) a bare ident carries
|
|
3580
|
+
// no work, and idents are the most common node, so skipping the per-ident
|
|
3581
|
+
// `value` slice matters.
|
|
3582
|
+
const dashedActive = dashed.active;
|
|
3583
|
+
const icss = icssActive();
|
|
3584
|
+
if (!dashedActive && !icss) return;
|
|
3585
|
+
const identValue = A.value(node);
|
|
3586
|
+
if (dashedActive && isDashedIdentifier(identValue)) {
|
|
3547
3587
|
// Dashed idents are scoped here, never `@value` ICSS-rewritten.
|
|
3548
3588
|
if (!dashed.emit) return;
|
|
3549
3589
|
// Resolve the `--foo from "./x.css"` / `--foo from global` import suffix via sibling lookahead.
|
|
@@ -3553,37 +3593,37 @@ class CssParser extends Parser {
|
|
|
3553
3593
|
const j = nextNonWhitespace(siblings, i + 1);
|
|
3554
3594
|
if (
|
|
3555
3595
|
j < siblings.length &&
|
|
3556
|
-
siblings[j]
|
|
3557
|
-
equalsLowerCase(
|
|
3596
|
+
A.type(siblings[j]) === NodeType.Ident &&
|
|
3597
|
+
equalsLowerCase(A.value(siblings[j]), "from")
|
|
3558
3598
|
) {
|
|
3559
3599
|
const fromIdent = siblings[j];
|
|
3560
3600
|
const sourceNode = siblings[nextNonWhitespace(siblings, j + 1)];
|
|
3561
3601
|
if (
|
|
3562
3602
|
sourceNode &&
|
|
3563
|
-
|
|
3564
|
-
|
|
3603
|
+
A.type(sourceNode) === NodeType.Ident &&
|
|
3604
|
+
A.value(sourceNode) === "global"
|
|
3565
3605
|
) {
|
|
3566
|
-
emitDashedIdentFromGlobal(
|
|
3606
|
+
emitDashedIdentFromGlobal(A.end(node), A.end(sourceNode));
|
|
3567
3607
|
return;
|
|
3568
3608
|
}
|
|
3569
|
-
if (sourceNode &&
|
|
3609
|
+
if (sourceNode && A.type(sourceNode) === NodeType.String) {
|
|
3570
3610
|
emitDashedIdentImport(
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
input.slice(
|
|
3611
|
+
A.start(node),
|
|
3612
|
+
A.end(node),
|
|
3613
|
+
A.start(fromIdent),
|
|
3614
|
+
A.end(sourceNode),
|
|
3615
|
+
input.slice(A.start(sourceNode) + 1, A.end(sourceNode) - 1)
|
|
3576
3616
|
);
|
|
3577
3617
|
return;
|
|
3578
3618
|
}
|
|
3579
3619
|
}
|
|
3580
3620
|
}
|
|
3581
|
-
emitDashedIdentExport(
|
|
3621
|
+
emitDashedIdentExport(A.start(node), A.end(node));
|
|
3582
3622
|
return;
|
|
3583
3623
|
}
|
|
3584
|
-
if (!
|
|
3624
|
+
if (!icss) return;
|
|
3585
3625
|
if (icssDefinitions.has(identValue)) {
|
|
3586
|
-
emitICSSSymbol(identValue,
|
|
3626
|
+
emitICSSSymbol(identValue, A.start(node), A.end(node));
|
|
3587
3627
|
}
|
|
3588
3628
|
}
|
|
3589
3629
|
};
|