@vue/compiler-vapor 3.6.0-beta.12 → 3.6.0-beta.13
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 +839 -138
- package/dist/compiler-vapor.d.ts +56 -32
- package/dist/compiler-vapor.esm-browser.js +951 -199
- 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.13
|
|
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()
|
|
1025
1031
|
];
|
|
1026
1032
|
}
|
|
1027
|
-
|
|
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
|
+
`)`
|
|
1044
|
+
];
|
|
1045
|
+
}
|
|
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) {
|
|
@@ -1175,6 +1198,8 @@ 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;
|
|
1179
1204
|
const onResetCalls = [];
|
|
1180
1205
|
for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`);
|
|
@@ -1207,6 +1232,21 @@ function genFor(oper, context) {
|
|
|
1207
1232
|
return idMap;
|
|
1208
1233
|
}
|
|
1209
1234
|
}
|
|
1235
|
+
function isSingleNodeBlock(block) {
|
|
1236
|
+
const child = getSingleReturnedChild(block);
|
|
1237
|
+
return !!child && child.template != null;
|
|
1238
|
+
}
|
|
1239
|
+
function isFragmentBlock(block) {
|
|
1240
|
+
const child = getSingleReturnedChild(block);
|
|
1241
|
+
const operation = child && child.operation;
|
|
1242
|
+
if (!operation) return false;
|
|
1243
|
+
return operation.type === 13 || operation.type === 16 || operation.type === 17 || operation.type === 15 && !operation.once || operation.type === 12 && !!operation.dynamic && !operation.dynamic.isStatic;
|
|
1244
|
+
}
|
|
1245
|
+
function getSingleReturnedChild(block) {
|
|
1246
|
+
if (block.returns.length !== 1) return;
|
|
1247
|
+
const id = block.returns[0];
|
|
1248
|
+
for (const child of block.dynamic.children) if (child.id === id) return child;
|
|
1249
|
+
}
|
|
1210
1250
|
function parseValueDestructure(value, context) {
|
|
1211
1251
|
const map = /* @__PURE__ */ new Map();
|
|
1212
1252
|
if (value) {
|
|
@@ -1392,6 +1432,7 @@ function genIf(oper, context, isNested = false) {
|
|
|
1392
1432
|
const { helper } = context;
|
|
1393
1433
|
const { condition, positive, negative, once, index, blockShape } = oper;
|
|
1394
1434
|
const [frag, push] = buildCodeFragment();
|
|
1435
|
+
const flags = genIfFlags(blockShape, once, negative ? index : void 0);
|
|
1395
1436
|
const conditionExpr = [
|
|
1396
1437
|
"() => (",
|
|
1397
1438
|
...genExpression(condition, context),
|
|
@@ -1402,9 +1443,24 @@ function genIf(oper, context, isNested = false) {
|
|
|
1402
1443
|
if (negative) if (negative.type === 1) negativeArg = genBlock(negative, context);
|
|
1403
1444
|
else negativeArg = ["() => ", ...genIf(negative, context, true)];
|
|
1404
1445
|
if (!isNested) push(NEWLINE, `const n${oper.id} = `);
|
|
1405
|
-
push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg,
|
|
1446
|
+
push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, flags));
|
|
1406
1447
|
return frag;
|
|
1407
1448
|
}
|
|
1449
|
+
function genIfFlags(blockShape, once, index) {
|
|
1450
|
+
let flags = blockShape;
|
|
1451
|
+
if (once) flags |= 16;
|
|
1452
|
+
else if (index !== void 0) flags |= index + 1 << 7;
|
|
1453
|
+
if (flags === 1) return false;
|
|
1454
|
+
return `${flags} /* ${genIfFlagNames(once, index, blockShape)} */`;
|
|
1455
|
+
}
|
|
1456
|
+
function genIfFlagNames(once, index, blockShape) {
|
|
1457
|
+
const names = ["BLOCK_SHAPE"];
|
|
1458
|
+
if (blockShape & 32) names.push("TRUE_NO_SCOPE");
|
|
1459
|
+
if (blockShape & 64) names.push("FALSE_NO_SCOPE");
|
|
1460
|
+
if (once) names.push("ONCE");
|
|
1461
|
+
else if (index !== void 0) names.push("INDEX_SHIFT");
|
|
1462
|
+
return names.join(", ");
|
|
1463
|
+
}
|
|
1408
1464
|
//#endregion
|
|
1409
1465
|
//#region packages/compiler-vapor/src/generators/prop.ts
|
|
1410
1466
|
const helpers = {
|
|
@@ -1454,15 +1510,16 @@ function resolveClassName(values, context) {
|
|
|
1454
1510
|
const entries = [];
|
|
1455
1511
|
let sawDynamic = false;
|
|
1456
1512
|
let sawSuffix = false;
|
|
1457
|
-
for (const
|
|
1513
|
+
for (const rawValue of values) {
|
|
1514
|
+
const value = context.getExpressionReplacement(rawValue);
|
|
1458
1515
|
const staticValue = getLiteralExpressionValue(value, true);
|
|
1459
1516
|
if (staticValue != null) {
|
|
1460
1517
|
const normalized = (0, _vue_shared.normalizeClass)(staticValue);
|
|
1461
|
-
if (normalized) if (sawSuffix) suffix = appendClass(suffix, normalized);
|
|
1518
|
+
if (normalized) if (sawSuffix) suffix = appendClass$1(suffix, normalized);
|
|
1462
1519
|
else if (sawDynamic) {
|
|
1463
1520
|
sawSuffix = true;
|
|
1464
|
-
suffix = appendClass(suffix, normalized);
|
|
1465
|
-
} else prefix = appendClass(prefix, normalized);
|
|
1521
|
+
suffix = appendClass$1(suffix, normalized);
|
|
1522
|
+
} else prefix = appendClass$1(prefix, normalized);
|
|
1466
1523
|
continue;
|
|
1467
1524
|
}
|
|
1468
1525
|
const ast = value.ast;
|
|
@@ -1483,7 +1540,7 @@ function resolveClassName(values, context) {
|
|
|
1483
1540
|
function resolveObjectClassName(source, ast, entries, context) {
|
|
1484
1541
|
for (const prop of ast.properties) {
|
|
1485
1542
|
if (prop.type !== "ObjectProperty" || prop.computed) return false;
|
|
1486
|
-
const rawClassName = getObjectPropertyName(prop);
|
|
1543
|
+
const rawClassName = getObjectPropertyName$1(prop);
|
|
1487
1544
|
if (rawClassName == null) return false;
|
|
1488
1545
|
const className = (0, _vue_shared.normalizeClass)(rawClassName);
|
|
1489
1546
|
if (!className) continue;
|
|
@@ -1528,10 +1585,10 @@ function genClassFlags(entries, context) {
|
|
|
1528
1585
|
});
|
|
1529
1586
|
return values;
|
|
1530
1587
|
}
|
|
1531
|
-
function appendClass(base, value) {
|
|
1588
|
+
function appendClass$1(base, value) {
|
|
1532
1589
|
return base ? value ? `${base} ${value}` : base : value;
|
|
1533
1590
|
}
|
|
1534
|
-
function getObjectPropertyName(prop) {
|
|
1591
|
+
function getObjectPropertyName$1(prop) {
|
|
1535
1592
|
const key = prop.key;
|
|
1536
1593
|
if (key.type === "Identifier") return key.name;
|
|
1537
1594
|
else if (key.type === "StringLiteral") return key.value;
|
|
@@ -1623,8 +1680,23 @@ function getSpecialHelper(keyName, tagName, isSVG) {
|
|
|
1623
1680
|
const setTemplateRefIdent = `_setTemplateRef`;
|
|
1624
1681
|
function genSetTemplateRef(oper, context) {
|
|
1625
1682
|
const [refValue, refKey] = genRefValue(oper.value, context);
|
|
1683
|
+
if (context.staticTemplateRefHelperCandidate === oper) return genSetStaticTemplateRef(oper, refValue, refKey, context);
|
|
1684
|
+
context.needsTemplateRefSetter = true;
|
|
1626
1685
|
return [NEWLINE, ...genCall(setTemplateRefIdent, `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
|
|
1627
1686
|
}
|
|
1687
|
+
function genSetStaticTemplateRef(oper, refValue, refKey, context) {
|
|
1688
|
+
return [NEWLINE, ...genCall(context.helper("setStaticTemplateRef"), `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
|
|
1689
|
+
}
|
|
1690
|
+
function genSetTemplateRefBinding(oper, context) {
|
|
1691
|
+
const [refValue, refKey] = genRefValue(oper.value, context);
|
|
1692
|
+
const setter = context.inSlotBlock && setTemplateRefIdent;
|
|
1693
|
+
if (context.inSlotBlock) context.needsTemplateRefSetter = true;
|
|
1694
|
+
return [NEWLINE, ...genCall([context.helper("setTemplateRefBinding"), "undefined"], `n${oper.element}`, ["() => ", ...refValue], ...setter || oper.refFor || refKey ? [
|
|
1695
|
+
setter,
|
|
1696
|
+
oper.refFor && "true",
|
|
1697
|
+
refKey
|
|
1698
|
+
] : [])];
|
|
1699
|
+
}
|
|
1628
1700
|
function genRefValue(value, context) {
|
|
1629
1701
|
if (value && context.options.inline) {
|
|
1630
1702
|
const binding = context.options.bindingMetadata[value.content];
|
|
@@ -1728,15 +1800,18 @@ function filterCustomDirectives(id, operations) {
|
|
|
1728
1800
|
//#region packages/compiler-vapor/src/generators/component.ts
|
|
1729
1801
|
function genCreateComponent(operation, context) {
|
|
1730
1802
|
const { helper } = context;
|
|
1803
|
+
const singleUseAssetComponentNames = context.singleUseAssetComponentNames;
|
|
1804
|
+
const useAssetComponentHelper = operation.asset && !operation.dynamic && context.block === context.ir.block && !!singleUseAssetComponentNames && singleUseAssetComponentNames.has(operation.tag);
|
|
1805
|
+
const maybeSelfReference = useAssetComponentHelper && operation.tag.endsWith("__self");
|
|
1731
1806
|
const tag = genTag();
|
|
1732
1807
|
const { root, props, slots, once } = operation;
|
|
1733
1808
|
const rawSlots = genRawSlots(slots, context);
|
|
1734
1809
|
const [ids, handlers] = processInlineHandlers(props, context);
|
|
1735
|
-
const rawProps = context.withId(() => genRawProps(props, context), ids);
|
|
1810
|
+
const rawProps = context.withId(() => genRawProps(props, context, true), ids);
|
|
1736
1811
|
return [
|
|
1737
1812
|
NEWLINE,
|
|
1738
1813
|
...handlers.reduce((acc, { name, value }) => {
|
|
1739
|
-
const handler = genEventHandler(context, [value]
|
|
1814
|
+
const handler = genEventHandler(context, [value]);
|
|
1740
1815
|
return [
|
|
1741
1816
|
...acc,
|
|
1742
1817
|
`const ${name} = `,
|
|
@@ -1745,7 +1820,7 @@ function genCreateComponent(operation, context) {
|
|
|
1745
1820
|
];
|
|
1746
1821
|
}, []),
|
|
1747
1822
|
`const n${operation.id} = `,
|
|
1748
|
-
...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
|
|
1823
|
+
...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true", maybeSelfReference && "true"),
|
|
1749
1824
|
...genDirectivesForElement(operation.id, context)
|
|
1750
1825
|
];
|
|
1751
1826
|
function genTag() {
|
|
@@ -1756,7 +1831,10 @@ function genCreateComponent(operation, context) {
|
|
|
1756
1831
|
...genExpression(operation.dynamic, context),
|
|
1757
1832
|
")"
|
|
1758
1833
|
];
|
|
1759
|
-
else if (
|
|
1834
|
+
else if (useAssetComponentHelper) {
|
|
1835
|
+
const name = maybeSelfReference ? operation.tag.slice(0, -6) : operation.tag;
|
|
1836
|
+
return JSON.stringify(name);
|
|
1837
|
+
} else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
|
|
1760
1838
|
else {
|
|
1761
1839
|
const { tag } = operation;
|
|
1762
1840
|
const builtInTag = isBuiltInComponent(tag);
|
|
@@ -1796,14 +1874,14 @@ function processInlineHandlers(props, context) {
|
|
|
1796
1874
|
}
|
|
1797
1875
|
return [ids, handlers];
|
|
1798
1876
|
}
|
|
1799
|
-
function genRawProps(props, context) {
|
|
1877
|
+
function genRawProps(props, context, directStaticLiteralProps = false) {
|
|
1800
1878
|
const staticProps = props[0];
|
|
1801
1879
|
if ((0, _vue_shared.isArray)(staticProps)) {
|
|
1802
1880
|
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));
|
|
1881
|
+
return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context, directStaticLiteralProps), directStaticLiteralProps);
|
|
1882
|
+
} else if (props.length) return genStaticProps([], context, genDynamicProps(props, context, directStaticLiteralProps), directStaticLiteralProps);
|
|
1805
1883
|
}
|
|
1806
|
-
function genStaticProps(props, context, dynamicProps) {
|
|
1884
|
+
function genStaticProps(props, context, dynamicProps, directStaticLiteralProps = false) {
|
|
1807
1885
|
const args = [];
|
|
1808
1886
|
const handlerGroups = /* @__PURE__ */ new Map();
|
|
1809
1887
|
const ensureHandlerGroup = (keyName, keyFrag) => {
|
|
@@ -1836,11 +1914,11 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1836
1914
|
continue;
|
|
1837
1915
|
}
|
|
1838
1916
|
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
|
|
1917
|
+
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 }));
|
|
1918
|
+
else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, { asComponentProp: true }));
|
|
1841
1919
|
continue;
|
|
1842
1920
|
}
|
|
1843
|
-
args.push(genProp(prop, context, true));
|
|
1921
|
+
args.push(genProp(prop, context, true, true, directStaticLiteralProps && isDirectStaticLiteralProp(prop, context)));
|
|
1844
1922
|
if (prop.model) {
|
|
1845
1923
|
if (prop.key.isStatic) {
|
|
1846
1924
|
const keyName = `onUpdate:${(0, _vue_shared.camelize)(prop.key.content)}`;
|
|
@@ -1865,7 +1943,7 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1865
1943
|
" + \"Modifiers\"]"
|
|
1866
1944
|
];
|
|
1867
1945
|
const modifiersVal = genDirectiveModifiers(modelModifiers);
|
|
1868
|
-
args.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
|
|
1946
|
+
args.push([...modifiersKey, directStaticLiteralProps ? `: { ${modifiersVal} }` : `: () => ({ ${modifiersVal} })`]);
|
|
1869
1947
|
}
|
|
1870
1948
|
}
|
|
1871
1949
|
}
|
|
@@ -1880,13 +1958,13 @@ function genStaticProps(props, context, dynamicProps) {
|
|
|
1880
1958
|
if (dynamicProps) args.push([`$: `, ...dynamicProps]);
|
|
1881
1959
|
return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args);
|
|
1882
1960
|
}
|
|
1883
|
-
function genDynamicProps(props, context) {
|
|
1961
|
+
function genDynamicProps(props, context, directStaticLiteralProps = false) {
|
|
1884
1962
|
const { helper } = context;
|
|
1885
1963
|
const frags = [];
|
|
1886
1964
|
for (const p of props) {
|
|
1887
1965
|
let expr;
|
|
1888
1966
|
if ((0, _vue_shared.isArray)(p)) {
|
|
1889
|
-
if (p.length) frags.push(genStaticProps(p, context));
|
|
1967
|
+
if (p.length) frags.push(genStaticProps(p, context, void 0, directStaticLiteralProps));
|
|
1890
1968
|
continue;
|
|
1891
1969
|
} else if (p.kind === 1) if (p.model) {
|
|
1892
1970
|
const entries = [genProp(p, context)];
|
|
@@ -1897,7 +1975,7 @@ function genDynamicProps(props, context) {
|
|
|
1897
1975
|
];
|
|
1898
1976
|
entries.push([
|
|
1899
1977
|
...updateKey,
|
|
1900
|
-
":
|
|
1978
|
+
": ",
|
|
1901
1979
|
...genModelHandler(p.values[0], context)
|
|
1902
1980
|
]);
|
|
1903
1981
|
const { modelModifiers } = p;
|
|
@@ -1908,10 +1986,10 @@ function genDynamicProps(props, context) {
|
|
|
1908
1986
|
" + \"Modifiers\"]"
|
|
1909
1987
|
];
|
|
1910
1988
|
const modifiersVal = genDirectiveModifiers(modelModifiers);
|
|
1911
|
-
entries.push([...modifiersKey, `:
|
|
1989
|
+
entries.push([...modifiersKey, `: { ${modifiersVal} }`]);
|
|
1912
1990
|
}
|
|
1913
1991
|
expr = genMulti(DELIMITERS_OBJECT_NEWLINE, ...entries);
|
|
1914
|
-
} else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context));
|
|
1992
|
+
} else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context, false, false));
|
|
1915
1993
|
else {
|
|
1916
1994
|
expr = genExpression(p.value, context);
|
|
1917
1995
|
if (p.handler) expr = genCall(helper("toHandlers"), expr);
|
|
@@ -1924,27 +2002,79 @@ function genDynamicProps(props, context) {
|
|
|
1924
2002
|
}
|
|
1925
2003
|
if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags);
|
|
1926
2004
|
}
|
|
1927
|
-
function genProp(prop, context, isStatic) {
|
|
2005
|
+
function genProp(prop, context, isStatic, wrapHandler = true, directStaticLiteral = false) {
|
|
1928
2006
|
const values = genPropValue(prop.values, context);
|
|
1929
2007
|
return [
|
|
1930
2008
|
...genPropKey(prop, context),
|
|
1931
2009
|
": ",
|
|
1932
|
-
...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers,
|
|
2010
|
+
...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, {
|
|
2011
|
+
asComponentProp: true,
|
|
2012
|
+
extraWrap: wrapHandler
|
|
2013
|
+
}) : isStatic ? directStaticLiteral ? values : [
|
|
1933
2014
|
"() => (",
|
|
1934
2015
|
...values,
|
|
1935
2016
|
")"
|
|
1936
2017
|
] : values
|
|
1937
2018
|
];
|
|
1938
2019
|
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Static literal values are safe to emit directly because reading them cannot
|
|
2022
|
+
* touch reactive state. Keep handlers, v-model values, and dynamic expressions
|
|
2023
|
+
* as getter sources to preserve lazy access and merge semantics.
|
|
2024
|
+
*/
|
|
2025
|
+
function isDirectStaticLiteralProp(prop, context) {
|
|
2026
|
+
return prop.key.isStatic && prop.values.length === 1 && !prop.handler && !prop.model && isDirectConstantValue(prop.values[0], context);
|
|
2027
|
+
}
|
|
2028
|
+
function isDirectConstantValue(value, context) {
|
|
2029
|
+
value = context.getExpressionReplacement(value);
|
|
2030
|
+
if (value.isStatic) return true;
|
|
2031
|
+
const ast = value.ast;
|
|
2032
|
+
if (ast === null) return value.content === "true" || value.content === "false" || value.content === "null" || value.content === "undefined";
|
|
2033
|
+
if (!ast) return false;
|
|
2034
|
+
return isDirectConstantAst(ast);
|
|
2035
|
+
}
|
|
2036
|
+
function isDirectConstantAst(node) {
|
|
2037
|
+
switch (node.type) {
|
|
2038
|
+
case "StringLiteral":
|
|
2039
|
+
case "NumericLiteral":
|
|
2040
|
+
case "BooleanLiteral":
|
|
2041
|
+
case "NullLiteral":
|
|
2042
|
+
case "BigIntLiteral": return true;
|
|
2043
|
+
case "Identifier": return node.name === "undefined";
|
|
2044
|
+
case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
|
|
2045
|
+
case "ArrayExpression": return node.elements.every((element) => element === null || element.type !== "SpreadElement" && isDirectConstantAst(element));
|
|
2046
|
+
case "ObjectExpression": return node.properties.every((prop) => prop.type === "ObjectProperty" && !prop.computed && isDirectConstantAst(prop.value));
|
|
2047
|
+
}
|
|
2048
|
+
return false;
|
|
2049
|
+
}
|
|
2050
|
+
function isDirectTemplateConstantAst(node) {
|
|
2051
|
+
switch (node.type) {
|
|
2052
|
+
case "StringLiteral":
|
|
2053
|
+
case "NumericLiteral":
|
|
2054
|
+
case "BooleanLiteral":
|
|
2055
|
+
case "NullLiteral":
|
|
2056
|
+
case "BigIntLiteral": return true;
|
|
2057
|
+
case "Identifier": return node.name === "undefined";
|
|
2058
|
+
case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
|
|
2059
|
+
}
|
|
2060
|
+
return false;
|
|
2061
|
+
}
|
|
1939
2062
|
function genRawSlots(slots, context) {
|
|
1940
2063
|
if (!slots.length) return;
|
|
1941
2064
|
const staticSlots = slots[0];
|
|
1942
|
-
if (staticSlots.slotType === 0)
|
|
1943
|
-
|
|
2065
|
+
if (staticSlots.slotType === 0) {
|
|
2066
|
+
const defaultSlot = getSingleDefaultSlot(staticSlots);
|
|
2067
|
+
if (defaultSlot && slots.length === 1) return genSlotBlockWithProps(defaultSlot, context);
|
|
2068
|
+
return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
|
|
2069
|
+
} else return genStaticSlots({
|
|
1944
2070
|
slotType: 0,
|
|
1945
2071
|
slots: {}
|
|
1946
2072
|
}, context, slots);
|
|
1947
2073
|
}
|
|
2074
|
+
function getSingleDefaultSlot({ slots }) {
|
|
2075
|
+
const names = Object.keys(slots);
|
|
2076
|
+
return names.length === 1 && names[0] === "default" ? slots.default : void 0;
|
|
2077
|
+
}
|
|
1948
2078
|
function genStaticSlots({ slots }, context, dynamicSlots) {
|
|
1949
2079
|
const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]);
|
|
1950
2080
|
if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]);
|
|
@@ -2036,7 +2166,9 @@ function genSlotBlockWithProps(oper, context) {
|
|
|
2036
2166
|
} else propsName = props.content;
|
|
2037
2167
|
const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {};
|
|
2038
2168
|
if (propsName) idMap[propsName] = null;
|
|
2169
|
+
const exitSlotBlock = context.enterSlotBlock();
|
|
2039
2170
|
let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap);
|
|
2171
|
+
exitSlotBlock();
|
|
2040
2172
|
exitScope && exitScope();
|
|
2041
2173
|
if (node.type === 1) {
|
|
2042
2174
|
if (needsVaporCtx(oper)) blockFn = [
|
|
@@ -2097,16 +2229,18 @@ function hasComponentOrSlotInIf(node) {
|
|
|
2097
2229
|
//#region packages/compiler-vapor/src/generators/slotOutlet.ts
|
|
2098
2230
|
function genSlotOutlet(oper, context) {
|
|
2099
2231
|
const { helper } = context;
|
|
2100
|
-
const { id, name, fallback,
|
|
2232
|
+
const { id, name, fallback, flags } = oper;
|
|
2101
2233
|
const [frag, push] = buildCodeFragment();
|
|
2102
|
-
|
|
2234
|
+
let fallbackArg;
|
|
2235
|
+
if (fallback) fallbackArg = genBlock(fallback, context);
|
|
2236
|
+
const createSlot = helper("createSlot");
|
|
2237
|
+
const rawPropsArg = genRawProps(oper.props, context, true);
|
|
2238
|
+
const nameArg = name.isStatic && name.content === "default" && !rawPropsArg && !fallbackArg && !flags ? void 0 : name.isStatic ? genExpression(name, context) : [
|
|
2103
2239
|
"() => (",
|
|
2104
2240
|
...genExpression(name, context),
|
|
2105
2241
|
")"
|
|
2106
2242
|
];
|
|
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"));
|
|
2243
|
+
push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, flags ? String(flags) : void 0));
|
|
2110
2244
|
return frag;
|
|
2111
2245
|
}
|
|
2112
2246
|
//#endregion
|
|
@@ -2166,28 +2300,35 @@ function genEffects(effects, context, genExtraFrag) {
|
|
|
2166
2300
|
const [frag, push, unshift] = buildCodeFragment();
|
|
2167
2301
|
const shouldDeclare = genExtraFrag === void 0;
|
|
2168
2302
|
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
|
-
|
|
2303
|
+
const { ids, frag: declarationFrags, varNames, expressionReplacements } = processExpressions(context, expressions, shouldDeclare);
|
|
2304
|
+
if (shouldDeclare && !declarationFrags.length && !varNames.length) {
|
|
2305
|
+
const effect = effects.length === 1 ? effects[0] : void 0;
|
|
2306
|
+
const operation = effect && effect.operations.length === 1 ? effect.operations[0] : void 0;
|
|
2307
|
+
if (operation && operation.type === 9 && operation.effect && !operation.refFor) return context.withExpressionReplacements(expressionReplacements, () => context.withId(() => genSetTemplateRefBinding(operation, context), ids));
|
|
2308
|
+
}
|
|
2309
|
+
return context.withExpressionReplacements(expressionReplacements, () => {
|
|
2310
|
+
push(...declarationFrags);
|
|
2311
|
+
for (let i = 0; i < effects.length; i++) {
|
|
2312
|
+
const effect = effects[i];
|
|
2313
|
+
operationsCount += effect.operations.length;
|
|
2314
|
+
const frags = context.withId(() => genEffect(effect, context), ids);
|
|
2315
|
+
i > 0 && push(NEWLINE);
|
|
2316
|
+
if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
|
|
2317
|
+
push(...frags);
|
|
2318
|
+
}
|
|
2319
|
+
if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
|
|
2320
|
+
unshift(`{`, INDENT_START, NEWLINE);
|
|
2321
|
+
push(INDENT_END, NEWLINE, "}");
|
|
2322
|
+
if (!effects.length) unshift(NEWLINE);
|
|
2323
|
+
}
|
|
2324
|
+
if (effects.length) {
|
|
2325
|
+
unshift(NEWLINE, `${helper("renderEffect")}(() => `);
|
|
2326
|
+
push(`)`);
|
|
2327
|
+
}
|
|
2328
|
+
if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
|
|
2329
|
+
if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
|
|
2330
|
+
return frag;
|
|
2331
|
+
});
|
|
2191
2332
|
}
|
|
2192
2333
|
function genEffect({ operations }, context) {
|
|
2193
2334
|
const [frag, push] = buildCodeFragment();
|
|
@@ -2206,9 +2347,8 @@ function genTemplates(templates, context) {
|
|
|
2206
2347
|
const result = [];
|
|
2207
2348
|
templates.forEach(({ content, ns, root, static: isStatic }, i) => {
|
|
2208
2349
|
let args = JSON.stringify(content).replace(IMPORT_EXPR_RE, `" + $1 + "`);
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
if (isStatic || ns) args += `, ${isStatic ? "true" : "false"}`;
|
|
2350
|
+
const flags = (root ? 1 : 0) | (isStatic ? 2 : 0);
|
|
2351
|
+
if (flags || ns) args += `, ${flags}`;
|
|
2212
2352
|
if (ns) args += `, ${ns}`;
|
|
2213
2353
|
result.push(`const ${context.tName(i)} = ${context.helper("template")}(${args})\n`);
|
|
2214
2354
|
});
|
|
@@ -2226,10 +2366,13 @@ function genSelf(dynamic, context, flushBeforeDynamic) {
|
|
|
2226
2366
|
return frag;
|
|
2227
2367
|
}
|
|
2228
2368
|
function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flushBeforeDynamic) {
|
|
2229
|
-
const { helper } = context;
|
|
2230
2369
|
const [frag, push] = buildCodeFragment();
|
|
2231
2370
|
const { children } = dynamic;
|
|
2232
2371
|
let offset = 0;
|
|
2372
|
+
/**
|
|
2373
|
+
* `reusable` means the previous access target is a p* cursor that can be
|
|
2374
|
+
* reassigned by the next lookup. Referenced n* variables must stay stable.
|
|
2375
|
+
*/
|
|
2233
2376
|
let prev;
|
|
2234
2377
|
for (const [index, child] of children.entries()) {
|
|
2235
2378
|
if (child.flags & 2) offset--;
|
|
@@ -2246,27 +2389,118 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flush
|
|
|
2246
2389
|
}
|
|
2247
2390
|
const elementIndex = index + offset;
|
|
2248
2391
|
const logicalIndex = child.logicalIndex !== void 0 ? String(child.logicalIndex) : void 0;
|
|
2249
|
-
const
|
|
2250
|
-
|
|
2251
|
-
if (
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2392
|
+
const inlinePlaceholder = id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6);
|
|
2393
|
+
const accessPath = genAccessPath(context, from, child, elementIndex, logicalIndex, prev);
|
|
2394
|
+
if (inlinePlaceholder) {
|
|
2395
|
+
if (prev && prev[2]) {
|
|
2396
|
+
push(...genChildren(child, context, pushBlock, [
|
|
2397
|
+
"(",
|
|
2398
|
+
prev[0],
|
|
2399
|
+
" = ",
|
|
2400
|
+
...accessPath,
|
|
2401
|
+
")"
|
|
2402
|
+
], flushBeforeDynamic));
|
|
2403
|
+
prev = [
|
|
2404
|
+
prev[0],
|
|
2405
|
+
elementIndex,
|
|
2406
|
+
true
|
|
2407
|
+
];
|
|
2408
|
+
continue;
|
|
2409
|
+
}
|
|
2410
|
+
if (!hasAdjacentFollowingAccessChild(children, index, elementIndex, offset)) {
|
|
2411
|
+
push(...genChildren(child, context, pushBlock, accessPath, flushBeforeDynamic));
|
|
2412
|
+
continue;
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
let variable;
|
|
2416
|
+
if (id === void 0 && prev && prev[2]) {
|
|
2417
|
+
variable = prev[0];
|
|
2418
|
+
pushBlock(NEWLINE, `${variable} = `, ...accessPath);
|
|
2419
|
+
} else {
|
|
2420
|
+
variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
|
|
2421
|
+
pushBlock(NEWLINE, id === void 0 ? `let ${variable} = ` : `const ${variable} = `, ...accessPath);
|
|
2259
2422
|
}
|
|
2260
2423
|
if (id === child.anchor && !child.hasDynamicChild) {
|
|
2261
2424
|
flushBeforeDynamic && flushBeforeDynamic(child, push);
|
|
2262
2425
|
push(...genSelf(child, context, flushBeforeDynamic));
|
|
2263
2426
|
}
|
|
2264
2427
|
if (id !== void 0) push(...genDirectivesForElement(id, context));
|
|
2265
|
-
prev = [
|
|
2428
|
+
prev = [
|
|
2429
|
+
variable,
|
|
2430
|
+
elementIndex,
|
|
2431
|
+
id === void 0
|
|
2432
|
+
];
|
|
2266
2433
|
push(...genChildren(child, context, pushBlock, variable, flushBeforeDynamic));
|
|
2267
2434
|
}
|
|
2268
2435
|
return frag;
|
|
2269
2436
|
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Build one DOM lookup path while preserving the fast sibling walk:
|
|
2439
|
+
* adjacent nodes use _next(prev), otherwise fall back to _nthChild(parent).
|
|
2440
|
+
*/
|
|
2441
|
+
function genAccessPath({ helper }, from, child, elementIndex, logicalIndex, prev) {
|
|
2442
|
+
if (prev) return elementIndex - prev[1] === 1 ? genCall(helper("next"), prev[0], logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
|
|
2443
|
+
if (elementIndex === 0) return genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0);
|
|
2444
|
+
const firstChild = genCall(helper("child"), from);
|
|
2445
|
+
return elementIndex === 1 ? genCall(helper("next"), firstChild, logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* Only inline a placeholder when materializing it would not save a parent
|
|
2449
|
+
* lookup. If its child tree needs the parent more than once, keep p* so the
|
|
2450
|
+
* generated code does not duplicate _child/_nthChild work.
|
|
2451
|
+
*/
|
|
2452
|
+
function canInlinePlaceholder(dynamic) {
|
|
2453
|
+
return dynamic.hasDynamicChild === true && countParentAccessUsages(dynamic) === 1;
|
|
2454
|
+
}
|
|
2455
|
+
/**
|
|
2456
|
+
* A following access can reuse the current placeholder cursor only when it is
|
|
2457
|
+
* the next DOM sibling. Gapped siblings need _nthChild(parent, index) instead.
|
|
2458
|
+
*/
|
|
2459
|
+
function hasAdjacentFollowingAccessChild(children, index, elementIndex, offset) {
|
|
2460
|
+
let futureOffset = offset;
|
|
2461
|
+
for (let i = index + 1; i < children.length; i++) {
|
|
2462
|
+
const child = children[i];
|
|
2463
|
+
if (child.flags & 2) futureOffset--;
|
|
2464
|
+
if (!(child.flags & 4 && child.template != null) && (!!(child.flags & 1) || child.hasDynamicChild)) return i + futureOffset - elementIndex === 1;
|
|
2465
|
+
}
|
|
2466
|
+
return false;
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Mirrors genChildren's traversal closely enough to count how many emitted
|
|
2470
|
+
* access paths would start from this placeholder's parent. This is the guard
|
|
2471
|
+
* that keeps inline placeholders from duplicating parent lookups.
|
|
2472
|
+
*/
|
|
2473
|
+
function countParentAccessUsages(dynamic) {
|
|
2474
|
+
let usages = 0;
|
|
2475
|
+
let offset = 0;
|
|
2476
|
+
let prev;
|
|
2477
|
+
for (const [index, child] of dynamic.children.entries()) {
|
|
2478
|
+
if (child.flags & 2) offset--;
|
|
2479
|
+
if (child.flags & 4 && child.template != null) continue;
|
|
2480
|
+
const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
|
|
2481
|
+
if (id === void 0 && !child.hasDynamicChild) continue;
|
|
2482
|
+
const elementIndex = index + offset;
|
|
2483
|
+
const usesParent = !prev || elementIndex - prev[0] !== 1;
|
|
2484
|
+
if (id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6)) {
|
|
2485
|
+
if (prev && prev[1]) {
|
|
2486
|
+
if (usesParent) usages++;
|
|
2487
|
+
prev = [elementIndex, true];
|
|
2488
|
+
continue;
|
|
2489
|
+
}
|
|
2490
|
+
if (!hasAdjacentFollowingAccessChild(dynamic.children, index, elementIndex, offset)) {
|
|
2491
|
+
if (usesParent) usages++;
|
|
2492
|
+
continue;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
if (usesParent) usages++;
|
|
2496
|
+
prev = [elementIndex, id === void 0];
|
|
2497
|
+
}
|
|
2498
|
+
return usages;
|
|
2499
|
+
}
|
|
2500
|
+
function genNthChild(nthChild, from, elementIndex, logicalIndex) {
|
|
2501
|
+
const index = String(elementIndex);
|
|
2502
|
+
return genCall(nthChild, from, index, logicalIndex === index ? void 0 : logicalIndex);
|
|
2503
|
+
}
|
|
2270
2504
|
//#endregion
|
|
2271
2505
|
//#region packages/compiler-vapor/src/generators/block.ts
|
|
2272
2506
|
function genBlock(oper, context, args = [], root) {
|
|
@@ -2285,8 +2519,12 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
|
2285
2519
|
const [frag, push] = buildCodeFragment();
|
|
2286
2520
|
const { dynamic, effect, operation, returns } = block;
|
|
2287
2521
|
const resetBlock = context.enterBlock(block);
|
|
2522
|
+
const singleUseAssetComponentNames = root ? collectSingleUseAssetComponents(block) : void 0;
|
|
2523
|
+
const prevSingleUseAssetComponentNames = context.singleUseAssetComponentNames;
|
|
2524
|
+
if (singleUseAssetComponentNames) context.singleUseAssetComponentNames = singleUseAssetComponentNames;
|
|
2288
2525
|
if (root) {
|
|
2289
2526
|
for (let name of context.ir.component) {
|
|
2527
|
+
if (singleUseAssetComponentNames && singleUseAssetComponentNames.has(name)) continue;
|
|
2290
2528
|
const id = (0, _vue_compiler_dom.toValidAssetId)(name, "component");
|
|
2291
2529
|
const maybeSelfReference = name.endsWith("__self");
|
|
2292
2530
|
if (maybeSelfReference) name = name.slice(0, -6);
|
|
@@ -2322,15 +2560,101 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
|
2322
2560
|
const returnNodes = returns.map((n) => `n${n}`);
|
|
2323
2561
|
push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"]);
|
|
2324
2562
|
resetBlock();
|
|
2563
|
+
context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames;
|
|
2325
2564
|
return frag;
|
|
2326
2565
|
function genResolveAssets(kind, helper) {
|
|
2327
2566
|
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
2567
|
}
|
|
2329
2568
|
}
|
|
2569
|
+
function collectSingleUseAssetComponents(block) {
|
|
2570
|
+
const usageMap = /* @__PURE__ */ new Map();
|
|
2571
|
+
const seenOperations = /* @__PURE__ */ new Set();
|
|
2572
|
+
visitBlock(block, true);
|
|
2573
|
+
const names = /* @__PURE__ */ new Set();
|
|
2574
|
+
for (const [name, usage] of usageMap) if (usage.count === 1 && usage.root) names.add(name);
|
|
2575
|
+
return names;
|
|
2576
|
+
function visitBlock(block, rootCandidate) {
|
|
2577
|
+
visitDynamic(block.dynamic, rootCandidate);
|
|
2578
|
+
for (const operation of block.operation) visitOperation(operation, rootCandidate);
|
|
2579
|
+
for (const effect of block.effect) for (const operation of effect.operations) visitOperation(operation, false);
|
|
2580
|
+
}
|
|
2581
|
+
function visitDynamic(dynamic, rootCandidate) {
|
|
2582
|
+
if (dynamic.operation) visitOperation(dynamic.operation, rootCandidate);
|
|
2583
|
+
for (const child of dynamic.children) visitDynamic(child, rootCandidate);
|
|
2584
|
+
}
|
|
2585
|
+
function visitOperation(operation, rootCandidate) {
|
|
2586
|
+
if (seenOperations.has(operation)) return;
|
|
2587
|
+
seenOperations.add(operation);
|
|
2588
|
+
if (operation.type === 12) {
|
|
2589
|
+
if (operation.asset) {
|
|
2590
|
+
const usage = usageMap.get(operation.tag) || {
|
|
2591
|
+
count: 0,
|
|
2592
|
+
root: false
|
|
2593
|
+
};
|
|
2594
|
+
usage.count++;
|
|
2595
|
+
if (rootCandidate) usage.root = true;
|
|
2596
|
+
usageMap.set(operation.tag, usage);
|
|
2597
|
+
}
|
|
2598
|
+
visitSlots(operation.slots);
|
|
2599
|
+
return;
|
|
2600
|
+
}
|
|
2601
|
+
switch (operation.type) {
|
|
2602
|
+
case 15:
|
|
2603
|
+
visitBlock(operation.positive, false);
|
|
2604
|
+
if (operation.negative) if (operation.negative.type === 15) visitOperation(operation.negative, false);
|
|
2605
|
+
else visitBlock(operation.negative, false);
|
|
2606
|
+
break;
|
|
2607
|
+
case 16:
|
|
2608
|
+
visitBlock(operation.render, false);
|
|
2609
|
+
break;
|
|
2610
|
+
case 17:
|
|
2611
|
+
visitBlock(operation.block, false);
|
|
2612
|
+
break;
|
|
2613
|
+
case 13:
|
|
2614
|
+
if (operation.fallback) visitBlock(operation.fallback, false);
|
|
2615
|
+
break;
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
function visitSlots(slots) {
|
|
2619
|
+
for (const slot of slots) switch (slot.slotType) {
|
|
2620
|
+
case 0:
|
|
2621
|
+
for (const name in slot.slots) visitBlock(slot.slots[name], false);
|
|
2622
|
+
break;
|
|
2623
|
+
case 1:
|
|
2624
|
+
case 2:
|
|
2625
|
+
visitBlock(slot.fn, false);
|
|
2626
|
+
break;
|
|
2627
|
+
case 3:
|
|
2628
|
+
visitSlots([slot.positive]);
|
|
2629
|
+
if (slot.negative) visitSlots([slot.negative]);
|
|
2630
|
+
break;
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2330
2634
|
//#endregion
|
|
2331
2635
|
//#region packages/compiler-vapor/src/generate.ts
|
|
2332
2636
|
const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/;
|
|
2637
|
+
const helperNameAliases = {
|
|
2638
|
+
withVaporKeys: "withKeys",
|
|
2639
|
+
withVaporModifiers: "withModifiers"
|
|
2640
|
+
};
|
|
2333
2641
|
var CodegenContext = class {
|
|
2642
|
+
withExpressionReplacements(map, fn) {
|
|
2643
|
+
if (map.size === 0) return fn();
|
|
2644
|
+
this.expressionReplacements.unshift(map);
|
|
2645
|
+
try {
|
|
2646
|
+
return fn();
|
|
2647
|
+
} finally {
|
|
2648
|
+
(0, _vue_shared.remove)(this.expressionReplacements, map);
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
getExpressionReplacement(node) {
|
|
2652
|
+
for (const map of this.expressionReplacements) {
|
|
2653
|
+
const replacement = map.get(node);
|
|
2654
|
+
if (replacement) return replacement;
|
|
2655
|
+
}
|
|
2656
|
+
return node;
|
|
2657
|
+
}
|
|
2334
2658
|
withId(fn, map) {
|
|
2335
2659
|
const { identifiers } = this;
|
|
2336
2660
|
const ids = Object.keys(map);
|
|
@@ -2347,9 +2671,19 @@ var CodegenContext = class {
|
|
|
2347
2671
|
this.block = block;
|
|
2348
2672
|
return () => this.block = parent;
|
|
2349
2673
|
}
|
|
2674
|
+
enterSlotBlock() {
|
|
2675
|
+
const parent = this.inSlotBlock;
|
|
2676
|
+
this.inSlotBlock = true;
|
|
2677
|
+
return () => this.inSlotBlock = parent;
|
|
2678
|
+
}
|
|
2350
2679
|
enterScope() {
|
|
2351
2680
|
return [this.scopeLevel++, () => this.scopeLevel--];
|
|
2352
2681
|
}
|
|
2682
|
+
isHelperNameAvailable(name) {
|
|
2683
|
+
if (this.bindingNames.has(name)) return false;
|
|
2684
|
+
for (const alias of this.helpers.values()) if (alias === name) return false;
|
|
2685
|
+
return true;
|
|
2686
|
+
}
|
|
2353
2687
|
initNextIdMap() {
|
|
2354
2688
|
if (this.bindingNames.size === 0) return;
|
|
2355
2689
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2384,19 +2718,29 @@ var CodegenContext = class {
|
|
|
2384
2718
|
this.ir = ir;
|
|
2385
2719
|
this.bindingNames = /* @__PURE__ */ new Set();
|
|
2386
2720
|
this.helpers = /* @__PURE__ */ new Map();
|
|
2721
|
+
this.needsTemplateRefSetter = false;
|
|
2722
|
+
this.inSlotBlock = false;
|
|
2387
2723
|
this.helper = (name) => {
|
|
2388
2724
|
if (this.helpers.has(name)) return this.helpers.get(name);
|
|
2389
|
-
const base = `_${name}`;
|
|
2390
|
-
if (this.
|
|
2725
|
+
const base = `_${helperNameAliases[name] || name}`;
|
|
2726
|
+
if (this.isHelperNameAvailable(base)) {
|
|
2391
2727
|
this.helpers.set(name, base);
|
|
2392
2728
|
return base;
|
|
2393
2729
|
}
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2396
|
-
|
|
2730
|
+
const map = this.nextIdMap.get(base);
|
|
2731
|
+
let next = 1;
|
|
2732
|
+
while (true) {
|
|
2733
|
+
const alias = `${base}${getNextId(map, next)}`;
|
|
2734
|
+
if (this.isHelperNameAvailable(alias)) {
|
|
2735
|
+
this.helpers.set(name, alias);
|
|
2736
|
+
return alias;
|
|
2737
|
+
}
|
|
2738
|
+
next++;
|
|
2739
|
+
}
|
|
2397
2740
|
};
|
|
2398
2741
|
this.delegates = /* @__PURE__ */ new Set();
|
|
2399
2742
|
this.identifiers = Object.create(null);
|
|
2743
|
+
this.expressionReplacements = [];
|
|
2400
2744
|
this.seenInlineHandlerNames = Object.create(null);
|
|
2401
2745
|
this.scopeLevel = 0;
|
|
2402
2746
|
this.templateVars = /* @__PURE__ */ new Map();
|
|
@@ -2423,6 +2767,7 @@ var CodegenContext = class {
|
|
|
2423
2767
|
this.block = ir.block;
|
|
2424
2768
|
this.bindingNames = new Set(this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []);
|
|
2425
2769
|
this.initNextIdMap();
|
|
2770
|
+
this.staticTemplateRefHelperCandidate = getStaticTemplateRefHelperCandidate(ir.block);
|
|
2426
2771
|
}
|
|
2427
2772
|
};
|
|
2428
2773
|
function generate(ir, options = {}) {
|
|
@@ -2435,8 +2780,11 @@ function generate(ir, options = {}) {
|
|
|
2435
2780
|
const signature = (options.isTS ? args.map((arg) => `${arg}: any`) : args).join(", ");
|
|
2436
2781
|
if (!inline) push(NEWLINE, `export function ${functionName}(${signature}) {`);
|
|
2437
2782
|
push(INDENT_START);
|
|
2438
|
-
|
|
2439
|
-
|
|
2783
|
+
const templateRefSetterHelper = ir.hasTemplateRef ? context.helper("createTemplateRefSetter") : void 0;
|
|
2784
|
+
const body = genBlockContent(ir.block, context, true);
|
|
2785
|
+
if (context.needsTemplateRefSetter) push(NEWLINE, `const ${setTemplateRefIdent} = ${templateRefSetterHelper}()`);
|
|
2786
|
+
else if (templateRefSetterHelper) context.helpers.delete("createTemplateRefSetter");
|
|
2787
|
+
push(...body);
|
|
2440
2788
|
push(INDENT_END, NEWLINE);
|
|
2441
2789
|
if (!inline) push("}");
|
|
2442
2790
|
const delegates = genDelegates(context);
|
|
@@ -2471,6 +2819,11 @@ function genAssetImports({ ir }) {
|
|
|
2471
2819
|
}
|
|
2472
2820
|
return imports;
|
|
2473
2821
|
}
|
|
2822
|
+
function getStaticTemplateRefHelperCandidate(block) {
|
|
2823
|
+
if (block.operation.length !== 1) return;
|
|
2824
|
+
const operation = block.operation[0];
|
|
2825
|
+
if (operation.type === 9 && !operation.effect && !operation.refFor && operation.value.isStatic) return operation;
|
|
2826
|
+
}
|
|
2474
2827
|
//#endregion
|
|
2475
2828
|
//#region packages/compiler-vapor/src/transforms/vBind.ts
|
|
2476
2829
|
function normalizeBindShorthand(arg, context) {
|
|
@@ -2636,6 +2989,7 @@ function resolveSetupReference(name, context) {
|
|
|
2636
2989
|
}
|
|
2637
2990
|
const dynamicKeys = ["indeterminate"];
|
|
2638
2991
|
const NEEDS_QUOTES_RE = /[\s"'`=<>]/;
|
|
2992
|
+
const UNSAFE_ATTR_NAME_RE = /[\u0000-\u0020"'<=/>]/;
|
|
2639
2993
|
function transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, omitEndTag) {
|
|
2640
2994
|
const { tag } = node;
|
|
2641
2995
|
const { scopeId } = context.options;
|
|
@@ -2653,18 +3007,55 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
|
|
|
2653
3007
|
}, getEffectIndex);
|
|
2654
3008
|
} else {
|
|
2655
3009
|
let prevWasQuoted = false;
|
|
3010
|
+
const appendTemplateProp = (key, value = "", generated = false) => {
|
|
3011
|
+
if (!prevWasQuoted) template += ` `;
|
|
3012
|
+
template += key;
|
|
3013
|
+
if (value) {
|
|
3014
|
+
const escapedValue = generated ? escapeGeneratedAttrValue(value) : value.replace(/"/g, """);
|
|
3015
|
+
template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${escapedValue}"` : `=${escapedValue}`;
|
|
3016
|
+
} else prevWasQuoted = false;
|
|
3017
|
+
};
|
|
2656
3018
|
for (const prop of propsResult[1]) {
|
|
2657
3019
|
const { key, values } = prop;
|
|
2658
3020
|
if (context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
|
|
2659
3021
|
if (!prevWasQuoted) template += ` `;
|
|
2660
3022
|
template += `${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
|
|
2661
3023
|
prevWasQuoted = true;
|
|
3024
|
+
} 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)) {
|
|
3025
|
+
const value = values[0].content === "''" ? "" : values[0].content;
|
|
3026
|
+
appendTemplateProp(key.content, value);
|
|
3027
|
+
} else {
|
|
3028
|
+
const include = foldBooleanAttrValue(values);
|
|
3029
|
+
if (include != null) {
|
|
3030
|
+
if (include) appendTemplateProp(key.content);
|
|
3031
|
+
} else {
|
|
3032
|
+
dynamicProps.push(key.content);
|
|
3033
|
+
context.registerEffect(values, {
|
|
3034
|
+
type: 3,
|
|
3035
|
+
element: context.reference(),
|
|
3036
|
+
prop,
|
|
3037
|
+
tag
|
|
3038
|
+
}, getEffectIndex);
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
else if (key.isStatic && !prop.modifier && hasBoundValue(values)) {
|
|
3042
|
+
let foldedValue;
|
|
3043
|
+
if (key.content === "class") foldedValue = foldClassValues(values);
|
|
3044
|
+
else if (key.content === "style") foldedValue = foldStyleValues(values);
|
|
3045
|
+
if (foldedValue != null) {
|
|
3046
|
+
if (foldedValue) appendTemplateProp(key.content, foldedValue, true);
|
|
3047
|
+
} else {
|
|
3048
|
+
dynamicProps.push(key.content);
|
|
3049
|
+
context.registerEffect(values, {
|
|
3050
|
+
type: 3,
|
|
3051
|
+
element: context.reference(),
|
|
3052
|
+
prop,
|
|
3053
|
+
tag
|
|
3054
|
+
}, getEffectIndex);
|
|
3055
|
+
}
|
|
2662
3056
|
} else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
|
|
2663
|
-
if (!prevWasQuoted) template += ` `;
|
|
2664
3057
|
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;
|
|
3058
|
+
appendTemplateProp(key.content, value);
|
|
2668
3059
|
} else {
|
|
2669
3060
|
dynamicProps.push(key.content);
|
|
2670
3061
|
context.registerEffect(values, {
|
|
@@ -2686,6 +3077,123 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
|
|
|
2686
3077
|
} else context.template += template;
|
|
2687
3078
|
if (staticKey) context.registerOperation(createSetBlockKey(context.reference(), staticKey));
|
|
2688
3079
|
}
|
|
3080
|
+
function escapeGeneratedAttrValue(value) {
|
|
3081
|
+
return value.replace(/&/g, "&").replace(/"/g, """);
|
|
3082
|
+
}
|
|
3083
|
+
function foldBooleanAttrValue(values) {
|
|
3084
|
+
if (values.length !== 1) return;
|
|
3085
|
+
const evaluated = evaluateConstantExpression(values[0]);
|
|
3086
|
+
if (!evaluated) return;
|
|
3087
|
+
const value = evaluated.value;
|
|
3088
|
+
if (value === true || value === false || value == null) return (0, _vue_shared.includeBooleanAttr)(value);
|
|
3089
|
+
}
|
|
3090
|
+
function foldStyleValues(values) {
|
|
3091
|
+
const evaluatedValues = [];
|
|
3092
|
+
for (const value of values) {
|
|
3093
|
+
const evaluated = evaluateConstantExpression(value);
|
|
3094
|
+
if (!evaluated || !isStaticStyleValue(evaluated.value)) return;
|
|
3095
|
+
evaluatedValues.push(evaluated.value);
|
|
3096
|
+
}
|
|
3097
|
+
return (0, _vue_shared.stringifyStyle)((0, _vue_shared.normalizeStyle)(evaluatedValues.length === 1 ? evaluatedValues[0] : evaluatedValues));
|
|
3098
|
+
}
|
|
3099
|
+
function isStaticStyleValue(value) {
|
|
3100
|
+
if (typeof value === "string") return true;
|
|
3101
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
3102
|
+
for (const key in value) {
|
|
3103
|
+
const propValue = value[key];
|
|
3104
|
+
if (!isSafeStylePropertyName(key) || !isSafeStylePropertyValue(propValue)) return false;
|
|
3105
|
+
}
|
|
3106
|
+
return true;
|
|
3107
|
+
}
|
|
3108
|
+
function isSafeStylePropertyName(key) {
|
|
3109
|
+
return !!key && !/[;:]/.test(key);
|
|
3110
|
+
}
|
|
3111
|
+
function isSafeStylePropertyValue(value) {
|
|
3112
|
+
return typeof value === "number" || typeof value === "string" && !value.includes(";");
|
|
3113
|
+
}
|
|
3114
|
+
function hasBoundValue(values) {
|
|
3115
|
+
return values.some((value) => !value.isStatic && value.content !== "''");
|
|
3116
|
+
}
|
|
3117
|
+
function foldClassValues(values) {
|
|
3118
|
+
let templateValue = "";
|
|
3119
|
+
let changed = false;
|
|
3120
|
+
for (const value of values) {
|
|
3121
|
+
const evaluated = evaluateConstantExpression(value);
|
|
3122
|
+
if (evaluated) {
|
|
3123
|
+
const normalized = (0, _vue_shared.normalizeClass)(evaluated.value);
|
|
3124
|
+
if (normalized) templateValue = appendClass(templateValue, normalized);
|
|
3125
|
+
else changed = true;
|
|
3126
|
+
continue;
|
|
3127
|
+
}
|
|
3128
|
+
return;
|
|
3129
|
+
}
|
|
3130
|
+
return changed || templateValue ? templateValue : void 0;
|
|
3131
|
+
}
|
|
3132
|
+
function appendClass(base, value) {
|
|
3133
|
+
return base ? value ? `${base} ${value}` : base : value;
|
|
3134
|
+
}
|
|
3135
|
+
function getObjectPropertyName(prop) {
|
|
3136
|
+
const key = prop.key;
|
|
3137
|
+
if (key.type === "Identifier") return key.name;
|
|
3138
|
+
else if (key.type === "StringLiteral") return key.value;
|
|
3139
|
+
else if (key.type === "NumericLiteral") return String(key.value);
|
|
3140
|
+
}
|
|
3141
|
+
function evaluateConstantExpression(node) {
|
|
3142
|
+
if (node.isStatic) return { value: node.content };
|
|
3143
|
+
const ast = node.ast;
|
|
3144
|
+
if (ast === null) {
|
|
3145
|
+
if (node.content === "true") return { value: true };
|
|
3146
|
+
else if (node.content === "false") return { value: false };
|
|
3147
|
+
else if (node.content === "null") return { value: null };
|
|
3148
|
+
else if (node.content === "undefined") return { value: void 0 };
|
|
3149
|
+
}
|
|
3150
|
+
if (!ast) return;
|
|
3151
|
+
return evaluateConstantAst(ast);
|
|
3152
|
+
}
|
|
3153
|
+
function evaluateConstantAst(node) {
|
|
3154
|
+
switch (node.type) {
|
|
3155
|
+
case "StringLiteral": return { value: node.value };
|
|
3156
|
+
case "NumericLiteral": return { value: node.value };
|
|
3157
|
+
case "BooleanLiteral": return { value: node.value };
|
|
3158
|
+
case "NullLiteral": return { value: null };
|
|
3159
|
+
case "Identifier": return node.name === "undefined" ? { value: void 0 } : void 0;
|
|
3160
|
+
case "UnaryExpression":
|
|
3161
|
+
if (node.operator === "void") return { value: void 0 };
|
|
3162
|
+
else if (node.operator === "-") {
|
|
3163
|
+
const value = evaluateConstantAst(node.argument);
|
|
3164
|
+
return value && typeof value.value === "number" ? { value: -value.value } : void 0;
|
|
3165
|
+
}
|
|
3166
|
+
return;
|
|
3167
|
+
case "TemplateLiteral": return evaluateTemplateLiteral(node);
|
|
3168
|
+
case "ObjectExpression": return evaluateObjectExpression(node);
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
function evaluateTemplateLiteral(node) {
|
|
3172
|
+
if (node.type !== "TemplateLiteral") return;
|
|
3173
|
+
let value = "";
|
|
3174
|
+
for (const [index, quasi] of node.quasis.entries()) {
|
|
3175
|
+
value += quasi.value.cooked || "";
|
|
3176
|
+
const expression = node.expressions[index];
|
|
3177
|
+
if (expression) {
|
|
3178
|
+
const evaluated = evaluateConstantAst(expression);
|
|
3179
|
+
if (!evaluated) return;
|
|
3180
|
+
value += evaluated.value;
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
return { value };
|
|
3184
|
+
}
|
|
3185
|
+
function evaluateObjectExpression(node) {
|
|
3186
|
+
const value = {};
|
|
3187
|
+
for (const prop of node.properties) {
|
|
3188
|
+
if (prop.type !== "ObjectProperty" || prop.computed) return;
|
|
3189
|
+
const key = getObjectPropertyName(prop);
|
|
3190
|
+
if (key == null) return;
|
|
3191
|
+
const evaluated = evaluateConstantAst(prop.value);
|
|
3192
|
+
if (!evaluated) return;
|
|
3193
|
+
value[key] = evaluated.value;
|
|
3194
|
+
}
|
|
3195
|
+
return { value };
|
|
3196
|
+
}
|
|
2689
3197
|
function resolveStaticKey(node, context, isComponent) {
|
|
2690
3198
|
const keyProp = findProp$1(node, "key", false, true);
|
|
2691
3199
|
if (!keyProp) return;
|
|
@@ -2712,27 +3220,42 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
|
|
|
2712
3220
|
results = [];
|
|
2713
3221
|
}
|
|
2714
3222
|
}
|
|
3223
|
+
function pushStaticObjectLiteralProps(props) {
|
|
3224
|
+
if (dynamicArgs.length) {
|
|
3225
|
+
pushMergeArg();
|
|
3226
|
+
dynamicArgs.push(props);
|
|
3227
|
+
} else results.push(...props.map(toDirectiveResult));
|
|
3228
|
+
}
|
|
2715
3229
|
for (const prop of props) {
|
|
2716
3230
|
if (prop.type === 7 && !prop.arg) {
|
|
2717
3231
|
if (prop.name === "bind") {
|
|
2718
3232
|
if (prop.exp) {
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
3233
|
+
const objectLiteralProps = isComponent ? resolveComponentObjectLiteralBindProps(prop.exp, context, props, prop) : resolveNativeObjectLiteralBindProps(prop.exp, context, props, prop);
|
|
3234
|
+
if (objectLiteralProps) if (isComponent) pushStaticObjectLiteralProps(objectLiteralProps);
|
|
3235
|
+
else results.push(...objectLiteralProps.map(toDirectiveResult));
|
|
3236
|
+
else {
|
|
3237
|
+
dynamicExpr.push(prop.exp);
|
|
3238
|
+
pushMergeArg();
|
|
3239
|
+
dynamicArgs.push({
|
|
3240
|
+
kind: 0,
|
|
3241
|
+
value: prop.exp
|
|
3242
|
+
});
|
|
3243
|
+
}
|
|
2725
3244
|
} else context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, prop.loc));
|
|
2726
3245
|
continue;
|
|
2727
3246
|
} else if (prop.name === "on") {
|
|
2728
3247
|
if (prop.exp) if (isComponent) {
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
3248
|
+
const objectLiteralProps = resolveComponentObjectLiteralOnProps(prop.exp, context, props, prop);
|
|
3249
|
+
if (objectLiteralProps) pushStaticObjectLiteralProps(objectLiteralProps);
|
|
3250
|
+
else {
|
|
3251
|
+
dynamicExpr.push(prop.exp);
|
|
3252
|
+
pushMergeArg();
|
|
3253
|
+
dynamicArgs.push({
|
|
3254
|
+
kind: 0,
|
|
3255
|
+
value: prop.exp,
|
|
3256
|
+
handler: true
|
|
3257
|
+
});
|
|
3258
|
+
}
|
|
2736
3259
|
} else context.registerEffect([prop.exp], {
|
|
2737
3260
|
type: 7,
|
|
2738
3261
|
element: context.reference(),
|
|
@@ -2762,6 +3285,151 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
|
|
|
2762
3285
|
}
|
|
2763
3286
|
return [false, dedupeProperties(results)];
|
|
2764
3287
|
}
|
|
3288
|
+
function resolveObjectLiteralProps(exp, context, keyTransform, isValidKey) {
|
|
3289
|
+
const ast = exp.ast;
|
|
3290
|
+
if (!ast || ast.type !== "ObjectExpression") return;
|
|
3291
|
+
const props = [];
|
|
3292
|
+
const knownKeys = /* @__PURE__ */ new Set();
|
|
3293
|
+
for (const property of ast.properties) {
|
|
3294
|
+
if (property.type !== "ObjectProperty" || property.computed) return;
|
|
3295
|
+
let key = getObjectPropertyName(property);
|
|
3296
|
+
if (key == null || key === "__proto__") return;
|
|
3297
|
+
if (isValidKey && !isValidKey(key)) return;
|
|
3298
|
+
if (keyTransform) key = keyTransform(key);
|
|
3299
|
+
if (knownKeys.has(key)) return;
|
|
3300
|
+
knownKeys.add(key);
|
|
3301
|
+
props.push({
|
|
3302
|
+
key: (0, _vue_compiler_dom.createSimpleExpression)(key, true),
|
|
3303
|
+
values: [resolveExpression(createObjectBindSubExpression(exp, property.value, context), true)]
|
|
3304
|
+
});
|
|
3305
|
+
}
|
|
3306
|
+
return props;
|
|
3307
|
+
}
|
|
3308
|
+
function resolveComponentObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
|
|
3309
|
+
const props = resolveObjectLiteralProps(exp, context, void 0, isSafeObjectLiteralBindKey);
|
|
3310
|
+
if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3311
|
+
return props;
|
|
3312
|
+
}
|
|
3313
|
+
function resolveNativeObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
|
|
3314
|
+
const props = resolveObjectLiteralProps(exp, context, void 0, isSafeNativeObjectLiteralBindKey);
|
|
3315
|
+
if (!props || hasNativeObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3316
|
+
return props;
|
|
3317
|
+
}
|
|
3318
|
+
function resolveComponentObjectLiteralOnProps(exp, context, nodeProps, currentProp) {
|
|
3319
|
+
const props = resolveObjectLiteralProps(exp, context, _vue_shared.toHandlerKey);
|
|
3320
|
+
if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
|
|
3321
|
+
return props;
|
|
3322
|
+
}
|
|
3323
|
+
function isSafeNativeObjectLiteralBindKey(key) {
|
|
3324
|
+
return key !== "" && !UNSAFE_ATTR_NAME_RE.test(key) && isSafeObjectLiteralBindKey(key) && !(0, _vue_shared.isOn)(key) && key.charCodeAt(0) !== 46 && key.charCodeAt(0) !== 94;
|
|
3325
|
+
}
|
|
3326
|
+
function isSafeObjectLiteralBindKey(key) {
|
|
3327
|
+
return !isReservedProp(key);
|
|
3328
|
+
}
|
|
3329
|
+
function hasComponentObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
|
|
3330
|
+
const keys = createComponentConflictKeySet(objectLiteralProps.map((prop) => prop.key.content));
|
|
3331
|
+
for (const prop of props) {
|
|
3332
|
+
if (prop === currentProp) continue;
|
|
3333
|
+
let key;
|
|
3334
|
+
if (prop.type === 6) key = prop.name;
|
|
3335
|
+
else if (prop.name === "bind") {
|
|
3336
|
+
if (!prop.arg) {
|
|
3337
|
+
const bindKeys = getObjectLiteralKeys(prop.exp);
|
|
3338
|
+
if (bindKeys && hasComponentKeyOverlap(keys, bindKeys)) return true;
|
|
3339
|
+
continue;
|
|
3340
|
+
}
|
|
3341
|
+
key = getStaticBindKey(prop);
|
|
3342
|
+
} else if (prop.name === "on") key = getStaticHandlerKey(prop);
|
|
3343
|
+
else if (prop.name === "model") {
|
|
3344
|
+
if (hasComponentModelKey(keys, prop)) return true;
|
|
3345
|
+
}
|
|
3346
|
+
if (key && hasComponentKey(keys, key)) return true;
|
|
3347
|
+
}
|
|
3348
|
+
return false;
|
|
3349
|
+
}
|
|
3350
|
+
function hasComponentModelKey(keys, prop) {
|
|
3351
|
+
const { arg } = prop;
|
|
3352
|
+
if (arg && (arg.type !== 4 || !arg.isStatic)) return true;
|
|
3353
|
+
const key = arg ? arg.content : "modelValue";
|
|
3354
|
+
return hasComponentKey(keys, key) || hasComponentKey(keys, `onUpdate:${(0, _vue_shared.camelize)(key)}`) || prop.modifiers.length > 0 && hasComponentKey(keys, (0, _vue_shared.getModifierPropName)(key));
|
|
3355
|
+
}
|
|
3356
|
+
function hasNativeObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
|
|
3357
|
+
const keys = new Set(objectLiteralProps.map((prop) => prop.key.content));
|
|
3358
|
+
for (const prop of props) {
|
|
3359
|
+
if (prop === currentProp) continue;
|
|
3360
|
+
let key;
|
|
3361
|
+
if (prop.type === 6) key = prop.name;
|
|
3362
|
+
else if (prop.name === "bind") {
|
|
3363
|
+
if (!prop.arg) return true;
|
|
3364
|
+
key = getStaticBindKey(prop);
|
|
3365
|
+
if (!key) return true;
|
|
3366
|
+
}
|
|
3367
|
+
if (key && keys.has(key)) return true;
|
|
3368
|
+
}
|
|
3369
|
+
return false;
|
|
3370
|
+
}
|
|
3371
|
+
function getStaticBindKey(prop) {
|
|
3372
|
+
const { arg } = prop;
|
|
3373
|
+
if (!arg || arg.type !== 4 || !arg.isStatic) return;
|
|
3374
|
+
let key = arg.content;
|
|
3375
|
+
if (isReservedProp(key)) return;
|
|
3376
|
+
if (prop.modifiers.some((modifier) => modifier.content === "camel")) key = (0, _vue_shared.camelize)(key);
|
|
3377
|
+
return key;
|
|
3378
|
+
}
|
|
3379
|
+
function getStaticHandlerKey(prop) {
|
|
3380
|
+
const { arg } = prop;
|
|
3381
|
+
if (!arg || arg.type !== 4 || !arg.isStatic) return;
|
|
3382
|
+
let key = arg.content;
|
|
3383
|
+
if (key.startsWith("vue:")) key = `vnode-${key.slice(4)}`;
|
|
3384
|
+
const { nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(`on${key}`, prop.modifiers, null, prop.loc);
|
|
3385
|
+
if (key.toLowerCase() === "click") {
|
|
3386
|
+
if (nonKeyModifiers.includes("middle")) key = "mouseup";
|
|
3387
|
+
if (nonKeyModifiers.includes("right")) key = "contextmenu";
|
|
3388
|
+
}
|
|
3389
|
+
key = (0, _vue_shared.toHandlerKey)((0, _vue_shared.camelize)(key));
|
|
3390
|
+
const optionPostfix = eventOptionModifiers.map(_vue_shared.capitalize).join("");
|
|
3391
|
+
if (optionPostfix) key += optionPostfix;
|
|
3392
|
+
return key;
|
|
3393
|
+
}
|
|
3394
|
+
function getObjectLiteralKeys(exp) {
|
|
3395
|
+
const ast = exp && exp.ast;
|
|
3396
|
+
if (!ast || ast.type !== "ObjectExpression") return;
|
|
3397
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3398
|
+
for (const property of ast.properties) {
|
|
3399
|
+
if (property.type !== "ObjectProperty" || property.computed) return;
|
|
3400
|
+
const key = getObjectPropertyName(property);
|
|
3401
|
+
if (key == null) return;
|
|
3402
|
+
keys.add(key);
|
|
3403
|
+
}
|
|
3404
|
+
return keys;
|
|
3405
|
+
}
|
|
3406
|
+
function createComponentConflictKeySet(keys) {
|
|
3407
|
+
const normalized = /* @__PURE__ */ new Set();
|
|
3408
|
+
for (const key of keys) {
|
|
3409
|
+
normalized.add(key);
|
|
3410
|
+
normalized.add((0, _vue_shared.camelize)(key));
|
|
3411
|
+
}
|
|
3412
|
+
return normalized;
|
|
3413
|
+
}
|
|
3414
|
+
function hasComponentKey(keys, key) {
|
|
3415
|
+
return keys.has(key) || keys.has((0, _vue_shared.camelize)(key));
|
|
3416
|
+
}
|
|
3417
|
+
function hasComponentKeyOverlap(left, right) {
|
|
3418
|
+
for (const key of right) if (hasComponentKey(left, key)) return true;
|
|
3419
|
+
return false;
|
|
3420
|
+
}
|
|
3421
|
+
function createObjectBindSubExpression(source, node, context) {
|
|
3422
|
+
const start = node.start == null ? 0 : node.start - 1;
|
|
3423
|
+
const end = node.end == null ? source.content.length : node.end - 1;
|
|
3424
|
+
const content = source.content.slice(start, end);
|
|
3425
|
+
const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
|
|
3426
|
+
start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
|
|
3427
|
+
end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
|
|
3428
|
+
source: content
|
|
3429
|
+
});
|
|
3430
|
+
expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
|
|
3431
|
+
return expression;
|
|
3432
|
+
}
|
|
2765
3433
|
function transformProp(prop, node, context) {
|
|
2766
3434
|
let { name } = prop;
|
|
2767
3435
|
if (prop.type === 6) {
|
|
@@ -2812,6 +3480,12 @@ function resolveDirectiveResult(prop) {
|
|
|
2812
3480
|
values: [prop.value]
|
|
2813
3481
|
});
|
|
2814
3482
|
}
|
|
3483
|
+
function toDirectiveResult(prop) {
|
|
3484
|
+
return (0, _vue_shared.extend)({}, prop, {
|
|
3485
|
+
values: void 0,
|
|
3486
|
+
value: prop.values[0]
|
|
3487
|
+
});
|
|
3488
|
+
}
|
|
2815
3489
|
function mergePropValues(existing, incoming) {
|
|
2816
3490
|
const newValues = incoming.values;
|
|
2817
3491
|
existing.values.push(...newValues);
|
|
@@ -3345,6 +4019,7 @@ function processIf(node, dir, context) {
|
|
|
3345
4019
|
}
|
|
3346
4020
|
context.dynamic.flags |= 2;
|
|
3347
4021
|
const forceMultiRoot = shouldForceMultiRoot(context);
|
|
4022
|
+
const allowNoScope = context.block === context.root.block;
|
|
3348
4023
|
if (dir.name === "if") {
|
|
3349
4024
|
const id = context.reference();
|
|
3350
4025
|
context.dynamic.flags |= 4;
|
|
@@ -3355,7 +4030,7 @@ function processIf(node, dir, context) {
|
|
|
3355
4030
|
type: 15,
|
|
3356
4031
|
id,
|
|
3357
4032
|
...context.effectBoundary(),
|
|
3358
|
-
blockShape: encodeIfBlockShape(branch, forceMultiRoot),
|
|
4033
|
+
blockShape: encodeIfBlockShape(branch, forceMultiRoot, void 0, allowNoScope),
|
|
3359
4034
|
condition: dir.exp,
|
|
3360
4035
|
positive: branch,
|
|
3361
4036
|
index: context.root.nextIfIndex(),
|
|
@@ -3397,8 +4072,8 @@ function processIf(node, dir, context) {
|
|
|
3397
4072
|
};
|
|
3398
4073
|
return () => {
|
|
3399
4074
|
onExit();
|
|
3400
|
-
if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot);
|
|
3401
|
-
lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative);
|
|
4075
|
+
if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot, void 0, allowNoScope);
|
|
4076
|
+
lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative, allowNoScope);
|
|
3402
4077
|
};
|
|
3403
4078
|
}
|
|
3404
4079
|
}
|
|
@@ -3413,14 +4088,38 @@ function createIfBranch(node, context) {
|
|
|
3413
4088
|
context.reference();
|
|
3414
4089
|
return [branch, exitBlock];
|
|
3415
4090
|
}
|
|
3416
|
-
function encodeIfBlockShape(positive, forceMultiRoot = false, negative) {
|
|
4091
|
+
function encodeIfBlockShape(positive, forceMultiRoot = false, negative, allowNoScope = true) {
|
|
3417
4092
|
if (forceMultiRoot) return 10;
|
|
3418
|
-
|
|
4093
|
+
const positiveNoScope = allowNoScope && canSkipIfBranchScope(positive);
|
|
4094
|
+
const negativeNoScope = allowNoScope && negative && negative.type !== 15 && canSkipIfBranchScope(negative);
|
|
4095
|
+
return getBlockShape(positive) | getNegativeIfBranchShape(negative) << 2 | (positiveNoScope ? 32 : 0) | (negativeNoScope ? 64 : 0);
|
|
3419
4096
|
}
|
|
3420
|
-
function
|
|
4097
|
+
function getNegativeIfBranchShape(negative) {
|
|
3421
4098
|
if (!negative) return 0;
|
|
3422
4099
|
return negative.type === 15 ? 1 : getBlockShape(negative);
|
|
3423
4100
|
}
|
|
4101
|
+
function canSkipIfBranchScope(block) {
|
|
4102
|
+
if (block.effect.length || block.operation.length) return false;
|
|
4103
|
+
if (!isStaticBranch(block.node)) return false;
|
|
4104
|
+
if (block.returns.length === 0 || block.dynamic.children.length !== block.returns.length) return false;
|
|
4105
|
+
return block.returns.every((id) => {
|
|
4106
|
+
const returned = findReturnedDynamic(block, id);
|
|
4107
|
+
return !!(returned && returned.template != null && !returned.operation && !returned.hasDynamicChild && !(returned.flags & 6));
|
|
4108
|
+
});
|
|
4109
|
+
}
|
|
4110
|
+
function findReturnedDynamic(block, id) {
|
|
4111
|
+
return block.dynamic.children.find((child) => child.id === id);
|
|
4112
|
+
}
|
|
4113
|
+
function isStaticBranch(node) {
|
|
4114
|
+
if (node.type !== 1 || node.tagType !== 3 || node.children.length === 0) return false;
|
|
4115
|
+
return node.children.every((child) => isStaticTemplateNode(child));
|
|
4116
|
+
}
|
|
4117
|
+
function isStaticTemplateNode(node) {
|
|
4118
|
+
if (node.type === 2 || node.type === 3) return true;
|
|
4119
|
+
if (node.type !== 1 || node.tagType !== 0) return false;
|
|
4120
|
+
for (const prop of node.props) if (prop.type === 7 || prop.name === "ref") return false;
|
|
4121
|
+
return node.children.every((child) => isStaticTemplateNode(child));
|
|
4122
|
+
}
|
|
3424
4123
|
function shouldForceMultiRoot(context) {
|
|
3425
4124
|
const parent = context.parent && context.parent.node;
|
|
3426
4125
|
return !!parent && parent.type === 1 && parent.tagType === 3 && parent.props.some((prop) => prop.type === 7 && prop.name === "for");
|
|
@@ -3505,6 +4204,9 @@ const transformSlotOutlet = (node, context) => {
|
|
|
3505
4204
|
}
|
|
3506
4205
|
return () => {
|
|
3507
4206
|
exitBlock && exitBlock();
|
|
4207
|
+
let flags = 0;
|
|
4208
|
+
if (context.options.scopeId && !context.options.slotted) flags |= 1;
|
|
4209
|
+
if (context.inVOnce) flags |= 2;
|
|
3508
4210
|
context.dynamic.operation = {
|
|
3509
4211
|
type: 13,
|
|
3510
4212
|
id,
|
|
@@ -3512,8 +4214,7 @@ const transformSlotOutlet = (node, context) => {
|
|
|
3512
4214
|
name: slotName,
|
|
3513
4215
|
props: irProps,
|
|
3514
4216
|
fallback,
|
|
3515
|
-
|
|
3516
|
-
once: context.inVOnce
|
|
4217
|
+
flags
|
|
3517
4218
|
};
|
|
3518
4219
|
};
|
|
3519
4220
|
};
|