@vue/compiler-vapor 3.6.0-alpha.1 → 3.6.0-alpha.3

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-vapor v3.6.0-alpha.1
2
+ * @vue/compiler-vapor v3.6.0-alpha.3
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -25,7 +25,8 @@ const newBlock = (node) => ({
25
25
  effect: [],
26
26
  operation: [],
27
27
  returns: [],
28
- tempId: 0
28
+ tempId: 0,
29
+ hasDeferredVShow: false
29
30
  });
30
31
  function wrapTemplate(node, dirs) {
31
32
  if (node.tagType === 3) {
@@ -89,6 +90,40 @@ function getLiteralExpressionValue(exp) {
89
90
  }
90
91
  return exp.isStatic ? exp.content : null;
91
92
  }
93
+ function isInTransition(context) {
94
+ const parentNode = context.parent && context.parent.node;
95
+ return !!(parentNode && isTransitionNode(parentNode));
96
+ }
97
+ function isTransitionNode(node) {
98
+ return node.type === 1 && isTransitionTag(node.tag);
99
+ }
100
+ function isTransitionTag(tag) {
101
+ tag = tag.toLowerCase();
102
+ return tag === "transition" || tag === "vaportransition";
103
+ }
104
+ function isTransitionGroupTag(tag) {
105
+ tag = tag.toLowerCase().replace(/-/g, "");
106
+ return tag === "transitiongroup" || tag === "vaportransitiongroup";
107
+ }
108
+ function isKeepAliveTag(tag) {
109
+ tag = tag.toLowerCase();
110
+ return tag === "keepalive" || tag === "vaporkeepalive";
111
+ }
112
+ function isTeleportTag(tag) {
113
+ tag = tag.toLowerCase();
114
+ return tag === "teleport" || tag === "vaporteleport";
115
+ }
116
+ function isBuiltInComponent(tag) {
117
+ if (isTeleportTag(tag)) {
118
+ return "VaporTeleport";
119
+ } else if (isKeepAliveTag(tag)) {
120
+ return "VaporKeepAlive";
121
+ } else if (isTransitionTag(tag)) {
122
+ return "VaporTransition";
123
+ } else if (isTransitionGroupTag(tag)) {
124
+ return "VaporTransitionGroup";
125
+ }
126
+ }
92
127
 
93
128
  class TransformContext {
94
129
  constructor(ir, node, options = {}) {
@@ -301,13 +336,13 @@ const DELIMITERS_ARRAY = ["[", "]", ", "];
301
336
  const DELIMITERS_ARRAY_NEWLINE = [
302
337
  ["[", INDENT_START, NEWLINE],
303
338
  [INDENT_END, NEWLINE, "]"],
304
- [", ", NEWLINE]
339
+ [",", NEWLINE]
305
340
  ];
306
341
  const DELIMITERS_OBJECT = ["{ ", " }", ", "];
307
342
  const DELIMITERS_OBJECT_NEWLINE = [
308
343
  ["{", INDENT_START, NEWLINE],
309
344
  [INDENT_END, NEWLINE, "}"],
310
- [", ", NEWLINE]
345
+ [",", NEWLINE]
311
346
  ];
312
347
  function genCall(name, ...frags) {
313
348
  const hasPlaceholder = shared.isArray(name);
@@ -1084,18 +1119,26 @@ function genFor(oper, context) {
1084
1119
  keyProp,
1085
1120
  idMap
1086
1121
  );
1087
- const patternFrag = [];
1122
+ const selectorDeclarations = [];
1123
+ const selectorSetup = [];
1088
1124
  for (let i = 0; i < selectorPatterns.length; i++) {
1089
1125
  const { selector } = selectorPatterns[i];
1090
1126
  const selectorName = `_selector${id}_${i}`;
1091
- patternFrag.push(
1127
+ selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
1128
+ if (i === 0) {
1129
+ selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
1130
+ }
1131
+ selectorSetup.push(
1092
1132
  NEWLINE,
1093
- `const ${selectorName} = `,
1094
- ...genCall(`n${id}.useSelector`, [
1133
+ `${selectorName} = `,
1134
+ ...genCall(`createSelector`, [
1095
1135
  `() => `,
1096
1136
  ...genExpression(selector, context)
1097
1137
  ])
1098
1138
  );
1139
+ if (i === selectorPatterns.length - 1) {
1140
+ selectorSetup.push(INDENT_END, NEWLINE, "}");
1141
+ }
1099
1142
  }
1100
1143
  const blockFn = context.withId(() => {
1101
1144
  const frag = [];
@@ -1103,25 +1146,25 @@ function genFor(oper, context) {
1103
1146
  if (selectorPatterns.length || keyOnlyBindingPatterns.length) {
1104
1147
  frag.push(
1105
1148
  ...genBlockContent(render, context, false, () => {
1106
- const patternFrag2 = [];
1149
+ const patternFrag = [];
1107
1150
  for (let i = 0; i < selectorPatterns.length; i++) {
1108
1151
  const { effect } = selectorPatterns[i];
1109
- patternFrag2.push(
1152
+ patternFrag.push(
1110
1153
  NEWLINE,
1111
1154
  `_selector${id}_${i}(() => {`,
1112
1155
  INDENT_START
1113
1156
  );
1114
1157
  for (const oper2 of effect.operations) {
1115
- patternFrag2.push(...genOperation(oper2, context));
1158
+ patternFrag.push(...genOperation(oper2, context));
1116
1159
  }
1117
- patternFrag2.push(INDENT_END, NEWLINE, `})`);
1160
+ patternFrag.push(INDENT_END, NEWLINE, `})`);
1118
1161
  }
1119
1162
  for (const { effect } of keyOnlyBindingPatterns) {
1120
1163
  for (const oper2 of effect.operations) {
1121
- patternFrag2.push(...genOperation(oper2, context));
1164
+ patternFrag.push(...genOperation(oper2, context));
1122
1165
  }
1123
1166
  }
1124
- return patternFrag2;
1167
+ return patternFrag;
1125
1168
  })
1126
1169
  );
1127
1170
  } else {
@@ -1143,16 +1186,17 @@ function genFor(oper, context) {
1143
1186
  }
1144
1187
  return [
1145
1188
  NEWLINE,
1189
+ ...selectorDeclarations,
1146
1190
  `const n${id} = `,
1147
1191
  ...genCall(
1148
- helper("createFor"),
1192
+ [helper("createFor"), "undefined"],
1149
1193
  sourceExpr,
1150
1194
  blockFn,
1151
1195
  genCallback(keyProp),
1152
- flags ? String(flags) : void 0
1196
+ flags ? String(flags) : void 0,
1197
+ selectorSetup.length ? selectorSetup : void 0
1153
1198
  // todo: hydrationNode
1154
- ),
1155
- ...patternFrag
1199
+ )
1156
1200
  ];
1157
1201
  function parseValueDestructure() {
1158
1202
  const map = /* @__PURE__ */ new Map();
@@ -1414,10 +1458,15 @@ function isKeyOnlyBinding(expr, keyAst) {
1414
1458
 
1415
1459
  function genSetHtml(oper, context) {
1416
1460
  const { helper } = context;
1417
- const { value, element } = oper;
1461
+ const { value, element, isComponent } = oper;
1418
1462
  return [
1419
1463
  NEWLINE,
1420
- ...genCall(helper("setHtml"), `n${element}`, genExpression(value, context))
1464
+ ...genCall(
1465
+ // use setBlockHtml for component
1466
+ isComponent ? helper("setBlockHtml") : helper("setHtml"),
1467
+ `n${element}`,
1468
+ genExpression(value, context)
1469
+ )
1421
1470
  ];
1422
1471
  }
1423
1472
 
@@ -1506,7 +1555,7 @@ function genLiteralObjectProps(props, context) {
1506
1555
  }
1507
1556
  function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModifiers }, context) {
1508
1557
  const { helper } = context;
1509
- const handlerModifierPostfix = handlerModifiers ? handlerModifiers.map(shared.capitalize).join("") : "";
1558
+ const handlerModifierPostfix = handlerModifiers && handlerModifiers.options ? handlerModifiers.options.map(shared.capitalize).join("") : "";
1510
1559
  if (node.isStatic) {
1511
1560
  const keyName = (handler ? shared.toHandlerKey(node.content) : node.content) + handlerModifierPostfix;
1512
1561
  return [
@@ -1581,6 +1630,7 @@ function getSpecialHelper(keyName, tagName) {
1581
1630
 
1582
1631
  const setTemplateRefIdent = `_setTemplateRef`;
1583
1632
  function genSetTemplateRef(oper, context) {
1633
+ const [refValue, refKey] = genRefValue(oper.value, context);
1584
1634
  return [
1585
1635
  NEWLINE,
1586
1636
  oper.effect && `r${oper.element} = `,
@@ -1588,9 +1638,10 @@ function genSetTemplateRef(oper, context) {
1588
1638
  setTemplateRefIdent,
1589
1639
  // will be generated in root scope
1590
1640
  `n${oper.element}`,
1591
- genRefValue(oper.value, context),
1641
+ refValue,
1592
1642
  oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : void 0,
1593
- oper.refFor && "true"
1643
+ oper.refFor && "true",
1644
+ refKey
1594
1645
  )
1595
1646
  ];
1596
1647
  }
@@ -1601,19 +1652,24 @@ function genRefValue(value, context) {
1601
1652
  if (value && context.options.inline) {
1602
1653
  const binding = context.options.bindingMetadata[value.content];
1603
1654
  if (binding === "setup-let" || binding === "setup-ref" || binding === "setup-maybe-ref") {
1604
- return [value.content];
1655
+ return [[value.content], JSON.stringify(value.content)];
1605
1656
  }
1606
1657
  }
1607
- return genExpression(value, context);
1658
+ return [genExpression(value, context)];
1608
1659
  }
1609
1660
 
1610
1661
  function genSetText(oper, context) {
1611
1662
  const { helper } = context;
1612
- const { element, values, generated, jsx } = oper;
1663
+ const { element, values, generated, jsx, isComponent } = oper;
1613
1664
  const texts = combineValues(values, context, jsx);
1614
1665
  return [
1615
1666
  NEWLINE,
1616
- ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)
1667
+ ...genCall(
1668
+ // use setBlockText for component
1669
+ isComponent ? helper("setBlockText") : helper("setText"),
1670
+ `${generated && !isComponent ? "x" : "n"}${element}`,
1671
+ texts
1672
+ )
1617
1673
  ];
1618
1674
  }
1619
1675
  function combineValues(values, context, jsx) {
@@ -1631,18 +1687,21 @@ function combineValues(values, context, jsx) {
1631
1687
  function genGetTextChild(oper, context) {
1632
1688
  return [
1633
1689
  NEWLINE,
1634
- `const x${oper.parent} = ${context.helper("child")}(n${oper.parent})`
1690
+ `const x${oper.parent} = ${context.helper("txt")}(n${oper.parent})`
1635
1691
  ];
1636
1692
  }
1637
1693
 
1638
1694
  function genVShow(oper, context) {
1695
+ const { deferred, element } = oper;
1639
1696
  return [
1640
1697
  NEWLINE,
1641
- ...genCall(context.helper("applyVShow"), `n${oper.element}`, [
1698
+ deferred ? `deferredApplyVShows.push(() => ` : void 0,
1699
+ ...genCall(context.helper("applyVShow"), `n${element}`, [
1642
1700
  `() => (`,
1643
1701
  ...genExpression(oper.dir.exp, context),
1644
1702
  `)`
1645
- ])
1703
+ ]),
1704
+ deferred ? `)` : void 0
1646
1705
  ];
1647
1706
  }
1648
1707
 
@@ -1781,8 +1840,14 @@ function genCreateComponent(operation, context) {
1781
1840
  } else if (operation.asset) {
1782
1841
  return compilerDom.toValidAssetId(operation.tag, "component");
1783
1842
  } else {
1843
+ const { tag: tag2 } = operation;
1844
+ const builtInTag = isBuiltInComponent(tag2);
1845
+ if (builtInTag) {
1846
+ helper(builtInTag);
1847
+ return `_${builtInTag}`;
1848
+ }
1784
1849
  return genExpression(
1785
- shared.extend(compilerDom.createSimpleExpression(operation.tag, false), { ast: null }),
1850
+ shared.extend(compilerDom.createSimpleExpression(tag2, false), { ast: null }),
1786
1851
  context
1787
1852
  );
1788
1853
  }
@@ -1790,6 +1855,7 @@ function genCreateComponent(operation, context) {
1790
1855
  }
1791
1856
  function getUniqueHandlerName(context, name) {
1792
1857
  const { seenInlineHandlerNames } = context;
1858
+ name = genVarName(name);
1793
1859
  const count = seenInlineHandlerNames[name] || 0;
1794
1860
  seenInlineHandlerNames[name] = count + 1;
1795
1861
  return count === 0 ? name : `${name}${count}`;
@@ -1805,7 +1871,10 @@ function processInlineHandlers(props, context) {
1805
1871
  prop.values.forEach((value, i2) => {
1806
1872
  const isMemberExp = compilerDom.isMemberExpression(value, context.options);
1807
1873
  if (!isMemberExp) {
1808
- const name = getUniqueHandlerName(context, `_on_${prop.key.content}`);
1874
+ const name = getUniqueHandlerName(
1875
+ context,
1876
+ `_on_${prop.key.content.replace(/-/g, "_")}`
1877
+ );
1809
1878
  handlers.push({ name, value });
1810
1879
  ids[name] = null;
1811
1880
  prop.values[i2] = shared.extend({ ast: null }, compilerDom.createSimpleExpression(name));
@@ -1872,7 +1941,7 @@ function genProp(prop, context, isStatic) {
1872
1941
  ...prop.handler ? genEventHandler(
1873
1942
  context,
1874
1943
  prop.values[0],
1875
- void 0,
1944
+ prop.handlerModifiers,
1876
1945
  true
1877
1946
  ) : isStatic ? ["() => (", ...values, ")"] : values,
1878
1947
  ...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : []
@@ -2004,7 +2073,7 @@ function genSlotBlockWithProps(oper, context) {
2004
2073
  let propsName;
2005
2074
  let exitScope;
2006
2075
  let depth;
2007
- const { props } = oper;
2076
+ const { props, key, node } = oper;
2008
2077
  const idsOfProps = /* @__PURE__ */ new Set();
2009
2078
  if (props) {
2010
2079
  rawProps = props.content;
@@ -2026,17 +2095,39 @@ function genSlotBlockWithProps(oper, context) {
2026
2095
  idsOfProps.forEach(
2027
2096
  (id) => idMap[id] = isDestructureAssignment ? `${propsName}[${JSON.stringify(id)}]` : null
2028
2097
  );
2029
- const blockFn = context.withId(
2098
+ let blockFn = context.withId(
2030
2099
  () => genBlock(oper, context, [propsName]),
2031
2100
  idMap
2032
2101
  );
2033
2102
  exitScope && exitScope();
2103
+ if (key) {
2104
+ blockFn = [
2105
+ `() => {`,
2106
+ INDENT_START,
2107
+ NEWLINE,
2108
+ `return `,
2109
+ ...genCall(
2110
+ context.helper("createKeyedFragment"),
2111
+ [`() => `, ...genExpression(key, context)],
2112
+ blockFn
2113
+ ),
2114
+ INDENT_END,
2115
+ NEWLINE,
2116
+ `}`
2117
+ ];
2118
+ }
2119
+ if (node.type === 1 && // Not a real component
2120
+ !isTeleportTag(node.tag) && // Needs to determine whether to activate/deactivate based on instance.parent being KeepAlive
2121
+ !isKeepAliveTag(node.tag) && // Slot updates need to trigger TransitionGroup's onBeforeUpdate/onUpdated hook
2122
+ !isTransitionGroupTag(node.tag)) {
2123
+ blockFn = [`${context.helper("withVaporCtx")}(`, ...blockFn, `)`];
2124
+ }
2034
2125
  return blockFn;
2035
2126
  }
2036
2127
 
2037
2128
  function genSlotOutlet(oper, context) {
2038
2129
  const { helper } = context;
2039
- const { id, name, fallback } = oper;
2130
+ const { id, name, fallback, noSlotted } = oper;
2040
2131
  const [frag, push] = buildCodeFragment();
2041
2132
  const nameExpr = name.isStatic ? genExpression(name, context) : ["() => (", ...genExpression(name, context), ")"];
2042
2133
  let fallbackArg;
@@ -2050,7 +2141,11 @@ function genSlotOutlet(oper, context) {
2050
2141
  helper("createSlot"),
2051
2142
  nameExpr,
2052
2143
  genRawProps(oper.props, context) || "null",
2053
- fallbackArg
2144
+ fallbackArg,
2145
+ noSlotted && "undefined",
2146
+ // instance
2147
+ noSlotted && "true"
2148
+ // noSlotted
2054
2149
  )
2055
2150
  );
2056
2151
  return frag;
@@ -2166,12 +2261,18 @@ function genEffect({ operations }, context) {
2166
2261
  return frag;
2167
2262
  }
2168
2263
  function genInsertionState(operation, context) {
2264
+ const { parent, anchor, append, last } = operation;
2169
2265
  return [
2170
2266
  NEWLINE,
2171
2267
  ...genCall(
2172
2268
  context.helper("setInsertionState"),
2173
- `n${operation.parent}`,
2174
- operation.anchor == null ? void 0 : operation.anchor === -1 ? `0` : `n${operation.anchor}`
2269
+ `n${parent}`,
2270
+ anchor == null ? void 0 : anchor === -1 ? `0` : append ? (
2271
+ // null or anchor > 0 for append
2272
+ // anchor > 0 is the logical index of append node - used for locate node during hydration
2273
+ anchor === 0 ? "null" : `${anchor}`
2274
+ ) : `n${anchor}`,
2275
+ last && "true"
2175
2276
  )
2176
2277
  ];
2177
2278
  }
@@ -2186,7 +2287,7 @@ function genTemplates(templates, rootIndex, { helper }) {
2186
2287
  }
2187
2288
  function genSelf(dynamic, context) {
2188
2289
  const [frag, push] = buildCodeFragment();
2189
- const { id, template, operation } = dynamic;
2290
+ const { id, template, operation, hasDynamicChild } = dynamic;
2190
2291
  if (id !== void 0 && template !== void 0) {
2191
2292
  push(NEWLINE, `const n${id} = t${template}()`);
2192
2293
  push(...genDirectivesForElement(id, context));
@@ -2194,6 +2295,9 @@ function genSelf(dynamic, context) {
2194
2295
  if (operation) {
2195
2296
  push(...genOperationWithInsertionState(operation, context));
2196
2297
  }
2298
+ if (hasDynamicChild) {
2299
+ push(...genChildren(dynamic, context, push, `n${id}`));
2300
+ }
2197
2301
  return frag;
2198
2302
  }
2199
2303
  function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
@@ -2202,51 +2306,65 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2202
2306
  const { children } = dynamic;
2203
2307
  let offset = 0;
2204
2308
  let prev;
2205
- const childrenToGen = [];
2309
+ let ifBranchCount = 0;
2310
+ let prependCount = 0;
2206
2311
  for (const [index, child] of children.entries()) {
2312
+ if (child.operation && child.operation.anchor === -1) {
2313
+ prependCount++;
2314
+ }
2207
2315
  if (child.flags & 2) {
2208
2316
  offset--;
2317
+ } else if (child.ifBranch) {
2318
+ ifBranchCount++;
2209
2319
  }
2210
2320
  const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2211
2321
  if (id === void 0 && !child.hasDynamicChild) {
2212
2322
  push(...genSelf(child, context));
2213
2323
  continue;
2214
2324
  }
2215
- const elementIndex = Number(index) + offset;
2325
+ const elementIndex = index + offset;
2326
+ const logicalIndex = elementIndex - ifBranchCount + prependCount;
2216
2327
  const variable = id === void 0 ? `p${context.block.tempId++}` : `n${id}`;
2217
2328
  pushBlock(NEWLINE, `const ${variable} = `);
2218
2329
  if (prev) {
2219
2330
  if (elementIndex - prev[1] === 1) {
2220
- pushBlock(...genCall(helper("next"), prev[0]));
2331
+ pushBlock(...genCall(helper("next"), prev[0], String(logicalIndex)));
2221
2332
  } else {
2222
- pushBlock(...genCall(helper("nthChild"), from, String(elementIndex)));
2333
+ pushBlock(
2334
+ ...genCall(
2335
+ helper("nthChild"),
2336
+ from,
2337
+ String(elementIndex),
2338
+ String(logicalIndex)
2339
+ )
2340
+ );
2223
2341
  }
2224
2342
  } else {
2225
2343
  if (elementIndex === 0) {
2226
- pushBlock(...genCall(helper("child"), from));
2344
+ pushBlock(...genCall(helper("child"), from, String(logicalIndex)));
2227
2345
  } else {
2228
2346
  let init = genCall(helper("child"), from);
2229
2347
  if (elementIndex === 1) {
2230
- init = genCall(helper("next"), init);
2348
+ init = genCall(helper("next"), init, String(logicalIndex));
2231
2349
  } else if (elementIndex > 1) {
2232
- init = genCall(helper("nthChild"), from, String(elementIndex));
2350
+ init = genCall(
2351
+ helper("nthChild"),
2352
+ from,
2353
+ String(elementIndex),
2354
+ String(logicalIndex)
2355
+ );
2233
2356
  }
2234
2357
  pushBlock(...init);
2235
2358
  }
2236
2359
  }
2237
- if (id === child.anchor) {
2360
+ if (id === child.anchor && !child.hasDynamicChild) {
2238
2361
  push(...genSelf(child, context));
2239
2362
  }
2240
2363
  if (id !== void 0) {
2241
2364
  push(...genDirectivesForElement(id, context));
2242
2365
  }
2243
2366
  prev = [variable, elementIndex];
2244
- childrenToGen.push([child, variable]);
2245
- }
2246
- if (childrenToGen.length) {
2247
- for (const [child, from2] of childrenToGen) {
2248
- push(...genChildren(child, context, pushBlock, from2));
2249
- }
2367
+ push(...genChildren(child, context, pushBlock, variable));
2250
2368
  }
2251
2369
  return frag;
2252
2370
  }
@@ -2265,8 +2383,11 @@ function genBlock(oper, context, args = [], root) {
2265
2383
  }
2266
2384
  function genBlockContent(block, context, root, genEffectsExtraFrag) {
2267
2385
  const [frag, push] = buildCodeFragment();
2268
- const { dynamic, effect, operation, returns } = block;
2386
+ const { dynamic, effect, operation, returns, key } = block;
2269
2387
  const resetBlock = context.enterBlock(block);
2388
+ if (block.hasDeferredVShow) {
2389
+ push(NEWLINE, `const deferredApplyVShows = []`);
2390
+ }
2270
2391
  if (root) {
2271
2392
  for (let name of context.ir.component) {
2272
2393
  const id = compilerDom.toValidAssetId(name, "component");
@@ -2289,10 +2410,21 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2289
2410
  push(...genSelf(child, context));
2290
2411
  }
2291
2412
  for (const child of dynamic.children) {
2292
- push(...genChildren(child, context, push, `n${child.id}`));
2413
+ if (!child.hasDynamicChild) {
2414
+ push(...genChildren(child, context, push, `n${child.id}`));
2415
+ }
2293
2416
  }
2294
2417
  push(...genOperations(operation, context));
2295
2418
  push(...genEffects(effect, context, genEffectsExtraFrag));
2419
+ if (block.hasDeferredVShow) {
2420
+ push(NEWLINE, `deferredApplyVShows.forEach(fn => fn())`);
2421
+ }
2422
+ if (dynamic.needsKey) {
2423
+ for (const child of dynamic.children) {
2424
+ const keyValue = key ? genExpression(key, context) : JSON.stringify(child.id);
2425
+ push(NEWLINE, `n${child.id}.$key = `, ...keyValue);
2426
+ }
2427
+ }
2296
2428
  push(NEWLINE, `return `);
2297
2429
  const returnNodes = returns.map((n) => `n${n}`);
2298
2430
  const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
@@ -2451,15 +2583,17 @@ const transformChildren = (node, context) => {
2451
2583
  };
2452
2584
  function processDynamicChildren(context) {
2453
2585
  let prevDynamics = [];
2454
- let hasStaticTemplate = false;
2586
+ let staticCount = 0;
2587
+ let dynamicCount = 0;
2588
+ let lastInsertionChild;
2455
2589
  const children = context.dynamic.children;
2456
2590
  for (const [index, child] of children.entries()) {
2457
2591
  if (child.flags & 4) {
2458
- prevDynamics.push(child);
2592
+ prevDynamics.push(lastInsertionChild = child);
2459
2593
  }
2460
2594
  if (!(child.flags & 2)) {
2461
2595
  if (prevDynamics.length) {
2462
- if (hasStaticTemplate) {
2596
+ if (staticCount) {
2463
2597
  context.childrenTemplate[index - prevDynamics.length] = `<!>`;
2464
2598
  prevDynamics[0].flags -= 2;
2465
2599
  const anchor = prevDynamics[0].anchor = context.increaseId();
@@ -2472,27 +2606,38 @@ function processDynamicChildren(context) {
2472
2606
  /* prepend */
2473
2607
  );
2474
2608
  }
2609
+ dynamicCount += prevDynamics.length;
2475
2610
  prevDynamics = [];
2476
2611
  }
2477
- hasStaticTemplate = true;
2612
+ staticCount++;
2478
2613
  }
2479
2614
  }
2480
2615
  if (prevDynamics.length) {
2481
- registerInsertion(prevDynamics, context);
2616
+ registerInsertion(
2617
+ prevDynamics,
2618
+ context,
2619
+ // the logical index of append child
2620
+ dynamicCount + staticCount,
2621
+ true
2622
+ );
2623
+ }
2624
+ if (lastInsertionChild && lastInsertionChild.operation) {
2625
+ lastInsertionChild.operation.last = true;
2482
2626
  }
2483
2627
  }
2484
- function registerInsertion(dynamics, context, anchor) {
2628
+ function registerInsertion(dynamics, context, anchor, append) {
2485
2629
  for (const child of dynamics) {
2486
2630
  if (child.template != null) {
2487
2631
  context.registerOperation({
2488
2632
  type: 9,
2489
2633
  elements: dynamics.map((child2) => child2.id),
2490
2634
  parent: context.reference(),
2491
- anchor
2635
+ anchor: append ? void 0 : anchor
2492
2636
  });
2493
2637
  } else if (child.operation && isBlockOperation(child.operation)) {
2494
2638
  child.operation.parent = context.reference();
2495
2639
  child.operation.anchor = anchor;
2640
+ child.operation.append = append;
2496
2641
  }
2497
2642
  }
2498
2643
  }
@@ -2560,6 +2705,11 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2560
2705
  tag = fromSetup;
2561
2706
  asset = false;
2562
2707
  }
2708
+ const builtInTag = isBuiltInComponent(tag);
2709
+ if (builtInTag) {
2710
+ tag = builtInTag;
2711
+ asset = false;
2712
+ }
2563
2713
  const dotIndex = tag.indexOf(".");
2564
2714
  if (dotIndex > 0) {
2565
2715
  const ns = resolveSetupReference(tag.slice(0, dotIndex), context);
@@ -2616,6 +2766,7 @@ function resolveSetupReference(name, context) {
2616
2766
  const PascalName = shared.capitalize(camelName);
2617
2767
  return bindings[name] ? name : bindings[camelName] ? camelName : bindings[PascalName] ? PascalName : void 0;
2618
2768
  }
2769
+ const dynamicKeys = ["indeterminate"];
2619
2770
  function transformNativeElement(node, propsResult, singleRoot, context, getEffectIndex) {
2620
2771
  const { tag } = node;
2621
2772
  const { scopeId } = context.options;
@@ -2638,7 +2789,7 @@ function transformNativeElement(node, propsResult, singleRoot, context, getEffec
2638
2789
  } else {
2639
2790
  for (const prop of propsResult[1]) {
2640
2791
  const { key, values } = prop;
2641
- if (key.isStatic && values.length === 1 && values[0].isStatic) {
2792
+ if (key.isStatic && values.length === 1 && values[0].isStatic && !dynamicKeys.includes(key.content)) {
2642
2793
  template += ` ${key.content}`;
2643
2794
  if (values[0].content) template += `="${values[0].content}"`;
2644
2795
  } else {
@@ -2794,7 +2945,7 @@ function dedupeProperties(results) {
2794
2945
  }
2795
2946
  const name = prop.key.content;
2796
2947
  const existing = knownProps.get(name);
2797
- if (existing) {
2948
+ if (existing && existing.handler === prop.handler) {
2798
2949
  if (name === "style" || name === "class") {
2799
2950
  mergePropValues(existing, prop);
2800
2951
  }
@@ -2836,11 +2987,11 @@ const transformVHtml = (dir, node, context) => {
2836
2987
  context.registerEffect([exp], {
2837
2988
  type: 7,
2838
2989
  element: context.reference(),
2839
- value: exp
2990
+ value: exp,
2991
+ isComponent: node.tagType === 1
2840
2992
  });
2841
2993
  };
2842
2994
 
2843
- /*! #__NO_SIDE_EFFECTS__ */
2844
2995
  // @__NO_SIDE_EFFECTS__
2845
2996
  function makeMap(str) {
2846
2997
  const map = /* @__PURE__ */ Object.create(null);
@@ -2873,15 +3024,19 @@ const transformVText = (dir, node, context) => {
2873
3024
  context.childrenTemplate = [String(literal)];
2874
3025
  } else {
2875
3026
  context.childrenTemplate = [" "];
2876
- context.registerOperation({
2877
- type: 17,
2878
- parent: context.reference()
2879
- });
3027
+ const isComponent = node.tagType === 1;
3028
+ if (!isComponent) {
3029
+ context.registerOperation({
3030
+ type: 17,
3031
+ parent: context.reference()
3032
+ });
3033
+ }
2880
3034
  context.registerEffect([exp], {
2881
3035
  type: 4,
2882
3036
  element: context.reference(),
2883
3037
  values: [exp],
2884
- generated: true
3038
+ generated: true,
3039
+ isComponent
2885
3040
  });
2886
3041
  }
2887
3042
  };
@@ -2974,7 +3129,11 @@ const transformVOn = (dir, node, context) => {
2974
3129
  key: arg,
2975
3130
  value: handler,
2976
3131
  handler: true,
2977
- handlerModifiers: eventOptionModifiers
3132
+ handlerModifiers: {
3133
+ keys: keyModifiers,
3134
+ nonKeys: nonKeyModifiers,
3135
+ options: eventOptionModifiers
3136
+ }
2978
3137
  };
2979
3138
  }
2980
3139
  const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
@@ -3012,12 +3171,21 @@ const transformVShow = (dir, node, context) => {
3012
3171
  );
3013
3172
  return;
3014
3173
  }
3174
+ let shouldDeferred = false;
3175
+ const parentNode = context.parent && context.parent.node;
3176
+ if (parentNode && parentNode.type === 1) {
3177
+ shouldDeferred = !!(isTransitionTag(parentNode.tag) && findProp(parentNode, "appear", false, true));
3178
+ if (shouldDeferred) {
3179
+ context.parent.parent.block.hasDeferredVShow = true;
3180
+ }
3181
+ }
3015
3182
  context.registerOperation({
3016
3183
  type: 13,
3017
3184
  element: context.reference(),
3018
3185
  dir,
3019
3186
  name: "show",
3020
- builtin: true
3187
+ builtin: true,
3188
+ deferred: shouldDeferred
3021
3189
  });
3022
3190
  };
3023
3191
 
@@ -3087,11 +3255,12 @@ const transformText = (node, context) => {
3087
3255
  } else if (node.type === 5) {
3088
3256
  processInterpolation(context);
3089
3257
  } else if (node.type === 2) {
3090
- context.template += node.content;
3258
+ context.template += shared.escapeHtml(node.content);
3091
3259
  }
3092
3260
  };
3093
3261
  function processInterpolation(context) {
3094
- const children = context.parent.node.children;
3262
+ const parentNode = context.parent.node;
3263
+ const children = parentNode.children;
3095
3264
  const nexts = children.slice(context.index);
3096
3265
  const idx = nexts.findIndex((n) => !isTextLike(n));
3097
3266
  const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
@@ -3099,9 +3268,15 @@ function processInterpolation(context) {
3099
3268
  if (prev && prev.type === 2) {
3100
3269
  nodes.unshift(prev);
3101
3270
  }
3271
+ const values = processTextLikeChildren(nodes, context);
3272
+ if (values.length === 0 && parentNode.type !== 0) {
3273
+ return;
3274
+ }
3102
3275
  context.template += " ";
3103
3276
  const id = context.reference();
3104
- const values = nodes.map((node) => createTextLikeExpression(node, context));
3277
+ if (values.length === 0) {
3278
+ return;
3279
+ }
3105
3280
  const nonConstantExps = values.filter((v) => !isConstantExpression(v));
3106
3281
  const isStatic = !nonConstantExps.length || nonConstantExps.every(
3107
3282
  (e) => isStaticExpression(e, context.options.bindingMetadata)
@@ -3121,10 +3296,10 @@ function processInterpolation(context) {
3121
3296
  }
3122
3297
  }
3123
3298
  function processTextContainer(children, context) {
3124
- const values = children.map((child) => createTextLikeExpression(child, context));
3299
+ const values = processTextLikeChildren(children, context);
3125
3300
  const literals = values.map(getLiteralExpressionValue);
3126
3301
  if (literals.every((l) => l != null)) {
3127
- context.childrenTemplate = literals.map((l) => String(l));
3302
+ context.childrenTemplate = literals.map((l) => shared.escapeHtml(String(l)));
3128
3303
  } else {
3129
3304
  context.childrenTemplate = [" "];
3130
3305
  context.registerOperation({
@@ -3140,13 +3315,19 @@ function processTextContainer(children, context) {
3140
3315
  });
3141
3316
  }
3142
3317
  }
3143
- function createTextLikeExpression(node, context) {
3144
- markNonTemplate(node, context);
3145
- if (node.type === 2) {
3146
- return compilerDom.createSimpleExpression(node.content, true, node.loc);
3147
- } else {
3148
- return node.content;
3318
+ function processTextLikeChildren(nodes, context) {
3319
+ const exps = [];
3320
+ for (const node of nodes) {
3321
+ let exp;
3322
+ markNonTemplate(node, context);
3323
+ if (node.type === 2) {
3324
+ exp = compilerDom.createSimpleExpression(node.content, true, node.loc);
3325
+ } else {
3326
+ exp = node.content;
3327
+ }
3328
+ if (exp.content) exps.push(exp);
3149
3329
  }
3330
+ return exps;
3150
3331
  }
3151
3332
  function isTextLike(node) {
3152
3333
  return node.type === 5 || node.type === 2;
@@ -3269,7 +3450,7 @@ const transformComment = (node, context) => {
3269
3450
  context.comment.push(node);
3270
3451
  context.dynamic.flags |= 2;
3271
3452
  } else {
3272
- context.template += `<!--${node.content}-->`;
3453
+ context.template += `<!--${shared.escapeHtml(node.content)}-->`;
3273
3454
  }
3274
3455
  };
3275
3456
  function getSiblingIf(context, reverse) {
@@ -3323,6 +3504,7 @@ function processIf(node, dir, context) {
3323
3504
  };
3324
3505
  } else {
3325
3506
  const siblingIf = getSiblingIf(context, true);
3507
+ context.dynamic.ifBranch = true;
3326
3508
  const siblings = context.parent && context.parent.dynamic.children;
3327
3509
  let lastIfNode;
3328
3510
  if (siblings) {
@@ -3379,6 +3561,7 @@ function createIfBranch(node, context) {
3379
3561
  const branch = newBlock(node);
3380
3562
  const exitBlock = context.enterBlock(branch);
3381
3563
  context.reference();
3564
+ branch.dynamic.needsKey = isInTransition(context);
3382
3565
  return [branch, exitBlock];
3383
3566
  }
3384
3567
 
@@ -3403,7 +3586,8 @@ function processFor(node, dir, context) {
3403
3586
  const { source, value, key, index } = parseResult;
3404
3587
  const keyProp = findProp(node, "key");
3405
3588
  const keyProperty = keyProp && propToExpression(keyProp);
3406
- const isComponent = node.tagType === 1;
3589
+ const isComponent = node.tagType === 1 || // template v-for with a single component child
3590
+ isTemplateWithSingleComponent(node);
3407
3591
  context.node = node = wrapTemplate(node, ["for"]);
3408
3592
  context.dynamic.flags |= 2 | 4;
3409
3593
  const id = context.reference();
@@ -3432,6 +3616,13 @@ function processFor(node, dir, context) {
3432
3616
  };
3433
3617
  };
3434
3618
  }
3619
+ function isTemplateWithSingleComponent(node) {
3620
+ if (node.tag !== "template") return false;
3621
+ const nonCommentChildren = node.children.filter(
3622
+ (c) => c.type !== 3
3623
+ );
3624
+ return nonCommentChildren.length === 1 && nonCommentChildren[0].type === 1 && nonCommentChildren[0].tagType === 1;
3625
+ }
3435
3626
 
3436
3627
  const transformSlotOutlet = (node, context) => {
3437
3628
  if (node.type !== 1 || node.tag !== "slot") {
@@ -3505,7 +3696,8 @@ const transformSlotOutlet = (node, context) => {
3505
3696
  id,
3506
3697
  name: slotName,
3507
3698
  props: irProps,
3508
- fallback
3699
+ fallback,
3700
+ noSlotted: !!(context.options.scopeId && !context.options.slotted)
3509
3701
  };
3510
3702
  };
3511
3703
  };
@@ -3567,7 +3759,22 @@ function transformComponentSlot(node, dir, context) {
3567
3759
  markNonTemplate(n, context);
3568
3760
  });
3569
3761
  }
3570
- const [block, onExit] = createSlotBlock(node, dir, context);
3762
+ let slotKey;
3763
+ if (isTransitionNode(node) && nonSlotTemplateChildren.length) {
3764
+ const nonCommentChild = nonSlotTemplateChildren.find(
3765
+ (n) => n.type !== 3
3766
+ );
3767
+ if (nonCommentChild) {
3768
+ const keyProp = findProp(
3769
+ nonCommentChild,
3770
+ "key"
3771
+ );
3772
+ if (keyProp) {
3773
+ slotKey = keyProp.exp;
3774
+ }
3775
+ }
3776
+ }
3777
+ const [block, onExit] = createSlotBlock(node, dir, context, slotKey);
3571
3778
  const { slots } = context;
3572
3779
  return () => {
3573
3780
  onExit();
@@ -3701,9 +3908,13 @@ function hasStaticSlot(slots, name) {
3701
3908
  if (slot.slotType === 0) return !!slot.slots[name];
3702
3909
  });
3703
3910
  }
3704
- function createSlotBlock(slotNode, dir, context) {
3911
+ function createSlotBlock(slotNode, dir, context, key = void 0) {
3705
3912
  const block = newBlock(slotNode);
3706
3913
  block.props = dir && dir.exp;
3914
+ if (key) {
3915
+ block.key = key;
3916
+ block.dynamic.needsKey = true;
3917
+ }
3707
3918
  const exitBlock = context.enterBlock(block);
3708
3919
  return [block, exitBlock];
3709
3920
  }
@@ -3712,6 +3923,37 @@ function isNonWhitespaceContent(node) {
3712
3923
  return !!node.content.trim();
3713
3924
  }
3714
3925
 
3926
+ const transformTransition = (node, context) => {
3927
+ if (node.type === 1 && node.tagType === 1) {
3928
+ if (isTransitionTag(node.tag)) {
3929
+ return compilerDom.postTransformTransition(
3930
+ node,
3931
+ context.options.onError,
3932
+ hasMultipleChildren
3933
+ );
3934
+ }
3935
+ }
3936
+ };
3937
+ function hasMultipleChildren(node) {
3938
+ const children = node.children = node.children.filter(
3939
+ (c) => c.type !== 3 && !(c.type === 2 && !c.content.trim())
3940
+ );
3941
+ const first = children[0];
3942
+ if (children.length === 1 && first.type === 1 && (findDir(first, "for") || compilerDom.isTemplateNode(first))) {
3943
+ return true;
3944
+ }
3945
+ const hasElse = (node2) => findDir(node2, "else-if") || findDir(node2, "else", true);
3946
+ if (children.every(
3947
+ (c, index) => c.type === 1 && // not template
3948
+ !compilerDom.isTemplateNode(c) && // not has v-for
3949
+ !findDir(c, "for") && // if the first child has v-if, the rest should also have v-else-if/v-else
3950
+ (index === 0 ? findDir(c, "if") : hasElse(c)) && !hasMultipleChildren(c)
3951
+ )) {
3952
+ return false;
3953
+ }
3954
+ return children.length > 1;
3955
+ }
3956
+
3715
3957
  function compile(source, options = {}) {
3716
3958
  const resolvedOptions = shared.extend({}, options);
3717
3959
  const ast = shared.isString(source) ? compilerDom.parse(source, resolvedOptions) : source;
@@ -3730,6 +3972,7 @@ function compile(source, options = {}) {
3730
3972
  shared.extend({}, resolvedOptions, {
3731
3973
  nodeTransforms: [
3732
3974
  ...nodeTransforms,
3975
+ ...[transformTransition] ,
3733
3976
  ...options.nodeTransforms || []
3734
3977
  // user transforms
3735
3978
  ],