@plumeria/vite-plugin 10.0.1 → 10.0.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/dist/index.js +584 -655
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -534,6 +534,448 @@ export function plumeria(options = {}) {
|
|
|
534
534
|
},
|
|
535
535
|
});
|
|
536
536
|
const jsxOpeningElementMap = new Map();
|
|
537
|
+
const getSource = (node) => {
|
|
538
|
+
const start = node.span.start - baseByteOffset;
|
|
539
|
+
const end = node.span.end - baseByteOffset;
|
|
540
|
+
return sourceBuffer.subarray(start, end).toString('utf-8');
|
|
541
|
+
};
|
|
542
|
+
const resolveStyleObject = (expr) => {
|
|
543
|
+
if (t.isObjectExpression(expr)) {
|
|
544
|
+
return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
545
|
+
}
|
|
546
|
+
else if (t.isMemberExpression(expr) &&
|
|
547
|
+
t.isIdentifier(expr.object) &&
|
|
548
|
+
(t.isIdentifier(expr.property) ||
|
|
549
|
+
expr.property.type === 'Computed')) {
|
|
550
|
+
if (expr.property.type === 'Computed')
|
|
551
|
+
return {};
|
|
552
|
+
const varName = expr.object.value;
|
|
553
|
+
const propName = expr.property.value;
|
|
554
|
+
const styleInfo = localCreateStyles[varName];
|
|
555
|
+
if (styleInfo?.obj[propName]) {
|
|
556
|
+
const style = styleInfo.obj[propName];
|
|
557
|
+
if (typeof style === 'object' && style !== null)
|
|
558
|
+
return style;
|
|
559
|
+
}
|
|
560
|
+
const hash = mergedCreateTable[varName];
|
|
561
|
+
if (hash) {
|
|
562
|
+
const obj = scannedTables.createObjectTable[hash];
|
|
563
|
+
if (obj?.[propName] && typeof obj[propName] === 'object')
|
|
564
|
+
return obj[propName];
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
else if (t.isIdentifier(expr)) {
|
|
568
|
+
const varName = expr.value;
|
|
569
|
+
const uniqueKey = `${resourcePath}-${varName}`;
|
|
570
|
+
let hash = scannedTables.createHashTable[uniqueKey];
|
|
571
|
+
if (!hash)
|
|
572
|
+
hash = mergedCreateTable[varName];
|
|
573
|
+
if (hash) {
|
|
574
|
+
const obj = scannedTables.createObjectTable[hash];
|
|
575
|
+
if (obj && typeof obj === 'object')
|
|
576
|
+
return obj;
|
|
577
|
+
}
|
|
578
|
+
const styleInfo = localCreateStyles[varName];
|
|
579
|
+
if (styleInfo?.obj)
|
|
580
|
+
return styleInfo.obj;
|
|
581
|
+
const vHash = mergedVariantsTable[varName];
|
|
582
|
+
if (vHash)
|
|
583
|
+
return scannedTables.variantsObjectTable[vHash];
|
|
584
|
+
}
|
|
585
|
+
return null;
|
|
586
|
+
};
|
|
587
|
+
const buildClassParts = (args, dynamicClassParts = [], existingClass = '') => {
|
|
588
|
+
const conditionals = [];
|
|
589
|
+
let groupIdCounter = 0;
|
|
590
|
+
let baseStyle = {};
|
|
591
|
+
let isOptimizable = true;
|
|
592
|
+
const collectConditions = (node, currentTestStrings = []) => {
|
|
593
|
+
const staticStyle = resolveStyleObject(node);
|
|
594
|
+
if (staticStyle) {
|
|
595
|
+
if (currentTestStrings.length === 0) {
|
|
596
|
+
baseStyle = deepMerge(baseStyle, staticStyle);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
conditionals.push({
|
|
600
|
+
test: node,
|
|
601
|
+
testString: currentTestStrings.join(' && '),
|
|
602
|
+
truthy: staticStyle,
|
|
603
|
+
falsy: {},
|
|
604
|
+
varName: undefined,
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
if (node.type === 'ConditionalExpression') {
|
|
610
|
+
const testSource = getSource(node.test);
|
|
611
|
+
if (currentTestStrings.length === 0) {
|
|
612
|
+
const trueStyle = resolveStyleObject(node.consequent);
|
|
613
|
+
const falseStyle = resolveStyleObject(node.alternate);
|
|
614
|
+
if (trueStyle && falseStyle) {
|
|
615
|
+
conditionals.push({
|
|
616
|
+
test: node,
|
|
617
|
+
testString: testSource,
|
|
618
|
+
truthy: trueStyle,
|
|
619
|
+
falsy: falseStyle,
|
|
620
|
+
varName: undefined,
|
|
621
|
+
});
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
collectConditions(node.consequent, [
|
|
626
|
+
...currentTestStrings,
|
|
627
|
+
`(${testSource})`,
|
|
628
|
+
]);
|
|
629
|
+
collectConditions(node.alternate, [
|
|
630
|
+
...currentTestStrings,
|
|
631
|
+
`!(${testSource})`,
|
|
632
|
+
]);
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
else if (node.type === 'BinaryExpression' &&
|
|
636
|
+
node.operator === '&&') {
|
|
637
|
+
collectConditions(node.right, [
|
|
638
|
+
...currentTestStrings,
|
|
639
|
+
`(${getSource(node.left)})`,
|
|
640
|
+
]);
|
|
641
|
+
return true;
|
|
642
|
+
}
|
|
643
|
+
else if (node.type === 'ParenthesisExpression') {
|
|
644
|
+
return collectConditions(node.expression, currentTestStrings);
|
|
645
|
+
}
|
|
646
|
+
return false;
|
|
647
|
+
};
|
|
648
|
+
for (const arg of args) {
|
|
649
|
+
const expr = arg.expression;
|
|
650
|
+
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
|
|
651
|
+
const varName = expr.callee.value;
|
|
652
|
+
const uniqueKey = `${resourcePath}-${varName}`;
|
|
653
|
+
let variantObj;
|
|
654
|
+
let hash = scannedTables.variantsHashTable[uniqueKey];
|
|
655
|
+
if (!hash)
|
|
656
|
+
hash = mergedVariantsTable[varName];
|
|
657
|
+
if (hash && scannedTables.variantsObjectTable[hash])
|
|
658
|
+
variantObj = scannedTables.variantsObjectTable[hash];
|
|
659
|
+
if (!variantObj && localCreateStyles[varName]?.obj)
|
|
660
|
+
variantObj = localCreateStyles[varName].obj;
|
|
661
|
+
if (variantObj) {
|
|
662
|
+
const callArgs = expr.arguments;
|
|
663
|
+
if (callArgs.length === 1 && !callArgs[0].spread) {
|
|
664
|
+
const arg = callArgs[0].expression;
|
|
665
|
+
if (arg.type === 'ObjectExpression') {
|
|
666
|
+
for (const prop of arg.properties) {
|
|
667
|
+
let groupName;
|
|
668
|
+
let valExpr;
|
|
669
|
+
if (prop.type === 'KeyValueProperty' &&
|
|
670
|
+
prop.key.type === 'Identifier') {
|
|
671
|
+
groupName = prop.key.value;
|
|
672
|
+
valExpr = prop.value;
|
|
673
|
+
}
|
|
674
|
+
else if (prop.type === 'Identifier') {
|
|
675
|
+
groupName = prop.value;
|
|
676
|
+
valExpr = prop;
|
|
677
|
+
}
|
|
678
|
+
if (groupName && valExpr) {
|
|
679
|
+
const groupVariants = variantObj[groupName];
|
|
680
|
+
if (!groupVariants)
|
|
681
|
+
continue;
|
|
682
|
+
const currentGroupId = ++groupIdCounter;
|
|
683
|
+
const valSource = getSource(valExpr);
|
|
684
|
+
if (valExpr.type === 'StringLiteral') {
|
|
685
|
+
if (groupVariants[valExpr.value])
|
|
686
|
+
baseStyle = deepMerge(baseStyle, groupVariants[valExpr.value]);
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
689
|
+
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
690
|
+
conditionals.push({
|
|
691
|
+
test: valExpr,
|
|
692
|
+
testLHS: valSource,
|
|
693
|
+
testString: `${valSource} === '${optionName}'`,
|
|
694
|
+
truthy: style,
|
|
695
|
+
falsy: {},
|
|
696
|
+
groupId: currentGroupId,
|
|
697
|
+
groupName,
|
|
698
|
+
valueName: optionName,
|
|
699
|
+
varName,
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
const argSource = getSource(arg);
|
|
707
|
+
if (t.isStringLiteral(arg)) {
|
|
708
|
+
if (variantObj[arg.value])
|
|
709
|
+
baseStyle = deepMerge(baseStyle, variantObj[arg.value]);
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
const currentGroupId = ++groupIdCounter;
|
|
713
|
+
Object.entries(variantObj).forEach(([key, style]) => {
|
|
714
|
+
conditionals.push({
|
|
715
|
+
test: arg,
|
|
716
|
+
testLHS: argSource,
|
|
717
|
+
testString: `${argSource} === '${key}'`,
|
|
718
|
+
truthy: style,
|
|
719
|
+
falsy: {},
|
|
720
|
+
groupId: currentGroupId,
|
|
721
|
+
groupName: undefined,
|
|
722
|
+
valueName: key,
|
|
723
|
+
varName,
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
isOptimizable = false;
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
else if (t.isIdentifier(expr)) {
|
|
733
|
+
const varName = expr.value;
|
|
734
|
+
const uniqueKey = `${resourcePath}-${varName}`;
|
|
735
|
+
let variantObj;
|
|
736
|
+
let hash = scannedTables.variantsHashTable[uniqueKey];
|
|
737
|
+
if (!hash)
|
|
738
|
+
hash = mergedVariantsTable[varName];
|
|
739
|
+
if (hash && scannedTables.variantsObjectTable[hash])
|
|
740
|
+
variantObj = scannedTables.variantsObjectTable[hash];
|
|
741
|
+
if (!variantObj && localCreateStyles[varName]?.obj)
|
|
742
|
+
variantObj = localCreateStyles[varName].obj;
|
|
743
|
+
if (variantObj) {
|
|
744
|
+
Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
|
|
745
|
+
if (!groupVariants)
|
|
746
|
+
return;
|
|
747
|
+
const currentGroupId = ++groupIdCounter;
|
|
748
|
+
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
749
|
+
conditionals.push({
|
|
750
|
+
test: expr,
|
|
751
|
+
testLHS: `props["${groupName}"]`,
|
|
752
|
+
testString: `props["${groupName}"] === '${optionName}'`,
|
|
753
|
+
truthy: style,
|
|
754
|
+
falsy: {},
|
|
755
|
+
groupId: currentGroupId,
|
|
756
|
+
groupName,
|
|
757
|
+
valueName: optionName,
|
|
758
|
+
varName,
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
const handled = collectConditions(expr);
|
|
766
|
+
if (handled)
|
|
767
|
+
continue;
|
|
768
|
+
isOptimizable = false;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
if (!isOptimizable ||
|
|
772
|
+
(args.length === 0 && Object.keys(baseStyle).length === 0)) {
|
|
773
|
+
return {
|
|
774
|
+
classParts: [...dynamicClassParts],
|
|
775
|
+
isOptimizable,
|
|
776
|
+
baseStyle,
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
const participation = {};
|
|
780
|
+
const registerParticipation = (style, sourceId) => {
|
|
781
|
+
Object.keys(style).forEach((key) => {
|
|
782
|
+
if (!participation[key])
|
|
783
|
+
participation[key] = new Set();
|
|
784
|
+
participation[key].add(sourceId);
|
|
785
|
+
});
|
|
786
|
+
};
|
|
787
|
+
registerParticipation(baseStyle, 'base');
|
|
788
|
+
conditionals
|
|
789
|
+
.filter((c) => c.groupId === undefined)
|
|
790
|
+
.forEach((c, idx) => {
|
|
791
|
+
registerParticipation(c.truthy, `std_${idx}`);
|
|
792
|
+
registerParticipation(c.falsy, `std_${idx}`);
|
|
793
|
+
});
|
|
794
|
+
const variantGroups = {};
|
|
795
|
+
conditionals.forEach((c) => {
|
|
796
|
+
if (c.groupId !== undefined) {
|
|
797
|
+
if (!variantGroups[c.groupId])
|
|
798
|
+
variantGroups[c.groupId] = [];
|
|
799
|
+
variantGroups[c.groupId].push(c);
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
Object.entries(variantGroups).forEach(([groupId, opts]) => {
|
|
803
|
+
opts.forEach((opt) => registerParticipation(opt.truthy, `var_${groupId}`));
|
|
804
|
+
});
|
|
805
|
+
const conflictingKeys = new Set();
|
|
806
|
+
Object.entries(participation).forEach(([key, sources]) => {
|
|
807
|
+
if (sources.size > 1)
|
|
808
|
+
conflictingKeys.add(key);
|
|
809
|
+
});
|
|
810
|
+
const baseIndependent = {};
|
|
811
|
+
const baseConflict = {};
|
|
812
|
+
Object.entries(baseStyle).forEach(([key, val]) => {
|
|
813
|
+
if (conflictingKeys.has(key))
|
|
814
|
+
baseConflict[key] = val;
|
|
815
|
+
else
|
|
816
|
+
baseIndependent[key] = val;
|
|
817
|
+
});
|
|
818
|
+
const indepConditionals = [];
|
|
819
|
+
const conflictConditionals = [];
|
|
820
|
+
conditionals.forEach((c) => {
|
|
821
|
+
const truthyIndep = {};
|
|
822
|
+
const truthyConf = {};
|
|
823
|
+
const falsyIndep = {};
|
|
824
|
+
const falsyConf = {};
|
|
825
|
+
let hasIndep = false;
|
|
826
|
+
let hasConf = false;
|
|
827
|
+
Object.entries(c.truthy).forEach(([k, v]) => {
|
|
828
|
+
if (conflictingKeys.has(k)) {
|
|
829
|
+
truthyConf[k] = v;
|
|
830
|
+
hasConf = true;
|
|
831
|
+
}
|
|
832
|
+
else {
|
|
833
|
+
truthyIndep[k] = v;
|
|
834
|
+
hasIndep = true;
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
Object.entries(c.falsy).forEach(([k, v]) => {
|
|
838
|
+
if (conflictingKeys.has(k)) {
|
|
839
|
+
falsyConf[k] = v;
|
|
840
|
+
hasConf = true;
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
falsyIndep[k] = v;
|
|
844
|
+
hasIndep = true;
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
if (hasIndep)
|
|
848
|
+
indepConditionals.push({
|
|
849
|
+
...c,
|
|
850
|
+
truthy: truthyIndep,
|
|
851
|
+
falsy: falsyIndep,
|
|
852
|
+
});
|
|
853
|
+
if (hasConf)
|
|
854
|
+
conflictConditionals.push({
|
|
855
|
+
...c,
|
|
856
|
+
truthy: truthyConf,
|
|
857
|
+
falsy: falsyConf,
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
const classParts = [];
|
|
861
|
+
if (existingClass)
|
|
862
|
+
classParts.push(JSON.stringify(existingClass));
|
|
863
|
+
if (Object.keys(baseIndependent).length > 0) {
|
|
864
|
+
const className = getStyleRecords(baseIndependent)
|
|
865
|
+
.map((r) => r.hash)
|
|
866
|
+
.join(' ');
|
|
867
|
+
if (className)
|
|
868
|
+
classParts.push(JSON.stringify(className));
|
|
869
|
+
}
|
|
870
|
+
indepConditionals
|
|
871
|
+
.filter((c) => c.groupId === undefined)
|
|
872
|
+
.forEach((c) => {
|
|
873
|
+
const processBranch = (style) => {
|
|
874
|
+
if (Object.keys(style).length === 0)
|
|
875
|
+
return '""';
|
|
876
|
+
return JSON.stringify(getStyleRecords(style)
|
|
877
|
+
.map((r) => r.hash)
|
|
878
|
+
.join(' '));
|
|
879
|
+
};
|
|
880
|
+
const testStr = c.testString ?? getSource(c.test);
|
|
881
|
+
classParts.push(`(${testStr} ? ${processBranch(c.truthy)} : ${processBranch(c.falsy)})`);
|
|
882
|
+
});
|
|
883
|
+
const indepVarGroups = {};
|
|
884
|
+
indepConditionals.forEach((c) => {
|
|
885
|
+
if (c.groupId !== undefined) {
|
|
886
|
+
if (!indepVarGroups[c.groupId])
|
|
887
|
+
indepVarGroups[c.groupId] = [];
|
|
888
|
+
indepVarGroups[c.groupId].push(c);
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
Object.values(indepVarGroups).forEach((options) => {
|
|
892
|
+
const commonTestExpr = options[0].testLHS ??
|
|
893
|
+
options[0].testString ??
|
|
894
|
+
getSource(options[0].test);
|
|
895
|
+
const lookupMap = {};
|
|
896
|
+
options.forEach((opt) => {
|
|
897
|
+
if (opt.valueName && opt.truthy) {
|
|
898
|
+
const className = getStyleRecords(opt.truthy)
|
|
899
|
+
.map((r) => r.hash)
|
|
900
|
+
.join(' ');
|
|
901
|
+
if (className)
|
|
902
|
+
lookupMap[opt.valueName] = className;
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
if (Object.keys(lookupMap).length > 0) {
|
|
906
|
+
const entries = Object.entries(lookupMap)
|
|
907
|
+
.map(([k, v]) => `"${k}":"${v}"`)
|
|
908
|
+
.join(',');
|
|
909
|
+
classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
if (Object.keys(baseConflict).length > 0 ||
|
|
913
|
+
conflictConditionals.length > 0) {
|
|
914
|
+
const dimensions = [];
|
|
915
|
+
conflictConditionals
|
|
916
|
+
.filter((c) => c.groupId === undefined)
|
|
917
|
+
.forEach((c) => {
|
|
918
|
+
dimensions.push({
|
|
919
|
+
type: 'std',
|
|
920
|
+
testExpr: c.testString ?? getSource(c.test),
|
|
921
|
+
options: [
|
|
922
|
+
{ value: 0, style: c.falsy, label: 'false' },
|
|
923
|
+
{ value: 1, style: c.truthy, label: 'true' },
|
|
924
|
+
],
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
const conflictVarGroups = {};
|
|
928
|
+
conflictConditionals.forEach((c) => {
|
|
929
|
+
if (c.groupId !== undefined) {
|
|
930
|
+
if (!conflictVarGroups[c.groupId])
|
|
931
|
+
conflictVarGroups[c.groupId] = [];
|
|
932
|
+
conflictVarGroups[c.groupId].push(c);
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
Object.entries(conflictVarGroups).forEach(([, opts]) => {
|
|
936
|
+
dimensions.push({
|
|
937
|
+
type: 'var',
|
|
938
|
+
testExpr: opts[0].testLHS ??
|
|
939
|
+
opts[0].testString ??
|
|
940
|
+
getSource(opts[0].test),
|
|
941
|
+
options: opts.map((opt) => ({
|
|
942
|
+
value: opt.valueName,
|
|
943
|
+
style: opt.truthy,
|
|
944
|
+
label: opt.valueName || 'default',
|
|
945
|
+
})),
|
|
946
|
+
});
|
|
947
|
+
});
|
|
948
|
+
const results = {};
|
|
949
|
+
const recurse = (dimIndex, currentStyle, keyParts) => {
|
|
950
|
+
if (dimIndex >= dimensions.length) {
|
|
951
|
+
const className = getStyleRecords(currentStyle)
|
|
952
|
+
.map((r) => r.hash)
|
|
953
|
+
.join(' ');
|
|
954
|
+
if (className)
|
|
955
|
+
results[keyParts.join('__')] = className;
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
dimensions[dimIndex].options.forEach((opt) => recurse(dimIndex + 1, deepMerge(currentStyle, opt.style), [
|
|
959
|
+
...keyParts,
|
|
960
|
+
String(opt.value),
|
|
961
|
+
]));
|
|
962
|
+
};
|
|
963
|
+
recurse(0, baseConflict, []);
|
|
964
|
+
const baseConflictClass = Object.keys(baseConflict).length > 0
|
|
965
|
+
? getStyleRecords(baseConflict)
|
|
966
|
+
.map((r) => r.hash)
|
|
967
|
+
.join(' ')
|
|
968
|
+
: '';
|
|
969
|
+
const masterKeyExpr = dimensions
|
|
970
|
+
.map((dim) => dim.type === 'std'
|
|
971
|
+
? `(${dim.testExpr} ? "1" : "0")`
|
|
972
|
+
: dim.testExpr || '""')
|
|
973
|
+
.join(' + "__" + ');
|
|
974
|
+
classParts.push(`(${JSON.stringify(results)}[${masterKeyExpr || '""'}] || ${baseConflictClass ? JSON.stringify(baseConflictClass) : '""'})`);
|
|
975
|
+
}
|
|
976
|
+
classParts.push(...dynamicClassParts);
|
|
977
|
+
return { classParts, isOptimizable, baseStyle };
|
|
978
|
+
};
|
|
537
979
|
traverse(ast, {
|
|
538
980
|
JSXOpeningElement({ node }) {
|
|
539
981
|
jsxOpeningElementMap.set(node.span.start, node.attributes);
|
|
@@ -664,7 +1106,7 @@ export function plumeria(options = {}) {
|
|
|
664
1106
|
if (!node.value || node.value.type !== 'JSXExpressionContainer')
|
|
665
1107
|
return;
|
|
666
1108
|
const expr = node.value.expression;
|
|
667
|
-
|
|
1109
|
+
let args = expr.type === 'ArrayExpression'
|
|
668
1110
|
? expr.elements
|
|
669
1111
|
.filter(Boolean)
|
|
670
1112
|
.map((el) => ({ expression: el.expression ?? el }))
|
|
@@ -708,668 +1150,105 @@ export function plumeria(options = {}) {
|
|
|
708
1150
|
dynamicStyleParts.push(stripped);
|
|
709
1151
|
}
|
|
710
1152
|
}
|
|
711
|
-
|
|
712
|
-
if (t.isObjectExpression(expr)) {
|
|
713
|
-
return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
714
|
-
}
|
|
715
|
-
else if (t.isMemberExpression(expr) &&
|
|
716
|
-
t.isIdentifier(expr.object) &&
|
|
717
|
-
(t.isIdentifier(expr.property) ||
|
|
718
|
-
expr.property.type === 'Computed')) {
|
|
719
|
-
if (expr.property.type === 'Computed') {
|
|
720
|
-
return {};
|
|
721
|
-
}
|
|
722
|
-
const varName = expr.object.value;
|
|
723
|
-
const propName = expr.property.value;
|
|
724
|
-
const styleInfo = localCreateStyles[varName];
|
|
725
|
-
if (styleInfo && styleInfo.obj[propName]) {
|
|
726
|
-
const style = styleInfo.obj[propName];
|
|
727
|
-
if (typeof style === 'object' && style !== null) {
|
|
728
|
-
return style;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
const hash = mergedCreateTable[varName];
|
|
732
|
-
if (hash) {
|
|
733
|
-
const obj = scannedTables.createObjectTable[hash];
|
|
734
|
-
if (obj && obj[propName]) {
|
|
735
|
-
const style = obj[propName];
|
|
736
|
-
if (typeof style === 'object' && style !== null) {
|
|
737
|
-
return style;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
else if (t.isIdentifier(expr)) {
|
|
743
|
-
const varName = expr.value;
|
|
744
|
-
const uniqueKey = `${resourcePath}-${varName}`;
|
|
745
|
-
let hash = scannedTables.createHashTable[uniqueKey];
|
|
746
|
-
if (!hash) {
|
|
747
|
-
hash = mergedCreateTable[varName];
|
|
748
|
-
}
|
|
749
|
-
if (hash) {
|
|
750
|
-
const obj = scannedTables.createObjectTable[hash];
|
|
751
|
-
if (obj && typeof obj === 'object') {
|
|
752
|
-
return obj;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
const styleInfo = localCreateStyles[varName];
|
|
756
|
-
if (styleInfo && styleInfo.obj) {
|
|
757
|
-
return styleInfo.obj;
|
|
758
|
-
}
|
|
759
|
-
if (localCreateStyles[varName]) {
|
|
760
|
-
return localCreateStyles[varName].obj;
|
|
761
|
-
}
|
|
762
|
-
const vHash = mergedVariantsTable[varName];
|
|
763
|
-
if (vHash) {
|
|
764
|
-
return scannedTables.variantsObjectTable[vHash];
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
return null;
|
|
768
|
-
};
|
|
769
|
-
const conditionals = [];
|
|
770
|
-
let groupIdCounter = 0;
|
|
771
|
-
let baseStyle = {};
|
|
772
|
-
let isOptimizable = true;
|
|
773
|
-
for (const arg of args) {
|
|
1153
|
+
args = args.filter((arg) => {
|
|
774
1154
|
const expr = arg.expression;
|
|
775
|
-
if (t.isCallExpression(expr)
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
}
|
|
810
|
-
else if (argSource.startsWith('"') &&
|
|
811
|
-
argSource.endsWith('"')) {
|
|
812
|
-
const processed = applyCssValue(argSource.slice(1, -1), targetProp);
|
|
813
|
-
valueExpr = JSON.stringify(processed);
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
const exception = [
|
|
817
|
-
'animationIterationCount',
|
|
818
|
-
'aspectRatio',
|
|
819
|
-
'columnCount',
|
|
820
|
-
'columns',
|
|
821
|
-
'fillOpacity',
|
|
822
|
-
'flex',
|
|
823
|
-
'flexGrow',
|
|
824
|
-
'flexShrink',
|
|
825
|
-
'floodOpacity',
|
|
826
|
-
'fontSizeAdjust',
|
|
827
|
-
'fontWeight',
|
|
828
|
-
'gridColumn',
|
|
829
|
-
'gridColumnEnd',
|
|
830
|
-
'gridColumnStart',
|
|
831
|
-
'gridRow',
|
|
832
|
-
'gridRowEnd',
|
|
833
|
-
'gridRowStart',
|
|
834
|
-
'hyphenateLimitChars',
|
|
835
|
-
'initialLetter',
|
|
836
|
-
'lineHeight',
|
|
837
|
-
'mathDepth',
|
|
838
|
-
'opacity',
|
|
839
|
-
'order',
|
|
840
|
-
'orphans',
|
|
841
|
-
'scale',
|
|
842
|
-
'shapeImageThreshold',
|
|
843
|
-
'stopOpacity',
|
|
844
|
-
'strokeMiterlimit',
|
|
845
|
-
'strokeOpacity',
|
|
846
|
-
'tabSize',
|
|
847
|
-
'widows',
|
|
848
|
-
'zIndex',
|
|
849
|
-
'zoom',
|
|
850
|
-
];
|
|
851
|
-
if (!exception.includes(targetProp)) {
|
|
852
|
-
valueExpr = `(typeof ${argSource} === 'number' ? ${argSource} + 'px' : ${argSource})`;
|
|
853
|
-
}
|
|
854
|
-
else {
|
|
855
|
-
valueExpr = argSource;
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
catch {
|
|
860
|
-
valueExpr = argSource;
|
|
861
|
-
}
|
|
862
|
-
dynamicStyleParts.push(`"${cssVar}": ${valueExpr}`);
|
|
863
|
-
});
|
|
864
|
-
continue;
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
|
|
869
|
-
const varName = expr.callee.value;
|
|
870
|
-
let variantObj;
|
|
871
|
-
const uniqueKey = `${resourcePath}-${varName}`;
|
|
872
|
-
let hash = scannedTables.variantsHashTable[uniqueKey];
|
|
873
|
-
if (!hash) {
|
|
874
|
-
hash = mergedVariantsTable[varName];
|
|
875
|
-
}
|
|
876
|
-
if (hash && scannedTables.variantsObjectTable[hash]) {
|
|
877
|
-
variantObj = scannedTables.variantsObjectTable[hash];
|
|
878
|
-
}
|
|
879
|
-
if (!variantObj) {
|
|
880
|
-
if (localCreateStyles[varName] &&
|
|
881
|
-
localCreateStyles[varName].obj) {
|
|
882
|
-
variantObj = localCreateStyles[varName].obj;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
if (variantObj) {
|
|
886
|
-
const callArgs = expr.arguments;
|
|
887
|
-
if (callArgs.length === 1 && !callArgs[0].spread) {
|
|
888
|
-
const arg = callArgs[0].expression;
|
|
889
|
-
if (arg.type === 'ObjectExpression') {
|
|
890
|
-
for (const prop of arg.properties) {
|
|
891
|
-
let groupName;
|
|
892
|
-
let valExpr;
|
|
893
|
-
if (prop.type === 'KeyValueProperty' &&
|
|
894
|
-
prop.key.type === 'Identifier') {
|
|
895
|
-
groupName = prop.key.value;
|
|
896
|
-
valExpr = prop.value;
|
|
897
|
-
}
|
|
898
|
-
else if (prop.type === 'Identifier') {
|
|
899
|
-
groupName = prop.value;
|
|
900
|
-
valExpr = prop;
|
|
901
|
-
}
|
|
902
|
-
if (groupName && valExpr) {
|
|
903
|
-
const groupVariants = variantObj[groupName];
|
|
904
|
-
if (!groupVariants)
|
|
905
|
-
continue;
|
|
906
|
-
const currentGroupId = ++groupIdCounter;
|
|
907
|
-
const valStart = valExpr.span.start - baseByteOffset;
|
|
908
|
-
const valEnd = valExpr.span.end - baseByteOffset;
|
|
909
|
-
const valSource = sourceBuffer
|
|
910
|
-
.subarray(valStart, valEnd)
|
|
911
|
-
.toString('utf-8');
|
|
912
|
-
if (valExpr.type === 'StringLiteral') {
|
|
913
|
-
if (groupVariants[valExpr.value]) {
|
|
914
|
-
baseStyle = deepMerge(baseStyle, groupVariants[valExpr.value]);
|
|
915
|
-
}
|
|
916
|
-
continue;
|
|
917
|
-
}
|
|
918
|
-
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
919
|
-
conditionals.push({
|
|
920
|
-
test: valExpr,
|
|
921
|
-
testLHS: valSource,
|
|
922
|
-
testString: `${valSource} === '${optionName}'`,
|
|
923
|
-
truthy: style,
|
|
924
|
-
falsy: {},
|
|
925
|
-
groupId: currentGroupId,
|
|
926
|
-
groupName,
|
|
927
|
-
valueName: optionName,
|
|
928
|
-
varName,
|
|
929
|
-
});
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
continue;
|
|
934
|
-
}
|
|
935
|
-
const argStart = arg.span.start - baseByteOffset;
|
|
936
|
-
const argEnd = arg.span.end - baseByteOffset;
|
|
937
|
-
const argSource = sourceBuffer
|
|
938
|
-
.subarray(argStart, argEnd)
|
|
939
|
-
.toString('utf-8');
|
|
940
|
-
if (t.isStringLiteral(arg)) {
|
|
941
|
-
if (variantObj[arg.value]) {
|
|
942
|
-
baseStyle = deepMerge(baseStyle, variantObj[arg.value]);
|
|
943
|
-
}
|
|
944
|
-
continue;
|
|
945
|
-
}
|
|
946
|
-
const currentGroupId = ++groupIdCounter;
|
|
947
|
-
Object.entries(variantObj).forEach(([key, style]) => {
|
|
948
|
-
conditionals.push({
|
|
949
|
-
test: arg,
|
|
950
|
-
testLHS: argSource,
|
|
951
|
-
testString: `${argSource} === '${key}'`,
|
|
952
|
-
truthy: style,
|
|
953
|
-
falsy: {},
|
|
954
|
-
groupId: currentGroupId,
|
|
955
|
-
groupName: undefined,
|
|
956
|
-
valueName: key,
|
|
957
|
-
varName,
|
|
958
|
-
});
|
|
959
|
-
});
|
|
960
|
-
continue;
|
|
961
|
-
}
|
|
962
|
-
isOptimizable = false;
|
|
963
|
-
break;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
else if (t.isIdentifier(expr)) {
|
|
967
|
-
const varName = expr.value;
|
|
968
|
-
let variantObj;
|
|
969
|
-
const uniqueKey = `${resourcePath}-${varName}`;
|
|
970
|
-
let hash = scannedTables.variantsHashTable[uniqueKey];
|
|
971
|
-
if (!hash) {
|
|
972
|
-
hash = mergedVariantsTable[varName];
|
|
973
|
-
}
|
|
974
|
-
if (hash && scannedTables.variantsObjectTable[hash]) {
|
|
975
|
-
variantObj = scannedTables.variantsObjectTable[hash];
|
|
976
|
-
}
|
|
977
|
-
if (!variantObj) {
|
|
978
|
-
if (localCreateStyles[varName] &&
|
|
979
|
-
localCreateStyles[varName].obj) {
|
|
980
|
-
variantObj = localCreateStyles[varName].obj;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
if (variantObj) {
|
|
984
|
-
Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
|
|
985
|
-
if (!groupVariants)
|
|
986
|
-
return;
|
|
987
|
-
const currentGroupId = ++groupIdCounter;
|
|
988
|
-
Object.entries(groupVariants).forEach(([optionName, style]) => {
|
|
989
|
-
conditionals.push({
|
|
990
|
-
test: expr,
|
|
991
|
-
testLHS: `props["${groupName}"]`,
|
|
992
|
-
testString: `props["${groupName}"] === '${optionName}'`,
|
|
993
|
-
truthy: style,
|
|
994
|
-
falsy: {},
|
|
995
|
-
groupId: currentGroupId,
|
|
996
|
-
groupName: groupName,
|
|
997
|
-
valueName: optionName,
|
|
998
|
-
varName: varName,
|
|
999
|
-
});
|
|
1000
|
-
});
|
|
1001
|
-
});
|
|
1002
|
-
continue;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
const getSource = (node) => {
|
|
1006
|
-
const start = node.span.start - baseByteOffset;
|
|
1007
|
-
const end = node.span.end - baseByteOffset;
|
|
1008
|
-
return sourceBuffer.subarray(start, end).toString('utf-8');
|
|
1009
|
-
};
|
|
1010
|
-
const collectConditions = (node, currentTestStrings = []) => {
|
|
1011
|
-
const staticStyle = resolveStyleObject(node);
|
|
1012
|
-
if (staticStyle) {
|
|
1013
|
-
if (currentTestStrings.length === 0) {
|
|
1014
|
-
baseStyle = deepMerge(baseStyle, staticStyle);
|
|
1015
|
-
}
|
|
1016
|
-
else {
|
|
1017
|
-
const combinedTest = currentTestStrings.join(' && ');
|
|
1018
|
-
conditionals.push({
|
|
1019
|
-
test: node,
|
|
1020
|
-
testString: combinedTest,
|
|
1021
|
-
truthy: staticStyle,
|
|
1022
|
-
falsy: {},
|
|
1023
|
-
varName: undefined,
|
|
1024
|
-
});
|
|
1025
|
-
}
|
|
1026
|
-
return true;
|
|
1027
|
-
}
|
|
1028
|
-
if (node.type === 'ConditionalExpression') {
|
|
1029
|
-
const testSource = getSource(node.test);
|
|
1030
|
-
if (currentTestStrings.length === 0) {
|
|
1031
|
-
const trueStyle = resolveStyleObject(node.consequent);
|
|
1032
|
-
const falseStyle = resolveStyleObject(node.alternate);
|
|
1033
|
-
if (trueStyle && falseStyle) {
|
|
1034
|
-
conditionals.push({
|
|
1035
|
-
test: node,
|
|
1036
|
-
testString: testSource,
|
|
1037
|
-
truthy: trueStyle,
|
|
1038
|
-
falsy: falseStyle,
|
|
1039
|
-
varName: undefined,
|
|
1040
|
-
});
|
|
1041
|
-
return true;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
collectConditions(node.consequent, [
|
|
1045
|
-
...currentTestStrings,
|
|
1046
|
-
`(${testSource})`,
|
|
1047
|
-
]);
|
|
1048
|
-
collectConditions(node.alternate, [
|
|
1049
|
-
...currentTestStrings,
|
|
1050
|
-
`!(${testSource})`,
|
|
1051
|
-
]);
|
|
1052
|
-
return true;
|
|
1155
|
+
if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
|
|
1156
|
+
return true;
|
|
1157
|
+
const callee = expr.callee;
|
|
1158
|
+
if (!t.isIdentifier(callee.object) ||
|
|
1159
|
+
!t.isIdentifier(callee.property))
|
|
1160
|
+
return true;
|
|
1161
|
+
const varName = callee.object.value;
|
|
1162
|
+
const propKey = callee.property.value;
|
|
1163
|
+
const styleInfo = localCreateStyles[varName];
|
|
1164
|
+
const atomMap = styleInfo?.hashMap?.[propKey];
|
|
1165
|
+
if (!atomMap?.['__cssVars__'])
|
|
1166
|
+
return true;
|
|
1167
|
+
const cssVarInfo = JSON.parse(atomMap['__cssVars__']);
|
|
1168
|
+
const hashes = Object.entries(atomMap)
|
|
1169
|
+
.filter(([k]) => k !== '__cssVars__')
|
|
1170
|
+
.map(([, v]) => v)
|
|
1171
|
+
.join(' ');
|
|
1172
|
+
if (hashes)
|
|
1173
|
+
dynamicClassParts.push(JSON.stringify(hashes));
|
|
1174
|
+
const callArgs = expr.arguments;
|
|
1175
|
+
Object.entries(cssVarInfo).forEach(([_, { cssVar, propKey: targetProp }], i) => {
|
|
1176
|
+
const callArg = callArgs[i];
|
|
1177
|
+
if (!callArg)
|
|
1178
|
+
return;
|
|
1179
|
+
const argStart = callArg.expression.span.start - baseByteOffset;
|
|
1180
|
+
const argEnd = callArg.expression.span.end - baseByteOffset;
|
|
1181
|
+
const argSource = sourceBuffer
|
|
1182
|
+
.subarray(argStart, argEnd)
|
|
1183
|
+
.toString('utf-8');
|
|
1184
|
+
let valueExpr;
|
|
1185
|
+
const maybeNumber = Number(argSource);
|
|
1186
|
+
if (!isNaN(maybeNumber) &&
|
|
1187
|
+
argSource.trim() === String(maybeNumber)) {
|
|
1188
|
+
valueExpr = JSON.stringify(applyCssValue(maybeNumber, targetProp));
|
|
1053
1189
|
}
|
|
1054
|
-
else if (
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
collectConditions(node.right, [
|
|
1058
|
-
...currentTestStrings,
|
|
1059
|
-
`(${leftSource})`,
|
|
1060
|
-
]);
|
|
1061
|
-
return true;
|
|
1190
|
+
else if (argSource.startsWith('"') &&
|
|
1191
|
+
argSource.endsWith('"')) {
|
|
1192
|
+
valueExpr = JSON.stringify(applyCssValue(argSource.slice(1, -1), targetProp));
|
|
1062
1193
|
}
|
|
1063
|
-
else
|
|
1064
|
-
|
|
1194
|
+
else {
|
|
1195
|
+
const exception = [
|
|
1196
|
+
'animationIterationCount',
|
|
1197
|
+
'aspectRatio',
|
|
1198
|
+
'columnCount',
|
|
1199
|
+
'columns',
|
|
1200
|
+
'fillOpacity',
|
|
1201
|
+
'flex',
|
|
1202
|
+
'flexGrow',
|
|
1203
|
+
'flexShrink',
|
|
1204
|
+
'floodOpacity',
|
|
1205
|
+
'fontSizeAdjust',
|
|
1206
|
+
'fontWeight',
|
|
1207
|
+
'gridColumn',
|
|
1208
|
+
'gridColumnEnd',
|
|
1209
|
+
'gridColumnStart',
|
|
1210
|
+
'gridRow',
|
|
1211
|
+
'gridRowEnd',
|
|
1212
|
+
'gridRowStart',
|
|
1213
|
+
'hyphenateLimitChars',
|
|
1214
|
+
'initialLetter',
|
|
1215
|
+
'lineHeight',
|
|
1216
|
+
'mathDepth',
|
|
1217
|
+
'opacity',
|
|
1218
|
+
'order',
|
|
1219
|
+
'orphans',
|
|
1220
|
+
'scale',
|
|
1221
|
+
'shapeImageThreshold',
|
|
1222
|
+
'stopOpacity',
|
|
1223
|
+
'strokeMiterlimit',
|
|
1224
|
+
'strokeOpacity',
|
|
1225
|
+
'tabSize',
|
|
1226
|
+
'widows',
|
|
1227
|
+
'zIndex',
|
|
1228
|
+
'zoom',
|
|
1229
|
+
];
|
|
1230
|
+
valueExpr = exception.includes(targetProp)
|
|
1231
|
+
? argSource
|
|
1232
|
+
: `(typeof ${argSource} === 'number' ? ${argSource} + 'px' : ${argSource})`;
|
|
1065
1233
|
}
|
|
1066
|
-
|
|
1067
|
-
};
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
continue;
|
|
1071
|
-
isOptimizable = false;
|
|
1072
|
-
break;
|
|
1073
|
-
}
|
|
1234
|
+
dynamicStyleParts.push(`"${cssVar}": ${valueExpr}`);
|
|
1235
|
+
});
|
|
1236
|
+
return false;
|
|
1237
|
+
});
|
|
1074
1238
|
const styleAttr = dynamicStyleParts.length > 0
|
|
1075
1239
|
? ` style={{${dynamicStyleParts.join(', ')}}}`
|
|
1076
1240
|
: '';
|
|
1241
|
+
const { classParts, isOptimizable, baseStyle } = buildClassParts(args, dynamicClassParts, existingClass);
|
|
1077
1242
|
if (isOptimizable &&
|
|
1078
|
-
(args.length > 0 ||
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
...dynamicClassParts,
|
|
1088
|
-
].join(' + " " + ');
|
|
1089
|
-
replacements.push({
|
|
1090
|
-
start: node.span.start - baseByteOffset,
|
|
1091
|
-
end: node.span.end - baseByteOffset,
|
|
1092
|
-
content: `className={${allParts || '""'}}${styleAttr}`,
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
else {
|
|
1096
|
-
const propertyCounts = {};
|
|
1097
|
-
const addCounts = (style) => {
|
|
1098
|
-
Object.keys(style).forEach((key) => {
|
|
1099
|
-
propertyCounts[key] = (propertyCounts[key] || 0) + 1;
|
|
1100
|
-
});
|
|
1101
|
-
};
|
|
1102
|
-
addCounts(baseStyle);
|
|
1103
|
-
const participation = {};
|
|
1104
|
-
const registerParticipation = (style, sourceId) => {
|
|
1105
|
-
Object.keys(style).forEach((key) => {
|
|
1106
|
-
if (!participation[key])
|
|
1107
|
-
participation[key] = new Set();
|
|
1108
|
-
participation[key].add(sourceId);
|
|
1109
|
-
});
|
|
1110
|
-
};
|
|
1111
|
-
registerParticipation(baseStyle, 'base');
|
|
1112
|
-
conditionals
|
|
1113
|
-
.filter((c) => c.groupId === undefined)
|
|
1114
|
-
.forEach((c, idx) => {
|
|
1115
|
-
const sourceId = `std_${idx}`;
|
|
1116
|
-
registerParticipation(c.truthy, sourceId);
|
|
1117
|
-
registerParticipation(c.falsy, sourceId);
|
|
1118
|
-
});
|
|
1119
|
-
const variantGroups = {};
|
|
1120
|
-
conditionals.forEach((c) => {
|
|
1121
|
-
if (c.groupId !== undefined) {
|
|
1122
|
-
if (!variantGroups[c.groupId])
|
|
1123
|
-
variantGroups[c.groupId] = [];
|
|
1124
|
-
variantGroups[c.groupId].push(c);
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
Object.entries(variantGroups).forEach(([groupId, opts]) => {
|
|
1128
|
-
const sourceId = `var_${groupId}`;
|
|
1129
|
-
opts.forEach((opt) => {
|
|
1130
|
-
registerParticipation(opt.truthy, sourceId);
|
|
1131
|
-
registerParticipation(opt.falsy, sourceId);
|
|
1132
|
-
});
|
|
1133
|
-
});
|
|
1134
|
-
const conflictingKeys = new Set();
|
|
1135
|
-
Object.entries(participation).forEach(([key, sources]) => {
|
|
1136
|
-
if (sources.size > 1) {
|
|
1137
|
-
conflictingKeys.add(key);
|
|
1138
|
-
}
|
|
1139
|
-
});
|
|
1140
|
-
const baseIndependent = {};
|
|
1141
|
-
const baseConflict = {};
|
|
1142
|
-
Object.entries(baseStyle).forEach(([key, val]) => {
|
|
1143
|
-
if (conflictingKeys.has(key)) {
|
|
1144
|
-
baseConflict[key] = val;
|
|
1145
|
-
}
|
|
1146
|
-
else {
|
|
1147
|
-
baseIndependent[key] = val;
|
|
1148
|
-
}
|
|
1149
|
-
});
|
|
1150
|
-
const indepConditionals = [];
|
|
1151
|
-
const conflictConditionals = [];
|
|
1152
|
-
const splitConditional = (c) => {
|
|
1153
|
-
const truthyIndep = {};
|
|
1154
|
-
const truthyConf = {};
|
|
1155
|
-
const falsyIndep = {};
|
|
1156
|
-
const falsyConf = {};
|
|
1157
|
-
let hasIndep = false;
|
|
1158
|
-
let hasConf = false;
|
|
1159
|
-
Object.entries(c.truthy).forEach(([k, v]) => {
|
|
1160
|
-
if (conflictingKeys.has(k)) {
|
|
1161
|
-
truthyConf[k] = v;
|
|
1162
|
-
hasConf = true;
|
|
1163
|
-
}
|
|
1164
|
-
else {
|
|
1165
|
-
truthyIndep[k] = v;
|
|
1166
|
-
hasIndep = true;
|
|
1167
|
-
}
|
|
1168
|
-
});
|
|
1169
|
-
Object.entries(c.falsy).forEach(([k, v]) => {
|
|
1170
|
-
if (conflictingKeys.has(k)) {
|
|
1171
|
-
falsyConf[k] = v;
|
|
1172
|
-
hasConf = true;
|
|
1173
|
-
}
|
|
1174
|
-
else {
|
|
1175
|
-
falsyIndep[k] = v;
|
|
1176
|
-
hasIndep = true;
|
|
1177
|
-
}
|
|
1178
|
-
});
|
|
1179
|
-
if (hasIndep) {
|
|
1180
|
-
indepConditionals.push({
|
|
1181
|
-
...c,
|
|
1182
|
-
truthy: truthyIndep,
|
|
1183
|
-
falsy: falsyIndep,
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
if (hasConf) {
|
|
1187
|
-
conflictConditionals.push({
|
|
1188
|
-
...c,
|
|
1189
|
-
truthy: truthyConf,
|
|
1190
|
-
falsy: falsyConf,
|
|
1191
|
-
});
|
|
1192
|
-
}
|
|
1193
|
-
};
|
|
1194
|
-
conditionals.forEach(splitConditional);
|
|
1195
|
-
const classParts = [];
|
|
1196
|
-
if (existingClass)
|
|
1197
|
-
classParts.push(JSON.stringify(existingClass));
|
|
1198
|
-
if (Object.keys(baseIndependent).length > 0) {
|
|
1199
|
-
const records = getStyleRecords(baseIndependent);
|
|
1200
|
-
const className = records.map((r) => r.hash).join(' ');
|
|
1201
|
-
if (className)
|
|
1202
|
-
classParts.push(JSON.stringify(className));
|
|
1203
|
-
}
|
|
1204
|
-
const indepStd = indepConditionals.filter((c) => c.groupId === undefined);
|
|
1205
|
-
indepStd.forEach((c) => {
|
|
1206
|
-
const processBranch = (style) => {
|
|
1207
|
-
if (Object.keys(style).length === 0)
|
|
1208
|
-
return '""';
|
|
1209
|
-
const records = getStyleRecords(style);
|
|
1210
|
-
return JSON.stringify(records.map((r) => r.hash).join(' '));
|
|
1211
|
-
};
|
|
1212
|
-
const tClass = processBranch(c.truthy);
|
|
1213
|
-
const fClass = processBranch(c.falsy);
|
|
1214
|
-
let testStr = c.testString;
|
|
1215
|
-
if (!testStr && c.test) {
|
|
1216
|
-
const start = c.test.span.start - baseByteOffset;
|
|
1217
|
-
const end = c.test.span.end - baseByteOffset;
|
|
1218
|
-
testStr = sourceBuffer.subarray(start, end).toString('utf-8');
|
|
1219
|
-
}
|
|
1220
|
-
classParts.push(`(${testStr} ? ${tClass} : ${fClass})`);
|
|
1221
|
-
});
|
|
1222
|
-
const indepVarGroups = {};
|
|
1223
|
-
indepConditionals.forEach((c) => {
|
|
1224
|
-
if (c.groupId !== undefined) {
|
|
1225
|
-
if (!indepVarGroups[c.groupId])
|
|
1226
|
-
indepVarGroups[c.groupId] = [];
|
|
1227
|
-
indepVarGroups[c.groupId].push(c);
|
|
1228
|
-
}
|
|
1229
|
-
});
|
|
1230
|
-
Object.values(indepVarGroups).forEach((options) => {
|
|
1231
|
-
let commonTestExpr = null;
|
|
1232
|
-
const lookupMap = {};
|
|
1233
|
-
if (options.length > 0) {
|
|
1234
|
-
if (options[0].testLHS) {
|
|
1235
|
-
commonTestExpr = options[0].testLHS;
|
|
1236
|
-
}
|
|
1237
|
-
else if (options[0].testString) {
|
|
1238
|
-
commonTestExpr = options[0].testString;
|
|
1239
|
-
}
|
|
1240
|
-
else {
|
|
1241
|
-
const firstTest = options[0].test;
|
|
1242
|
-
const firstStart = firstTest.span.start - baseByteOffset;
|
|
1243
|
-
const firstEnd = firstTest.span.end - baseByteOffset;
|
|
1244
|
-
commonTestExpr = sourceBuffer
|
|
1245
|
-
.subarray(firstStart, firstEnd)
|
|
1246
|
-
.toString('utf-8');
|
|
1247
|
-
}
|
|
1248
|
-
options.forEach((opt) => {
|
|
1249
|
-
if (opt.valueName && opt.truthy) {
|
|
1250
|
-
const records = getStyleRecords(opt.truthy);
|
|
1251
|
-
const className = records.map((r) => r.hash).join(' ');
|
|
1252
|
-
if (className) {
|
|
1253
|
-
lookupMap[opt.valueName] = className;
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
if (commonTestExpr && Object.keys(lookupMap).length > 0) {
|
|
1259
|
-
const entries = Object.entries(lookupMap)
|
|
1260
|
-
.map(([key, val]) => `"${key}":"${val}"`)
|
|
1261
|
-
.join(',');
|
|
1262
|
-
classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
|
|
1263
|
-
}
|
|
1264
|
-
});
|
|
1265
|
-
if (Object.keys(baseConflict).length > 0 ||
|
|
1266
|
-
conflictConditionals.length > 0) {
|
|
1267
|
-
const conflictStd = conflictConditionals.filter((c) => c.groupId === undefined);
|
|
1268
|
-
const conflictVarGroups = {};
|
|
1269
|
-
conflictConditionals.forEach((c) => {
|
|
1270
|
-
if (c.groupId !== undefined) {
|
|
1271
|
-
if (!conflictVarGroups[c.groupId])
|
|
1272
|
-
conflictVarGroups[c.groupId] = [];
|
|
1273
|
-
conflictVarGroups[c.groupId].push(c);
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
const dimensions = [];
|
|
1277
|
-
conflictStd.forEach((c) => {
|
|
1278
|
-
let testStr = c.testString;
|
|
1279
|
-
if (!testStr && c.test) {
|
|
1280
|
-
const start = c.test.span.start - baseByteOffset;
|
|
1281
|
-
const end = c.test.span.end - baseByteOffset;
|
|
1282
|
-
testStr = sourceBuffer
|
|
1283
|
-
.subarray(start, end)
|
|
1284
|
-
.toString('utf-8');
|
|
1285
|
-
}
|
|
1286
|
-
dimensions.push({
|
|
1287
|
-
type: 'std',
|
|
1288
|
-
testExpr: testStr,
|
|
1289
|
-
options: [
|
|
1290
|
-
{ value: 0, style: c.falsy, label: 'false' },
|
|
1291
|
-
{ value: 1, style: c.truthy, label: 'true' },
|
|
1292
|
-
],
|
|
1293
|
-
});
|
|
1294
|
-
});
|
|
1295
|
-
Object.entries(conflictVarGroups).forEach(([_groupId, opts]) => {
|
|
1296
|
-
let commonTestExpr = null;
|
|
1297
|
-
if (opts.length > 0) {
|
|
1298
|
-
if (opts[0].testLHS) {
|
|
1299
|
-
commonTestExpr = opts[0].testLHS;
|
|
1300
|
-
}
|
|
1301
|
-
else if (opts[0].testString) {
|
|
1302
|
-
commonTestExpr = opts[0].testString;
|
|
1303
|
-
}
|
|
1304
|
-
else {
|
|
1305
|
-
const firstTest = opts[0].test;
|
|
1306
|
-
const firstStart = firstTest.span.start - baseByteOffset;
|
|
1307
|
-
const firstEnd = firstTest.span.end - baseByteOffset;
|
|
1308
|
-
commonTestExpr = sourceBuffer
|
|
1309
|
-
.subarray(firstStart, firstEnd)
|
|
1310
|
-
.toString('utf-8');
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
const options = opts.map((opt) => ({
|
|
1314
|
-
value: opt.valueName,
|
|
1315
|
-
style: opt.truthy,
|
|
1316
|
-
label: opt.valueName || 'default',
|
|
1317
|
-
}));
|
|
1318
|
-
dimensions.push({
|
|
1319
|
-
type: 'var',
|
|
1320
|
-
testExpr: commonTestExpr || '""',
|
|
1321
|
-
options: options,
|
|
1322
|
-
});
|
|
1323
|
-
});
|
|
1324
|
-
const results = {};
|
|
1325
|
-
const recurse = (dimIndex, currentStyle, keyParts) => {
|
|
1326
|
-
if (dimIndex >= dimensions.length) {
|
|
1327
|
-
const records = getStyleRecords(currentStyle);
|
|
1328
|
-
const className = records.map((r) => r.hash).join(' ');
|
|
1329
|
-
const finalKey = keyParts.join('__');
|
|
1330
|
-
if (className)
|
|
1331
|
-
results[finalKey] = className;
|
|
1332
|
-
return;
|
|
1333
|
-
}
|
|
1334
|
-
const dim = dimensions[dimIndex];
|
|
1335
|
-
dim.options.forEach((opt) => {
|
|
1336
|
-
const nextStyle = deepMerge(currentStyle, opt.style);
|
|
1337
|
-
recurse(dimIndex + 1, nextStyle, [
|
|
1338
|
-
...keyParts,
|
|
1339
|
-
String(opt.value),
|
|
1340
|
-
]);
|
|
1341
|
-
});
|
|
1342
|
-
};
|
|
1343
|
-
recurse(0, baseConflict, []);
|
|
1344
|
-
let baseConflictClass = '';
|
|
1345
|
-
if (Object.keys(baseConflict).length > 0) {
|
|
1346
|
-
const records = getStyleRecords(baseConflict);
|
|
1347
|
-
baseConflictClass = records.map((r) => r.hash).join(' ');
|
|
1348
|
-
}
|
|
1349
|
-
const keyExprs = [];
|
|
1350
|
-
dimensions.forEach((dim) => {
|
|
1351
|
-
if (dim.type === 'std') {
|
|
1352
|
-
keyExprs.push(`(${dim.testExpr} ? "1" : "0")`);
|
|
1353
|
-
}
|
|
1354
|
-
else {
|
|
1355
|
-
keyExprs.push(dim.testExpr || '""');
|
|
1356
|
-
}
|
|
1357
|
-
});
|
|
1358
|
-
const masterKeyExpr = keyExprs.length > 0 ? keyExprs.join(' + "__" + ') : '""';
|
|
1359
|
-
const tableJson = JSON.stringify(results);
|
|
1360
|
-
const fallback = baseConflictClass
|
|
1361
|
-
? JSON.stringify(baseConflictClass)
|
|
1362
|
-
: '""';
|
|
1363
|
-
classParts.push(`(${tableJson}[${masterKeyExpr}] || ${fallback})`);
|
|
1364
|
-
}
|
|
1365
|
-
classParts.push(...dynamicClassParts);
|
|
1366
|
-
const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
|
|
1367
|
-
replacements.push({
|
|
1368
|
-
start: node.span.start - baseByteOffset,
|
|
1369
|
-
end: node.span.end - baseByteOffset,
|
|
1370
|
-
content: `className={${replacement}}${styleAttr}`,
|
|
1371
|
-
});
|
|
1372
|
-
}
|
|
1243
|
+
(args.length > 0 ||
|
|
1244
|
+
Object.keys(baseStyle).length > 0 ||
|
|
1245
|
+
dynamicClassParts.length > 0)) {
|
|
1246
|
+
const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
|
|
1247
|
+
replacements.push({
|
|
1248
|
+
start: node.span.start - baseByteOffset,
|
|
1249
|
+
end: node.span.end - baseByteOffset,
|
|
1250
|
+
content: `className={${replacement}}${styleAttr}`,
|
|
1251
|
+
});
|
|
1373
1252
|
}
|
|
1374
1253
|
else {
|
|
1375
1254
|
replacements.push({
|
|
@@ -1379,6 +1258,56 @@ export function plumeria(options = {}) {
|
|
|
1379
1258
|
});
|
|
1380
1259
|
}
|
|
1381
1260
|
},
|
|
1261
|
+
CallExpression({ node }) {
|
|
1262
|
+
const callee = node.callee;
|
|
1263
|
+
let isUseCall = false;
|
|
1264
|
+
if (t.isMemberExpression(callee) &&
|
|
1265
|
+
t.isIdentifier(callee.object) &&
|
|
1266
|
+
t.isIdentifier(callee.property)) {
|
|
1267
|
+
const objectName = callee.object.value;
|
|
1268
|
+
const propertyName = callee.property.value;
|
|
1269
|
+
const alias = plumeriaAliases[objectName];
|
|
1270
|
+
if (alias === 'NAMESPACE' && propertyName === 'use') {
|
|
1271
|
+
isUseCall = true;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
else if (t.isIdentifier(callee)) {
|
|
1275
|
+
const calleeName = callee.value;
|
|
1276
|
+
const originalName = plumeriaAliases[calleeName];
|
|
1277
|
+
if (originalName === 'use') {
|
|
1278
|
+
isUseCall = true;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
if (!isUseCall)
|
|
1282
|
+
return;
|
|
1283
|
+
const args = node.arguments;
|
|
1284
|
+
for (const arg of args) {
|
|
1285
|
+
const expr = arg.expression;
|
|
1286
|
+
if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
|
|
1287
|
+
continue;
|
|
1288
|
+
const callee = expr.callee;
|
|
1289
|
+
if (!t.isIdentifier(callee.object) ||
|
|
1290
|
+
!t.isIdentifier(callee.property))
|
|
1291
|
+
continue;
|
|
1292
|
+
const varName = callee.object.value;
|
|
1293
|
+
const propKey = callee.property.value;
|
|
1294
|
+
const styleInfo = localCreateStyles[varName];
|
|
1295
|
+
const atomMap = styleInfo?.hashMap?.[propKey];
|
|
1296
|
+
if (atomMap?.['__cssVars__']) {
|
|
1297
|
+
throw new Error(`Plumeria: css.use(${getSource(expr)}) does not support dynamic function keys.\n`);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
const { classParts, isOptimizable, baseStyle } = buildClassParts(args);
|
|
1301
|
+
if (isOptimizable &&
|
|
1302
|
+
(args.length > 0 || Object.keys(baseStyle).length > 0)) {
|
|
1303
|
+
const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
|
|
1304
|
+
replacements.push({
|
|
1305
|
+
start: node.span.start - baseByteOffset,
|
|
1306
|
+
end: node.span.end - baseByteOffset,
|
|
1307
|
+
content: replacement,
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
},
|
|
1382
1311
|
});
|
|
1383
1312
|
Object.values(localCreateStyles).forEach((info) => {
|
|
1384
1313
|
if (info.type === 'constant') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/vite-plugin",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Plumeria Vite plugin",
|
|
6
6
|
"author": "Refirst 11",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dist/"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@plumeria/utils": "^10.0.
|
|
25
|
+
"@plumeria/utils": "^10.0.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@swc/core": "1.15.18",
|