@plumeria/unplugin 18.0.1 → 18.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.js +198 -36
- package/dist/core.mjs +198 -36
- package/package.json +2 -2
package/dist/core.js
CHANGED
|
@@ -813,6 +813,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
813
813
|
});
|
|
814
814
|
const conditionals = [];
|
|
815
815
|
let groupIdCounter = 0;
|
|
816
|
+
let sourceOrder = 0;
|
|
817
|
+
const baseChunks = [];
|
|
816
818
|
let baseStyle = {};
|
|
817
819
|
let isOptimizable = true;
|
|
818
820
|
const resolveCreateObject = (varName) => {
|
|
@@ -826,11 +828,104 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
826
828
|
return scannedTables.createObjectTable[hash];
|
|
827
829
|
return null;
|
|
828
830
|
};
|
|
831
|
+
const resolveBracketGroup = (node) => {
|
|
832
|
+
if (!utils_1.t.isMemberExpression(node) ||
|
|
833
|
+
!utils_1.t.isIdentifier(node.object) ||
|
|
834
|
+
node.property.type !== 'Computed' ||
|
|
835
|
+
utils_1.t.isStringLiteral(node.property.expression)) {
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
const varName = node.object.value;
|
|
839
|
+
const obj = resolveCreateObject(varName);
|
|
840
|
+
return obj
|
|
841
|
+
? { varName, keyExpr: node.property.expression, obj }
|
|
842
|
+
: null;
|
|
843
|
+
};
|
|
844
|
+
const buildDecision = (node, prefix, off, counter) => {
|
|
845
|
+
if (node.type === 'ParenthesisExpression') {
|
|
846
|
+
return buildDecision(node.expression, prefix, off, counter);
|
|
847
|
+
}
|
|
848
|
+
if (node.type === 'ConditionalExpression') {
|
|
849
|
+
const a = buildDecision(node.consequent, prefix, off, counter);
|
|
850
|
+
if (!a)
|
|
851
|
+
return null;
|
|
852
|
+
const b = buildDecision(node.alternate, prefix, off, counter);
|
|
853
|
+
if (!b)
|
|
854
|
+
return null;
|
|
855
|
+
return {
|
|
856
|
+
keyExpr: `((${getSource(node.test)}) ? ${a.keyExpr} : ${b.keyExpr})`,
|
|
857
|
+
options: [...a.options, ...b.options],
|
|
858
|
+
leaves: a.leaves + b.leaves,
|
|
859
|
+
hasGroup: a.hasGroup || b.hasGroup,
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
if (node.type === 'BinaryExpression' && node.operator === '&&') {
|
|
863
|
+
const right = buildDecision(node.right, prefix, off, counter);
|
|
864
|
+
if (!right)
|
|
865
|
+
return null;
|
|
866
|
+
return {
|
|
867
|
+
keyExpr: `((${getSource(node.left)}) ? ${right.keyExpr} : ${JSON.stringify(off)})`,
|
|
868
|
+
options: right.options,
|
|
869
|
+
leaves: right.leaves,
|
|
870
|
+
hasGroup: right.hasGroup,
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
const group = resolveBracketGroup(node);
|
|
874
|
+
if (group) {
|
|
875
|
+
return {
|
|
876
|
+
keyExpr: getSource(group.keyExpr),
|
|
877
|
+
options: Object.entries(group.obj).map(([value, style]) => ({
|
|
878
|
+
value,
|
|
879
|
+
style: style,
|
|
880
|
+
})),
|
|
881
|
+
leaves: 1,
|
|
882
|
+
hasGroup: true,
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
const style = resolveStyleObject(node);
|
|
886
|
+
if (!style)
|
|
887
|
+
return null;
|
|
888
|
+
const value = `${prefix}${counter.n++}`;
|
|
889
|
+
return {
|
|
890
|
+
keyExpr: JSON.stringify(value),
|
|
891
|
+
options: [{ value, style }],
|
|
892
|
+
leaves: 1,
|
|
893
|
+
hasGroup: false,
|
|
894
|
+
};
|
|
895
|
+
};
|
|
896
|
+
const collectGroupKeys = (node, acc) => {
|
|
897
|
+
if (node.type === 'ParenthesisExpression') {
|
|
898
|
+
collectGroupKeys(node.expression, acc);
|
|
899
|
+
}
|
|
900
|
+
else if (node.type === 'ConditionalExpression') {
|
|
901
|
+
collectGroupKeys(node.consequent, acc);
|
|
902
|
+
collectGroupKeys(node.alternate, acc);
|
|
903
|
+
}
|
|
904
|
+
else if (node.type === 'BinaryExpression' &&
|
|
905
|
+
node.operator === '&&') {
|
|
906
|
+
collectGroupKeys(node.right, acc);
|
|
907
|
+
}
|
|
908
|
+
else {
|
|
909
|
+
const group = resolveBracketGroup(node);
|
|
910
|
+
if (group)
|
|
911
|
+
Object.keys(group.obj).forEach((k) => acc.add(k));
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
const resolveDecision = (node) => {
|
|
915
|
+
const groupKeys = new Set();
|
|
916
|
+
collectGroupKeys(node, groupKeys);
|
|
917
|
+
let prefix = '#';
|
|
918
|
+
while ([...groupKeys].some((k) => k.startsWith(prefix)))
|
|
919
|
+
prefix += '#';
|
|
920
|
+
const off = groupKeys.has('') ? `${prefix}off` : '';
|
|
921
|
+
return buildDecision(node, prefix, off, { n: 0 });
|
|
922
|
+
};
|
|
829
923
|
const collectConditions = (node, currentTestStrings = []) => {
|
|
830
924
|
const staticStyle = resolveStyleObject(node);
|
|
831
925
|
if (staticStyle) {
|
|
832
926
|
if (currentTestStrings.length === 0) {
|
|
833
927
|
baseStyle = (0, utils_1.deepMerge)(baseStyle, staticStyle);
|
|
928
|
+
baseChunks.push({ order: sourceOrder++, style: staticStyle });
|
|
834
929
|
}
|
|
835
930
|
else {
|
|
836
931
|
conditionals.push({
|
|
@@ -839,6 +934,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
839
934
|
truthy: staticStyle,
|
|
840
935
|
falsy: {},
|
|
841
936
|
varName: undefined,
|
|
937
|
+
order: sourceOrder++,
|
|
842
938
|
});
|
|
843
939
|
}
|
|
844
940
|
return true;
|
|
@@ -855,6 +951,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
855
951
|
truthy: trueStyle,
|
|
856
952
|
falsy: falseStyle,
|
|
857
953
|
varName: undefined,
|
|
954
|
+
order: sourceOrder++,
|
|
858
955
|
});
|
|
859
956
|
return true;
|
|
860
957
|
}
|
|
@@ -880,14 +977,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
880
977
|
else if (node.type === 'ParenthesisExpression') {
|
|
881
978
|
return collectConditions(node.expression, currentTestStrings);
|
|
882
979
|
}
|
|
883
|
-
if (currentTestStrings.length > 0 &&
|
|
884
|
-
utils_1.t.isMemberExpression(node) &&
|
|
885
|
-
utils_1.t.isIdentifier(node.object) &&
|
|
886
|
-
node.property.type === 'Computed' &&
|
|
887
|
-
resolveCreateObject(node.object.value)) {
|
|
888
|
-
const varName = node.object.value;
|
|
889
|
-
throwCompilationError(`Plumeria: "${getSource(node)}" cannot be used inside a condition, because its bracket key is not a literal.\nMove the condition into the brackets instead, e.g. ${varName}[cond ? 'a' : 'b'].`, node);
|
|
890
|
-
}
|
|
891
980
|
assertResolvable(node);
|
|
892
981
|
return false;
|
|
893
982
|
};
|
|
@@ -914,6 +1003,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
914
1003
|
}
|
|
915
1004
|
if (propPossibilities && propPossibilities.length > 0) {
|
|
916
1005
|
const currentGroupId = ++groupIdCounter;
|
|
1006
|
+
const currentOrder = sourceOrder++;
|
|
917
1007
|
const uniqueEntries = [];
|
|
918
1008
|
propPossibilities.forEach((entry) => {
|
|
919
1009
|
if (!uniqueEntries.some((x) => x.key === entry.key)) {
|
|
@@ -928,6 +1018,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
928
1018
|
truthy: entry.styleObj,
|
|
929
1019
|
falsy: {},
|
|
930
1020
|
groupId: currentGroupId,
|
|
1021
|
+
order: currentOrder,
|
|
931
1022
|
groupName: undefined,
|
|
932
1023
|
valueName: entry.key,
|
|
933
1024
|
varName,
|
|
@@ -984,11 +1075,18 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
984
1075
|
if (!groupVariants)
|
|
985
1076
|
continue;
|
|
986
1077
|
const currentGroupId = ++groupIdCounter;
|
|
1078
|
+
const currentOrder = sourceOrder++;
|
|
987
1079
|
const valSource = getSource(valExpr);
|
|
988
1080
|
if (valExpr.type === 'StringLiteral') {
|
|
989
1081
|
const groupVariantsAsObj = groupVariants;
|
|
990
|
-
|
|
991
|
-
|
|
1082
|
+
const picked = groupVariantsAsObj[valExpr.value];
|
|
1083
|
+
if (picked) {
|
|
1084
|
+
baseStyle = (0, utils_1.deepMerge)(baseStyle, picked);
|
|
1085
|
+
baseChunks.push({
|
|
1086
|
+
order: sourceOrder++,
|
|
1087
|
+
style: picked,
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
992
1090
|
continue;
|
|
993
1091
|
}
|
|
994
1092
|
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
@@ -999,6 +1097,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
999
1097
|
truthy: style,
|
|
1000
1098
|
falsy: {},
|
|
1001
1099
|
groupId: currentGroupId,
|
|
1100
|
+
order: currentOrder,
|
|
1002
1101
|
groupName,
|
|
1003
1102
|
valueName: optionName,
|
|
1004
1103
|
varName,
|
|
@@ -1010,11 +1109,15 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1010
1109
|
}
|
|
1011
1110
|
const argSource = getSource(arg);
|
|
1012
1111
|
if (utils_1.t.isStringLiteral(arg)) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1112
|
+
const picked = variantObj[arg.value];
|
|
1113
|
+
if (picked) {
|
|
1114
|
+
baseStyle = (0, utils_1.deepMerge)(baseStyle, picked);
|
|
1115
|
+
baseChunks.push({ order: sourceOrder++, style: picked });
|
|
1116
|
+
}
|
|
1015
1117
|
continue;
|
|
1016
1118
|
}
|
|
1017
1119
|
const currentGroupId = ++groupIdCounter;
|
|
1120
|
+
const currentOrder = sourceOrder++;
|
|
1018
1121
|
Object.entries(variantObj).forEach(([key, style]) => {
|
|
1019
1122
|
conditionals.push({
|
|
1020
1123
|
test: arg,
|
|
@@ -1023,6 +1126,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1023
1126
|
truthy: style,
|
|
1024
1127
|
falsy: {},
|
|
1025
1128
|
groupId: currentGroupId,
|
|
1129
|
+
order: currentOrder,
|
|
1026
1130
|
groupName: undefined,
|
|
1027
1131
|
valueName: key,
|
|
1028
1132
|
varName,
|
|
@@ -1050,6 +1154,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1050
1154
|
if (!groupVariants)
|
|
1051
1155
|
return;
|
|
1052
1156
|
const currentGroupId = ++groupIdCounter;
|
|
1157
|
+
const currentOrder = sourceOrder++;
|
|
1053
1158
|
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
1054
1159
|
conditionals.push({
|
|
1055
1160
|
test: expr,
|
|
@@ -1058,6 +1163,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1058
1163
|
truthy: style,
|
|
1059
1164
|
falsy: {},
|
|
1060
1165
|
groupId: currentGroupId,
|
|
1166
|
+
order: currentOrder,
|
|
1061
1167
|
groupName,
|
|
1062
1168
|
valueName: optionName,
|
|
1063
1169
|
varName,
|
|
@@ -1076,6 +1182,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1076
1182
|
const dynExpr = expr.property.expression;
|
|
1077
1183
|
const dynSource = getSource(dynExpr);
|
|
1078
1184
|
const currentGroupId = ++groupIdCounter;
|
|
1185
|
+
const currentOrder = sourceOrder++;
|
|
1079
1186
|
Object.entries(styleObj).forEach(([optionName, style]) => {
|
|
1080
1187
|
conditionals.push({
|
|
1081
1188
|
test: dynExpr,
|
|
@@ -1084,6 +1191,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1084
1191
|
truthy: style,
|
|
1085
1192
|
falsy: {},
|
|
1086
1193
|
groupId: currentGroupId,
|
|
1194
|
+
order: currentOrder,
|
|
1087
1195
|
groupName: undefined,
|
|
1088
1196
|
valueName: optionName,
|
|
1089
1197
|
varName,
|
|
@@ -1092,6 +1200,24 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1092
1200
|
continue;
|
|
1093
1201
|
}
|
|
1094
1202
|
}
|
|
1203
|
+
const decision = resolveDecision(expr);
|
|
1204
|
+
if (decision && (decision.hasGroup || decision.leaves > 2)) {
|
|
1205
|
+
const groupId = ++groupIdCounter;
|
|
1206
|
+
const currentOrder = sourceOrder++;
|
|
1207
|
+
decision.options.forEach(({ value, style }) => conditionals.push({
|
|
1208
|
+
test: expr,
|
|
1209
|
+
testLHS: decision.keyExpr,
|
|
1210
|
+
testString: `${decision.keyExpr} === '${value}'`,
|
|
1211
|
+
truthy: style,
|
|
1212
|
+
falsy: {},
|
|
1213
|
+
groupId,
|
|
1214
|
+
order: currentOrder,
|
|
1215
|
+
groupName: undefined,
|
|
1216
|
+
valueName: value,
|
|
1217
|
+
varName: undefined,
|
|
1218
|
+
}));
|
|
1219
|
+
continue;
|
|
1220
|
+
}
|
|
1095
1221
|
const handled = collectConditions(expr);
|
|
1096
1222
|
if (handled)
|
|
1097
1223
|
continue;
|
|
@@ -1225,7 +1351,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1225
1351
|
getSource(options[0].test);
|
|
1226
1352
|
const lookupMap = {};
|
|
1227
1353
|
options.forEach((opt) => {
|
|
1228
|
-
if (opt.valueName && opt.truthy) {
|
|
1354
|
+
if (opt.valueName !== undefined && opt.truthy) {
|
|
1229
1355
|
const className = processStyleRecords(opt.truthy)
|
|
1230
1356
|
.map((r) => r.hash)
|
|
1231
1357
|
.join(' ');
|
|
@@ -1242,17 +1368,38 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1242
1368
|
});
|
|
1243
1369
|
if (Object.keys(baseConflict).length > 0 ||
|
|
1244
1370
|
conflictConditionals.length > 0) {
|
|
1245
|
-
const
|
|
1371
|
+
const ordered = [];
|
|
1372
|
+
baseChunks.forEach(({ order, style }) => {
|
|
1373
|
+
const conflicting = {};
|
|
1374
|
+
Object.entries(style).forEach(([key, value]) => {
|
|
1375
|
+
if (conflictingKeys.has(key))
|
|
1376
|
+
conflicting[key] = value;
|
|
1377
|
+
});
|
|
1378
|
+
if (Object.keys(conflicting).length === 0)
|
|
1379
|
+
return;
|
|
1380
|
+
ordered.push({
|
|
1381
|
+
order,
|
|
1382
|
+
dimension: {
|
|
1383
|
+
type: 'const',
|
|
1384
|
+
options: [
|
|
1385
|
+
{ value: undefined, style: conflicting, label: 'base' },
|
|
1386
|
+
],
|
|
1387
|
+
},
|
|
1388
|
+
});
|
|
1389
|
+
});
|
|
1246
1390
|
conflictConditionals
|
|
1247
1391
|
.filter((c) => c.groupId === undefined)
|
|
1248
1392
|
.forEach((c) => {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1393
|
+
ordered.push({
|
|
1394
|
+
order: c.order ?? 0,
|
|
1395
|
+
dimension: {
|
|
1396
|
+
type: 'std',
|
|
1397
|
+
testExpr: c.testString ?? getSource(c.test),
|
|
1398
|
+
options: [
|
|
1399
|
+
{ value: 0, style: c.falsy, label: 'false' },
|
|
1400
|
+
{ value: 1, style: c.truthy, label: 'true' },
|
|
1401
|
+
],
|
|
1402
|
+
},
|
|
1256
1403
|
});
|
|
1257
1404
|
});
|
|
1258
1405
|
const conflictVarGroups = {};
|
|
@@ -1263,19 +1410,33 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1263
1410
|
conflictVarGroups[c.groupId].push(c);
|
|
1264
1411
|
}
|
|
1265
1412
|
});
|
|
1413
|
+
Object.keys(conflictVarGroups).forEach((id) => {
|
|
1414
|
+
const groupId = Number(id);
|
|
1415
|
+
const opts = conflictVarGroups[groupId];
|
|
1416
|
+
if (opts.some((c) => c.valueName === ''))
|
|
1417
|
+
return;
|
|
1418
|
+
const off = conditionals.find((c) => c.groupId === groupId && c.valueName === '');
|
|
1419
|
+
if (off)
|
|
1420
|
+
opts.push({ ...off, truthy: {}, falsy: {} });
|
|
1421
|
+
});
|
|
1266
1422
|
Object.entries(conflictVarGroups).forEach(([, opts]) => {
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1423
|
+
ordered.push({
|
|
1424
|
+
order: opts[0].order ?? 0,
|
|
1425
|
+
dimension: {
|
|
1426
|
+
type: 'var',
|
|
1427
|
+
testExpr: opts[0].testLHS ??
|
|
1428
|
+
opts[0].testString ??
|
|
1429
|
+
getSource(opts[0].test),
|
|
1430
|
+
options: opts.map((opt) => ({
|
|
1431
|
+
value: opt.valueName,
|
|
1432
|
+
style: opt.truthy,
|
|
1433
|
+
label: opt.valueName || 'default',
|
|
1434
|
+
})),
|
|
1435
|
+
},
|
|
1277
1436
|
});
|
|
1278
1437
|
});
|
|
1438
|
+
ordered.sort((a, b) => a.order - b.order);
|
|
1439
|
+
const dimensions = ordered.map((o) => o.dimension);
|
|
1279
1440
|
const results = {};
|
|
1280
1441
|
const recurse = (dimIndex, currentStyle, keyParts) => {
|
|
1281
1442
|
if (dimIndex >= dimensions.length) {
|
|
@@ -1286,18 +1447,19 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1286
1447
|
results[keyParts.join('__')] = className;
|
|
1287
1448
|
return;
|
|
1288
1449
|
}
|
|
1289
|
-
dimensions[dimIndex]
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1450
|
+
const dimension = dimensions[dimIndex];
|
|
1451
|
+
dimension.options.forEach((opt) => recurse(dimIndex + 1, (0, utils_1.deepMerge)(currentStyle, opt.style), dimension.type === 'const'
|
|
1452
|
+
? keyParts
|
|
1453
|
+
: [...keyParts, String(opt.value)]));
|
|
1293
1454
|
};
|
|
1294
|
-
recurse(0,
|
|
1455
|
+
recurse(0, {}, []);
|
|
1295
1456
|
const baseConflictClass = Object.keys(baseConflict).length > 0
|
|
1296
1457
|
? processStyleRecords(baseConflict)
|
|
1297
1458
|
.map((r) => r.hash)
|
|
1298
1459
|
.join(' ')
|
|
1299
1460
|
: '';
|
|
1300
1461
|
const masterKeyExpr = dimensions
|
|
1462
|
+
.filter((dim) => dim.type !== 'const')
|
|
1301
1463
|
.map((dim) => dim.type === 'std'
|
|
1302
1464
|
? `(${dim.testExpr} ? "1" : "0")`
|
|
1303
1465
|
: dim.testExpr || '""')
|
package/dist/core.mjs
CHANGED
|
@@ -777,6 +777,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
777
777
|
});
|
|
778
778
|
const conditionals = [];
|
|
779
779
|
let groupIdCounter = 0;
|
|
780
|
+
let sourceOrder = 0;
|
|
781
|
+
const baseChunks = [];
|
|
780
782
|
let baseStyle = {};
|
|
781
783
|
let isOptimizable = true;
|
|
782
784
|
const resolveCreateObject = (varName) => {
|
|
@@ -790,11 +792,104 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
790
792
|
return scannedTables.createObjectTable[hash];
|
|
791
793
|
return null;
|
|
792
794
|
};
|
|
795
|
+
const resolveBracketGroup = (node) => {
|
|
796
|
+
if (!t.isMemberExpression(node) ||
|
|
797
|
+
!t.isIdentifier(node.object) ||
|
|
798
|
+
node.property.type !== 'Computed' ||
|
|
799
|
+
t.isStringLiteral(node.property.expression)) {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
const varName = node.object.value;
|
|
803
|
+
const obj = resolveCreateObject(varName);
|
|
804
|
+
return obj
|
|
805
|
+
? { varName, keyExpr: node.property.expression, obj }
|
|
806
|
+
: null;
|
|
807
|
+
};
|
|
808
|
+
const buildDecision = (node, prefix, off, counter) => {
|
|
809
|
+
if (node.type === 'ParenthesisExpression') {
|
|
810
|
+
return buildDecision(node.expression, prefix, off, counter);
|
|
811
|
+
}
|
|
812
|
+
if (node.type === 'ConditionalExpression') {
|
|
813
|
+
const a = buildDecision(node.consequent, prefix, off, counter);
|
|
814
|
+
if (!a)
|
|
815
|
+
return null;
|
|
816
|
+
const b = buildDecision(node.alternate, prefix, off, counter);
|
|
817
|
+
if (!b)
|
|
818
|
+
return null;
|
|
819
|
+
return {
|
|
820
|
+
keyExpr: `((${getSource(node.test)}) ? ${a.keyExpr} : ${b.keyExpr})`,
|
|
821
|
+
options: [...a.options, ...b.options],
|
|
822
|
+
leaves: a.leaves + b.leaves,
|
|
823
|
+
hasGroup: a.hasGroup || b.hasGroup,
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
if (node.type === 'BinaryExpression' && node.operator === '&&') {
|
|
827
|
+
const right = buildDecision(node.right, prefix, off, counter);
|
|
828
|
+
if (!right)
|
|
829
|
+
return null;
|
|
830
|
+
return {
|
|
831
|
+
keyExpr: `((${getSource(node.left)}) ? ${right.keyExpr} : ${JSON.stringify(off)})`,
|
|
832
|
+
options: right.options,
|
|
833
|
+
leaves: right.leaves,
|
|
834
|
+
hasGroup: right.hasGroup,
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
const group = resolveBracketGroup(node);
|
|
838
|
+
if (group) {
|
|
839
|
+
return {
|
|
840
|
+
keyExpr: getSource(group.keyExpr),
|
|
841
|
+
options: Object.entries(group.obj).map(([value, style]) => ({
|
|
842
|
+
value,
|
|
843
|
+
style: style,
|
|
844
|
+
})),
|
|
845
|
+
leaves: 1,
|
|
846
|
+
hasGroup: true,
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
const style = resolveStyleObject(node);
|
|
850
|
+
if (!style)
|
|
851
|
+
return null;
|
|
852
|
+
const value = `${prefix}${counter.n++}`;
|
|
853
|
+
return {
|
|
854
|
+
keyExpr: JSON.stringify(value),
|
|
855
|
+
options: [{ value, style }],
|
|
856
|
+
leaves: 1,
|
|
857
|
+
hasGroup: false,
|
|
858
|
+
};
|
|
859
|
+
};
|
|
860
|
+
const collectGroupKeys = (node, acc) => {
|
|
861
|
+
if (node.type === 'ParenthesisExpression') {
|
|
862
|
+
collectGroupKeys(node.expression, acc);
|
|
863
|
+
}
|
|
864
|
+
else if (node.type === 'ConditionalExpression') {
|
|
865
|
+
collectGroupKeys(node.consequent, acc);
|
|
866
|
+
collectGroupKeys(node.alternate, acc);
|
|
867
|
+
}
|
|
868
|
+
else if (node.type === 'BinaryExpression' &&
|
|
869
|
+
node.operator === '&&') {
|
|
870
|
+
collectGroupKeys(node.right, acc);
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
const group = resolveBracketGroup(node);
|
|
874
|
+
if (group)
|
|
875
|
+
Object.keys(group.obj).forEach((k) => acc.add(k));
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
const resolveDecision = (node) => {
|
|
879
|
+
const groupKeys = new Set();
|
|
880
|
+
collectGroupKeys(node, groupKeys);
|
|
881
|
+
let prefix = '#';
|
|
882
|
+
while ([...groupKeys].some((k) => k.startsWith(prefix)))
|
|
883
|
+
prefix += '#';
|
|
884
|
+
const off = groupKeys.has('') ? `${prefix}off` : '';
|
|
885
|
+
return buildDecision(node, prefix, off, { n: 0 });
|
|
886
|
+
};
|
|
793
887
|
const collectConditions = (node, currentTestStrings = []) => {
|
|
794
888
|
const staticStyle = resolveStyleObject(node);
|
|
795
889
|
if (staticStyle) {
|
|
796
890
|
if (currentTestStrings.length === 0) {
|
|
797
891
|
baseStyle = deepMerge(baseStyle, staticStyle);
|
|
892
|
+
baseChunks.push({ order: sourceOrder++, style: staticStyle });
|
|
798
893
|
}
|
|
799
894
|
else {
|
|
800
895
|
conditionals.push({
|
|
@@ -803,6 +898,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
803
898
|
truthy: staticStyle,
|
|
804
899
|
falsy: {},
|
|
805
900
|
varName: undefined,
|
|
901
|
+
order: sourceOrder++,
|
|
806
902
|
});
|
|
807
903
|
}
|
|
808
904
|
return true;
|
|
@@ -819,6 +915,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
819
915
|
truthy: trueStyle,
|
|
820
916
|
falsy: falseStyle,
|
|
821
917
|
varName: undefined,
|
|
918
|
+
order: sourceOrder++,
|
|
822
919
|
});
|
|
823
920
|
return true;
|
|
824
921
|
}
|
|
@@ -844,14 +941,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
844
941
|
else if (node.type === 'ParenthesisExpression') {
|
|
845
942
|
return collectConditions(node.expression, currentTestStrings);
|
|
846
943
|
}
|
|
847
|
-
if (currentTestStrings.length > 0 &&
|
|
848
|
-
t.isMemberExpression(node) &&
|
|
849
|
-
t.isIdentifier(node.object) &&
|
|
850
|
-
node.property.type === 'Computed' &&
|
|
851
|
-
resolveCreateObject(node.object.value)) {
|
|
852
|
-
const varName = node.object.value;
|
|
853
|
-
throwCompilationError(`Plumeria: "${getSource(node)}" cannot be used inside a condition, because its bracket key is not a literal.\nMove the condition into the brackets instead, e.g. ${varName}[cond ? 'a' : 'b'].`, node);
|
|
854
|
-
}
|
|
855
944
|
assertResolvable(node);
|
|
856
945
|
return false;
|
|
857
946
|
};
|
|
@@ -878,6 +967,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
878
967
|
}
|
|
879
968
|
if (propPossibilities && propPossibilities.length > 0) {
|
|
880
969
|
const currentGroupId = ++groupIdCounter;
|
|
970
|
+
const currentOrder = sourceOrder++;
|
|
881
971
|
const uniqueEntries = [];
|
|
882
972
|
propPossibilities.forEach((entry) => {
|
|
883
973
|
if (!uniqueEntries.some((x) => x.key === entry.key)) {
|
|
@@ -892,6 +982,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
892
982
|
truthy: entry.styleObj,
|
|
893
983
|
falsy: {},
|
|
894
984
|
groupId: currentGroupId,
|
|
985
|
+
order: currentOrder,
|
|
895
986
|
groupName: undefined,
|
|
896
987
|
valueName: entry.key,
|
|
897
988
|
varName,
|
|
@@ -948,11 +1039,18 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
948
1039
|
if (!groupVariants)
|
|
949
1040
|
continue;
|
|
950
1041
|
const currentGroupId = ++groupIdCounter;
|
|
1042
|
+
const currentOrder = sourceOrder++;
|
|
951
1043
|
const valSource = getSource(valExpr);
|
|
952
1044
|
if (valExpr.type === 'StringLiteral') {
|
|
953
1045
|
const groupVariantsAsObj = groupVariants;
|
|
954
|
-
|
|
955
|
-
|
|
1046
|
+
const picked = groupVariantsAsObj[valExpr.value];
|
|
1047
|
+
if (picked) {
|
|
1048
|
+
baseStyle = deepMerge(baseStyle, picked);
|
|
1049
|
+
baseChunks.push({
|
|
1050
|
+
order: sourceOrder++,
|
|
1051
|
+
style: picked,
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
956
1054
|
continue;
|
|
957
1055
|
}
|
|
958
1056
|
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
@@ -963,6 +1061,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
963
1061
|
truthy: style,
|
|
964
1062
|
falsy: {},
|
|
965
1063
|
groupId: currentGroupId,
|
|
1064
|
+
order: currentOrder,
|
|
966
1065
|
groupName,
|
|
967
1066
|
valueName: optionName,
|
|
968
1067
|
varName,
|
|
@@ -974,11 +1073,15 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
974
1073
|
}
|
|
975
1074
|
const argSource = getSource(arg);
|
|
976
1075
|
if (t.isStringLiteral(arg)) {
|
|
977
|
-
|
|
978
|
-
|
|
1076
|
+
const picked = variantObj[arg.value];
|
|
1077
|
+
if (picked) {
|
|
1078
|
+
baseStyle = deepMerge(baseStyle, picked);
|
|
1079
|
+
baseChunks.push({ order: sourceOrder++, style: picked });
|
|
1080
|
+
}
|
|
979
1081
|
continue;
|
|
980
1082
|
}
|
|
981
1083
|
const currentGroupId = ++groupIdCounter;
|
|
1084
|
+
const currentOrder = sourceOrder++;
|
|
982
1085
|
Object.entries(variantObj).forEach(([key, style]) => {
|
|
983
1086
|
conditionals.push({
|
|
984
1087
|
test: arg,
|
|
@@ -987,6 +1090,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
987
1090
|
truthy: style,
|
|
988
1091
|
falsy: {},
|
|
989
1092
|
groupId: currentGroupId,
|
|
1093
|
+
order: currentOrder,
|
|
990
1094
|
groupName: undefined,
|
|
991
1095
|
valueName: key,
|
|
992
1096
|
varName,
|
|
@@ -1014,6 +1118,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1014
1118
|
if (!groupVariants)
|
|
1015
1119
|
return;
|
|
1016
1120
|
const currentGroupId = ++groupIdCounter;
|
|
1121
|
+
const currentOrder = sourceOrder++;
|
|
1017
1122
|
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
1018
1123
|
conditionals.push({
|
|
1019
1124
|
test: expr,
|
|
@@ -1022,6 +1127,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1022
1127
|
truthy: style,
|
|
1023
1128
|
falsy: {},
|
|
1024
1129
|
groupId: currentGroupId,
|
|
1130
|
+
order: currentOrder,
|
|
1025
1131
|
groupName,
|
|
1026
1132
|
valueName: optionName,
|
|
1027
1133
|
varName,
|
|
@@ -1040,6 +1146,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1040
1146
|
const dynExpr = expr.property.expression;
|
|
1041
1147
|
const dynSource = getSource(dynExpr);
|
|
1042
1148
|
const currentGroupId = ++groupIdCounter;
|
|
1149
|
+
const currentOrder = sourceOrder++;
|
|
1043
1150
|
Object.entries(styleObj).forEach(([optionName, style]) => {
|
|
1044
1151
|
conditionals.push({
|
|
1045
1152
|
test: dynExpr,
|
|
@@ -1048,6 +1155,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1048
1155
|
truthy: style,
|
|
1049
1156
|
falsy: {},
|
|
1050
1157
|
groupId: currentGroupId,
|
|
1158
|
+
order: currentOrder,
|
|
1051
1159
|
groupName: undefined,
|
|
1052
1160
|
valueName: optionName,
|
|
1053
1161
|
varName,
|
|
@@ -1056,6 +1164,24 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1056
1164
|
continue;
|
|
1057
1165
|
}
|
|
1058
1166
|
}
|
|
1167
|
+
const decision = resolveDecision(expr);
|
|
1168
|
+
if (decision && (decision.hasGroup || decision.leaves > 2)) {
|
|
1169
|
+
const groupId = ++groupIdCounter;
|
|
1170
|
+
const currentOrder = sourceOrder++;
|
|
1171
|
+
decision.options.forEach(({ value, style }) => conditionals.push({
|
|
1172
|
+
test: expr,
|
|
1173
|
+
testLHS: decision.keyExpr,
|
|
1174
|
+
testString: `${decision.keyExpr} === '${value}'`,
|
|
1175
|
+
truthy: style,
|
|
1176
|
+
falsy: {},
|
|
1177
|
+
groupId,
|
|
1178
|
+
order: currentOrder,
|
|
1179
|
+
groupName: undefined,
|
|
1180
|
+
valueName: value,
|
|
1181
|
+
varName: undefined,
|
|
1182
|
+
}));
|
|
1183
|
+
continue;
|
|
1184
|
+
}
|
|
1059
1185
|
const handled = collectConditions(expr);
|
|
1060
1186
|
if (handled)
|
|
1061
1187
|
continue;
|
|
@@ -1189,7 +1315,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1189
1315
|
getSource(options[0].test);
|
|
1190
1316
|
const lookupMap = {};
|
|
1191
1317
|
options.forEach((opt) => {
|
|
1192
|
-
if (opt.valueName && opt.truthy) {
|
|
1318
|
+
if (opt.valueName !== undefined && opt.truthy) {
|
|
1193
1319
|
const className = processStyleRecords(opt.truthy)
|
|
1194
1320
|
.map((r) => r.hash)
|
|
1195
1321
|
.join(' ');
|
|
@@ -1206,17 +1332,38 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1206
1332
|
});
|
|
1207
1333
|
if (Object.keys(baseConflict).length > 0 ||
|
|
1208
1334
|
conflictConditionals.length > 0) {
|
|
1209
|
-
const
|
|
1335
|
+
const ordered = [];
|
|
1336
|
+
baseChunks.forEach(({ order, style }) => {
|
|
1337
|
+
const conflicting = {};
|
|
1338
|
+
Object.entries(style).forEach(([key, value]) => {
|
|
1339
|
+
if (conflictingKeys.has(key))
|
|
1340
|
+
conflicting[key] = value;
|
|
1341
|
+
});
|
|
1342
|
+
if (Object.keys(conflicting).length === 0)
|
|
1343
|
+
return;
|
|
1344
|
+
ordered.push({
|
|
1345
|
+
order,
|
|
1346
|
+
dimension: {
|
|
1347
|
+
type: 'const',
|
|
1348
|
+
options: [
|
|
1349
|
+
{ value: undefined, style: conflicting, label: 'base' },
|
|
1350
|
+
],
|
|
1351
|
+
},
|
|
1352
|
+
});
|
|
1353
|
+
});
|
|
1210
1354
|
conflictConditionals
|
|
1211
1355
|
.filter((c) => c.groupId === undefined)
|
|
1212
1356
|
.forEach((c) => {
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1357
|
+
ordered.push({
|
|
1358
|
+
order: c.order ?? 0,
|
|
1359
|
+
dimension: {
|
|
1360
|
+
type: 'std',
|
|
1361
|
+
testExpr: c.testString ?? getSource(c.test),
|
|
1362
|
+
options: [
|
|
1363
|
+
{ value: 0, style: c.falsy, label: 'false' },
|
|
1364
|
+
{ value: 1, style: c.truthy, label: 'true' },
|
|
1365
|
+
],
|
|
1366
|
+
},
|
|
1220
1367
|
});
|
|
1221
1368
|
});
|
|
1222
1369
|
const conflictVarGroups = {};
|
|
@@ -1227,19 +1374,33 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1227
1374
|
conflictVarGroups[c.groupId].push(c);
|
|
1228
1375
|
}
|
|
1229
1376
|
});
|
|
1377
|
+
Object.keys(conflictVarGroups).forEach((id) => {
|
|
1378
|
+
const groupId = Number(id);
|
|
1379
|
+
const opts = conflictVarGroups[groupId];
|
|
1380
|
+
if (opts.some((c) => c.valueName === ''))
|
|
1381
|
+
return;
|
|
1382
|
+
const off = conditionals.find((c) => c.groupId === groupId && c.valueName === '');
|
|
1383
|
+
if (off)
|
|
1384
|
+
opts.push({ ...off, truthy: {}, falsy: {} });
|
|
1385
|
+
});
|
|
1230
1386
|
Object.entries(conflictVarGroups).forEach(([, opts]) => {
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1387
|
+
ordered.push({
|
|
1388
|
+
order: opts[0].order ?? 0,
|
|
1389
|
+
dimension: {
|
|
1390
|
+
type: 'var',
|
|
1391
|
+
testExpr: opts[0].testLHS ??
|
|
1392
|
+
opts[0].testString ??
|
|
1393
|
+
getSource(opts[0].test),
|
|
1394
|
+
options: opts.map((opt) => ({
|
|
1395
|
+
value: opt.valueName,
|
|
1396
|
+
style: opt.truthy,
|
|
1397
|
+
label: opt.valueName || 'default',
|
|
1398
|
+
})),
|
|
1399
|
+
},
|
|
1241
1400
|
});
|
|
1242
1401
|
});
|
|
1402
|
+
ordered.sort((a, b) => a.order - b.order);
|
|
1403
|
+
const dimensions = ordered.map((o) => o.dimension);
|
|
1243
1404
|
const results = {};
|
|
1244
1405
|
const recurse = (dimIndex, currentStyle, keyParts) => {
|
|
1245
1406
|
if (dimIndex >= dimensions.length) {
|
|
@@ -1250,18 +1411,19 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1250
1411
|
results[keyParts.join('__')] = className;
|
|
1251
1412
|
return;
|
|
1252
1413
|
}
|
|
1253
|
-
dimensions[dimIndex]
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1414
|
+
const dimension = dimensions[dimIndex];
|
|
1415
|
+
dimension.options.forEach((opt) => recurse(dimIndex + 1, deepMerge(currentStyle, opt.style), dimension.type === 'const'
|
|
1416
|
+
? keyParts
|
|
1417
|
+
: [...keyParts, String(opt.value)]));
|
|
1257
1418
|
};
|
|
1258
|
-
recurse(0,
|
|
1419
|
+
recurse(0, {}, []);
|
|
1259
1420
|
const baseConflictClass = Object.keys(baseConflict).length > 0
|
|
1260
1421
|
? processStyleRecords(baseConflict)
|
|
1261
1422
|
.map((r) => r.hash)
|
|
1262
1423
|
.join(' ')
|
|
1263
1424
|
: '';
|
|
1264
1425
|
const masterKeyExpr = dimensions
|
|
1426
|
+
.filter((dim) => dim.type !== 'const')
|
|
1265
1427
|
.map((dim) => dim.type === 'std'
|
|
1266
1428
|
? `(${dim.testExpr} ? "1" : "0")`
|
|
1267
1429
|
: dim.testExpr || '""')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/unplugin",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.1.1",
|
|
4
4
|
"description": "Universal Plumeria plugin for various build tools",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@rollup/pluginutils": "^5.4.0",
|
|
91
91
|
"unplugin": "^3.0.0",
|
|
92
|
-
"@plumeria/utils": "^18.
|
|
92
|
+
"@plumeria/utils": "^18.1.1"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@swc/core": "1.15.43",
|