@homebound/truss 2.15.1 → 2.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/plugin/index.js +260 -208
- package/build/plugin/index.js.map +1 -1
- package/package.json +1 -1
package/build/plugin/index.js
CHANGED
|
@@ -544,7 +544,7 @@ var RELATIONSHIP_BASE = {
|
|
|
544
544
|
siblingAfter: 40
|
|
545
545
|
};
|
|
546
546
|
function computeRulePriority(rule) {
|
|
547
|
-
let priority = getPropertyPriority(rule.cssProperty);
|
|
547
|
+
let priority = getPropertyPriority(rule.declarations[0].cssProperty);
|
|
548
548
|
if (rule.pseudoElement) {
|
|
549
549
|
priority += PSEUDO_ELEMENT_PRIORITY;
|
|
550
550
|
}
|
|
@@ -565,10 +565,7 @@ function computeRulePriority(rule) {
|
|
|
565
565
|
return priority;
|
|
566
566
|
}
|
|
567
567
|
function isVariableRule(rule) {
|
|
568
|
-
|
|
569
|
-
return rule.declarations.some((d) => d.cssVarName !== void 0);
|
|
570
|
-
}
|
|
571
|
-
return rule.cssVarName !== void 0;
|
|
568
|
+
return rule.declarations.some((d) => d.cssVarName !== void 0);
|
|
572
569
|
}
|
|
573
570
|
function sortRulesByPriority(rules) {
|
|
574
571
|
const decorated = rules.map((rule, i) => {
|
|
@@ -1013,6 +1010,27 @@ function whenPrefix(whenPseudo) {
|
|
|
1013
1010
|
const markerPart = whenPseudo.markerNode?.type === "Identifier" ? `${whenPseudo.markerNode.name}_` : "";
|
|
1014
1011
|
return `wh_${rel}_${pseudoTag}_${markerPart}`;
|
|
1015
1012
|
}
|
|
1013
|
+
function conditionPrefix(pseudoClass, mediaQuery, pseudoElement, breakpoints) {
|
|
1014
|
+
const parts = [];
|
|
1015
|
+
if (pseudoElement) {
|
|
1016
|
+
parts.push(`${pseudoElement.replace(/^::/, "")}_`);
|
|
1017
|
+
}
|
|
1018
|
+
if (mediaQuery && breakpoints) {
|
|
1019
|
+
const bpKey = Object.entries(breakpoints).find(([, v]) => v === mediaQuery)?.[0];
|
|
1020
|
+
if (bpKey) {
|
|
1021
|
+
const shortName = bpKey.replace(/^if/, "").toLowerCase();
|
|
1022
|
+
parts.push(`${shortName}_`);
|
|
1023
|
+
} else {
|
|
1024
|
+
parts.push("mq_");
|
|
1025
|
+
}
|
|
1026
|
+
} else if (mediaQuery) {
|
|
1027
|
+
parts.push("mq_");
|
|
1028
|
+
}
|
|
1029
|
+
if (pseudoClass) {
|
|
1030
|
+
parts.push(`${pseudoSelectorTag(pseudoClass)}_`);
|
|
1031
|
+
}
|
|
1032
|
+
return parts.join("");
|
|
1033
|
+
}
|
|
1016
1034
|
function pseudoSelectorTag(pseudo) {
|
|
1017
1035
|
const replaced = pseudo.trim().replace(/::?[a-zA-Z-]+/g, (match) => {
|
|
1018
1036
|
return `_${pseudoIdentifierTag(match)}_`;
|
|
@@ -1036,27 +1054,6 @@ function normalizePseudoIdentifier(pseudo) {
|
|
|
1036
1054
|
});
|
|
1037
1055
|
return `${prefix}${name}`;
|
|
1038
1056
|
}
|
|
1039
|
-
function conditionPrefix(pseudoClass, mediaQuery, pseudoElement, breakpoints) {
|
|
1040
|
-
const parts = [];
|
|
1041
|
-
if (pseudoElement) {
|
|
1042
|
-
parts.push(`${pseudoElement.replace(/^::/, "")}_`);
|
|
1043
|
-
}
|
|
1044
|
-
if (mediaQuery && breakpoints) {
|
|
1045
|
-
const bpKey = Object.entries(breakpoints).find(([, v]) => v === mediaQuery)?.[0];
|
|
1046
|
-
if (bpKey) {
|
|
1047
|
-
const shortName = bpKey.replace(/^if/, "").toLowerCase();
|
|
1048
|
-
parts.push(`${shortName}_`);
|
|
1049
|
-
} else {
|
|
1050
|
-
parts.push("mq_");
|
|
1051
|
-
}
|
|
1052
|
-
} else if (mediaQuery) {
|
|
1053
|
-
parts.push("mq_");
|
|
1054
|
-
}
|
|
1055
|
-
if (pseudoClass) {
|
|
1056
|
-
parts.push(`${pseudoSelectorTag(pseudoClass)}_`);
|
|
1057
|
-
}
|
|
1058
|
-
return parts.join("");
|
|
1059
|
-
}
|
|
1060
1057
|
function camelToKebab(s) {
|
|
1061
1058
|
return s.replace(/^(Webkit|Moz|Ms|O)/, (m) => `-${m.toLowerCase()}`).replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
1062
1059
|
}
|
|
@@ -1067,6 +1064,9 @@ function cleanValueForClassName(value) {
|
|
|
1067
1064
|
}
|
|
1068
1065
|
return cleaned.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
1069
1066
|
}
|
|
1067
|
+
function getPropertyAbbreviation(cssProp) {
|
|
1068
|
+
return cssPropertyAbbreviations[cssProp] ?? cssProp;
|
|
1069
|
+
}
|
|
1070
1070
|
function buildLonghandLookup(mapping) {
|
|
1071
1071
|
const lookup = /* @__PURE__ */ new Map();
|
|
1072
1072
|
for (const [abbrev, entry] of Object.entries(mapping.abbreviations)) {
|
|
@@ -1091,9 +1091,6 @@ function getLonghandLookup(mapping) {
|
|
|
1091
1091
|
}
|
|
1092
1092
|
return cachedLookup;
|
|
1093
1093
|
}
|
|
1094
|
-
function getPropertyAbbreviation(cssProp) {
|
|
1095
|
-
return cssPropertyAbbreviations[cssProp] ?? cssProp;
|
|
1096
|
-
}
|
|
1097
1094
|
function computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping) {
|
|
1098
1095
|
const abbr = seg.abbr;
|
|
1099
1096
|
if (seg.argResolved !== void 0) {
|
|
@@ -1145,10 +1142,11 @@ function collectAtomicRules(chains, mapping) {
|
|
|
1145
1142
|
return { rules, needsMaybeInc };
|
|
1146
1143
|
}
|
|
1147
1144
|
function segmentContext(seg, mapping) {
|
|
1145
|
+
const prefix = `${conditionPrefix(seg.pseudoClass, seg.mediaQuery, seg.pseudoElement, mapping.breakpoints)}${seg.whenPseudo ? whenPrefix(seg.whenPseudo) : ""}`;
|
|
1148
1146
|
if (seg.whenPseudo) {
|
|
1149
1147
|
const wp = seg.whenPseudo;
|
|
1150
1148
|
return {
|
|
1151
|
-
prefix
|
|
1149
|
+
prefix,
|
|
1152
1150
|
whenSelector: {
|
|
1153
1151
|
relationship: wp.relationship ?? "ancestor",
|
|
1154
1152
|
markerClass: markerClassName(wp.markerNode),
|
|
@@ -1156,7 +1154,7 @@ function segmentContext(seg, mapping) {
|
|
|
1156
1154
|
}
|
|
1157
1155
|
};
|
|
1158
1156
|
}
|
|
1159
|
-
return { prefix
|
|
1157
|
+
return { prefix };
|
|
1160
1158
|
}
|
|
1161
1159
|
function baseRuleFields(seg) {
|
|
1162
1160
|
return {
|
|
@@ -1175,9 +1173,8 @@ function collectStaticRules(rules, seg, mapping) {
|
|
|
1175
1173
|
if (!rules.has(className)) {
|
|
1176
1174
|
rules.set(className, {
|
|
1177
1175
|
className,
|
|
1178
|
-
cssProperty: camelToKebab(cssProp),
|
|
1179
|
-
|
|
1180
|
-
...!whenSelector && baseRuleFields(seg),
|
|
1176
|
+
declarations: [{ cssProperty: camelToKebab(cssProp), cssValue }],
|
|
1177
|
+
...baseRuleFields(seg),
|
|
1181
1178
|
whenSelector
|
|
1182
1179
|
});
|
|
1183
1180
|
}
|
|
@@ -1193,22 +1190,12 @@ function collectVariableRules(rules, seg, mapping) {
|
|
|
1193
1190
|
if (!existingRule) {
|
|
1194
1191
|
rules.set(className, {
|
|
1195
1192
|
className,
|
|
1196
|
-
cssProperty: declaration.cssProperty,
|
|
1197
|
-
cssValue: declaration.cssValue,
|
|
1198
1193
|
declarations: [declaration],
|
|
1199
|
-
|
|
1200
|
-
...!whenSelector && baseRuleFields(seg),
|
|
1194
|
+
...baseRuleFields(seg),
|
|
1201
1195
|
whenSelector
|
|
1202
1196
|
});
|
|
1203
1197
|
continue;
|
|
1204
1198
|
}
|
|
1205
|
-
existingRule.declarations ??= [
|
|
1206
|
-
{
|
|
1207
|
-
cssProperty: existingRule.cssProperty,
|
|
1208
|
-
cssValue: existingRule.cssValue,
|
|
1209
|
-
cssVarName: existingRule.cssVarName
|
|
1210
|
-
}
|
|
1211
|
-
];
|
|
1212
1199
|
if (!existingRule.declarations.some((entry) => {
|
|
1213
1200
|
return entry.cssProperty === declaration.cssProperty;
|
|
1214
1201
|
})) {
|
|
@@ -1225,9 +1212,8 @@ function collectVariableRules(rules, seg, mapping) {
|
|
|
1225
1212
|
if (!rules.has(extraName)) {
|
|
1226
1213
|
rules.set(extraName, {
|
|
1227
1214
|
className: extraName,
|
|
1228
|
-
cssProperty: camelToKebab(cssProp),
|
|
1229
|
-
|
|
1230
|
-
...!whenSelector && baseRuleFields(seg),
|
|
1215
|
+
declarations: [{ cssProperty: camelToKebab(cssProp), cssValue }],
|
|
1216
|
+
...baseRuleFields(seg),
|
|
1231
1217
|
whenSelector
|
|
1232
1218
|
});
|
|
1233
1219
|
}
|
|
@@ -1256,61 +1242,51 @@ function generateCssText(rules) {
|
|
|
1256
1242
|
return lines.join("\n");
|
|
1257
1243
|
}
|
|
1258
1244
|
function formatRule(rule) {
|
|
1259
|
-
if (rule.whenSelector) return formatWhenRule(rule);
|
|
1260
|
-
if (rule.mediaQuery && rule.pseudoClass) return formatMediaPseudoRule(rule);
|
|
1261
|
-
if (rule.mediaQuery && rule.pseudoElement) return formatMediaPseudoElementRule(rule);
|
|
1262
|
-
if (rule.mediaQuery) return formatMediaRule(rule);
|
|
1263
|
-
if (rule.pseudoClass && rule.pseudoElement) return formatPseudoRule(rule);
|
|
1264
|
-
if (rule.pseudoElement) return formatPseudoElementRule(rule);
|
|
1265
|
-
if (rule.pseudoClass) return formatPseudoRule(rule);
|
|
1266
|
-
return formatBaseRule(rule);
|
|
1267
|
-
}
|
|
1268
|
-
function formatBaseRule(rule) {
|
|
1269
|
-
return formatRuleBlock(`.${rule.className}`, rule);
|
|
1270
|
-
}
|
|
1271
|
-
function formatPseudoRule(rule) {
|
|
1272
|
-
const pe = rule.pseudoElement ? rule.pseudoElement : "";
|
|
1273
|
-
return formatRuleBlock(`.${rule.className}${rule.pseudoClass}${pe}`, rule);
|
|
1274
|
-
}
|
|
1275
|
-
function formatPseudoElementRule(rule) {
|
|
1276
|
-
return formatRuleBlock(`.${rule.className}${rule.pseudoElement}`, rule);
|
|
1277
|
-
}
|
|
1278
|
-
function formatWhenRule(rule) {
|
|
1279
1245
|
const whenSelector = rule.whenSelector;
|
|
1280
|
-
if (
|
|
1281
|
-
|
|
1282
|
-
|
|
1246
|
+
if (whenSelector) return formatWhenRule(rule, whenSelector);
|
|
1247
|
+
const selector = buildTargetSelector(rule, !!rule.mediaQuery);
|
|
1248
|
+
return formatRuleWithOptionalMedia(rule, selector);
|
|
1249
|
+
}
|
|
1250
|
+
function formatWhenRule(rule, whenSelector) {
|
|
1283
1251
|
const markerSelector = `.${whenSelector.markerClass}${whenSelector.pseudo}`;
|
|
1284
|
-
const
|
|
1252
|
+
const duplicateClassName = !!rule.mediaQuery;
|
|
1285
1253
|
if (whenSelector.relationship === "ancestor") {
|
|
1286
|
-
return
|
|
1254
|
+
return formatRuleWithOptionalMedia(rule, `${markerSelector} ${buildTargetSelector(rule, duplicateClassName)}`);
|
|
1287
1255
|
}
|
|
1288
1256
|
if (whenSelector.relationship === "descendant") {
|
|
1289
|
-
return
|
|
1257
|
+
return formatRuleWithOptionalMedia(rule, buildTargetSelector(rule, duplicateClassName, `:has(${markerSelector})`));
|
|
1290
1258
|
}
|
|
1291
1259
|
if (whenSelector.relationship === "siblingAfter") {
|
|
1292
|
-
return
|
|
1260
|
+
return formatRuleWithOptionalMedia(
|
|
1261
|
+
rule,
|
|
1262
|
+
buildTargetSelector(rule, duplicateClassName, `:has(~ ${markerSelector})`)
|
|
1263
|
+
);
|
|
1293
1264
|
}
|
|
1294
1265
|
if (whenSelector.relationship === "siblingBefore") {
|
|
1295
|
-
return
|
|
1266
|
+
return formatRuleWithOptionalMedia(rule, `${markerSelector} ~ ${buildTargetSelector(rule, duplicateClassName)}`);
|
|
1296
1267
|
}
|
|
1297
1268
|
if (whenSelector.relationship === "anySibling") {
|
|
1298
|
-
|
|
1269
|
+
const afterSelector = buildTargetSelector(rule, duplicateClassName, `:has(~ ${markerSelector})`);
|
|
1270
|
+
const beforeSelector = `${markerSelector} ~ ${buildTargetSelector(rule, duplicateClassName)}`;
|
|
1271
|
+
return formatRuleWithOptionalMedia(rule, `${afterSelector}, ${beforeSelector}`);
|
|
1299
1272
|
}
|
|
1300
|
-
return
|
|
1301
|
-
}
|
|
1302
|
-
function formatMediaRule(rule) {
|
|
1303
|
-
return formatNestedRuleBlock(rule.mediaQuery, `.${rule.className}.${rule.className}`, rule);
|
|
1273
|
+
return formatRuleWithOptionalMedia(rule, `${markerSelector} ${buildTargetSelector(rule, duplicateClassName)}`);
|
|
1304
1274
|
}
|
|
1305
|
-
function
|
|
1306
|
-
|
|
1275
|
+
function buildTargetSelector(rule, duplicateClassName, extraPseudoClass) {
|
|
1276
|
+
const classSelector = duplicateClassName ? `.${rule.className}.${rule.className}` : `.${rule.className}`;
|
|
1277
|
+
const pseudoClass = rule.pseudoClass ?? "";
|
|
1278
|
+
const relationshipPseudoClass = extraPseudoClass ?? "";
|
|
1279
|
+
const pseudoElement = rule.pseudoElement ?? "";
|
|
1280
|
+
return `${classSelector}${pseudoClass}${relationshipPseudoClass}${pseudoElement}`;
|
|
1307
1281
|
}
|
|
1308
|
-
function
|
|
1309
|
-
|
|
1310
|
-
|
|
1282
|
+
function formatRuleWithOptionalMedia(rule, selector) {
|
|
1283
|
+
if (rule.mediaQuery) {
|
|
1284
|
+
return formatNestedRuleBlock(rule.mediaQuery, selector, rule);
|
|
1285
|
+
}
|
|
1286
|
+
return formatRuleBlock(selector, rule);
|
|
1311
1287
|
}
|
|
1312
1288
|
function getRuleDeclarations(rule) {
|
|
1313
|
-
return rule.declarations
|
|
1289
|
+
return rule.declarations;
|
|
1314
1290
|
}
|
|
1315
1291
|
function formatRuleBlock(selector, rule) {
|
|
1316
1292
|
const body = getRuleDeclarations(rule).map((declaration) => {
|
|
@@ -1449,6 +1425,78 @@ import * as t4 from "@babel/types";
|
|
|
1449
1425
|
import { basename } from "path";
|
|
1450
1426
|
|
|
1451
1427
|
// src/plugin/resolve-chain.ts
|
|
1428
|
+
function emptyConditionContext() {
|
|
1429
|
+
return {
|
|
1430
|
+
mediaQuery: null,
|
|
1431
|
+
pseudoClass: null,
|
|
1432
|
+
pseudoElement: null,
|
|
1433
|
+
whenPseudo: null
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
function cloneConditionContext(context) {
|
|
1437
|
+
return {
|
|
1438
|
+
mediaQuery: context.mediaQuery,
|
|
1439
|
+
pseudoClass: context.pseudoClass,
|
|
1440
|
+
pseudoElement: context.pseudoElement,
|
|
1441
|
+
whenPseudo: context.whenPseudo ? { ...context.whenPseudo } : null
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
function segmentWithConditionContext(segment, context) {
|
|
1445
|
+
return {
|
|
1446
|
+
...segment,
|
|
1447
|
+
mediaQuery: context.mediaQuery,
|
|
1448
|
+
pseudoClass: context.pseudoClass,
|
|
1449
|
+
pseudoElement: context.pseudoElement,
|
|
1450
|
+
whenPseudo: context.whenPseudo
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
function applyModifierNodeToConditionContext(context, node, mapping) {
|
|
1454
|
+
if (node.type === "__mediaQuery") {
|
|
1455
|
+
context.mediaQuery = node.mediaQuery;
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
if (node.type === "getter") {
|
|
1459
|
+
if (isPseudoMethod(node.name)) {
|
|
1460
|
+
context.pseudoClass = pseudoSelector(node.name);
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
if (mapping.breakpoints && node.name in mapping.breakpoints) {
|
|
1464
|
+
context.mediaQuery = mapping.breakpoints[node.name];
|
|
1465
|
+
}
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
if (node.type !== "call") {
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
if (node.name === "ifContainer") {
|
|
1472
|
+
try {
|
|
1473
|
+
context.mediaQuery = containerSelectorFromCall(node);
|
|
1474
|
+
} catch {
|
|
1475
|
+
}
|
|
1476
|
+
return;
|
|
1477
|
+
}
|
|
1478
|
+
if (node.name === "element") {
|
|
1479
|
+
if (node.args.length === 1 && node.args[0].type === "StringLiteral") {
|
|
1480
|
+
context.pseudoElement = node.args[0].value;
|
|
1481
|
+
}
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
if (node.name === "when") {
|
|
1485
|
+
try {
|
|
1486
|
+
const resolved = resolveWhenCall(node);
|
|
1487
|
+
if (resolved.kind === "selector") {
|
|
1488
|
+
context.pseudoClass = resolved.pseudo;
|
|
1489
|
+
} else {
|
|
1490
|
+
context.whenPseudo = resolved;
|
|
1491
|
+
}
|
|
1492
|
+
} catch {
|
|
1493
|
+
}
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
if (isPseudoMethod(node.name)) {
|
|
1497
|
+
context.pseudoClass = pseudoSelector(node.name);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1452
1500
|
function resolveFullChain(chain, mapping) {
|
|
1453
1501
|
const parts = [];
|
|
1454
1502
|
const markers = [];
|
|
@@ -1470,20 +1518,38 @@ function resolveFullChain(chain, mapping) {
|
|
|
1470
1518
|
}
|
|
1471
1519
|
let i = 0;
|
|
1472
1520
|
let currentNodes = [];
|
|
1521
|
+
let currentContext = emptyConditionContext();
|
|
1522
|
+
let currentNodesStartContext = emptyConditionContext();
|
|
1523
|
+
function flushCurrentNodes() {
|
|
1524
|
+
if (currentNodes.length === 0) {
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
parts.push({
|
|
1528
|
+
type: "unconditional",
|
|
1529
|
+
segments: resolveChain(currentNodes, mapping, currentNodesStartContext)
|
|
1530
|
+
});
|
|
1531
|
+
currentNodes = [];
|
|
1532
|
+
currentNodesStartContext = cloneConditionContext(currentContext);
|
|
1533
|
+
}
|
|
1534
|
+
function pushCurrentNode(nodeToPush) {
|
|
1535
|
+
if (currentNodes.length === 0) {
|
|
1536
|
+
currentNodesStartContext = cloneConditionContext(currentContext);
|
|
1537
|
+
}
|
|
1538
|
+
currentNodes.push(nodeToPush);
|
|
1539
|
+
applyModifierNodeToConditionContext(currentContext, nodeToPush, mapping);
|
|
1540
|
+
}
|
|
1473
1541
|
while (i < filteredChain.length) {
|
|
1474
1542
|
const node = filteredChain[i];
|
|
1475
1543
|
const mediaStart = getMediaConditionalStartNode(node, mapping);
|
|
1476
1544
|
if (mediaStart) {
|
|
1477
1545
|
const elseIndex = findElseIndex(filteredChain, i + 1);
|
|
1478
1546
|
if (elseIndex !== -1) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
currentNodes = [];
|
|
1482
|
-
}
|
|
1547
|
+
flushCurrentNodes();
|
|
1548
|
+
const branchContext = cloneConditionContext(currentContext);
|
|
1483
1549
|
const thenNodes = mediaStart.thenNodes ? [...mediaStart.thenNodes, ...filteredChain.slice(i + 1, elseIndex)] : filteredChain.slice(i, elseIndex);
|
|
1484
1550
|
const elseNodes = [makeMediaQueryNode(mediaStart.inverseMediaQuery), ...filteredChain.slice(elseIndex + 1)];
|
|
1485
|
-
const thenSegs = resolveChain(thenNodes, mapping);
|
|
1486
|
-
const elseSegs = resolveChain(elseNodes, mapping);
|
|
1551
|
+
const thenSegs = resolveChain(thenNodes, mapping, branchContext);
|
|
1552
|
+
const elseSegs = resolveChain(elseNodes, mapping, branchContext);
|
|
1487
1553
|
parts.push({ type: "unconditional", segments: [...thenSegs, ...elseSegs] });
|
|
1488
1554
|
i = filteredChain.length;
|
|
1489
1555
|
break;
|
|
@@ -1492,14 +1558,12 @@ function resolveFullChain(chain, mapping) {
|
|
|
1492
1558
|
if (node.type === "if") {
|
|
1493
1559
|
if (node.conditionNode.type === "StringLiteral") {
|
|
1494
1560
|
const mediaQuery = node.conditionNode.value;
|
|
1495
|
-
|
|
1561
|
+
pushCurrentNode({ type: "__mediaQuery", mediaQuery });
|
|
1496
1562
|
i++;
|
|
1497
1563
|
continue;
|
|
1498
1564
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
currentNodes = [];
|
|
1502
|
-
}
|
|
1565
|
+
flushCurrentNodes();
|
|
1566
|
+
const branchContext = cloneConditionContext(currentContext);
|
|
1503
1567
|
const thenNodes = [];
|
|
1504
1568
|
const elseNodes = [];
|
|
1505
1569
|
i++;
|
|
@@ -1520,8 +1584,8 @@ function resolveFullChain(chain, mapping) {
|
|
|
1520
1584
|
}
|
|
1521
1585
|
i++;
|
|
1522
1586
|
}
|
|
1523
|
-
const thenSegs = resolveChain(thenNodes, mapping);
|
|
1524
|
-
const elseSegs = resolveChain(elseNodes, mapping);
|
|
1587
|
+
const thenSegs = resolveChain(thenNodes, mapping, branchContext);
|
|
1588
|
+
const elseSegs = resolveChain(elseNodes, mapping, branchContext);
|
|
1525
1589
|
parts.push({
|
|
1526
1590
|
type: "conditional",
|
|
1527
1591
|
conditionNode: node.conditionNode,
|
|
@@ -1529,13 +1593,11 @@ function resolveFullChain(chain, mapping) {
|
|
|
1529
1593
|
elseSegments: elseSegs
|
|
1530
1594
|
});
|
|
1531
1595
|
} else {
|
|
1532
|
-
|
|
1596
|
+
pushCurrentNode(node);
|
|
1533
1597
|
i++;
|
|
1534
1598
|
}
|
|
1535
1599
|
}
|
|
1536
|
-
|
|
1537
|
-
parts.push({ type: "unconditional", segments: resolveChain(currentNodes, mapping) });
|
|
1538
|
-
}
|
|
1600
|
+
flushCurrentNodes();
|
|
1539
1601
|
const segmentErrors = [];
|
|
1540
1602
|
for (const part of parts) {
|
|
1541
1603
|
const segs = part.type === "unconditional" ? part.segments : [...part.thenSegments, ...part.elseSegments];
|
|
@@ -1594,29 +1656,23 @@ function invertMediaQuery(query) {
|
|
|
1594
1656
|
}
|
|
1595
1657
|
return query.replace("@media", "@media not");
|
|
1596
1658
|
}
|
|
1597
|
-
function resolveChain(chain, mapping) {
|
|
1659
|
+
function resolveChain(chain, mapping, initialContext = emptyConditionContext()) {
|
|
1598
1660
|
const segments = [];
|
|
1599
|
-
|
|
1600
|
-
let currentPseudoClass = null;
|
|
1601
|
-
let currentPseudoElement = null;
|
|
1602
|
-
let currentWhenPseudo = null;
|
|
1661
|
+
const context = cloneConditionContext(initialContext);
|
|
1603
1662
|
for (const node of chain) {
|
|
1604
1663
|
try {
|
|
1605
1664
|
if (node.type === "__mediaQuery") {
|
|
1606
|
-
|
|
1607
|
-
currentWhenPseudo = null;
|
|
1665
|
+
context.mediaQuery = node.mediaQuery;
|
|
1608
1666
|
continue;
|
|
1609
1667
|
}
|
|
1610
1668
|
if (node.type === "getter") {
|
|
1611
1669
|
const abbr = node.name;
|
|
1612
1670
|
if (isPseudoMethod(abbr)) {
|
|
1613
|
-
|
|
1614
|
-
currentWhenPseudo = null;
|
|
1671
|
+
context.pseudoClass = pseudoSelector(abbr);
|
|
1615
1672
|
continue;
|
|
1616
1673
|
}
|
|
1617
1674
|
if (mapping.breakpoints && abbr in mapping.breakpoints) {
|
|
1618
|
-
|
|
1619
|
-
currentWhenPseudo = null;
|
|
1675
|
+
context.mediaQuery = mapping.breakpoints[abbr];
|
|
1620
1676
|
continue;
|
|
1621
1677
|
}
|
|
1622
1678
|
const entry = mapping.abbreviations[abbr];
|
|
@@ -1627,27 +1683,26 @@ function resolveChain(chain, mapping) {
|
|
|
1627
1683
|
abbr,
|
|
1628
1684
|
entry,
|
|
1629
1685
|
mapping,
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1686
|
+
context.mediaQuery,
|
|
1687
|
+
context.pseudoClass,
|
|
1688
|
+
context.pseudoElement,
|
|
1689
|
+
context.whenPseudo
|
|
1634
1690
|
);
|
|
1635
1691
|
segments.push(...resolved);
|
|
1636
1692
|
} else if (node.type === "call") {
|
|
1637
1693
|
const abbr = node.name;
|
|
1638
1694
|
if (abbr === "ifContainer") {
|
|
1639
|
-
|
|
1640
|
-
currentWhenPseudo = null;
|
|
1695
|
+
context.mediaQuery = containerSelectorFromCall(node);
|
|
1641
1696
|
continue;
|
|
1642
1697
|
}
|
|
1643
1698
|
if (abbr === "add" || abbr === "addCss") {
|
|
1644
1699
|
const seg = resolveAddCall(
|
|
1645
1700
|
node,
|
|
1646
1701
|
mapping,
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1702
|
+
context.mediaQuery,
|
|
1703
|
+
context.pseudoClass,
|
|
1704
|
+
context.pseudoElement,
|
|
1705
|
+
context.whenPseudo
|
|
1651
1706
|
);
|
|
1652
1707
|
segments.push(seg);
|
|
1653
1708
|
continue;
|
|
@@ -1655,10 +1710,10 @@ function resolveChain(chain, mapping) {
|
|
|
1655
1710
|
if (abbr === "className") {
|
|
1656
1711
|
const seg = resolveClassNameCall(
|
|
1657
1712
|
node,
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1713
|
+
context.mediaQuery,
|
|
1714
|
+
context.pseudoClass,
|
|
1715
|
+
context.pseudoElement,
|
|
1716
|
+
context.whenPseudo
|
|
1662
1717
|
);
|
|
1663
1718
|
segments.push(seg);
|
|
1664
1719
|
continue;
|
|
@@ -1667,9 +1722,10 @@ function resolveChain(chain, mapping) {
|
|
|
1667
1722
|
const resolved = resolveTypographyCall(
|
|
1668
1723
|
node,
|
|
1669
1724
|
mapping,
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1725
|
+
context.mediaQuery,
|
|
1726
|
+
context.pseudoClass,
|
|
1727
|
+
context.pseudoElement,
|
|
1728
|
+
context.whenPseudo
|
|
1673
1729
|
);
|
|
1674
1730
|
segments.push(...resolved);
|
|
1675
1731
|
continue;
|
|
@@ -1680,24 +1736,20 @@ function resolveChain(chain, mapping) {
|
|
|
1680
1736
|
`element() requires exactly one string literal argument (e.g. "::placeholder")`
|
|
1681
1737
|
);
|
|
1682
1738
|
}
|
|
1683
|
-
|
|
1739
|
+
context.pseudoElement = node.args[0].value;
|
|
1684
1740
|
continue;
|
|
1685
1741
|
}
|
|
1686
1742
|
if (abbr === "when") {
|
|
1687
1743
|
const resolved = resolveWhenCall(node);
|
|
1688
1744
|
if (resolved.kind === "selector") {
|
|
1689
|
-
|
|
1690
|
-
currentWhenPseudo = null;
|
|
1745
|
+
context.pseudoClass = resolved.pseudo;
|
|
1691
1746
|
} else {
|
|
1692
|
-
|
|
1693
|
-
currentMediaQuery = null;
|
|
1694
|
-
currentWhenPseudo = resolved;
|
|
1747
|
+
context.whenPseudo = resolved;
|
|
1695
1748
|
}
|
|
1696
1749
|
continue;
|
|
1697
1750
|
}
|
|
1698
1751
|
if (isPseudoMethod(abbr)) {
|
|
1699
|
-
|
|
1700
|
-
currentWhenPseudo = null;
|
|
1752
|
+
context.pseudoClass = pseudoSelector(abbr);
|
|
1701
1753
|
if (node.args.length > 0) {
|
|
1702
1754
|
throw new UnsupportedPatternError(
|
|
1703
1755
|
`${abbr}() does not take arguments -- use when(marker, "ancestor", ":hover") for relationship selectors`
|
|
@@ -1715,10 +1767,10 @@ function resolveChain(chain, mapping) {
|
|
|
1715
1767
|
entry,
|
|
1716
1768
|
node,
|
|
1717
1769
|
mapping,
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1770
|
+
context.mediaQuery,
|
|
1771
|
+
context.pseudoClass,
|
|
1772
|
+
context.pseudoElement,
|
|
1773
|
+
context.whenPseudo
|
|
1722
1774
|
);
|
|
1723
1775
|
segments.push(seg);
|
|
1724
1776
|
} else if (entry.kind === "delegate") {
|
|
@@ -1727,10 +1779,10 @@ function resolveChain(chain, mapping) {
|
|
|
1727
1779
|
entry,
|
|
1728
1780
|
node,
|
|
1729
1781
|
mapping,
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1782
|
+
context.mediaQuery,
|
|
1783
|
+
context.pseudoClass,
|
|
1784
|
+
context.pseudoElement,
|
|
1785
|
+
context.whenPseudo
|
|
1734
1786
|
);
|
|
1735
1787
|
segments.push(seg);
|
|
1736
1788
|
} else {
|
|
@@ -1747,7 +1799,7 @@ function resolveChain(chain, mapping) {
|
|
|
1747
1799
|
}
|
|
1748
1800
|
return segments;
|
|
1749
1801
|
}
|
|
1750
|
-
function typographyLookupKeySuffix(mediaQuery, pseudoClass, pseudoElement, breakpoints) {
|
|
1802
|
+
function typographyLookupKeySuffix(mediaQuery, pseudoClass, pseudoElement, whenPseudo, breakpoints) {
|
|
1751
1803
|
const parts = [];
|
|
1752
1804
|
if (pseudoElement) parts.push(pseudoElement.replace(/^::/, ""));
|
|
1753
1805
|
if (mediaQuery && breakpoints) {
|
|
@@ -1757,25 +1809,36 @@ function typographyLookupKeySuffix(mediaQuery, pseudoClass, pseudoElement, break
|
|
|
1757
1809
|
parts.push("mq");
|
|
1758
1810
|
}
|
|
1759
1811
|
if (pseudoClass) parts.push(pseudoClass.replace(/^:+/, "").replace(/-/g, "_"));
|
|
1812
|
+
if (whenPseudo) parts.push(whenLookupKeyPart(whenPseudo));
|
|
1760
1813
|
return parts.join("_");
|
|
1761
1814
|
}
|
|
1762
|
-
function
|
|
1815
|
+
function whenLookupKeyPart(whenPseudo) {
|
|
1816
|
+
const parts = ["when", whenPseudo.relationship ?? "ancestor", sanitizeLookupToken(whenPseudo.pseudo)];
|
|
1817
|
+
if (whenPseudo.markerNode?.type === "Identifier" && whenPseudo.markerNode.name) {
|
|
1818
|
+
parts.push(whenPseudo.markerNode.name);
|
|
1819
|
+
}
|
|
1820
|
+
return parts.join("_");
|
|
1821
|
+
}
|
|
1822
|
+
function sanitizeLookupToken(value) {
|
|
1823
|
+
return value.replace(/[^a-zA-Z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "") || "value";
|
|
1824
|
+
}
|
|
1825
|
+
function resolveTypographyCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
1763
1826
|
if (node.args.length !== 1) {
|
|
1764
1827
|
throw new UnsupportedPatternError(`typography() expects exactly 1 argument, got ${node.args.length}`);
|
|
1765
1828
|
}
|
|
1766
1829
|
const argAst = node.args[0];
|
|
1767
1830
|
if (argAst.type === "StringLiteral") {
|
|
1768
|
-
return resolveTypographyEntry(argAst.value, mapping, mediaQuery, pseudoClass, pseudoElement);
|
|
1831
|
+
return resolveTypographyEntry(argAst.value, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo);
|
|
1769
1832
|
}
|
|
1770
1833
|
const typography = mapping.typography ?? [];
|
|
1771
1834
|
if (typography.length === 0) {
|
|
1772
1835
|
throw new UnsupportedPatternError(`typography() is unavailable because no typography abbreviations were generated`);
|
|
1773
1836
|
}
|
|
1774
|
-
const suffix = typographyLookupKeySuffix(mediaQuery, pseudoClass, pseudoElement, mapping.breakpoints);
|
|
1837
|
+
const suffix = typographyLookupKeySuffix(mediaQuery, pseudoClass, pseudoElement, whenPseudo, mapping.breakpoints);
|
|
1775
1838
|
const lookupKey = suffix ? `typography__${suffix}` : "typography";
|
|
1776
1839
|
const segmentsByName = {};
|
|
1777
1840
|
for (const name of typography) {
|
|
1778
|
-
segmentsByName[name] = resolveTypographyEntry(name, mapping, mediaQuery, pseudoClass, pseudoElement);
|
|
1841
|
+
segmentsByName[name] = resolveTypographyEntry(name, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo);
|
|
1779
1842
|
}
|
|
1780
1843
|
return [
|
|
1781
1844
|
{
|
|
@@ -1789,7 +1852,7 @@ function resolveTypographyCall(node, mapping, mediaQuery, pseudoClass, pseudoEle
|
|
|
1789
1852
|
}
|
|
1790
1853
|
];
|
|
1791
1854
|
}
|
|
1792
|
-
function resolveTypographyEntry(name, mapping, mediaQuery, pseudoClass, pseudoElement) {
|
|
1855
|
+
function resolveTypographyEntry(name, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
1793
1856
|
if (!(mapping.typography ?? []).includes(name)) {
|
|
1794
1857
|
throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
|
|
1795
1858
|
}
|
|
@@ -1797,21 +1860,24 @@ function resolveTypographyEntry(name, mapping, mediaQuery, pseudoClass, pseudoEl
|
|
|
1797
1860
|
if (!entry) {
|
|
1798
1861
|
throw new UnsupportedPatternError(`Unknown typography abbreviation "${name}"`);
|
|
1799
1862
|
}
|
|
1800
|
-
const resolved = resolveEntry(name, entry, mapping, mediaQuery, pseudoClass, pseudoElement,
|
|
1863
|
+
const resolved = resolveEntry(name, entry, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo);
|
|
1801
1864
|
for (const segment of resolved) {
|
|
1802
|
-
if (segment.variableProps
|
|
1865
|
+
if (segment.variableProps) {
|
|
1803
1866
|
throw new UnsupportedPatternError(`Typography abbreviation "${name}" cannot require runtime arguments`);
|
|
1804
1867
|
}
|
|
1805
1868
|
}
|
|
1806
1869
|
return resolved;
|
|
1807
1870
|
}
|
|
1808
1871
|
function resolveEntry(abbr, entry, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
1872
|
+
const context = {
|
|
1873
|
+
mediaQuery,
|
|
1874
|
+
pseudoClass,
|
|
1875
|
+
pseudoElement,
|
|
1876
|
+
whenPseudo
|
|
1877
|
+
};
|
|
1809
1878
|
switch (entry.kind) {
|
|
1810
1879
|
case "static": {
|
|
1811
|
-
|
|
1812
|
-
return [{ abbr, defs: entry.defs, whenPseudo }];
|
|
1813
|
-
}
|
|
1814
|
-
return [{ abbr, defs: entry.defs, mediaQuery, pseudoClass, pseudoElement }];
|
|
1880
|
+
return [segmentWithConditionContext({ abbr, defs: entry.defs }, context)];
|
|
1815
1881
|
}
|
|
1816
1882
|
case "alias": {
|
|
1817
1883
|
const result = [];
|
|
@@ -1874,40 +1940,32 @@ function resolveDelegateCall(abbr, entry, node, mapping, mediaQuery, pseudoClass
|
|
|
1874
1940
|
}
|
|
1875
1941
|
function buildParameterizedSegment(params) {
|
|
1876
1942
|
const { abbr, props, incremented, appendPx, extraDefs, argAst, literalValue, whenPseudo } = params;
|
|
1943
|
+
const context = {
|
|
1944
|
+
mediaQuery: params.mediaQuery,
|
|
1945
|
+
pseudoClass: params.pseudoClass,
|
|
1946
|
+
pseudoElement: params.pseudoElement,
|
|
1947
|
+
whenPseudo
|
|
1948
|
+
};
|
|
1877
1949
|
if (literalValue !== null) {
|
|
1878
1950
|
const defs = {};
|
|
1879
1951
|
for (const prop of props) {
|
|
1880
1952
|
defs[prop] = literalValue;
|
|
1881
1953
|
}
|
|
1882
1954
|
if (extraDefs) Object.assign(defs, extraDefs);
|
|
1883
|
-
|
|
1884
|
-
return { abbr, defs, whenPseudo, argResolved: literalValue };
|
|
1885
|
-
}
|
|
1886
|
-
return {
|
|
1887
|
-
abbr,
|
|
1888
|
-
defs,
|
|
1889
|
-
mediaQuery: params.mediaQuery,
|
|
1890
|
-
pseudoClass: params.pseudoClass,
|
|
1891
|
-
pseudoElement: params.pseudoElement,
|
|
1892
|
-
argResolved: literalValue
|
|
1893
|
-
};
|
|
1955
|
+
return segmentWithConditionContext({ abbr, defs, argResolved: literalValue }, context);
|
|
1894
1956
|
}
|
|
1895
|
-
const base =
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1957
|
+
const base = segmentWithConditionContext(
|
|
1958
|
+
{
|
|
1959
|
+
abbr,
|
|
1960
|
+
defs: {},
|
|
1961
|
+
variableProps: props,
|
|
1962
|
+
incremented,
|
|
1963
|
+
variableExtraDefs: extraDefs,
|
|
1964
|
+
argNode: argAst
|
|
1965
|
+
},
|
|
1966
|
+
context
|
|
1967
|
+
);
|
|
1903
1968
|
if (appendPx) base.appendPx = true;
|
|
1904
|
-
if (whenPseudo) {
|
|
1905
|
-
base.whenPseudo = whenPseudo;
|
|
1906
|
-
} else {
|
|
1907
|
-
base.mediaQuery = params.mediaQuery;
|
|
1908
|
-
base.pseudoClass = params.pseudoClass;
|
|
1909
|
-
base.pseudoElement = params.pseudoElement;
|
|
1910
|
-
}
|
|
1911
1969
|
return base;
|
|
1912
1970
|
}
|
|
1913
1971
|
function resolveClassNameCall(node, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
@@ -1977,34 +2035,28 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
1977
2035
|
const propName = propArg.value;
|
|
1978
2036
|
const valueArg = node.args[1];
|
|
1979
2037
|
const literalValue = tryEvaluateAddLiteral(valueArg);
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
}
|
|
2038
|
+
const context = {
|
|
2039
|
+
mediaQuery,
|
|
2040
|
+
pseudoClass,
|
|
2041
|
+
pseudoElement,
|
|
2042
|
+
whenPseudo
|
|
2043
|
+
};
|
|
1987
2044
|
if (literalValue !== null) {
|
|
1988
|
-
return
|
|
1989
|
-
abbr: propName,
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
};
|
|
1996
|
-
} else {
|
|
1997
|
-
return {
|
|
2045
|
+
return segmentWithConditionContext(
|
|
2046
|
+
{ abbr: propName, defs: { [propName]: literalValue }, argResolved: literalValue },
|
|
2047
|
+
context
|
|
2048
|
+
);
|
|
2049
|
+
}
|
|
2050
|
+
return segmentWithConditionContext(
|
|
2051
|
+
{
|
|
1998
2052
|
abbr: propName,
|
|
1999
2053
|
defs: {},
|
|
2000
|
-
mediaQuery,
|
|
2001
|
-
pseudoClass,
|
|
2002
|
-
pseudoElement,
|
|
2003
2054
|
variableProps: [propName],
|
|
2004
2055
|
incremented: false,
|
|
2005
2056
|
argNode: valueArg
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2057
|
+
},
|
|
2058
|
+
context
|
|
2059
|
+
);
|
|
2008
2060
|
}
|
|
2009
2061
|
function tryEvaluateAddLiteral(node) {
|
|
2010
2062
|
if (node.type === "StringLiteral") {
|