@vue/compiler-vapor 3.6.0-beta.12 → 3.6.0-beta.14
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/compiler-vapor.cjs.js +890 -208
- package/dist/compiler-vapor.d.ts +68 -93
- package/dist/compiler-vapor.esm-browser.js +1002 -269
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vue/compiler-vapor v3.6.0-beta.
|
|
2
|
+
* @vue/compiler-vapor v3.6.0-beta.14
|
|
3
3
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
4
4
|
* @license MIT
|
|
5
5
|
**/
|
|
@@ -661,6 +661,7 @@ function genPrependNode(oper, { helper }) {
|
|
|
661
661
|
//#endregion
|
|
662
662
|
//#region packages/compiler-vapor/src/generators/expression.ts
|
|
663
663
|
function genExpression(node, context, assignment) {
|
|
664
|
+
node = context.getExpressionReplacement(node);
|
|
664
665
|
const { content, ast, isStatic, loc } = node;
|
|
665
666
|
if (isStatic) return [[
|
|
666
667
|
JSON.stringify(content),
|
|
@@ -775,11 +776,15 @@ function canPrefix(name) {
|
|
|
775
776
|
return true;
|
|
776
777
|
}
|
|
777
778
|
function processExpressions(context, expressions, shouldDeclare) {
|
|
779
|
+
const expressionReplacements = /* @__PURE__ */ new Map();
|
|
778
780
|
const { seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
|
|
779
781
|
const reservedNames = new Set(seenIdentifier);
|
|
780
|
-
const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames);
|
|
781
|
-
const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames);
|
|
782
|
-
return
|
|
782
|
+
const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames, expressionReplacements);
|
|
783
|
+
const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames, expressionReplacements);
|
|
784
|
+
return {
|
|
785
|
+
...genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare),
|
|
786
|
+
expressionReplacements
|
|
787
|
+
};
|
|
783
788
|
}
|
|
784
789
|
function analyzeExpressions(expressions) {
|
|
785
790
|
const seenVariable = Object.create(null);
|
|
@@ -837,7 +842,13 @@ function analyzeExpressions(expressions) {
|
|
|
837
842
|
updatedVariable
|
|
838
843
|
};
|
|
839
844
|
}
|
|
840
|
-
function
|
|
845
|
+
function getProcessedExpression(exp, expressionReplacements) {
|
|
846
|
+
return expressionReplacements.get(exp) || exp;
|
|
847
|
+
}
|
|
848
|
+
function setExpressionReplacement(expressionReplacements, exp, content, ast) {
|
|
849
|
+
expressionReplacements.set(exp, (0, _vue_shared.extend)({ ast }, (0, _vue_compiler_dom.createSimpleExpression)(content, exp.isStatic, exp.loc, exp.constType)));
|
|
850
|
+
}
|
|
851
|
+
function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames, expressionReplacements) {
|
|
841
852
|
const declarations = [];
|
|
842
853
|
const expToReplacementMap = /* @__PURE__ */ new Map();
|
|
843
854
|
for (const [name, exps] of variableToExpMap) {
|
|
@@ -870,14 +881,15 @@ function processRepeatedVariables(context, seenVariable, variableToExpMap, expTo
|
|
|
870
881
|
}
|
|
871
882
|
}
|
|
872
883
|
for (const [exp, replacements] of expToReplacementMap) {
|
|
884
|
+
let content = getProcessedExpression(exp, expressionReplacements).content;
|
|
873
885
|
replacements.flatMap(({ name, locs }) => locs.map(({ start, end }) => ({
|
|
874
886
|
start,
|
|
875
887
|
end,
|
|
876
888
|
name
|
|
877
889
|
}))).sort((a, b) => b.end - a.end).forEach(({ start, end, name }) => {
|
|
878
|
-
|
|
890
|
+
content = content.slice(0, start - 1) + name + content.slice(end - 1);
|
|
879
891
|
});
|
|
880
|
-
exp
|
|
892
|
+
setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content));
|
|
881
893
|
}
|
|
882
894
|
return declarations;
|
|
883
895
|
}
|
|
@@ -893,13 +905,14 @@ function shouldDeclareVariable(name, expToVariableMap, exps) {
|
|
|
893
905
|
if (vars.every((v) => v.every((e, idx) => e === first[idx]))) return false;
|
|
894
906
|
return true;
|
|
895
907
|
}
|
|
896
|
-
function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames) {
|
|
908
|
+
function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames, expressionReplacements) {
|
|
897
909
|
const declarations = [];
|
|
898
910
|
const seenExp = expressions.reduce((acc, exp) => {
|
|
899
911
|
const vars = expToVariableMap.get(exp);
|
|
900
912
|
if (!vars) return acc;
|
|
913
|
+
const processed = getProcessedExpression(exp, expressionReplacements);
|
|
901
914
|
const variables = vars.map((v) => v.name);
|
|
902
|
-
if (
|
|
915
|
+
if (processed.ast && processed.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v))) && !variables.some((v) => (0, _vue_shared.isGloballyAllowed)(v))) acc[processed.content] = (acc[processed.content] || 0) + 1;
|
|
903
916
|
return acc;
|
|
904
917
|
}, Object.create(null));
|
|
905
918
|
Object.entries(seenExp).forEach(([content, count]) => {
|
|
@@ -908,13 +921,13 @@ function processRepeatedExpressions(context, expressions, varDeclarations, updat
|
|
|
908
921
|
for (let i = varDeclarations.length - 1; i >= 0; i--) {
|
|
909
922
|
const item = varDeclarations[i];
|
|
910
923
|
if (!item.exps || !item.seenCount) continue;
|
|
911
|
-
if ([...item.exps].every((node) => node.content === content && item.seenCount === count)) {
|
|
924
|
+
if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) {
|
|
912
925
|
delVars[item.name] = item.rawName;
|
|
913
926
|
reservedNames.delete(item.name);
|
|
914
927
|
varDeclarations.splice(i, 1);
|
|
915
928
|
}
|
|
916
929
|
}
|
|
917
|
-
const value = (0, _vue_shared.extend)({}, expressions.find((exp) => exp.content === content));
|
|
930
|
+
const value = (0, _vue_shared.extend)({}, getProcessedExpression(expressions.find((exp) => getProcessedExpression(exp, expressionReplacements).content === content), expressionReplacements));
|
|
918
931
|
Object.keys(delVars).forEach((name) => {
|
|
919
932
|
value.content = value.content.replace(name, delVars[name]);
|
|
920
933
|
if (value.ast) value.ast = parseExp(context, value.content);
|
|
@@ -925,12 +938,11 @@ function processRepeatedExpressions(context, expressions, varDeclarations, updat
|
|
|
925
938
|
value
|
|
926
939
|
});
|
|
927
940
|
expressions.forEach((exp) => {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
exp.ast = parseExp(context, exp.content);
|
|
941
|
+
const processed = getProcessedExpression(exp, expressionReplacements);
|
|
942
|
+
if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null);
|
|
943
|
+
else if (processed.content.includes(content)) {
|
|
944
|
+
const replacedContent = processed.content.replace(new RegExp(escapeRegExp(content), "g"), varName);
|
|
945
|
+
setExpressionReplacement(expressionReplacements, exp, replacedContent, parseExp(context, replacedContent));
|
|
934
946
|
}
|
|
935
947
|
});
|
|
936
948
|
}
|
|
@@ -1009,22 +1021,31 @@ const isMemberExpression$3 = (node) => {
|
|
|
1009
1021
|
function genSetEvent(oper, context) {
|
|
1010
1022
|
const { helper } = context;
|
|
1011
1023
|
const { element, key, keyOverride, value, modifiers, delegate, effect } = oper;
|
|
1012
|
-
|
|
1013
|
-
const handler = [
|
|
1014
|
-
`${context.helper("createInvoker")}(`,
|
|
1015
|
-
...genEventHandler(context, [value], modifiers),
|
|
1016
|
-
`)`
|
|
1017
|
-
];
|
|
1018
|
-
const eventOptions = genEventOptions();
|
|
1024
|
+
let handler;
|
|
1019
1025
|
if (delegate) {
|
|
1020
1026
|
context.delegates.add(key.content);
|
|
1021
1027
|
if (!context.block.operation.some(isSameDelegateEvent)) return [
|
|
1022
1028
|
NEWLINE,
|
|
1023
1029
|
`n${element}.$evt${key.content} = `,
|
|
1024
|
-
...
|
|
1030
|
+
...genDirectHandler()
|
|
1031
|
+
];
|
|
1032
|
+
}
|
|
1033
|
+
const name = genName();
|
|
1034
|
+
const eventOptions = genEventOptions();
|
|
1035
|
+
return [NEWLINE, ...genCall(helper(effect ? "onBinding" : delegate ? "delegate" : "on"), `n${element}`, name, genHandler(), eventOptions)];
|
|
1036
|
+
function genHandler() {
|
|
1037
|
+
return handler || (handler = genEventHandler(context, [value], modifiers));
|
|
1038
|
+
}
|
|
1039
|
+
function genInvoker() {
|
|
1040
|
+
return [
|
|
1041
|
+
`${helper("createInvoker")}(`,
|
|
1042
|
+
...genHandler(),
|
|
1043
|
+
`)`
|
|
1025
1044
|
];
|
|
1026
1045
|
}
|
|
1027
|
-
|
|
1046
|
+
function genDirectHandler() {
|
|
1047
|
+
return modifiers.keys.length || modifiers.nonKeys.length ? genEventHandler(context, [value], modifiers, { modifierHelper: "vapor" }) : genInvoker();
|
|
1048
|
+
}
|
|
1028
1049
|
function genName() {
|
|
1029
1050
|
const expr = genExpression(key, context);
|
|
1030
1051
|
if (keyOverride) {
|
|
@@ -1044,8 +1065,8 @@ function genSetEvent(oper, context) {
|
|
|
1044
1065
|
}
|
|
1045
1066
|
function genEventOptions() {
|
|
1046
1067
|
let { options } = modifiers;
|
|
1047
|
-
if (!options.length
|
|
1048
|
-
return genMulti(DELIMITERS_OBJECT_NEWLINE,
|
|
1068
|
+
if (!options.length) return;
|
|
1069
|
+
return genMulti(DELIMITERS_OBJECT_NEWLINE, ...options.map((option) => [`${option}: true`]));
|
|
1049
1070
|
}
|
|
1050
1071
|
function isSameDelegateEvent(op) {
|
|
1051
1072
|
if (op.type === 6 && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true;
|
|
@@ -1058,7 +1079,9 @@ function genSetDynamicEvents(oper, context) {
|
|
|
1058
1079
|
function genEventHandler(context, values, modifiers = {
|
|
1059
1080
|
nonKeys: [],
|
|
1060
1081
|
keys: []
|
|
1061
|
-
},
|
|
1082
|
+
}, options = {}) {
|
|
1083
|
+
const { asComponentProp = false, extraWrap = false, modifierHelper = "runtime" } = options;
|
|
1084
|
+
const useVaporModifierHelper = modifierHelper === "vapor";
|
|
1062
1085
|
let handlerExp = [];
|
|
1063
1086
|
if (values) {
|
|
1064
1087
|
values.forEach((value, index) => {
|
|
@@ -1099,16 +1122,16 @@ function genEventHandler(context, values, modifiers = {
|
|
|
1099
1122
|
}
|
|
1100
1123
|
if (handlerExp.length === 0) handlerExp = ["() => {}"];
|
|
1101
1124
|
const { keys, nonKeys } = modifiers;
|
|
1102
|
-
if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys);
|
|
1103
|
-
if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys);
|
|
1125
|
+
if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys, useVaporModifierHelper && !keys.length);
|
|
1126
|
+
if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys, useVaporModifierHelper);
|
|
1104
1127
|
if (extraWrap) handlerExp.unshift(`() => `);
|
|
1105
1128
|
return handlerExp;
|
|
1106
1129
|
}
|
|
1107
|
-
function genWithModifiers(context, handler, nonKeys) {
|
|
1108
|
-
return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys));
|
|
1130
|
+
function genWithModifiers(context, handler, nonKeys, useVaporHelper = false) {
|
|
1131
|
+
return genCall(context.helper(useVaporHelper ? "withVaporModifiers" : "withModifiers"), handler, JSON.stringify(nonKeys));
|
|
1109
1132
|
}
|
|
1110
|
-
function genWithKeys(context, handler, keys) {
|
|
1111
|
-
return genCall(context.helper("withKeys"), handler, JSON.stringify(keys));
|
|
1133
|
+
function genWithKeys(context, handler, keys, useVaporHelper = false) {
|
|
1134
|
+
return genCall(context.helper(useVaporHelper ? "withVaporKeys" : "withKeys"), handler, JSON.stringify(keys));
|
|
1112
1135
|
}
|
|
1113
1136
|
function isConstantBinding(value, context) {
|
|
1114
1137
|
if (value.ast === null) {
|
|
@@ -1119,7 +1142,7 @@ function isConstantBinding(value, context) {
|
|
|
1119
1142
|
//#region packages/compiler-vapor/src/generators/for.ts
|
|
1120
1143
|
function genFor(oper, context) {
|
|
1121
1144
|
const { helper } = context;
|
|
1122
|
-
const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper;
|
|
1145
|
+
const { source, value, key, index, render, keyProp, once, id, component, onlyChild, slotRoot } = oper;
|
|
1123
1146
|
const rawValue = value && value.content;
|
|
1124
1147
|
const rawKey = key && key.content;
|
|
1125
1148
|
const rawIndex = index && index.content;
|
|
@@ -1175,7 +1198,10 @@ function genFor(oper, context) {
|
|
|
1175
1198
|
let flags = 0;
|
|
1176
1199
|
if (onlyChild) flags |= 1;
|
|
1177
1200
|
if (component) flags |= 2;
|
|
1201
|
+
if (isFragmentBlock(render)) flags |= 16;
|
|
1202
|
+
if (!component && isSingleNodeBlock(render)) flags |= 8;
|
|
1178
1203
|
if (once) flags |= 4;
|
|
1204
|
+
if (slotRoot) flags |= 32;
|
|
1179
1205
|
const onResetCalls = [];
|
|
1180
1206
|
for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`);
|
|
1181
1207
|
return [
|
|
@@ -1207,6 +1233,21 @@ function genFor(oper, context) {
|
|
|
1207
1233
|
return idMap;
|
|
1208
1234
|
}
|
|
1209
1235
|
}
|
|
1236
|
+
function isSingleNodeBlock(block) {
|
|
1237
|
+
const child = getSingleReturnedChild(block);
|
|
1238
|
+
return !!child && child.template != null;
|
|
1239
|
+
}
|
|
1240
|
+
function isFragmentBlock(block) {
|
|
1241
|
+
const child = getSingleReturnedChild(block);
|
|
1242
|
+
const operation = child && child.operation;
|
|
1243
|
+
if (!operation) return false;
|
|
1244
|
+
return operation.type === 13 || operation.type === 16 || operation.type === 17 || operation.type === 15 && !operation.once || operation.type === 12 && !!operation.dynamic && !operation.dynamic.isStatic;
|
|
1245
|
+
}
|
|
1246
|
+
function getSingleReturnedChild(block) {
|
|
1247
|
+
if (block.returns.length !== 1) return;
|
|
1248
|
+
const id = block.returns[0];
|
|
1249
|
+
for (const child of block.dynamic.children) if (child.id === id) return child;
|
|
1250
|
+
}
|
|
1210
1251
|
function parseValueDestructure(value, context) {
|
|
1211
1252
|
const map = /* @__PURE__ */ new Map();
|
|
1212
1253
|
if (value) {
|
|
@@ -1242,7 +1283,7 @@ function parseValueDestructure(value, context) {
|
|
|
1242
1283
|
if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
|
|
1243
1284
|
isDynamic = true;
|
|
1244
1285
|
helper = context.helper("getDefaultValue");
|
|
1245
|
-
helperArgs = rawValue.slice(child.right.start - 1, child.right.end - 1)
|
|
1286
|
+
helperArgs = `() => (${rawValue.slice(child.right.start - 1, child.right.end - 1)})`;
|
|
1246
1287
|
}
|
|
1247
1288
|
}
|
|
1248
1289
|
map.set(id.name, {
|
|
@@ -1390,8 +1431,9 @@ function genSetHtml(oper, context) {
|
|
|
1390
1431
|
//#region packages/compiler-vapor/src/generators/if.ts
|
|
1391
1432
|
function genIf(oper, context, isNested = false) {
|
|
1392
1433
|
const { helper } = context;
|
|
1393
|
-
const { condition, positive, negative, once, index, blockShape } = oper;
|
|
1434
|
+
const { condition, positive, negative, once, slotRoot, index, blockShape } = oper;
|
|
1394
1435
|
const [frag, push] = buildCodeFragment();
|
|
1436
|
+
const flags = genIfFlags(blockShape, once, slotRoot, negative ? index : void 0);
|
|
1395
1437
|
const conditionExpr = [
|
|
1396
1438
|
"() => (",
|
|
1397
1439
|
...genExpression(condition, context),
|
|
@@ -1402,9 +1444,26 @@ function genIf(oper, context, isNested = false) {
|
|
|
1402
1444
|
if (negative) if (negative.type === 1) negativeArg = genBlock(negative, context);
|
|
1403
1445
|
else negativeArg = ["() => ", ...genIf(negative, context, true)];
|
|
1404
1446
|
if (!isNested) push(NEWLINE, `const n${oper.id} = `);
|
|
1405
|
-
push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg,
|
|
1447
|
+
push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, flags));
|
|
1406
1448
|
return frag;
|
|
1407
1449
|
}
|
|
1450
|
+
function genIfFlags(blockShape, once, slotRoot, index) {
|
|
1451
|
+
let flags = blockShape;
|
|
1452
|
+
if (slotRoot) flags |= 128;
|
|
1453
|
+
if (once) flags |= 16;
|
|
1454
|
+
else if (index !== void 0) flags |= index + 1 << 8;
|
|
1455
|
+
if (flags === 1) return false;
|
|
1456
|
+
return `${flags} /* ${genIfFlagNames(once, slotRoot, index, blockShape)} */`;
|
|
1457
|
+
}
|
|
1458
|
+
function genIfFlagNames(once, slotRoot, index, blockShape) {
|
|
1459
|
+
const names = ["BLOCK_SHAPE"];
|
|
1460
|
+
if (blockShape & 32) names.push("TRUE_NO_SCOPE");
|
|
1461
|
+
if (blockShape & 64) names.push("FALSE_NO_SCOPE");
|
|
1462
|
+
if (once) names.push("ONCE");
|
|
1463
|
+
if (slotRoot) names.push("SLOT_ROOT");
|
|
1464
|
+
if (!once && index !== void 0) names.push("INDEX_SHIFT");
|
|
1465
|
+
return names.join(", ");
|
|
1466
|
+
}
|
|
1408
1467
|
//#endregion
|
|
1409
1468
|
//#region packages/compiler-vapor/src/generators/prop.ts
|
|
1410
1469
|
const helpers = {
|
|
@@ -1454,15 +1513,16 @@ function resolveClassName(values, context) {
|
|
|
1454
1513
|
const entries = [];
|
|
1455
1514
|
let sawDynamic = false;
|
|
1456
1515
|
let sawSuffix = false;
|
|
1457
|
-
for (const
|
|
1516
|
+
for (const rawValue of values) {
|
|
1517
|
+
const value = context.getExpressionReplacement(rawValue);
|
|
1458
1518
|
const staticValue = getLiteralExpressionValue(value, true);
|
|
1459
1519
|
if (staticValue != null) {
|
|
1460
1520
|
const normalized = (0, _vue_shared.normalizeClass)(staticValue);
|
|
1461
|
-
if (normalized) if (sawSuffix) suffix = appendClass(suffix, normalized);
|
|
1521
|
+
if (normalized) if (sawSuffix) suffix = appendClass$1(suffix, normalized);
|
|
1462
1522
|
else if (sawDynamic) {
|
|
1463
1523
|
sawSuffix = true;
|
|
1464
|
-
suffix = appendClass(suffix, normalized);
|
|
1465
|
-
} else prefix = appendClass(prefix, normalized);
|
|
1524
|
+
suffix = appendClass$1(suffix, normalized);
|
|
1525
|
+
} else prefix = appendClass$1(prefix, normalized);
|
|
1466
1526
|
continue;
|
|
1467
1527
|
}
|
|
1468
1528
|
const ast = value.ast;
|
|
@@ -1483,7 +1543,7 @@ function resolveClassName(values, context) {
|
|
|
1483
1543
|
function resolveObjectClassName(source, ast, entries, context) {
|
|
1484
1544
|
for (const prop of ast.properties) {
|
|
1485
1545
|
if (prop.type !== "ObjectProperty" || prop.computed) return false;
|
|
1486
|
-
const rawClassName = getObjectPropertyName(prop);
|
|
1546
|
+
const rawClassName = getObjectPropertyName$1(prop);
|
|
1487
1547
|
if (rawClassName == null) return false;
|
|
1488
1548
|
const className = (0, _vue_shared.normalizeClass)(rawClassName);
|
|
1489
1549
|
if (!className) continue;
|
|
@@ -1528,10 +1588,10 @@ function genClassFlags(entries, context) {
|
|
|
1528
1588
|
});
|
|
1529
1589
|
return values;
|
|
1530
1590
|
}
|
|
1531
|
-
function appendClass(base, value) {
|
|
1591
|
+
function appendClass$1(base, value) {
|
|
1532
1592
|
return base ? value ? `${base} ${value}` : base : value;
|
|
1533
1593
|
}
|
|
1534
|
-
function getObjectPropertyName(prop) {
|
|
1594
|
+
function getObjectPropertyName$1(prop) {
|
|
1535
1595
|
const key = prop.key;
|
|
1536
1596
|
if (key.type === "Identifier") return key.name;
|
|
1537
1597
|
else if (key.type === "StringLiteral") return key.value;
|
|
@@ -1623,8 +1683,23 @@ function getSpecialHelper(keyName, tagName, isSVG) {
|
|
|
1623
1683
|
const setTemplateRefIdent = `_setTemplateRef`;
|
|
1624
1684
|
function genSetTemplateRef(oper, context) {
|
|
1625
1685
|
const [refValue, refKey] = genRefValue(oper.value, context);
|
|
1686
|
+
if (context.staticTemplateRefHelperCandidate === oper) return genSetStaticTemplateRef(oper, refValue, refKey, context);
|
|
1687
|
+
context.needsTemplateRefSetter = true;
|
|
1626
1688
|
return [NEWLINE, ...genCall(setTemplateRefIdent, `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
|
|
1627
1689
|
}
|
|
1690
|
+
function genSetStaticTemplateRef(oper, refValue, refKey, context) {
|
|
1691
|
+
return [NEWLINE, ...genCall(context.helper("setStaticTemplateRef"), `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
|
|
1692
|
+
}
|
|
1693
|
+
function genSetTemplateRefBinding(oper, context) {
|
|
1694
|
+
const [refValue, refKey] = genRefValue(oper.value, context);
|
|
1695
|
+
const setter = context.inSlotBlock && setTemplateRefIdent;
|
|
1696
|
+
if (context.inSlotBlock) context.needsTemplateRefSetter = true;
|
|
1697
|
+
return [NEWLINE, ...genCall([context.helper("setTemplateRefBinding"), "undefined"], `n${oper.element}`, ["() => ", ...refValue], ...setter || oper.refFor || refKey ? [
|
|
1698
|
+
setter,
|
|
1699
|
+
oper.refFor && "true",
|
|
1700
|
+
refKey
|
|
1701
|
+
] : [])];
|
|
1702
|
+
}
|
|
1628
1703
|
function genRefValue(value, context) {
|
|
1629
1704
|
if (value && context.options.inline) {
|
|
1630
1705
|
const binding = context.options.bindingMetadata[value.content];
|
|
@@ -1728,15 +1803,20 @@ function filterCustomDirectives(id, operations) {
|
|
|
1728
1803
|
//#region packages/compiler-vapor/src/generators/component.ts
|
|
1729
1804
|
function genCreateComponent(operation, context) {
|
|
1730
1805
|
const { helper } = context;
|
|
1806
|
+
const singleUseAssetComponentNames = context.singleUseAssetComponentNames;
|
|
1807
|
+
const useAssetComponentHelper = operation.asset && !operation.dynamic && context.block === context.ir.block && !!singleUseAssetComponentNames && singleUseAssetComponentNames.has(operation.tag);
|
|
1808
|
+
const maybeSelfReference = useAssetComponentHelper && operation.tag.endsWith("__self");
|
|
1731
1809
|
const tag = genTag();
|
|
1732
|
-
const { root, props, slots, once } = operation;
|
|
1810
|
+
const { root, props, slots, once, slotRoot } = operation;
|
|
1811
|
+
const isRuntimeDynamicComponent = !!(operation.dynamic && !operation.dynamic.isStatic);
|
|
1812
|
+
const dynamicComponentFlags = isRuntimeDynamicComponent ? (root ? 1 : 0) | (once ? 2 : 0) | (slotRoot ? 4 : 0) : 0;
|
|
1733
1813
|
const rawSlots = genRawSlots(slots, context);
|
|
1734
1814
|
const [ids, handlers] = processInlineHandlers(props, context);
|
|
1735
|
-
const rawProps = context.withId(() => genRawProps(props, context), ids);
|
|
1815
|
+
const rawProps = context.withId(() => genRawProps(props, context, true), ids);
|
|
1736
1816
|
return [
|
|
1737
1817
|
NEWLINE,
|
|
1738
1818
|
...handlers.reduce((acc, { name, value }) => {
|
|
1739
|
-
const handler = genEventHandler(context, [value]
|
|
1819
|
+
const handler = genEventHandler(context, [value]);
|
|
1740
1820
|
return [
|
|
1741
1821
|
...acc,
|
|
1742
1822
|
`const ${name} = `,
|
|
@@ -1745,7 +1825,7 @@ function genCreateComponent(operation, context) {
|
|
|
1745
1825
|
];
|
|
1746
1826
|
}, []),
|
|
1747
1827
|
`const n${operation.id} = `,
|
|
1748
|
-
...genCall(
|
|
1828
|
+
...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags ? String(dynamicComponentFlags) : false : root ? "true" : false, isRuntimeDynamicComponent ? false : once && "true", isRuntimeDynamicComponent ? false : maybeSelfReference && "true"),
|
|
1749
1829
|
...genDirectivesForElement(operation.id, context)
|
|
1750
1830
|
];
|
|
1751
1831
|
function genTag() {
|
|
@@ -1756,7 +1836,10 @@ function genCreateComponent(operation, context) {
|
|
|
1756
1836
|
...genExpression(operation.dynamic, context),
|
|
1757
1837
|
")"
|
|
1758
1838
|
];
|
|
1759
|
-
else if (
|
|
1839
|
+
else if (useAssetComponentHelper) {
|
|
1840
|
+
const name = maybeSelfReference ? operation.tag.slice(0, -6) : operation.tag;
|
|
1841
|
+
return JSON.stringify(name);
|
|
1842
|
+
} else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
|
|
1760
1843
|
else {
|
|
1761
1844
|
const { tag } = operation;
|
|
1762
1845
|
const builtInTag = isBuiltInComponent(tag);
|
|
@@ -1796,14 +1879,14 @@ function processInlineHandlers(props, context) {
|
|
|
1796
1879
|
}
|
|
1797
1880
|
return [ids, handlers];
|
|
1798
1881
|
}
|
|
1799
|
-
function genRawProps(props, context) {
|
|
1882
|
+
function genRawProps(props, context, directStaticLiteralProps = false) {
|
|
1800
1883
|
const staticProps = props[0];
|
|
1801
1884
|
if ((0, _vue_shared.isArray)(staticProps)) {
|
|
1802
1885
|
if (!staticProps.length && props.length === 1) return;
|
|
1803
|
-
return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context));
|
|
1804
|
-
} else if (props.length) return genStaticProps([], context, genDynamicProps(props, context));
|
|
1886
|
+
return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context, directStaticLiteralProps), directStaticLiteralProps);
|
|
1887
|
+
} else if (props.length) return genStaticProps([], context, genDynamicProps(props, context, directStaticLiteralProps), directStaticLiteralProps);
|
|
1805
1888
|
}
|
|
1806
|
-
function genStaticProps(props, context, dynamicProps) {
|
|
1889
|
+
function genStaticProps(props, context, dynamicProps, directStaticLiteralProps = false) {
|
|
1807
1890
|
const args = [];
|
|
1808
1891
|
const handlerGroups = /* @__PURE__ */ new Map();
|
|
1809
1892
|
const ensureHandlerGroup = (keyName, keyFrag) => {
|
|
@@ -1836,11 +1919,11 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1836
1919
|
continue;
|
|
1837
1920
|
}
|
|
1838
1921
|
const keyFrag = genPropKey(prop, context);
|
|
1839
|
-
if (!!prop.handlerModifiers && (prop.handlerModifiers.keys.length > 0 || prop.handlerModifiers.nonKeys.length > 0) || prop.values.length <= 1) addHandler(keyName, keyFrag, genEventHandler(context, prop.values, prop.handlerModifiers, true
|
|
1840
|
-
else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, true
|
|
1922
|
+
if (!!prop.handlerModifiers && (prop.handlerModifiers.keys.length > 0 || prop.handlerModifiers.nonKeys.length > 0) || prop.values.length <= 1) addHandler(keyName, keyFrag, genEventHandler(context, prop.values, prop.handlerModifiers, { asComponentProp: true }));
|
|
1923
|
+
else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, { asComponentProp: true }));
|
|
1841
1924
|
continue;
|
|
1842
1925
|
}
|
|
1843
|
-
args.push(genProp(prop, context, true));
|
|
1926
|
+
args.push(genProp(prop, context, true, true, directStaticLiteralProps && isDirectStaticLiteralProp(prop, context)));
|
|
1844
1927
|
if (prop.model) {
|
|
1845
1928
|
if (prop.key.isStatic) {
|
|
1846
1929
|
const keyName = `onUpdate:${(0, _vue_shared.camelize)(prop.key.content)}`;
|
|
@@ -1865,7 +1948,7 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1865
1948
|
" + \"Modifiers\"]"
|
|
1866
1949
|
];
|
|
1867
1950
|
const modifiersVal = genDirectiveModifiers(modelModifiers);
|
|
1868
|
-
args.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
|
|
1951
|
+
args.push([...modifiersKey, directStaticLiteralProps ? `: { ${modifiersVal} }` : `: () => ({ ${modifiersVal} })`]);
|
|
1869
1952
|
}
|
|
1870
1953
|
}
|
|
1871
1954
|
}
|
|
@@ -1880,13 +1963,13 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1880
1963
|
if (dynamicProps) args.push([`$: `, ...dynamicProps]);
|
|
1881
1964
|
return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args);
|
|
1882
1965
|
}
|
|
1883
|
-
function genDynamicProps(props, context) {
|
|
1966
|
+
function genDynamicProps(props, context, directStaticLiteralProps = false) {
|
|
1884
1967
|
const { helper } = context;
|
|
1885
1968
|
const frags = [];
|
|
1886
1969
|
for (const p of props) {
|
|
1887
1970
|
let expr;
|
|
1888
1971
|
if ((0, _vue_shared.isArray)(p)) {
|
|
1889
|
-
if (p.length) frags.push(genStaticProps(p, context));
|
|
1972
|
+
if (p.length) frags.push(genStaticProps(p, context, void 0, directStaticLiteralProps));
|
|
1890
1973
|
continue;
|
|
1891
1974
|
} else if (p.kind === 1) if (p.model) {
|
|
1892
1975
|
const entries = [genProp(p, context)];
|
|
@@ -1897,7 +1980,7 @@ function genDynamicProps(props, context) {
|
|
|
1897
1980
|
];
|
|
1898
1981
|
entries.push([
|
|
1899
1982
|
...updateKey,
|
|
1900
|
-
":
|
|
1983
|
+
": ",
|
|
1901
1984
|
...genModelHandler(p.values[0], context)
|
|
1902
1985
|
]);
|
|
1903
1986
|
const { modelModifiers } = p;
|
|
@@ -1908,10 +1991,10 @@ function genDynamicProps(props, context) {
|
|
|
1908
1991
|
" + \"Modifiers\"]"
|
|
1909
1992
|
];
|
|
1910
1993
|
const modifiersVal = genDirectiveModifiers(modelModifiers);
|
|
1911
|
-
entries.push([...modifiersKey, `:
|
|
1994
|
+
entries.push([...modifiersKey, `: { ${modifiersVal} }`]);
|
|
1912
1995
|
}
|
|
1913
1996
|
expr = genMulti(DELIMITERS_OBJECT_NEWLINE, ...entries);
|
|
1914
|
-
} else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context));
|
|
1997
|
+
} else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context, false, false));
|
|
1915
1998
|
else {
|
|
1916
1999
|
expr = genExpression(p.value, context);
|
|
1917
2000
|
if (p.handler) expr = genCall(helper("toHandlers"), expr);
|
|
@@ -1924,27 +2007,79 @@ function genDynamicProps(props, context) {
|
|
|
1924
2007
|
}
|
|
1925
2008
|
if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags);
|
|
1926
2009
|
}
|
|
1927
|
-
function genProp(prop, context, isStatic) {
|
|
2010
|
+
function genProp(prop, context, isStatic, wrapHandler = true, directStaticLiteral = false) {
|
|
1928
2011
|
const values = genPropValue(prop.values, context);
|
|
1929
2012
|
return [
|
|
1930
2013
|
...genPropKey(prop, context),
|
|
1931
2014
|
": ",
|
|
1932
|
-
...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers,
|
|
2015
|
+
...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, {
|
|
2016
|
+
asComponentProp: true,
|
|
2017
|
+
extraWrap: wrapHandler
|
|
2018
|
+
}) : isStatic ? directStaticLiteral ? values : [
|
|
1933
2019
|
"() => (",
|
|
1934
2020
|
...values,
|
|
1935
2021
|
")"
|
|
1936
2022
|
] : values
|
|
1937
2023
|
];
|
|
1938
2024
|
}
|
|
2025
|
+
/**
|
|
2026
|
+
* Static literal values are safe to emit directly because reading them cannot
|
|
2027
|
+
* touch reactive state. Keep handlers, v-model values, and dynamic expressions
|
|
2028
|
+
* as getter sources to preserve lazy access and merge semantics.
|
|
2029
|
+
*/
|
|
2030
|
+
function isDirectStaticLiteralProp(prop, context) {
|
|
2031
|
+
return prop.key.isStatic && prop.values.length === 1 && !prop.handler && !prop.model && isDirectConstantValue(prop.values[0], context);
|
|
2032
|
+
}
|
|
2033
|
+
function isDirectConstantValue(value, context) {
|
|
2034
|
+
value = context.getExpressionReplacement(value);
|
|
2035
|
+
if (value.isStatic) return true;
|
|
2036
|
+
const ast = value.ast;
|
|
2037
|
+
if (ast === null) return value.content === "true" || value.content === "false" || value.content === "null" || value.content === "undefined";
|
|
2038
|
+
if (!ast) return false;
|
|
2039
|
+
return isDirectConstantAst(ast);
|
|
2040
|
+
}
|
|
2041
|
+
function isDirectConstantAst(node) {
|
|
2042
|
+
switch (node.type) {
|
|
2043
|
+
case "StringLiteral":
|
|
2044
|
+
case "NumericLiteral":
|
|
2045
|
+
case "BooleanLiteral":
|
|
2046
|
+
case "NullLiteral":
|
|
2047
|
+
case "BigIntLiteral": return true;
|
|
2048
|
+
case "Identifier": return node.name === "undefined";
|
|
2049
|
+
case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
|
|
2050
|
+
case "ArrayExpression": return node.elements.every((element) => element === null || element.type !== "SpreadElement" && isDirectConstantAst(element));
|
|
2051
|
+
case "ObjectExpression": return node.properties.every((prop) => prop.type === "ObjectProperty" && !prop.computed && isDirectConstantAst(prop.value));
|
|
2052
|
+
}
|
|
2053
|
+
return false;
|
|
2054
|
+
}
|
|
2055
|
+
function isDirectTemplateConstantAst(node) {
|
|
2056
|
+
switch (node.type) {
|
|
2057
|
+
case "StringLiteral":
|
|
2058
|
+
case "NumericLiteral":
|
|
2059
|
+
case "BooleanLiteral":
|
|
2060
|
+
case "NullLiteral":
|
|
2061
|
+
case "BigIntLiteral": return true;
|
|
2062
|
+
case "Identifier": return node.name === "undefined";
|
|
2063
|
+
case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
|
|
2064
|
+
}
|
|
2065
|
+
return false;
|
|
2066
|
+
}
|
|
1939
2067
|
function genRawSlots(slots, context) {
|
|
1940
2068
|
if (!slots.length) return;
|
|
1941
2069
|
const staticSlots = slots[0];
|
|
1942
|
-
if (staticSlots.slotType === 0)
|
|
1943
|
-
|
|
2070
|
+
if (staticSlots.slotType === 0) {
|
|
2071
|
+
const defaultSlot = getSingleDefaultSlot(staticSlots);
|
|
2072
|
+
if (defaultSlot && slots.length === 1) return genSlotBlockWithProps(defaultSlot, context);
|
|
2073
|
+
return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
|
|
2074
|
+
} else return genStaticSlots({
|
|
1944
2075
|
slotType: 0,
|
|
1945
2076
|
slots: {}
|
|
1946
2077
|
}, context, slots);
|
|
1947
2078
|
}
|
|
2079
|
+
function getSingleDefaultSlot({ slots }) {
|
|
2080
|
+
const names = Object.keys(slots);
|
|
2081
|
+
return names.length === 1 && names[0] === "default" ? slots.default : void 0;
|
|
2082
|
+
}
|
|
1948
2083
|
function genStaticSlots({ slots }, context, dynamicSlots) {
|
|
1949
2084
|
const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]);
|
|
1950
2085
|
if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]);
|
|
@@ -1967,23 +2102,12 @@ function genDynamicSlot(slot, context, withFunction = false) {
|
|
|
1967
2102
|
break;
|
|
1968
2103
|
}
|
|
1969
2104
|
if (!withFunction) return frag;
|
|
1970
|
-
return
|
|
1971
|
-
`${context.helper("withVaporCtx")}(() => (`,
|
|
1972
|
-
...frag,
|
|
1973
|
-
"))"
|
|
1974
|
-
] : [
|
|
2105
|
+
return [
|
|
1975
2106
|
"() => (",
|
|
1976
2107
|
...frag,
|
|
1977
2108
|
")"
|
|
1978
2109
|
];
|
|
1979
2110
|
}
|
|
1980
|
-
function needsDynamicSlotSourceCtx(slot) {
|
|
1981
|
-
switch (slot.slotType) {
|
|
1982
|
-
case 1: return needsVaporCtx(slot.fn);
|
|
1983
|
-
case 2: return needsVaporCtx(slot.fn);
|
|
1984
|
-
case 3: return needsDynamicSlotSourceCtx(slot.positive) || (slot.negative ? needsDynamicSlotSourceCtx(slot.negative) : false);
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
2111
|
function genBasicDynamicSlot(slot, context) {
|
|
1988
2112
|
const { name, fn } = slot;
|
|
1989
2113
|
return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]);
|
|
@@ -2028,7 +2152,7 @@ function genSlotBlockWithProps(oper, context) {
|
|
|
2028
2152
|
let propsName;
|
|
2029
2153
|
let exitScope;
|
|
2030
2154
|
let depth;
|
|
2031
|
-
const { props
|
|
2155
|
+
const { props } = oper;
|
|
2032
2156
|
const idToPathMap = props ? parseValueDestructure(props, context) : /* @__PURE__ */ new Map();
|
|
2033
2157
|
if (props) if (props.ast) {
|
|
2034
2158
|
[depth, exitScope] = context.enterScope();
|
|
@@ -2036,77 +2160,32 @@ function genSlotBlockWithProps(oper, context) {
|
|
|
2036
2160
|
} else propsName = props.content;
|
|
2037
2161
|
const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {};
|
|
2038
2162
|
if (propsName) idMap[propsName] = null;
|
|
2163
|
+
const exitSlotBlock = context.enterSlotBlock();
|
|
2164
|
+
markSlotRootOperations(oper);
|
|
2039
2165
|
let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap);
|
|
2166
|
+
exitSlotBlock();
|
|
2040
2167
|
exitScope && exitScope();
|
|
2041
|
-
if (node.type === 1) {
|
|
2042
|
-
if (needsVaporCtx(oper)) blockFn = [
|
|
2043
|
-
`${context.helper("withVaporCtx")}(`,
|
|
2044
|
-
...blockFn,
|
|
2045
|
-
`)`
|
|
2046
|
-
];
|
|
2047
|
-
}
|
|
2048
2168
|
return blockFn;
|
|
2049
2169
|
}
|
|
2050
|
-
/**
|
|
2051
|
-
* Check if a slot block needs withVaporCtx wrapper.
|
|
2052
|
-
* Returns true if the block contains:
|
|
2053
|
-
* - Component creation (needs scopeId inheritance)
|
|
2054
|
-
* - Slot outlet (needs rawSlots from slot owner)
|
|
2055
|
-
*/
|
|
2056
|
-
function needsVaporCtx(block) {
|
|
2057
|
-
return hasComponentOrSlotInBlock(block);
|
|
2058
|
-
}
|
|
2059
|
-
function hasComponentOrSlotInBlock(block) {
|
|
2060
|
-
if (hasComponentOrSlotInOperations(block.operation)) return true;
|
|
2061
|
-
return hasComponentOrSlotInDynamic(block.dynamic);
|
|
2062
|
-
}
|
|
2063
|
-
function hasComponentOrSlotInDynamic(dynamic) {
|
|
2064
|
-
if (dynamic.operation) {
|
|
2065
|
-
const type = dynamic.operation.type;
|
|
2066
|
-
if (type === 12 || type === 13) return true;
|
|
2067
|
-
if (type === 15) {
|
|
2068
|
-
if (hasComponentOrSlotInIf(dynamic.operation)) return true;
|
|
2069
|
-
}
|
|
2070
|
-
if (type === 16) {
|
|
2071
|
-
if (hasComponentOrSlotInBlock(dynamic.operation.render)) return true;
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
for (const child of dynamic.children) if (hasComponentOrSlotInDynamic(child)) return true;
|
|
2075
|
-
return false;
|
|
2076
|
-
}
|
|
2077
|
-
function hasComponentOrSlotInOperations(operations) {
|
|
2078
|
-
for (const op of operations) switch (op.type) {
|
|
2079
|
-
case 12:
|
|
2080
|
-
case 13: return true;
|
|
2081
|
-
case 15:
|
|
2082
|
-
if (hasComponentOrSlotInIf(op)) return true;
|
|
2083
|
-
break;
|
|
2084
|
-
case 16:
|
|
2085
|
-
if (hasComponentOrSlotInBlock(op.render)) return true;
|
|
2086
|
-
break;
|
|
2087
|
-
}
|
|
2088
|
-
return false;
|
|
2089
|
-
}
|
|
2090
|
-
function hasComponentOrSlotInIf(node) {
|
|
2091
|
-
if (hasComponentOrSlotInBlock(node.positive)) return true;
|
|
2092
|
-
if (node.negative) if ("positive" in node.negative) return hasComponentOrSlotInIf(node.negative);
|
|
2093
|
-
else return hasComponentOrSlotInBlock(node.negative);
|
|
2094
|
-
return false;
|
|
2095
|
-
}
|
|
2096
2170
|
//#endregion
|
|
2097
2171
|
//#region packages/compiler-vapor/src/generators/slotOutlet.ts
|
|
2098
2172
|
function genSlotOutlet(oper, context) {
|
|
2099
2173
|
const { helper } = context;
|
|
2100
|
-
const { id, name, fallback,
|
|
2174
|
+
const { id, name, fallback, flags } = oper;
|
|
2101
2175
|
const [frag, push] = buildCodeFragment();
|
|
2102
|
-
|
|
2176
|
+
let fallbackArg;
|
|
2177
|
+
if (fallback) {
|
|
2178
|
+
markSlotRootOperations(fallback);
|
|
2179
|
+
fallbackArg = genBlock(fallback, context);
|
|
2180
|
+
}
|
|
2181
|
+
const createSlot = helper("createSlot");
|
|
2182
|
+
const rawPropsArg = genRawProps(oper.props, context, true);
|
|
2183
|
+
const nameArg = name.isStatic && name.content === "default" && !rawPropsArg && !fallbackArg && !flags ? void 0 : name.isStatic ? genExpression(name, context) : [
|
|
2103
2184
|
"() => (",
|
|
2104
2185
|
...genExpression(name, context),
|
|
2105
2186
|
")"
|
|
2106
2187
|
];
|
|
2107
|
-
|
|
2108
|
-
if (fallback) fallbackArg = genBlock(fallback, context);
|
|
2109
|
-
push(NEWLINE, `const n${id} = `, ...genCall(helper("createSlot"), nameExpr, genRawProps(oper.props, context) || "null", fallbackArg, noSlotted && "true", once && "true"));
|
|
2188
|
+
push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, flags ? String(flags) : void 0));
|
|
2110
2189
|
return frag;
|
|
2111
2190
|
}
|
|
2112
2191
|
//#endregion
|
|
@@ -2166,28 +2245,35 @@ function genEffects(effects, context, genExtraFrag) {
|
|
|
2166
2245
|
const [frag, push, unshift] = buildCodeFragment();
|
|
2167
2246
|
const shouldDeclare = genExtraFrag === void 0;
|
|
2168
2247
|
let operationsCount = 0;
|
|
2169
|
-
const { ids, frag: declarationFrags, varNames } = processExpressions(context, expressions, shouldDeclare);
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
const
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2248
|
+
const { ids, frag: declarationFrags, varNames, expressionReplacements } = processExpressions(context, expressions, shouldDeclare);
|
|
2249
|
+
if (shouldDeclare && !declarationFrags.length && !varNames.length) {
|
|
2250
|
+
const effect = effects.length === 1 ? effects[0] : void 0;
|
|
2251
|
+
const operation = effect && effect.operations.length === 1 ? effect.operations[0] : void 0;
|
|
2252
|
+
if (operation && operation.type === 9 && operation.effect && !operation.refFor) return context.withExpressionReplacements(expressionReplacements, () => context.withId(() => genSetTemplateRefBinding(operation, context), ids));
|
|
2253
|
+
}
|
|
2254
|
+
return context.withExpressionReplacements(expressionReplacements, () => {
|
|
2255
|
+
push(...declarationFrags);
|
|
2256
|
+
for (let i = 0; i < effects.length; i++) {
|
|
2257
|
+
const effect = effects[i];
|
|
2258
|
+
operationsCount += effect.operations.length;
|
|
2259
|
+
const frags = context.withId(() => genEffect(effect, context), ids);
|
|
2260
|
+
i > 0 && push(NEWLINE);
|
|
2261
|
+
if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
|
|
2262
|
+
push(...frags);
|
|
2263
|
+
}
|
|
2264
|
+
if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
|
|
2265
|
+
unshift(`{`, INDENT_START, NEWLINE);
|
|
2266
|
+
push(INDENT_END, NEWLINE, "}");
|
|
2267
|
+
if (!effects.length) unshift(NEWLINE);
|
|
2268
|
+
}
|
|
2269
|
+
if (effects.length) {
|
|
2270
|
+
unshift(NEWLINE, `${helper("renderEffect")}(() => `);
|
|
2271
|
+
push(`)`);
|
|
2272
|
+
}
|
|
2273
|
+
if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
|
|
2274
|
+
if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
|
|
2275
|
+
return frag;
|
|
2276
|
+
});
|
|
2191
2277
|
}
|
|
2192
2278
|
function genEffect({ operations }, context) {
|
|
2193
2279
|
const [frag, push] = buildCodeFragment();
|
|
@@ -2206,9 +2292,8 @@ function genTemplates(templates, context) {
|
|
|
2206
2292
|
const result = [];
|
|
2207
2293
|
templates.forEach(({ content, ns, root, static: isStatic }, i) => {
|
|
2208
2294
|
let args = JSON.stringify(content).replace(IMPORT_EXPR_RE, `" + $1 + "`);
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
if (isStatic || ns) args += `, ${isStatic ? "true" : "false"}`;
|
|
2295
|
+
const flags = (root ? 1 : 0) | (isStatic ? 2 : 0);
|
|
2296
|
+
if (flags || ns) args += `, ${flags}`;
|
|
2212
2297
|
if (ns) args += `, ${ns}`;
|
|
2213
2298
|
result.push(`const ${context.tName(i)} = ${context.helper("template")}(${args})\n`);
|
|
2214
2299
|
});
|
|
@@ -2226,10 +2311,13 @@ function genSelf(dynamic, context, flushBeforeDynamic) {
|
|
|
2226
2311
|
return frag;
|
|
2227
2312
|
}
|
|
2228
2313
|
function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flushBeforeDynamic) {
|
|
2229
|
-
const { helper } = context;
|
|
2230
2314
|
const [frag, push] = buildCodeFragment();
|
|
2231
2315
|
const { children } = dynamic;
|
|
2232
2316
|
let offset = 0;
|
|
2317
|
+
/**
|
|
2318
|
+
* `reusable` means the previous access target is a p* cursor that can be
|
|
2319
|
+
* reassigned by the next lookup. Referenced n* variables must stay stable.
|
|
2320
|
+
*/
|
|
2233
2321
|
let prev;
|
|
2234
2322
|
for (const [index, child] of children.entries()) {
|
|
2235
2323
|
if (child.flags & 2) offset--;
|
|
@@ -2246,27 +2334,118 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flush
|
|
|
2246
2334
|
}
|
|
2247
2335
|
const elementIndex = index + offset;
|
|
2248
2336
|
const logicalIndex = child.logicalIndex !== void 0 ? String(child.logicalIndex) : void 0;
|
|
2249
|
-
const
|
|
2250
|
-
|
|
2251
|
-
if (
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2337
|
+
const inlinePlaceholder = id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6);
|
|
2338
|
+
const accessPath = genAccessPath(context, from, child, elementIndex, logicalIndex, prev);
|
|
2339
|
+
if (inlinePlaceholder) {
|
|
2340
|
+
if (prev && prev[2]) {
|
|
2341
|
+
push(...genChildren(child, context, pushBlock, [
|
|
2342
|
+
"(",
|
|
2343
|
+
prev[0],
|
|
2344
|
+
" = ",
|
|
2345
|
+
...accessPath,
|
|
2346
|
+
")"
|
|
2347
|
+
], flushBeforeDynamic));
|
|
2348
|
+
prev = [
|
|
2349
|
+
prev[0],
|
|
2350
|
+
elementIndex,
|
|
2351
|
+
true
|
|
2352
|
+
];
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
if (!hasAdjacentFollowingAccessChild(children, index, elementIndex, offset)) {
|
|
2356
|
+
push(...genChildren(child, context, pushBlock, accessPath, flushBeforeDynamic));
|
|
2357
|
+
continue;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
let variable;
|
|
2361
|
+
if (id === void 0 && prev && prev[2]) {
|
|
2362
|
+
variable = prev[0];
|
|
2363
|
+
pushBlock(NEWLINE, `${variable} = `, ...accessPath);
|
|
2364
|
+
} else {
|
|
2365
|
+
variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
|
|
2366
|
+
pushBlock(NEWLINE, id === void 0 ? `let ${variable} = ` : `const ${variable} = `, ...accessPath);
|
|
2259
2367
|
}
|
|
2260
2368
|
if (id === child.anchor && !child.hasDynamicChild) {
|
|
2261
2369
|
flushBeforeDynamic && flushBeforeDynamic(child, push);
|
|
2262
2370
|
push(...genSelf(child, context, flushBeforeDynamic));
|
|
2263
2371
|
}
|
|
2264
2372
|
if (id !== void 0) push(...genDirectivesForElement(id, context));
|
|
2265
|
-
prev = [
|
|
2373
|
+
prev = [
|
|
2374
|
+
variable,
|
|
2375
|
+
elementIndex,
|
|
2376
|
+
id === void 0
|
|
2377
|
+
];
|
|
2266
2378
|
push(...genChildren(child, context, pushBlock, variable, flushBeforeDynamic));
|
|
2267
2379
|
}
|
|
2268
2380
|
return frag;
|
|
2269
2381
|
}
|
|
2382
|
+
/**
|
|
2383
|
+
* Build one DOM lookup path while preserving the fast sibling walk:
|
|
2384
|
+
* adjacent nodes use _next(prev), otherwise fall back to _nthChild(parent).
|
|
2385
|
+
*/
|
|
2386
|
+
function genAccessPath({ helper }, from, child, elementIndex, logicalIndex, prev) {
|
|
2387
|
+
if (prev) return elementIndex - prev[1] === 1 ? genCall(helper("next"), prev[0], logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
|
|
2388
|
+
if (elementIndex === 0) return genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0);
|
|
2389
|
+
const firstChild = genCall(helper("child"), from);
|
|
2390
|
+
return elementIndex === 1 ? genCall(helper("next"), firstChild, logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
|
|
2391
|
+
}
|
|
2392
|
+
/**
|
|
2393
|
+
* Only inline a placeholder when materializing it would not save a parent
|
|
2394
|
+
* lookup. If its child tree needs the parent more than once, keep p* so the
|
|
2395
|
+
* generated code does not duplicate _child/_nthChild work.
|
|
2396
|
+
*/
|
|
2397
|
+
function canInlinePlaceholder(dynamic) {
|
|
2398
|
+
return dynamic.hasDynamicChild === true && countParentAccessUsages(dynamic) === 1;
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* A following access can reuse the current placeholder cursor only when it is
|
|
2402
|
+
* the next DOM sibling. Gapped siblings need _nthChild(parent, index) instead.
|
|
2403
|
+
*/
|
|
2404
|
+
function hasAdjacentFollowingAccessChild(children, index, elementIndex, offset) {
|
|
2405
|
+
let futureOffset = offset;
|
|
2406
|
+
for (let i = index + 1; i < children.length; i++) {
|
|
2407
|
+
const child = children[i];
|
|
2408
|
+
if (child.flags & 2) futureOffset--;
|
|
2409
|
+
if (!(child.flags & 4 && child.template != null) && (!!(child.flags & 1) || child.hasDynamicChild)) return i + futureOffset - elementIndex === 1;
|
|
2410
|
+
}
|
|
2411
|
+
return false;
|
|
2412
|
+
}
|
|
2413
|
+
/**
|
|
2414
|
+
* Mirrors genChildren's traversal closely enough to count how many emitted
|
|
2415
|
+
* access paths would start from this placeholder's parent. This is the guard
|
|
2416
|
+
* that keeps inline placeholders from duplicating parent lookups.
|
|
2417
|
+
*/
|
|
2418
|
+
function countParentAccessUsages(dynamic) {
|
|
2419
|
+
let usages = 0;
|
|
2420
|
+
let offset = 0;
|
|
2421
|
+
let prev;
|
|
2422
|
+
for (const [index, child] of dynamic.children.entries()) {
|
|
2423
|
+
if (child.flags & 2) offset--;
|
|
2424
|
+
if (child.flags & 4 && child.template != null) continue;
|
|
2425
|
+
const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
|
|
2426
|
+
if (id === void 0 && !child.hasDynamicChild) continue;
|
|
2427
|
+
const elementIndex = index + offset;
|
|
2428
|
+
const usesParent = !prev || elementIndex - prev[0] !== 1;
|
|
2429
|
+
if (id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6)) {
|
|
2430
|
+
if (prev && prev[1]) {
|
|
2431
|
+
if (usesParent) usages++;
|
|
2432
|
+
prev = [elementIndex, true];
|
|
2433
|
+
continue;
|
|
2434
|
+
}
|
|
2435
|
+
if (!hasAdjacentFollowingAccessChild(dynamic.children, index, elementIndex, offset)) {
|
|
2436
|
+
if (usesParent) usages++;
|
|
2437
|
+
continue;
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
if (usesParent) usages++;
|
|
2441
|
+
prev = [elementIndex, id === void 0];
|
|
2442
|
+
}
|
|
2443
|
+
return usages;
|
|
2444
|
+
}
|
|
2445
|
+
function genNthChild(nthChild, from, elementIndex, logicalIndex) {
|
|
2446
|
+
const index = String(elementIndex);
|
|
2447
|
+
return genCall(nthChild, from, index, logicalIndex === index ? void 0 : logicalIndex);
|
|
2448
|
+
}
|
|
2270
2449
|
//#endregion
|
|
2271
2450
|
//#region packages/compiler-vapor/src/generators/block.ts
|
|
2272
2451
|
function genBlock(oper, context, args = [], root) {
|
|
@@ -2285,8 +2464,12 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
|
2285
2464
|
const [frag, push] = buildCodeFragment();
|
|
2286
2465
|
const { dynamic, effect, operation, returns } = block;
|
|
2287
2466
|
const resetBlock = context.enterBlock(block);
|
|
2467
|
+
const singleUseAssetComponentNames = root ? collectSingleUseAssetComponents(block) : void 0;
|
|
2468
|
+
const prevSingleUseAssetComponentNames = context.singleUseAssetComponentNames;
|
|
2469
|
+
if (singleUseAssetComponentNames) context.singleUseAssetComponentNames = singleUseAssetComponentNames;
|
|
2288
2470
|
if (root) {
|
|
2289
2471
|
for (let name of context.ir.component) {
|
|
2472
|
+
if (singleUseAssetComponentNames && singleUseAssetComponentNames.has(name)) continue;
|
|
2290
2473
|
const id = (0, _vue_compiler_dom.toValidAssetId)(name, "component");
|
|
2291
2474
|
const maybeSelfReference = name.endsWith("__self");
|
|
2292
2475
|
if (maybeSelfReference) name = name.slice(0, -6);
|
|
@@ -2322,15 +2505,137 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
|
2322
2505
|
const returnNodes = returns.map((n) => `n${n}`);
|
|
2323
2506
|
push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"]);
|
|
2324
2507
|
resetBlock();
|
|
2508
|
+
context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames;
|
|
2325
2509
|
return frag;
|
|
2326
2510
|
function genResolveAssets(kind, helper) {
|
|
2327
2511
|
for (const name of context.ir[kind]) push(NEWLINE, `const ${(0, _vue_compiler_dom.toValidAssetId)(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
|
|
2328
2512
|
}
|
|
2329
2513
|
}
|
|
2514
|
+
function markSlotRootOperations(block) {
|
|
2515
|
+
for (let i = 0; i < block.returns.length; i++) {
|
|
2516
|
+
const child = findReturnedDynamic$1(block, block.returns[i]);
|
|
2517
|
+
const operation = child && child.operation;
|
|
2518
|
+
if (!operation) continue;
|
|
2519
|
+
if (operation.type === 15) markSlotRootIf(operation);
|
|
2520
|
+
else if (operation.type === 16) markSlotRootFor(operation);
|
|
2521
|
+
else if (operation.type === 13) markSlotRootSlotOutlet(operation);
|
|
2522
|
+
else if (operation.type === 12) markSlotRootComponent(operation);
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
function markSlotRootIf(operation) {
|
|
2526
|
+
if (!operation.once) operation.slotRoot = true;
|
|
2527
|
+
markSlotRootOperations(operation.positive);
|
|
2528
|
+
const negative = operation.negative;
|
|
2529
|
+
if (!negative) return;
|
|
2530
|
+
if (negative.type === 15) markSlotRootIf(negative);
|
|
2531
|
+
else markSlotRootOperations(negative);
|
|
2532
|
+
}
|
|
2533
|
+
function markSlotRootFor(operation) {
|
|
2534
|
+
if (!operation.once) operation.slotRoot = true;
|
|
2535
|
+
markSlotRootOperations(operation.render);
|
|
2536
|
+
}
|
|
2537
|
+
function markSlotRootSlotOutlet(operation) {
|
|
2538
|
+
operation.flags |= 4;
|
|
2539
|
+
if (operation.fallback) markSlotRootOperations(operation.fallback);
|
|
2540
|
+
}
|
|
2541
|
+
function markSlotRootComponent(operation) {
|
|
2542
|
+
if (!operation.once && operation.dynamic && !operation.dynamic.isStatic) operation.slotRoot = true;
|
|
2543
|
+
}
|
|
2544
|
+
function findReturnedDynamic$1(block, id) {
|
|
2545
|
+
for (let i = 0; i < block.dynamic.children.length; i++) {
|
|
2546
|
+
const child = block.dynamic.children[i];
|
|
2547
|
+
if (child.id === id) return child;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
function collectSingleUseAssetComponents(block) {
|
|
2551
|
+
const usageMap = /* @__PURE__ */ new Map();
|
|
2552
|
+
const seenOperations = /* @__PURE__ */ new Set();
|
|
2553
|
+
visitBlock(block, true);
|
|
2554
|
+
const names = /* @__PURE__ */ new Set();
|
|
2555
|
+
for (const [name, usage] of usageMap) if (usage.count === 1 && usage.root) names.add(name);
|
|
2556
|
+
return names;
|
|
2557
|
+
function visitBlock(block, rootCandidate) {
|
|
2558
|
+
visitDynamic(block.dynamic, rootCandidate);
|
|
2559
|
+
for (const operation of block.operation) visitOperation(operation, rootCandidate);
|
|
2560
|
+
for (const effect of block.effect) for (const operation of effect.operations) visitOperation(operation, false);
|
|
2561
|
+
}
|
|
2562
|
+
function visitDynamic(dynamic, rootCandidate) {
|
|
2563
|
+
if (dynamic.operation) visitOperation(dynamic.operation, rootCandidate);
|
|
2564
|
+
for (const child of dynamic.children) visitDynamic(child, rootCandidate);
|
|
2565
|
+
}
|
|
2566
|
+
function visitOperation(operation, rootCandidate) {
|
|
2567
|
+
if (seenOperations.has(operation)) return;
|
|
2568
|
+
seenOperations.add(operation);
|
|
2569
|
+
if (operation.type === 12) {
|
|
2570
|
+
if (operation.asset) {
|
|
2571
|
+
const usage = usageMap.get(operation.tag) || {
|
|
2572
|
+
count: 0,
|
|
2573
|
+
root: false
|
|
2574
|
+
};
|
|
2575
|
+
usage.count++;
|
|
2576
|
+
if (rootCandidate) usage.root = true;
|
|
2577
|
+
usageMap.set(operation.tag, usage);
|
|
2578
|
+
}
|
|
2579
|
+
visitSlots(operation.slots);
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
switch (operation.type) {
|
|
2583
|
+
case 15:
|
|
2584
|
+
visitBlock(operation.positive, false);
|
|
2585
|
+
if (operation.negative) if (operation.negative.type === 15) visitOperation(operation.negative, false);
|
|
2586
|
+
else visitBlock(operation.negative, false);
|
|
2587
|
+
break;
|
|
2588
|
+
case 16:
|
|
2589
|
+
visitBlock(operation.render, false);
|
|
2590
|
+
break;
|
|
2591
|
+
case 17:
|
|
2592
|
+
visitBlock(operation.block, false);
|
|
2593
|
+
break;
|
|
2594
|
+
case 13:
|
|
2595
|
+
if (operation.fallback) visitBlock(operation.fallback, false);
|
|
2596
|
+
break;
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
function visitSlots(slots) {
|
|
2600
|
+
for (const slot of slots) switch (slot.slotType) {
|
|
2601
|
+
case 0:
|
|
2602
|
+
for (const name in slot.slots) visitBlock(slot.slots[name], false);
|
|
2603
|
+
break;
|
|
2604
|
+
case 1:
|
|
2605
|
+
case 2:
|
|
2606
|
+
visitBlock(slot.fn, false);
|
|
2607
|
+
break;
|
|
2608
|
+
case 3:
|
|
2609
|
+
visitSlots([slot.positive]);
|
|
2610
|
+
if (slot.negative) visitSlots([slot.negative]);
|
|
2611
|
+
break;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2330
2615
|
//#endregion
|
|
2331
2616
|
//#region packages/compiler-vapor/src/generate.ts
|
|
2332
2617
|
const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/;
|
|
2618
|
+
const helperNameAliases = {
|
|
2619
|
+
withVaporKeys: "withKeys",
|
|
2620
|
+
withVaporModifiers: "withModifiers"
|
|
2621
|
+
};
|
|
2333
2622
|
var CodegenContext = class {
|
|
2623
|
+
withExpressionReplacements(map, fn) {
|
|
2624
|
+
if (map.size === 0) return fn();
|
|
2625
|
+
this.expressionReplacements.unshift(map);
|
|
2626
|
+
try {
|
|
2627
|
+
return fn();
|
|
2628
|
+
} finally {
|
|
2629
|
+
(0, _vue_shared.remove)(this.expressionReplacements, map);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
getExpressionReplacement(node) {
|
|
2633
|
+
for (const map of this.expressionReplacements) {
|
|
2634
|
+
const replacement = map.get(node);
|
|
2635
|
+
if (replacement) return replacement;
|
|
2636
|
+
}
|
|
2637
|
+
return node;
|
|
2638
|
+
}
|
|
2334
2639
|
withId(fn, map) {
|
|
2335
2640
|
const { identifiers } = this;
|
|
2336
2641
|
const ids = Object.keys(map);
|
|
@@ -2347,9 +2652,19 @@ var CodegenContext = class {
|
|
|
2347
2652
|
this.block = block;
|
|
2348
2653
|
return () => this.block = parent;
|
|
2349
2654
|
}
|
|
2655
|
+
enterSlotBlock() {
|
|
2656
|
+
const parent = this.inSlotBlock;
|
|
2657
|
+
this.inSlotBlock = true;
|
|
2658
|
+
return () => this.inSlotBlock = parent;
|
|
2659
|
+
}
|
|
2350
2660
|
enterScope() {
|
|
2351
2661
|
return [this.scopeLevel++, () => this.scopeLevel--];
|
|
2352
2662
|
}
|
|
2663
|
+
isHelperNameAvailable(name) {
|
|
2664
|
+
if (this.bindingNames.has(name)) return false;
|
|
2665
|
+
for (const alias of this.helpers.values()) if (alias === name) return false;
|
|
2666
|
+
return true;
|
|
2667
|
+
}
|
|
2353
2668
|
initNextIdMap() {
|
|
2354
2669
|
if (this.bindingNames.size === 0) return;
|
|
2355
2670
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2384,19 +2699,29 @@ var CodegenContext = class {
|
|
|
2384
2699
|
this.ir = ir;
|
|
2385
2700
|
this.bindingNames = /* @__PURE__ */ new Set();
|
|
2386
2701
|
this.helpers = /* @__PURE__ */ new Map();
|
|
2702
|
+
this.needsTemplateRefSetter = false;
|
|
2703
|
+
this.inSlotBlock = false;
|
|
2387
2704
|
this.helper = (name) => {
|
|
2388
2705
|
if (this.helpers.has(name)) return this.helpers.get(name);
|
|
2389
|
-
const base = `_${name}`;
|
|
2390
|
-
if (this.
|
|
2706
|
+
const base = `_${helperNameAliases[name] || name}`;
|
|
2707
|
+
if (this.isHelperNameAvailable(base)) {
|
|
2391
2708
|
this.helpers.set(name, base);
|
|
2392
2709
|
return base;
|
|
2393
2710
|
}
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2396
|
-
|
|
2711
|
+
const map = this.nextIdMap.get(base);
|
|
2712
|
+
let next = 1;
|
|
2713
|
+
while (true) {
|
|
2714
|
+
const alias = `${base}${getNextId(map, next)}`;
|
|
2715
|
+
if (this.isHelperNameAvailable(alias)) {
|
|
2716
|
+
this.helpers.set(name, alias);
|
|
2717
|
+
return alias;
|
|
2718
|
+
}
|
|
2719
|
+
next++;
|
|
2720
|
+
}
|
|
2397
2721
|
};
|
|
2398
2722
|
this.delegates = /* @__PURE__ */ new Set();
|
|
2399
2723
|
this.identifiers = Object.create(null);
|
|
2724
|
+
this.expressionReplacements = [];
|
|
2400
2725
|
this.seenInlineHandlerNames = Object.create(null);
|
|
2401
2726
|
this.scopeLevel = 0;
|
|
2402
2727
|
this.templateVars = /* @__PURE__ */ new Map();
|
|
@@ -2423,6 +2748,7 @@ var CodegenContext = class {
|
|
|
2423
2748
|
this.block = ir.block;
|
|
2424
2749
|
this.bindingNames = new Set(this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []);
|
|
2425
2750
|
this.initNextIdMap();
|
|
2751
|
+
this.staticTemplateRefHelperCandidate = getStaticTemplateRefHelperCandidate(ir.block);
|
|
2426
2752
|
}
|
|
2427
2753
|
};
|
|
2428
2754
|
function generate(ir, options = {}) {
|
|
@@ -2435,8 +2761,11 @@ function generate(ir, options = {}) {
|
|
|
2435
2761
|
const signature = (options.isTS ? args.map((arg) => `${arg}: any`) : args).join(", ");
|
|
2436
2762
|
if (!inline) push(NEWLINE, `export function ${functionName}(${signature}) {`);
|
|
2437
2763
|
push(INDENT_START);
|
|
2438
|
-
|
|
2439
|
-
|
|
2764
|
+
const templateRefSetterHelper = ir.hasTemplateRef ? context.helper("createTemplateRefSetter") : void 0;
|
|
2765
|
+
const body = genBlockContent(ir.block, context, true);
|
|
2766
|
+
if (context.needsTemplateRefSetter) push(NEWLINE, `const ${setTemplateRefIdent} = ${templateRefSetterHelper}()`);
|
|
2767
|
+
else if (templateRefSetterHelper) context.helpers.delete("createTemplateRefSetter");
|
|
2768
|
+
push(...body);
|
|
2440
2769
|
push(INDENT_END, NEWLINE);
|
|
2441
2770
|
if (!inline) push("}");
|
|
2442
2771
|
const delegates = genDelegates(context);
|
|
@@ -2471,6 +2800,11 @@ function genAssetImports({ ir }) {
|
|
|
2471
2800
|
}
|
|
2472
2801
|
return imports;
|
|
2473
2802
|
}
|
|
2803
|
+
function getStaticTemplateRefHelperCandidate(block) {
|
|
2804
|
+
if (block.operation.length !== 1) return;
|
|
2805
|
+
const operation = block.operation[0];
|
|
2806
|
+
if (operation.type === 9 && !operation.effect && !operation.refFor && operation.value.isStatic) return operation;
|
|
2807
|
+
}
|
|
2474
2808
|
//#endregion
|
|
2475
2809
|
//#region packages/compiler-vapor/src/transforms/vBind.ts
|
|
2476
2810
|
function normalizeBindShorthand(arg, context) {
|
|
@@ -2636,6 +2970,7 @@ function resolveSetupReference(name, context) {
|
|
|
2636
2970
|
}
|
|
2637
2971
|
const dynamicKeys = ["indeterminate"];
|
|
2638
2972
|
const NEEDS_QUOTES_RE = /[\s"'`=<>]/;
|
|
2973
|
+
const UNSAFE_ATTR_NAME_RE = /[\u0000-\u0020"'<=/>]/;
|
|
2639
2974
|
function transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, omitEndTag) {
|
|
2640
2975
|
const { tag } = node;
|
|
2641
2976
|
const { scopeId } = context.options;
|
|
@@ -2653,18 +2988,55 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
|
|
|
2653
2988
|
}, getEffectIndex);
|
|
2654
2989
|
} else {
|
|
2655
2990
|
let prevWasQuoted = false;
|
|
2991
|
+
const appendTemplateProp = (key, value = "", generated = false) => {
|
|
2992
|
+
if (!prevWasQuoted) template += ` `;
|
|
2993
|
+
template += key;
|
|
2994
|
+
if (value) {
|
|
2995
|
+
const escapedValue = generated ? escapeGeneratedAttrValue(value) : value.replace(/"/g, """);
|
|
2996
|
+
template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${escapedValue}"` : `=${escapedValue}`;
|
|
2997
|
+
} else prevWasQuoted = false;
|
|
2998
|
+
};
|
|
2656
2999
|
for (const prop of propsResult[1]) {
|
|
2657
3000
|
const { key, values } = prop;
|
|
2658
3001
|
if (context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
|
|
2659
3002
|
if (!prevWasQuoted) template += ` `;
|
|
2660
3003
|
template += `${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
|
|
2661
3004
|
prevWasQuoted = true;
|
|
3005
|
+
} else if (key.isStatic && !prop.modifier && (0, _vue_shared.isBooleanAttr)(key.content)) if (values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
|
|
3006
|
+
const value = values[0].content === "''" ? "" : values[0].content;
|
|
3007
|
+
appendTemplateProp(key.content, value);
|
|
3008
|
+
} else {
|
|
3009
|
+
const include = foldBooleanAttrValue(values);
|
|
3010
|
+
if (include != null) {
|
|
3011
|
+
if (include) appendTemplateProp(key.content);
|
|
3012
|
+
} else {
|
|
3013
|
+
dynamicProps.push(key.content);
|
|
3014
|
+
context.registerEffect(values, {
|
|
3015
|
+
type: 3,
|
|
3016
|
+
element: context.reference(),
|
|
3017
|
+
prop,
|
|
3018
|
+
tag
|
|
3019
|
+
}, getEffectIndex);
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
else if (key.isStatic && !prop.modifier && hasBoundValue(values)) {
|
|
3023
|
+
let foldedValue;
|
|
3024
|
+
if (key.content === "class") foldedValue = foldClassValues(values);
|
|
3025
|
+
else if (key.content === "style") foldedValue = foldStyleValues(values);
|
|
3026
|
+
if (foldedValue != null) {
|
|
3027
|
+
if (foldedValue) appendTemplateProp(key.content, foldedValue, true);
|
|
3028
|
+
} else {
|
|
3029
|
+
dynamicProps.push(key.content);
|
|
3030
|
+
context.registerEffect(values, {
|
|
3031
|
+
type: 3,
|
|
3032
|
+
element: context.reference(),
|
|
3033
|
+
prop,
|
|
3034
|
+
tag
|
|
3035
|
+
}, getEffectIndex);
|
|
3036
|
+
}
|
|
2662
3037
|
} else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
|
|
2663
|
-
if (!prevWasQuoted) template += ` `;
|
|
2664
3038
|
const value = values[0].content === "''" ? "" : values[0].content;
|
|
2665
|
-
|
|
2666
|
-
if (value) template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${value.replace(/"/g, """)}"` : `=${value}`;
|
|
2667
|
-
else prevWasQuoted = false;
|
|
3039
|
+
appendTemplateProp(key.content, value);
|
|
2668
3040
|
} else {
|
|
2669
3041
|
dynamicProps.push(key.content);
|
|
2670
3042
|
context.registerEffect(values, {
|
|
@@ -2686,6 +3058,123 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
|
|
|
2686
3058
|
} else context.template += template;
|
|
2687
3059
|
if (staticKey) context.registerOperation(createSetBlockKey(context.reference(), staticKey));
|
|
2688
3060
|
}
|
|
3061
|
+
function escapeGeneratedAttrValue(value) {
|
|
3062
|
+
return value.replace(/&/g, "&").replace(/"/g, """);
|
|
3063
|
+
}
|
|
3064
|
+
function foldBooleanAttrValue(values) {
|
|
3065
|
+
if (values.length !== 1) return;
|
|
3066
|
+
const evaluated = evaluateConstantExpression(values[0]);
|
|
3067
|
+
if (!evaluated) return;
|
|
3068
|
+
const value = evaluated.value;
|
|
3069
|
+
if (value === true || value === false || value == null) return (0, _vue_shared.includeBooleanAttr)(value);
|
|
3070
|
+
}
|
|
3071
|
+
function foldStyleValues(values) {
|
|
3072
|
+
const evaluatedValues = [];
|
|
3073
|
+
for (const value of values) {
|
|
3074
|
+
const evaluated = evaluateConstantExpression(value);
|
|
3075
|
+
if (!evaluated || !isStaticStyleValue(evaluated.value)) return;
|
|
3076
|
+
evaluatedValues.push(evaluated.value);
|
|
3077
|
+
}
|
|
3078
|
+
return (0, _vue_shared.stringifyStyle)((0, _vue_shared.normalizeStyle)(evaluatedValues.length === 1 ? evaluatedValues[0] : evaluatedValues));
|
|
3079
|
+
}
|
|
3080
|
+
function isStaticStyleValue(value) {
|
|
3081
|
+
if (typeof value === "string") return true;
|
|
3082
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
3083
|
+
for (const key in value) {
|
|
3084
|
+
const propValue = value[key];
|
|
3085
|
+
if (!isSafeStylePropertyName(key) || !isSafeStylePropertyValue(propValue)) return false;
|
|
3086
|
+
}
|
|
3087
|
+
return true;
|
|
3088
|
+
}
|
|
3089
|
+
function isSafeStylePropertyName(key) {
|
|
3090
|
+
return !!key && !/[;:]/.test(key);
|
|
3091
|
+
}
|
|
3092
|
+
function isSafeStylePropertyValue(value) {
|
|
3093
|
+
return typeof value === "number" || typeof value === "string" && !value.includes(";");
|
|
3094
|
+
}
|
|
3095
|
+
function hasBoundValue(values) {
|
|
3096
|
+
return values.some((value) => !value.isStatic && value.content !== "''");
|
|
3097
|
+
}
|
|
3098
|
+
function foldClassValues(values) {
|
|
3099
|
+
let templateValue = "";
|
|
3100
|
+
let changed = false;
|
|
3101
|
+
for (const value of values) {
|
|
3102
|
+
const evaluated = evaluateConstantExpression(value);
|
|
3103
|
+
if (evaluated) {
|
|
3104
|
+
const normalized = (0, _vue_shared.normalizeClass)(evaluated.value);
|
|
3105
|
+
if (normalized) templateValue = appendClass(templateValue, normalized);
|
|
3106
|
+
else changed = true;
|
|
3107
|
+
continue;
|
|
3108
|
+
}
|
|
3109
|
+
return;
|
|
3110
|
+
}
|
|
3111
|
+
return changed || templateValue ? templateValue : void 0;
|
|
3112
|
+
}
|
|
3113
|
+
function appendClass(base, value) {
|
|
3114
|
+
return base ? value ? `${base} ${value}` : base : value;
|
|
3115
|
+
}
|
|
3116
|
+
function getObjectPropertyName(prop) {
|
|
3117
|
+
const key = prop.key;
|
|
3118
|
+
if (key.type === "Identifier") return key.name;
|
|
3119
|
+
else if (key.type === "StringLiteral") return key.value;
|
|
3120
|
+
else if (key.type === "NumericLiteral") return String(key.value);
|
|
3121
|
+
}
|
|
3122
|
+
function evaluateConstantExpression(node) {
|
|
3123
|
+
if (node.isStatic) return { value: node.content };
|
|
3124
|
+
const ast = node.ast;
|
|
3125
|
+
if (ast === null) {
|
|
3126
|
+
if (node.content === "true") return { value: true };
|
|
3127
|
+
else if (node.content === "false") return { value: false };
|
|
3128
|
+
else if (node.content === "null") return { value: null };
|
|
3129
|
+
else if (node.content === "undefined") return { value: void 0 };
|
|
3130
|
+
}
|
|
3131
|
+
if (!ast) return;
|
|
3132
|
+
return evaluateConstantAst(ast);
|
|
3133
|
+
}
|
|
3134
|
+
function evaluateConstantAst(node) {
|
|
3135
|
+
switch (node.type) {
|
|
3136
|
+
case "StringLiteral": return { value: node.value };
|
|
3137
|
+
case "NumericLiteral": return { value: node.value };
|
|
3138
|
+
case "BooleanLiteral": return { value: node.value };
|
|
3139
|
+
case "NullLiteral": return { value: null };
|
|
3140
|
+
case "Identifier": return node.name === "undefined" ? { value: void 0 } : void 0;
|
|
3141
|
+
case "UnaryExpression":
|
|
3142
|
+
if (node.operator === "void") return { value: void 0 };
|
|
3143
|
+
else if (node.operator === "-") {
|
|
3144
|
+
const value = evaluateConstantAst(node.argument);
|
|
3145
|
+
return value && typeof value.value === "number" ? { value: -value.value } : void 0;
|
|
3146
|
+
}
|
|
3147
|
+
return;
|
|
3148
|
+
case "TemplateLiteral": return evaluateTemplateLiteral(node);
|
|
3149
|
+
case "ObjectExpression": return evaluateObjectExpression(node);
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
function evaluateTemplateLiteral(node) {
|
|
3153
|
+
if (node.type !== "TemplateLiteral") return;
|
|
3154
|
+
let value = "";
|
|
3155
|
+
for (const [index, quasi] of node.quasis.entries()) {
|
|
3156
|
+
value += quasi.value.cooked || "";
|
|
3157
|
+
const expression = node.expressions[index];
|
|
3158
|
+
if (expression) {
|
|
3159
|
+
const evaluated = evaluateConstantAst(expression);
|
|
3160
|
+
if (!evaluated) return;
|
|
3161
|
+
value += evaluated.value;
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
return { value };
|
|
3165
|
+
}
|
|
3166
|
+
function evaluateObjectExpression(node) {
|
|
3167
|
+
const value = {};
|
|
3168
|
+
for (const prop of node.properties) {
|
|
3169
|
+
if (prop.type !== "ObjectProperty" || prop.computed) return;
|
|
3170
|
+
const key = getObjectPropertyName(prop);
|
|
3171
|
+
if (key == null) return;
|
|
3172
|
+
const evaluated = evaluateConstantAst(prop.value);
|
|
3173
|
+
if (!evaluated) return;
|
|
3174
|
+
value[key] = evaluated.value;
|
|
3175
|
+
}
|
|
3176
|
+
return { value };
|
|
3177
|
+
}
|
|
2689
3178
|
function resolveStaticKey(node, context, isComponent) {
|
|
2690
3179
|
const keyProp = findProp$1(node, "key", false, true);
|
|
2691
3180
|
if (!keyProp) return;
|
|
@@ -2712,27 +3201,42 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
|
|
|
2712
3201
|
results = [];
|
|
2713
3202
|
}
|
|
2714
3203
|
}
|
|
3204
|
+
function pushStaticObjectLiteralProps(props) {
|
|
3205
|
+
if (dynamicArgs.length) {
|
|
3206
|
+
pushMergeArg();
|
|
3207
|
+
dynamicArgs.push(props);
|
|
3208
|
+
} else results.push(...props.map(toDirectiveResult));
|
|
3209
|
+
}
|
|
2715
3210
|
for (const prop of props) {
|
|
2716
3211
|
if (prop.type === 7 && !prop.arg) {
|
|
2717
3212
|
if (prop.name === "bind") {
|
|
2718
3213
|
if (prop.exp) {
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
3214
|
+
const objectLiteralProps = isComponent ? resolveComponentObjectLiteralBindProps(prop.exp, context, props, prop) : resolveNativeObjectLiteralBindProps(prop.exp, context, props, prop);
|
|
3215
|
+
if (objectLiteralProps) if (isComponent) pushStaticObjectLiteralProps(objectLiteralProps);
|
|
3216
|
+
else results.push(...objectLiteralProps.map(toDirectiveResult));
|
|
3217
|
+
else {
|
|
3218
|
+
dynamicExpr.push(prop.exp);
|
|
3219
|
+
pushMergeArg();
|
|
3220
|
+
dynamicArgs.push({
|
|
3221
|
+
kind: 0,
|
|
3222
|
+
value: prop.exp
|
|
3223
|
+
});
|
|
3224
|
+
}
|
|
2725
3225
|
} else context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, prop.loc));
|
|
2726
3226
|
continue;
|
|
2727
3227
|
} else if (prop.name === "on") {
|
|
2728
3228
|
if (prop.exp) if (isComponent) {
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
3229
|
+
const objectLiteralProps = resolveComponentObjectLiteralOnProps(prop.exp, context, props, prop);
|
|
3230
|
+
if (objectLiteralProps) pushStaticObjectLiteralProps(objectLiteralProps);
|
|
3231
|
+
else {
|
|
3232
|
+
dynamicExpr.push(prop.exp);
|
|
3233
|
+
pushMergeArg();
|
|
3234
|
+
dynamicArgs.push({
|
|
3235
|
+
kind: 0,
|
|
3236
|
+
value: prop.exp,
|
|
3237
|
+
handler: true
|
|
3238
|
+
});
|
|
3239
|
+
}
|
|
2736
3240
|
} else context.registerEffect([prop.exp], {
|
|
2737
3241
|
type: 7,
|
|
2738
3242
|
element: context.reference(),
|
|
@@ -2762,6 +3266,151 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
|
|
|
2762
3266
|
}
|
|
2763
3267
|
return [false, dedupeProperties(results)];
|
|
2764
3268
|
}
|
|
3269
|
+
function resolveObjectLiteralProps(exp, context, keyTransform, isValidKey) {
|
|
3270
|
+
const ast = exp.ast;
|
|
3271
|
+
if (!ast || ast.type !== "ObjectExpression") return;
|
|
3272
|
+
const props = [];
|
|
3273
|
+
const knownKeys = /* @__PURE__ */ new Set();
|
|
3274
|
+
for (const property of ast.properties) {
|
|
3275
|
+
if (property.type !== "ObjectProperty" || property.computed) return;
|
|
3276
|
+
let key = getObjectPropertyName(property);
|
|
3277
|
+
if (key == null || key === "__proto__") return;
|
|
3278
|
+
if (isValidKey && !isValidKey(key)) return;
|
|
3279
|
+
if (keyTransform) key = keyTransform(key);
|
|
3280
|
+
if (knownKeys.has(key)) return;
|
|
3281
|
+
knownKeys.add(key);
|
|
3282
|
+
props.push({
|
|
3283
|
+
key: (0, _vue_compiler_dom.createSimpleExpression)(key, true),
|
|
3284
|
+
values: [resolveExpression(createObjectBindSubExpression(exp, property.value, context), true)]
|
|
3285
|
+
});
|
|
3286
|
+
}
|
|
3287
|
+
return props;
|
|
3288
|
+
}
|
|
3289
|
+
function resolveComponentObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
|
|
3290
|
+
const props = resolveObjectLiteralProps(exp, context, void 0, isSafeObjectLiteralBindKey);
|
|
3291
|
+
if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3292
|
+
return props;
|
|
3293
|
+
}
|
|
3294
|
+
function resolveNativeObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
|
|
3295
|
+
const props = resolveObjectLiteralProps(exp, context, void 0, isSafeNativeObjectLiteralBindKey);
|
|
3296
|
+
if (!props || hasNativeObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3297
|
+
return props;
|
|
3298
|
+
}
|
|
3299
|
+
function resolveComponentObjectLiteralOnProps(exp, context, nodeProps, currentProp) {
|
|
3300
|
+
const props = resolveObjectLiteralProps(exp, context, _vue_shared.toHandlerKey);
|
|
3301
|
+
if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3302
|
+
return props;
|
|
3303
|
+
}
|
|
3304
|
+
function isSafeNativeObjectLiteralBindKey(key) {
|
|
3305
|
+
return key !== "" && !UNSAFE_ATTR_NAME_RE.test(key) && isSafeObjectLiteralBindKey(key) && !(0, _vue_shared.isOn)(key) && key.charCodeAt(0) !== 46 && key.charCodeAt(0) !== 94;
|
|
3306
|
+
}
|
|
3307
|
+
function isSafeObjectLiteralBindKey(key) {
|
|
3308
|
+
return !isReservedProp(key);
|
|
3309
|
+
}
|
|
3310
|
+
function hasComponentObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
|
|
3311
|
+
const keys = createComponentConflictKeySet(objectLiteralProps.map((prop) => prop.key.content));
|
|
3312
|
+
for (const prop of props) {
|
|
3313
|
+
if (prop === currentProp) continue;
|
|
3314
|
+
let key;
|
|
3315
|
+
if (prop.type === 6) key = prop.name;
|
|
3316
|
+
else if (prop.name === "bind") {
|
|
3317
|
+
if (!prop.arg) {
|
|
3318
|
+
const bindKeys = getObjectLiteralKeys(prop.exp);
|
|
3319
|
+
if (bindKeys && hasComponentKeyOverlap(keys, bindKeys)) return true;
|
|
3320
|
+
continue;
|
|
3321
|
+
}
|
|
3322
|
+
key = getStaticBindKey(prop);
|
|
3323
|
+
} else if (prop.name === "on") key = getStaticHandlerKey(prop);
|
|
3324
|
+
else if (prop.name === "model") {
|
|
3325
|
+
if (hasComponentModelKey(keys, prop)) return true;
|
|
3326
|
+
}
|
|
3327
|
+
if (key && hasComponentKey(keys, key)) return true;
|
|
3328
|
+
}
|
|
3329
|
+
return false;
|
|
3330
|
+
}
|
|
3331
|
+
function hasComponentModelKey(keys, prop) {
|
|
3332
|
+
const { arg } = prop;
|
|
3333
|
+
if (arg && (arg.type !== 4 || !arg.isStatic)) return true;
|
|
3334
|
+
const key = arg ? arg.content : "modelValue";
|
|
3335
|
+
return hasComponentKey(keys, key) || hasComponentKey(keys, `onUpdate:${(0, _vue_shared.camelize)(key)}`) || prop.modifiers.length > 0 && hasComponentKey(keys, (0, _vue_shared.getModifierPropName)(key));
|
|
3336
|
+
}
|
|
3337
|
+
function hasNativeObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
|
|
3338
|
+
const keys = new Set(objectLiteralProps.map((prop) => prop.key.content));
|
|
3339
|
+
for (const prop of props) {
|
|
3340
|
+
if (prop === currentProp) continue;
|
|
3341
|
+
let key;
|
|
3342
|
+
if (prop.type === 6) key = prop.name;
|
|
3343
|
+
else if (prop.name === "bind") {
|
|
3344
|
+
if (!prop.arg) return true;
|
|
3345
|
+
key = getStaticBindKey(prop);
|
|
3346
|
+
if (!key) return true;
|
|
3347
|
+
}
|
|
3348
|
+
if (key && keys.has(key)) return true;
|
|
3349
|
+
}
|
|
3350
|
+
return false;
|
|
3351
|
+
}
|
|
3352
|
+
function getStaticBindKey(prop) {
|
|
3353
|
+
const { arg } = prop;
|
|
3354
|
+
if (!arg || arg.type !== 4 || !arg.isStatic) return;
|
|
3355
|
+
let key = arg.content;
|
|
3356
|
+
if (isReservedProp(key)) return;
|
|
3357
|
+
if (prop.modifiers.some((modifier) => modifier.content === "camel")) key = (0, _vue_shared.camelize)(key);
|
|
3358
|
+
return key;
|
|
3359
|
+
}
|
|
3360
|
+
function getStaticHandlerKey(prop) {
|
|
3361
|
+
const { arg } = prop;
|
|
3362
|
+
if (!arg || arg.type !== 4 || !arg.isStatic) return;
|
|
3363
|
+
let key = arg.content;
|
|
3364
|
+
if (key.startsWith("vue:")) key = `vnode-${key.slice(4)}`;
|
|
3365
|
+
const { nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(`on${key}`, prop.modifiers, null, prop.loc);
|
|
3366
|
+
if (key.toLowerCase() === "click") {
|
|
3367
|
+
if (nonKeyModifiers.includes("middle")) key = "mouseup";
|
|
3368
|
+
if (nonKeyModifiers.includes("right")) key = "contextmenu";
|
|
3369
|
+
}
|
|
3370
|
+
key = (0, _vue_shared.toHandlerKey)((0, _vue_shared.camelize)(key));
|
|
3371
|
+
const optionPostfix = eventOptionModifiers.map(_vue_shared.capitalize).join("");
|
|
3372
|
+
if (optionPostfix) key += optionPostfix;
|
|
3373
|
+
return key;
|
|
3374
|
+
}
|
|
3375
|
+
function getObjectLiteralKeys(exp) {
|
|
3376
|
+
const ast = exp && exp.ast;
|
|
3377
|
+
if (!ast || ast.type !== "ObjectExpression") return;
|
|
3378
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3379
|
+
for (const property of ast.properties) {
|
|
3380
|
+
if (property.type !== "ObjectProperty" || property.computed) return;
|
|
3381
|
+
const key = getObjectPropertyName(property);
|
|
3382
|
+
if (key == null) return;
|
|
3383
|
+
keys.add(key);
|
|
3384
|
+
}
|
|
3385
|
+
return keys;
|
|
3386
|
+
}
|
|
3387
|
+
function createComponentConflictKeySet(keys) {
|
|
3388
|
+
const normalized = /* @__PURE__ */ new Set();
|
|
3389
|
+
for (const key of keys) {
|
|
3390
|
+
normalized.add(key);
|
|
3391
|
+
normalized.add((0, _vue_shared.camelize)(key));
|
|
3392
|
+
}
|
|
3393
|
+
return normalized;
|
|
3394
|
+
}
|
|
3395
|
+
function hasComponentKey(keys, key) {
|
|
3396
|
+
return keys.has(key) || keys.has((0, _vue_shared.camelize)(key));
|
|
3397
|
+
}
|
|
3398
|
+
function hasComponentKeyOverlap(left, right) {
|
|
3399
|
+
for (const key of right) if (hasComponentKey(left, key)) return true;
|
|
3400
|
+
return false;
|
|
3401
|
+
}
|
|
3402
|
+
function createObjectBindSubExpression(source, node, context) {
|
|
3403
|
+
const start = node.start == null ? 0 : node.start - 1;
|
|
3404
|
+
const end = node.end == null ? source.content.length : node.end - 1;
|
|
3405
|
+
const content = source.content.slice(start, end);
|
|
3406
|
+
const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
|
|
3407
|
+
start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
|
|
3408
|
+
end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
|
|
3409
|
+
source: content
|
|
3410
|
+
});
|
|
3411
|
+
expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
|
|
3412
|
+
return expression;
|
|
3413
|
+
}
|
|
2765
3414
|
function transformProp(prop, node, context) {
|
|
2766
3415
|
let { name } = prop;
|
|
2767
3416
|
if (prop.type === 6) {
|
|
@@ -2812,6 +3461,12 @@ function resolveDirectiveResult(prop) {
|
|
|
2812
3461
|
values: [prop.value]
|
|
2813
3462
|
});
|
|
2814
3463
|
}
|
|
3464
|
+
function toDirectiveResult(prop) {
|
|
3465
|
+
return (0, _vue_shared.extend)({}, prop, {
|
|
3466
|
+
values: void 0,
|
|
3467
|
+
value: prop.values[0]
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
2815
3470
|
function mergePropValues(existing, incoming) {
|
|
2816
3471
|
const newValues = incoming.values;
|
|
2817
3472
|
existing.values.push(...newValues);
|
|
@@ -3345,6 +4000,7 @@ function processIf(node, dir, context) {
|
|
|
3345
4000
|
}
|
|
3346
4001
|
context.dynamic.flags |= 2;
|
|
3347
4002
|
const forceMultiRoot = shouldForceMultiRoot(context);
|
|
4003
|
+
const allowNoScope = context.block === context.root.block;
|
|
3348
4004
|
if (dir.name === "if") {
|
|
3349
4005
|
const id = context.reference();
|
|
3350
4006
|
context.dynamic.flags |= 4;
|
|
@@ -3355,7 +4011,7 @@ function processIf(node, dir, context) {
|
|
|
3355
4011
|
type: 15,
|
|
3356
4012
|
id,
|
|
3357
4013
|
...context.effectBoundary(),
|
|
3358
|
-
blockShape: encodeIfBlockShape(branch, forceMultiRoot),
|
|
4014
|
+
blockShape: encodeIfBlockShape(branch, forceMultiRoot, void 0, allowNoScope),
|
|
3359
4015
|
condition: dir.exp,
|
|
3360
4016
|
positive: branch,
|
|
3361
4017
|
index: context.root.nextIfIndex(),
|
|
@@ -3397,8 +4053,8 @@ function processIf(node, dir, context) {
|
|
|
3397
4053
|
};
|
|
3398
4054
|
return () => {
|
|
3399
4055
|
onExit();
|
|
3400
|
-
if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot);
|
|
3401
|
-
lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative);
|
|
4056
|
+
if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot, void 0, allowNoScope);
|
|
4057
|
+
lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative, allowNoScope);
|
|
3402
4058
|
};
|
|
3403
4059
|
}
|
|
3404
4060
|
}
|
|
@@ -3413,14 +4069,38 @@ function createIfBranch(node, context) {
|
|
|
3413
4069
|
context.reference();
|
|
3414
4070
|
return [branch, exitBlock];
|
|
3415
4071
|
}
|
|
3416
|
-
function encodeIfBlockShape(positive, forceMultiRoot = false, negative) {
|
|
4072
|
+
function encodeIfBlockShape(positive, forceMultiRoot = false, negative, allowNoScope = true) {
|
|
3417
4073
|
if (forceMultiRoot) return 10;
|
|
3418
|
-
|
|
4074
|
+
const positiveNoScope = allowNoScope && canSkipIfBranchScope(positive);
|
|
4075
|
+
const negativeNoScope = allowNoScope && negative && negative.type !== 15 && canSkipIfBranchScope(negative);
|
|
4076
|
+
return getBlockShape(positive) | getNegativeIfBranchShape(negative) << 2 | (positiveNoScope ? 32 : 0) | (negativeNoScope ? 64 : 0);
|
|
3419
4077
|
}
|
|
3420
|
-
function
|
|
4078
|
+
function getNegativeIfBranchShape(negative) {
|
|
3421
4079
|
if (!negative) return 0;
|
|
3422
4080
|
return negative.type === 15 ? 1 : getBlockShape(negative);
|
|
3423
4081
|
}
|
|
4082
|
+
function canSkipIfBranchScope(block) {
|
|
4083
|
+
if (block.effect.length || block.operation.length) return false;
|
|
4084
|
+
if (!isStaticBranch(block.node)) return false;
|
|
4085
|
+
if (block.returns.length === 0 || block.dynamic.children.length !== block.returns.length) return false;
|
|
4086
|
+
return block.returns.every((id) => {
|
|
4087
|
+
const returned = findReturnedDynamic(block, id);
|
|
4088
|
+
return !!(returned && returned.template != null && !returned.operation && !returned.hasDynamicChild && !(returned.flags & 6));
|
|
4089
|
+
});
|
|
4090
|
+
}
|
|
4091
|
+
function findReturnedDynamic(block, id) {
|
|
4092
|
+
return block.dynamic.children.find((child) => child.id === id);
|
|
4093
|
+
}
|
|
4094
|
+
function isStaticBranch(node) {
|
|
4095
|
+
if (node.type !== 1 || node.tagType !== 3 || node.children.length === 0) return false;
|
|
4096
|
+
return node.children.every((child) => isStaticTemplateNode(child));
|
|
4097
|
+
}
|
|
4098
|
+
function isStaticTemplateNode(node) {
|
|
4099
|
+
if (node.type === 2 || node.type === 3) return true;
|
|
4100
|
+
if (node.type !== 1 || node.tagType !== 0) return false;
|
|
4101
|
+
for (const prop of node.props) if (prop.type === 7 || prop.name === "ref") return false;
|
|
4102
|
+
return node.children.every((child) => isStaticTemplateNode(child));
|
|
4103
|
+
}
|
|
3424
4104
|
function shouldForceMultiRoot(context) {
|
|
3425
4105
|
const parent = context.parent && context.parent.node;
|
|
3426
4106
|
return !!parent && parent.type === 1 && parent.tagType === 3 && parent.props.some((prop) => prop.type === 7 && prop.name === "for");
|
|
@@ -3505,6 +4185,9 @@ const transformSlotOutlet = (node, context) => {
|
|
|
3505
4185
|
}
|
|
3506
4186
|
return () => {
|
|
3507
4187
|
exitBlock && exitBlock();
|
|
4188
|
+
let flags = 0;
|
|
4189
|
+
if (context.options.scopeId && !context.options.slotted) flags |= 1;
|
|
4190
|
+
if (context.inVOnce) flags |= 2;
|
|
3508
4191
|
context.dynamic.operation = {
|
|
3509
4192
|
type: 13,
|
|
3510
4193
|
id,
|
|
@@ -3512,8 +4195,7 @@ const transformSlotOutlet = (node, context) => {
|
|
|
3512
4195
|
name: slotName,
|
|
3513
4196
|
props: irProps,
|
|
3514
4197
|
fallback,
|
|
3515
|
-
|
|
3516
|
-
once: context.inVOnce
|
|
4198
|
+
flags
|
|
3517
4199
|
};
|
|
3518
4200
|
};
|
|
3519
4201
|
};
|