@vue/compiler-vapor 3.6.0-beta.9 → 3.6.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-vapor v3.6.0-beta.9
2
+ * @vue/compiler-vapor v3.6.0-rc.1
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -12,6 +12,90 @@ let _vue_shared = require("@vue/shared");
12
12
  let source_map_js = require("source-map-js");
13
13
  let _babel_parser = require("@babel/parser");
14
14
  let estree_walker = require("estree-walker");
15
+ //#region packages/compiler-vapor/src/ir/component.ts
16
+ const IRDynamicPropsKind = {
17
+ "EXPRESSION": 0,
18
+ "0": "EXPRESSION",
19
+ "ATTRIBUTE": 1,
20
+ "1": "ATTRIBUTE"
21
+ };
22
+ const IRSlotType = {
23
+ "STATIC": 0,
24
+ "0": "STATIC",
25
+ "DYNAMIC": 1,
26
+ "1": "DYNAMIC",
27
+ "LOOP": 2,
28
+ "2": "LOOP",
29
+ "CONDITIONAL": 3,
30
+ "3": "CONDITIONAL",
31
+ "EXPRESSION": 4,
32
+ "4": "EXPRESSION"
33
+ };
34
+ //#endregion
35
+ //#region packages/compiler-vapor/src/ir/index.ts
36
+ const IRNodeTypes = {
37
+ "ROOT": 0,
38
+ "0": "ROOT",
39
+ "BLOCK": 1,
40
+ "1": "BLOCK",
41
+ "SET_BLOCK_KEY": 2,
42
+ "2": "SET_BLOCK_KEY",
43
+ "SET_PROP": 3,
44
+ "3": "SET_PROP",
45
+ "SET_DYNAMIC_PROPS": 4,
46
+ "4": "SET_DYNAMIC_PROPS",
47
+ "SET_TEXT": 5,
48
+ "5": "SET_TEXT",
49
+ "SET_EVENT": 6,
50
+ "6": "SET_EVENT",
51
+ "SET_DYNAMIC_EVENTS": 7,
52
+ "7": "SET_DYNAMIC_EVENTS",
53
+ "SET_HTML": 8,
54
+ "8": "SET_HTML",
55
+ "SET_TEMPLATE_REF": 9,
56
+ "9": "SET_TEMPLATE_REF",
57
+ "INSERT_NODE": 10,
58
+ "10": "INSERT_NODE",
59
+ "PREPEND_NODE": 11,
60
+ "11": "PREPEND_NODE",
61
+ "CREATE_COMPONENT_NODE": 12,
62
+ "12": "CREATE_COMPONENT_NODE",
63
+ "SLOT_OUTLET_NODE": 13,
64
+ "13": "SLOT_OUTLET_NODE",
65
+ "DIRECTIVE": 14,
66
+ "14": "DIRECTIVE",
67
+ "IF": 15,
68
+ "15": "IF",
69
+ "FOR": 16,
70
+ "16": "FOR",
71
+ "KEY": 17,
72
+ "17": "KEY",
73
+ "GET_TEXT_CHILD": 18,
74
+ "18": "GET_TEXT_CHILD"
75
+ };
76
+ var TemplateRegistry = class {
77
+ constructor() {
78
+ this.entries = [];
79
+ }
80
+ keys() {
81
+ return this.entries.map(({ content }) => content);
82
+ }
83
+ };
84
+ const DynamicFlag = {
85
+ "NONE": 0,
86
+ "0": "NONE",
87
+ "REFERENCED": 1,
88
+ "1": "REFERENCED",
89
+ "NON_TEMPLATE": 2,
90
+ "2": "NON_TEMPLATE",
91
+ "INSERT": 4,
92
+ "4": "INSERT"
93
+ };
94
+ function isBlockOperation(op) {
95
+ const type = op.type;
96
+ return type === 12 || type === 13 || type === 15 || type === 17 || type === 16;
97
+ }
98
+ //#endregion
15
99
  //#region packages/compiler-vapor/src/transforms/utils.ts
16
100
  const newDynamic = () => ({
17
101
  flags: 1,
@@ -68,7 +152,7 @@ const EMPTY_EXPRESSION = (0, _vue_compiler_dom.createSimpleExpression)("", true)
68
152
  //#region packages/compiler-vapor/src/utils.ts
69
153
  const findProp$1 = _vue_compiler_dom.findProp;
70
154
  /** find directive */
71
- const findDir$2 = _vue_compiler_dom.findDir;
155
+ const findDir$4 = _vue_compiler_dom.findDir;
72
156
  function propToExpression(prop) {
73
157
  return prop.type === 6 ? prop.value ? (0, _vue_compiler_dom.createSimpleExpression)(prop.value.content, true, prop.value.loc) : EMPTY_EXPRESSION : prop.exp;
74
158
  }
@@ -109,6 +193,13 @@ function getLiteralExpressionValue(exp, excludeNumber) {
109
193
  }
110
194
  return exp.isStatic ? exp.content : null;
111
195
  }
196
+ function isInTransition(context) {
197
+ const parentNode = context.parent && context.parent.node;
198
+ return !!(parentNode && isTransitionNode(parentNode));
199
+ }
200
+ function isTransitionNode(node) {
201
+ return node.type === 1 && isTransitionTag(node.tag);
202
+ }
112
203
  function isTransitionTag(tag) {
113
204
  tag = tag.toLowerCase();
114
205
  return tag === "transition" || tag === "vaportransition";
@@ -127,6 +218,7 @@ function isTeleportTag(tag) {
127
218
  }
128
219
  function isBuiltInComponent(tag) {
129
220
  if (isTeleportTag(tag)) return "VaporTeleport";
221
+ else if (tag === "Suspense" || tag === "suspense") return "Suspense";
130
222
  else if (isKeepAliveTag(tag)) return "VaporKeepAlive";
131
223
  else if (isTransitionTag(tag)) return "VaporTransition";
132
224
  else if (isTransitionGroupTag(tag)) return "VaporTransitionGroup";
@@ -138,6 +230,7 @@ function getBlockShape(block) {
138
230
  //#endregion
139
231
  //#region packages/compiler-vapor/src/transform.ts
140
232
  const generatedVarRE = /^[nxr](\d+)$/;
233
+ const childContextInfoCache = /* @__PURE__ */ new WeakMap();
141
234
  var TransformContext = class TransformContext {
142
235
  constructor(ir, node, options = {}) {
143
236
  this.ir = ir;
@@ -148,6 +241,8 @@ var TransformContext = class TransformContext {
148
241
  this.index = 0;
149
242
  this.block = this.ir.block;
150
243
  this.template = "";
244
+ this.templateRoot = false;
245
+ this.templateIndexMap = /* @__PURE__ */ new Map();
151
246
  this.childrenTemplate = [];
152
247
  this.dynamic = this.ir.block.dynamic;
153
248
  this.imports = [];
@@ -157,9 +252,13 @@ var TransformContext = class TransformContext {
157
252
  this.component = this.ir.component;
158
253
  this.directive = this.ir.directive;
159
254
  this.slots = [];
255
+ this.effectIndex = this.block.effect.length;
256
+ this.operationIndex = this.block.operation.length;
160
257
  this.isLastEffectiveChild = true;
161
258
  this.isOnRightmostPath = true;
162
- this.hasInlineAncestorNeedingClose = false;
259
+ this.isSingleRoot = false;
260
+ this.templateCloseTags = void 0;
261
+ this.templateCloseBlocks = false;
163
262
  this.globalId = 0;
164
263
  this.nextIdMap = null;
165
264
  this.ifIndex = 0;
@@ -174,20 +273,28 @@ var TransformContext = class TransformContext {
174
273
  this.initNextIdMap();
175
274
  }
176
275
  enterBlock(ir, isVFor = false) {
177
- const { block, template, dynamic, childrenTemplate, slots } = this;
276
+ const { block, template, templateRoot, templateIndexMap, dynamic, childrenTemplate, slots, effectIndex, operationIndex } = this;
178
277
  this.block = ir;
179
278
  this.dynamic = ir.dynamic;
180
279
  this.template = "";
280
+ this.templateRoot = false;
281
+ this.templateIndexMap = templateIndexMap;
181
282
  this.childrenTemplate = [];
182
283
  this.slots = [];
284
+ this.effectIndex = ir.effect.length;
285
+ this.operationIndex = ir.operation.length;
183
286
  isVFor && this.inVFor++;
184
287
  return () => {
185
288
  this.registerTemplate();
186
289
  this.block = block;
187
290
  this.template = template;
291
+ this.templateRoot = templateRoot;
292
+ this.templateIndexMap = templateIndexMap;
188
293
  this.dynamic = dynamic;
189
294
  this.childrenTemplate = childrenTemplate;
190
295
  this.slots = slots;
296
+ this.effectIndex = effectIndex;
297
+ this.operationIndex = operationIndex;
191
298
  isVFor && this.inVFor--;
192
299
  };
193
300
  }
@@ -212,60 +319,150 @@ var TransformContext = class TransformContext {
212
319
  nextIfIndex() {
213
320
  return this.ifIndex++;
214
321
  }
215
- pushTemplate(content) {
216
- const existingIndex = this.ir.templateIndexMap.get(content);
322
+ getTemplateNamespace() {
323
+ return this.node.type === 1 ? this.node.ns : 0;
324
+ }
325
+ canUseStaticTemplate() {
326
+ if (!this.template) return false;
327
+ if (this.inVFor) return false;
328
+ if (this.dynamic.hasDynamicChild) return false;
329
+ if (this.block.effect.length !== this.effectIndex) return false;
330
+ if (this.block.operation.length !== this.operationIndex) return false;
331
+ if (this.node.type === 2 || this.node.type === 3) return true;
332
+ return this.node.type === 1 && this.node.tagType === 0 && !(this.options.isCustomElement(this.node.tag) || this.node.tag === "template");
333
+ }
334
+ pushTemplate(content, { root = false, static: isStatic = false } = {}) {
335
+ const templateKey = JSON.stringify([
336
+ this.getTemplateNamespace(),
337
+ root,
338
+ isStatic,
339
+ content
340
+ ]);
341
+ const existingIndex = this.templateIndexMap.get(templateKey);
217
342
  if (existingIndex !== void 0) return existingIndex;
218
- const newIndex = this.ir.template.size;
219
- this.ir.template.set(content, this.node.ns);
220
- this.ir.templateIndexMap.set(content, newIndex);
343
+ const ns = this.getTemplateNamespace();
344
+ const newIndex = this.ir.template.entries.length;
345
+ this.ir.template.entries.push({
346
+ content,
347
+ ns,
348
+ root,
349
+ static: isStatic
350
+ });
351
+ this.templateIndexMap.set(templateKey, newIndex);
221
352
  return newIndex;
222
353
  }
223
354
  registerTemplate() {
224
355
  if (!this.template) return -1;
225
- const id = this.pushTemplate(this.template);
356
+ const id = this.pushTemplate(this.template, {
357
+ root: this.templateRoot,
358
+ static: this.canUseStaticTemplate()
359
+ });
226
360
  return this.dynamic.template = id;
227
361
  }
228
- registerEffect(expressions, operation, getIndex = () => this.block.effect.length) {
362
+ registerEffect(expressions, operation, getIndex) {
229
363
  const operations = [operation].flat();
230
364
  expressions = expressions.filter((exp) => !isConstantExpression(exp));
231
365
  if (this.inVOnce || expressions.length === 0 || expressions.every((e) => isStaticExpression(e, this.root.options.bindingMetadata))) return this.registerOperation(...operations);
232
- this.block.effect.splice(getIndex(), 0, {
366
+ const index = getIndex ? getIndex() : this.block.effect.length;
367
+ this.block.effect.splice(index, 0, {
233
368
  expressions,
234
369
  operations
235
370
  });
371
+ if (getIndex) this.shiftEffectBoundaries(index);
236
372
  }
237
373
  registerOperation(...node) {
238
374
  this.block.operation.push(...node);
239
375
  }
376
+ effectBoundary() {
377
+ return {
378
+ operationIndex: this.operationIndex,
379
+ effectIndex: this.effectIndex
380
+ };
381
+ }
240
382
  create(node, index) {
241
383
  let effectiveParent = this;
242
384
  while (effectiveParent && effectiveParent.node.type === 1 && effectiveParent.node.tagType === 3) effectiveParent = effectiveParent.parent;
243
- const isLastEffectiveChild = this.isEffectivelyLastChild(index);
385
+ const childInfo = this.getChildContextInfo();
386
+ const isLastEffectiveChild = childInfo.isLastEffectiveChild[index];
244
387
  const isOnRightmostPath = this.isOnRightmostPath && isLastEffectiveChild;
245
- let hasInlineAncestorNeedingClose = this.hasInlineAncestorNeedingClose;
246
- if (this.node.type === 1) {
247
- if (this.node.tag === "template") hasInlineAncestorNeedingClose = false;
248
- else if (!hasInlineAncestorNeedingClose && !this.isOnRightmostPath && (0, _vue_shared.isInlineTag)(this.node.tag)) hasInlineAncestorNeedingClose = true;
249
- }
388
+ const isSingleRoot = this.isSingleRootChild(childInfo);
250
389
  return Object.assign(Object.create(TransformContext.prototype), this, {
251
390
  node,
252
391
  parent: this,
253
392
  index,
254
393
  template: "",
394
+ templateRoot: false,
255
395
  childrenTemplate: [],
396
+ templateIndexMap: this.templateIndexMap,
256
397
  dynamic: newDynamic(),
398
+ effectIndex: this.block.effect.length,
399
+ operationIndex: this.block.operation.length,
257
400
  effectiveParent,
258
401
  isLastEffectiveChild,
259
402
  isOnRightmostPath,
260
- hasInlineAncestorNeedingClose
403
+ isSingleRoot,
404
+ templateCloseTags: this.templateCloseTags,
405
+ templateCloseBlocks: this.templateCloseBlocks
261
406
  });
262
407
  }
263
- isEffectivelyLastChild(index) {
264
- const children = this.node.children;
265
- if (!children) return true;
266
- return children.every((c, i) => i <= index || c.type === 1 && c.tagType === 1);
408
+ shiftEffectBoundaries(index, dynamic = this.dynamic) {
409
+ const operation = dynamic.operation;
410
+ if (operation && isBlockOperation(operation) && operation.effectIndex !== void 0 && operation.effectIndex >= index) operation.effectIndex++;
411
+ for (const child of dynamic.children) this.shiftEffectBoundaries(index, child);
412
+ }
413
+ getChildContextInfo() {
414
+ const node = this.node;
415
+ if (node.type !== 0 && node.type !== 1) return {
416
+ node,
417
+ hasSingleRootChild: true,
418
+ isLastEffectiveChild: []
419
+ };
420
+ const cached = childContextInfoCache.get(this);
421
+ if (cached && cached.node === node) return cached;
422
+ const { children } = node;
423
+ const isLastEffectiveChild = new Array(children.length);
424
+ let hasFollowingEffectiveChild = false;
425
+ for (let i = children.length - 1; i >= 0; i--) {
426
+ isLastEffectiveChild[i] = !hasFollowingEffectiveChild;
427
+ if (!isComponentChild(children[i])) hasFollowingEffectiveChild = true;
428
+ }
429
+ const childInfo = {
430
+ node,
431
+ hasSingleRootChild: hasSingleRootChild(children),
432
+ isLastEffectiveChild
433
+ };
434
+ childContextInfoCache.set(this, childInfo);
435
+ return childInfo;
436
+ }
437
+ isSingleRootChild(childInfo) {
438
+ if (this.inVFor || !childInfo.hasSingleRootChild) return false;
439
+ if (this.node.type === 0) return true;
440
+ return this.node.type === 1 && this.node.tagType === 3 && !!this.parent && this.isSingleRoot;
267
441
  }
268
442
  };
443
+ function hasSingleRootChild(children) {
444
+ let nonCommentChildren = 0;
445
+ let hasEncounteredIf = false;
446
+ let isSingleIfBlock = true;
447
+ for (const child of children) {
448
+ if ((0, _vue_compiler_dom.isCommentOrWhitespace)(child)) continue;
449
+ nonCommentChildren++;
450
+ if (isIfChild(child)) {
451
+ if (hasEncounteredIf) isSingleIfBlock = false;
452
+ hasEncounteredIf = true;
453
+ } else if (!hasEncounteredIf || !isElseChild(child)) isSingleIfBlock = false;
454
+ }
455
+ return nonCommentChildren === 1 || isSingleIfBlock;
456
+ }
457
+ function isComponentChild(child) {
458
+ return child.type === 1 && child.tagType === 1;
459
+ }
460
+ function isIfChild(child) {
461
+ return child.type === 9 || child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, "if");
462
+ }
463
+ function isElseChild(child) {
464
+ return child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, /^else(-if)?$/, true);
465
+ }
269
466
  const defaultOptions = {
270
467
  filename: "",
271
468
  prefixIdentifiers: true,
@@ -286,6 +483,7 @@ const defaultOptions = {
286
483
  bindingMetadata: _vue_shared.EMPTY_OBJ,
287
484
  inline: false,
288
485
  isTS: false,
486
+ eventDelegation: true,
289
487
  onError: _vue_compiler_dom.defaultOnError,
290
488
  onWarn: _vue_compiler_dom.defaultOnWarn
291
489
  };
@@ -294,14 +492,11 @@ function transform(node, options = {}) {
294
492
  type: 0,
295
493
  node,
296
494
  source: node.source,
297
- template: /* @__PURE__ */ new Map(),
298
- templateIndexMap: /* @__PURE__ */ new Map(),
299
- rootTemplateIndexes: /* @__PURE__ */ new Set(),
495
+ template: new TemplateRegistry(),
300
496
  component: /* @__PURE__ */ new Set(),
301
497
  directive: /* @__PURE__ */ new Set(),
302
498
  block: newBlock(node),
303
- hasTemplateRef: false,
304
- hasDeferredVShow: false
499
+ hasTemplateRef: false
305
500
  };
306
501
  const context = new TransformContext(ir, node, options);
307
502
  transformNode(context);
@@ -448,6 +643,9 @@ function genCall(name, ...frags) {
448
643
  hasPlaceholder ? name[1] : "null"
449
644
  ], ...frags)];
450
645
  }
646
+ function getParserOptions(plugins) {
647
+ return { plugins: plugins ? plugins.some((plugin) => plugin === "typescript") ? plugins : [...plugins, "typescript"] : ["typescript"] };
648
+ }
451
649
  function codeFragmentToString(code, context) {
452
650
  const { options: { filename, sourceMap } } = context;
453
651
  let map;
@@ -511,82 +709,6 @@ function codeFragmentToString(code, context) {
511
709
  }
512
710
  }
513
711
  //#endregion
514
- //#region packages/compiler-vapor/src/ir/component.ts
515
- const IRDynamicPropsKind = {
516
- "EXPRESSION": 0,
517
- "0": "EXPRESSION",
518
- "ATTRIBUTE": 1,
519
- "1": "ATTRIBUTE"
520
- };
521
- const IRSlotType = {
522
- "STATIC": 0,
523
- "0": "STATIC",
524
- "DYNAMIC": 1,
525
- "1": "DYNAMIC",
526
- "LOOP": 2,
527
- "2": "LOOP",
528
- "CONDITIONAL": 3,
529
- "3": "CONDITIONAL",
530
- "EXPRESSION": 4,
531
- "4": "EXPRESSION"
532
- };
533
- //#endregion
534
- //#region packages/compiler-vapor/src/ir/index.ts
535
- const IRNodeTypes = {
536
- "ROOT": 0,
537
- "0": "ROOT",
538
- "BLOCK": 1,
539
- "1": "BLOCK",
540
- "SET_BLOCK_KEY": 2,
541
- "2": "SET_BLOCK_KEY",
542
- "SET_PROP": 3,
543
- "3": "SET_PROP",
544
- "SET_DYNAMIC_PROPS": 4,
545
- "4": "SET_DYNAMIC_PROPS",
546
- "SET_TEXT": 5,
547
- "5": "SET_TEXT",
548
- "SET_EVENT": 6,
549
- "6": "SET_EVENT",
550
- "SET_DYNAMIC_EVENTS": 7,
551
- "7": "SET_DYNAMIC_EVENTS",
552
- "SET_HTML": 8,
553
- "8": "SET_HTML",
554
- "SET_TEMPLATE_REF": 9,
555
- "9": "SET_TEMPLATE_REF",
556
- "INSERT_NODE": 10,
557
- "10": "INSERT_NODE",
558
- "PREPEND_NODE": 11,
559
- "11": "PREPEND_NODE",
560
- "CREATE_COMPONENT_NODE": 12,
561
- "12": "CREATE_COMPONENT_NODE",
562
- "SLOT_OUTLET_NODE": 13,
563
- "13": "SLOT_OUTLET_NODE",
564
- "DIRECTIVE": 14,
565
- "14": "DIRECTIVE",
566
- "IF": 15,
567
- "15": "IF",
568
- "FOR": 16,
569
- "16": "FOR",
570
- "KEY": 17,
571
- "17": "KEY",
572
- "GET_TEXT_CHILD": 18,
573
- "18": "GET_TEXT_CHILD"
574
- };
575
- const DynamicFlag = {
576
- "NONE": 0,
577
- "0": "NONE",
578
- "REFERENCED": 1,
579
- "1": "REFERENCED",
580
- "NON_TEMPLATE": 2,
581
- "2": "NON_TEMPLATE",
582
- "INSERT": 4,
583
- "4": "INSERT"
584
- };
585
- function isBlockOperation(op) {
586
- const type = op.type;
587
- return type === 12 || type === 13 || type === 15 || type === 17 || type === 16;
588
- }
589
- //#endregion
590
712
  //#region packages/compiler-vapor/src/generators/dom.ts
591
713
  function genInsertNode({ parent, elements, anchor }, { helper }) {
592
714
  let element = elements.map((el) => `n${el}`).join(", ");
@@ -599,7 +721,10 @@ function genPrependNode(oper, { helper }) {
599
721
  //#endregion
600
722
  //#region packages/compiler-vapor/src/generators/expression.ts
601
723
  function genExpression(node, context, assignment) {
724
+ node = context.getExpressionReplacement(node);
602
725
  const { content, ast, isStatic, loc } = node;
726
+ const { options } = context;
727
+ const { inline } = options;
603
728
  if (isStatic) return [[
604
729
  JSON.stringify(content),
605
730
  -2,
@@ -621,23 +746,31 @@ function genExpression(node, context, assignment) {
621
746
  let hasMemberExpression = false;
622
747
  if (ids.length) {
623
748
  const [frag, push] = buildCodeFragment();
624
- ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
625
- const start = id.start - 1;
626
- const end = id.end - 1;
627
- const last = ids[i - 1];
628
- const leadingText = content.slice(last ? last.end - 1 : 0, start);
629
- if (leadingText.length) push([leadingText, -3]);
630
- const source = content.slice(start, end);
749
+ let lastEnd = 0;
750
+ ids.sort((a, b) => a.start - b.start).forEach((id) => {
751
+ const idStart = id.start - 1;
752
+ const idEnd = id.end - 1;
753
+ const source = content.slice(idStart, idEnd);
631
754
  const parentStack = parentStackMap.get(id);
632
755
  const parent = parentStack[parentStack.length - 1];
756
+ let start = idStart;
757
+ let end = idEnd;
758
+ if (inline && options.bindingMetadata && options.bindingMetadata[source] === "setup-let" && parent && parent.type === "UpdateExpression" && parent.argument === id) {
759
+ start = parent.start - 1;
760
+ end = parent.end - 1;
761
+ }
762
+ if (start < lastEnd) return;
763
+ const leadingText = content.slice(lastEnd, start);
764
+ if (leadingText.length) push([leadingText, -3]);
633
765
  hasMemberExpression || (hasMemberExpression = parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"));
634
766
  push(...genIdentifier(source, context, {
635
767
  start: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, start),
636
768
  end: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, end),
637
769
  source
638
- }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack));
639
- if (i === ids.length - 1 && end < content.length) push([content.slice(end), -3]);
770
+ }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack, node));
771
+ lastEnd = end;
640
772
  });
773
+ if (lastEnd < content.length) push([content.slice(lastEnd), -3]);
641
774
  if (assignment && hasMemberExpression) push(` = ${assignment}`);
642
775
  return frag;
643
776
  } else return [[
@@ -646,7 +779,7 @@ function genExpression(node, context, assignment) {
646
779
  loc
647
780
  ]];
648
781
  }
649
- function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
782
+ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack, sourceNode) {
650
783
  const { options, helper, identifiers } = context;
651
784
  const { inline, bindingMetadata } = options;
652
785
  let name = raw;
@@ -666,19 +799,49 @@ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
666
799
  else return genExpression(replacement, context, assignment);
667
800
  }
668
801
  let prefix;
669
- if ((0, _vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand) prefix = `${raw}: `;
670
802
  const type = bindingMetadata && bindingMetadata[raw];
803
+ const isDestructureAssignment = parent && (0, _vue_compiler_dom.isInDestructureAssignment)(parent, parentStack || []);
804
+ const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
805
+ const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
806
+ if ((0, _vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand && !(inline && type === "setup-let" && isDestructureAssignment)) prefix = `${raw}: `;
671
807
  if (inline) switch (type) {
672
808
  case "setup-let":
673
- name = raw = assignment ? `_isRef(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
809
+ if (isAssignmentLVal) {
810
+ const { right, operator } = parent;
811
+ const source = sourceNode;
812
+ const sourceContent = source.content;
813
+ const rightStart = right.start - 1;
814
+ const rightEnd = right.end - 1;
815
+ const rightContent = sourceContent.slice(rightStart, rightEnd);
816
+ const rightExp = (0, _vue_compiler_dom.createSimpleExpression)(rightContent, false, {
817
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightStart),
818
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightEnd),
819
+ source: rightContent
820
+ });
821
+ rightExp.ast = parseExp(context, rightContent);
822
+ return [
823
+ prefix,
824
+ `${helper("isRef")}(${raw}) ? ${raw}.value ${operator} `,
825
+ ...genExpression(rightExp, context),
826
+ ` : `,
827
+ [
828
+ raw,
829
+ -2,
830
+ loc,
831
+ name
832
+ ]
833
+ ];
834
+ } else if (isUpdateArg) {
835
+ const { prefix: isPrefix, operator } = parent;
836
+ const updatePrefix = isPrefix ? operator : ``;
837
+ const updatePostfix = isPrefix ? `` : operator;
838
+ raw = `${helper("isRef")}(${raw}) ? ${updatePrefix}${raw}.value${updatePostfix} : ${updatePrefix}${raw}${updatePostfix}`;
839
+ } else if (!isDestructureAssignment) name = raw = assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
674
840
  break;
675
841
  case "setup-ref":
676
842
  name = raw = withAssignment(`${raw}.value`);
677
843
  break;
678
844
  case "setup-maybe-ref":
679
- const isDestructureAssignment = parent && (0, _vue_compiler_dom.isInDestructureAssignment)(parent, parentStack || []);
680
- const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
681
- const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
682
845
  raw = isAssignmentLVal || isUpdateArg || isDestructureAssignment ? name = `${raw}.value` : assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : null` : unref();
683
846
  break;
684
847
  case "props":
@@ -713,28 +876,35 @@ function canPrefix(name) {
713
876
  return true;
714
877
  }
715
878
  function processExpressions(context, expressions, shouldDeclare) {
716
- const { seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
879
+ const expressionReplacements = /* @__PURE__ */ new Map();
880
+ const { seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
717
881
  const reservedNames = new Set(seenIdentifier);
718
- const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames);
719
- const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames);
720
- return genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare);
882
+ const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements);
883
+ const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements);
884
+ return {
885
+ ...genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare),
886
+ expressionReplacements
887
+ };
721
888
  }
722
889
  function analyzeExpressions(expressions) {
723
890
  const seenVariable = Object.create(null);
724
891
  const variableToExpMap = /* @__PURE__ */ new Map();
725
- const expToVariableMap = /* @__PURE__ */ new Map();
892
+ const expressionRecords = /* @__PURE__ */ new Map();
726
893
  const seenIdentifier = /* @__PURE__ */ new Set();
727
894
  const updatedVariable = /* @__PURE__ */ new Set();
895
+ const getRecord = (exp) => {
896
+ let record = expressionRecords.get(exp);
897
+ if (!record) expressionRecords.set(exp, record = { variables: [] });
898
+ return record;
899
+ };
728
900
  const registerVariable = (name, exp, isIdentifier, loc, parentStack = []) => {
729
901
  if (isIdentifier) seenIdentifier.add(name);
730
902
  seenVariable[name] = (seenVariable[name] || 0) + 1;
731
903
  variableToExpMap.set(name, (variableToExpMap.get(name) || /* @__PURE__ */ new Set()).add(exp));
732
- const variables = expToVariableMap.get(exp) || [];
733
- variables.push({
904
+ getRecord(exp).variables.push({
734
905
  name,
735
906
  loc
736
907
  });
737
- expToVariableMap.set(exp, variables);
738
908
  if (parentStack.some((p) => p.type === "UpdateExpression" || p.type === "AssignmentExpression")) updatedVariable.add(name);
739
909
  };
740
910
  for (const exp of expressions) {
@@ -771,13 +941,20 @@ function analyzeExpressions(expressions) {
771
941
  seenVariable,
772
942
  seenIdentifier,
773
943
  variableToExpMap,
774
- expToVariableMap,
944
+ expressionRecords,
775
945
  updatedVariable
776
946
  };
777
947
  }
778
- function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames) {
948
+ function getProcessedExpression(exp, expressionReplacements) {
949
+ return expressionReplacements.get(exp) || exp;
950
+ }
951
+ function setExpressionReplacement(expressionReplacements, exp, content, ast) {
952
+ expressionReplacements.set(exp, (0, _vue_shared.extend)({ ast }, (0, _vue_compiler_dom.createSimpleExpression)(content, exp.isStatic, exp.loc, exp.constType)));
953
+ }
954
+ function processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements) {
779
955
  const declarations = [];
780
- const expToReplacementMap = /* @__PURE__ */ new Map();
956
+ const declaredNames = /* @__PURE__ */ new Set();
957
+ const replacementPlan = /* @__PURE__ */ new Map();
781
958
  for (const [name, exps] of variableToExpMap) {
782
959
  if (updatedVariable.has(name)) continue;
783
960
  if ((0, _vue_shared.isGloballyAllowed)(name)) continue;
@@ -786,95 +963,201 @@ function processRepeatedVariables(context, seenVariable, variableToExpMap, expTo
786
963
  const varName = isIdentifier ? name : getUniqueDeclarationName(genVarName(name), reservedNames);
787
964
  exps.forEach((node) => {
788
965
  if (node.ast && varName !== name) {
789
- const replacements = expToReplacementMap.get(node) || [];
790
- replacements.push({
791
- name: varName,
792
- locs: expToVariableMap.get(node).reduce((locs, v) => {
793
- if (v.name === name && v.loc) locs.push(v.loc);
794
- return locs;
795
- }, [])
966
+ for (const variable of getExpressionVariables(expressionRecords, node)) if (variable.name === name && variable.loc) queueContentReplacement(replacementPlan, node, {
967
+ start: variable.loc.start - 1,
968
+ end: variable.loc.end - 1,
969
+ content: varName
796
970
  });
797
- expToReplacementMap.set(node, replacements);
798
971
  }
799
972
  });
800
- if (!declarations.some((d) => d.name === varName) && (!isIdentifier || shouldDeclareVariable(name, expToVariableMap, exps))) declarations.push({
801
- name: varName,
802
- isIdentifier,
803
- value: (0, _vue_shared.extend)({ ast: isIdentifier ? null : parseExp(context, name) }, (0, _vue_compiler_dom.createSimpleExpression)(name)),
804
- rawName: name,
805
- exps,
806
- seenCount: seenVariable[name]
807
- });
973
+ if (!declaredNames.has(varName) && (!isIdentifier || shouldDeclareVariable(name, expressionRecords, exps))) {
974
+ declaredNames.add(varName);
975
+ declarations.push({
976
+ name: varName,
977
+ isIdentifier,
978
+ value: (0, _vue_shared.extend)({ ast: isIdentifier ? null : parseExp(context, name) }, (0, _vue_compiler_dom.createSimpleExpression)(name)),
979
+ rawName: name,
980
+ exps,
981
+ seenCount: seenVariable[name]
982
+ });
983
+ }
808
984
  }
809
985
  }
810
- for (const [exp, replacements] of expToReplacementMap) {
811
- replacements.flatMap(({ name, locs }) => locs.map(({ start, end }) => ({
812
- start,
813
- end,
814
- name
815
- }))).sort((a, b) => b.end - a.end).forEach(({ start, end, name }) => {
816
- exp.content = exp.content.slice(0, start - 1) + name + exp.content.slice(end - 1);
817
- });
818
- exp.ast = parseExp(context, exp.content);
819
- }
986
+ applyReplacementPlan(context, expressionReplacements, replacementPlan);
820
987
  return declarations;
821
988
  }
822
- function shouldDeclareVariable(name, expToVariableMap, exps) {
823
- const vars = Array.from(exps, (exp) => expToVariableMap.get(exp).map((v) => v.name));
824
- if (vars.every((v) => v.length === 1)) return true;
825
- if (vars.some((v) => v.filter((e) => e === name).length > 1)) return true;
826
- const first = vars[0];
827
- if (vars.some((v) => v.length !== first.length)) {
828
- if (vars.some((v) => v.length > first.length && v.every((e) => first.includes(e))) || vars.some((v) => first.length > v.length && first.every((e) => v.includes(e)))) return false;
989
+ function shouldDeclareVariable(name, expressionRecords, exps) {
990
+ const variableUsages = [];
991
+ let allSingleVariable = true;
992
+ let hasRepeatedName = false;
993
+ let hasDifferentLength = false;
994
+ outer: for (const exp of exps) {
995
+ const variables = getExpressionVariables(expressionRecords, exp);
996
+ if (allSingleVariable && variables.length !== 1) allSingleVariable = false;
997
+ if (!hasDifferentLength && variableUsages.length > 0 && variables.length !== variableUsages[0].length) hasDifferentLength = true;
998
+ let nameCount = 0;
999
+ for (const variable of variables) if (variable.name === name && ++nameCount > 1) {
1000
+ hasRepeatedName = true;
1001
+ break outer;
1002
+ }
1003
+ variableUsages.push(variables);
1004
+ }
1005
+ if (allSingleVariable) return true;
1006
+ if (hasRepeatedName) return true;
1007
+ const first = variableUsages[0];
1008
+ if (hasDifferentLength) {
1009
+ for (const variables of variableUsages) {
1010
+ if (variables.length === first.length) continue;
1011
+ const longer = variables.length > first.length ? variables : first;
1012
+ const shorter = variables.length > first.length ? first : variables;
1013
+ const shorterNames = /* @__PURE__ */ new Set();
1014
+ for (const variable of shorter) shorterNames.add(variable.name);
1015
+ let isSubset = true;
1016
+ for (const variable of longer) if (!shorterNames.has(variable.name)) {
1017
+ isSubset = false;
1018
+ break;
1019
+ }
1020
+ if (isSubset) return false;
1021
+ }
829
1022
  return true;
830
1023
  }
831
- if (vars.every((v) => v.every((e, idx) => e === first[idx]))) return false;
832
- return true;
1024
+ for (const variables of variableUsages) for (let i = 0; i < variables.length; i++) if (variables[i].name !== first[i].name) return true;
1025
+ return false;
833
1026
  }
834
- function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames) {
1027
+ function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements) {
835
1028
  const declarations = [];
836
- const seenExp = expressions.reduce((acc, exp) => {
837
- const vars = expToVariableMap.get(exp);
838
- if (!vars) return acc;
839
- const variables = vars.map((v) => v.name);
840
- if (exp.ast && exp.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v))) && !variables.some((v) => (0, _vue_shared.isGloballyAllowed)(v))) acc[exp.content] = (acc[exp.content] || 0) + 1;
841
- return acc;
842
- }, Object.create(null));
843
- Object.entries(seenExp).forEach(([content, count]) => {
844
- if (count > 1) {
845
- const delVars = {};
846
- for (let i = varDeclarations.length - 1; i >= 0; i--) {
847
- const item = varDeclarations[i];
848
- if (!item.exps || !item.seenCount) continue;
849
- if ([...item.exps].every((node) => node.content === content && item.seenCount === count)) {
850
- delVars[item.name] = item.rawName;
851
- reservedNames.delete(item.name);
852
- varDeclarations.splice(i, 1);
853
- }
854
- }
855
- const value = (0, _vue_shared.extend)({}, expressions.find((exp) => exp.content === content));
856
- Object.keys(delVars).forEach((name) => {
857
- value.content = value.content.replace(name, delVars[name]);
858
- if (value.ast) value.ast = parseExp(context, value.content);
859
- });
860
- const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
861
- declarations.push({
862
- name: varName,
863
- value
1029
+ const seenExp = /* @__PURE__ */ new Map();
1030
+ for (const exp of expressions) {
1031
+ var _expressionRecords$ge;
1032
+ const vars = (_expressionRecords$ge = expressionRecords.get(exp)) === null || _expressionRecords$ge === void 0 ? void 0 : _expressionRecords$ge.variables;
1033
+ if (!vars) continue;
1034
+ const processed = getProcessedExpression(exp, expressionReplacements);
1035
+ if (canCacheExpression(processed, vars, updatedVariable)) {
1036
+ const seen = seenExp.get(processed.content);
1037
+ if (seen) seen.count++;
1038
+ else seenExp.set(processed.content, {
1039
+ count: 1,
1040
+ first: exp
864
1041
  });
865
- expressions.forEach((exp) => {
866
- if (exp.content === content) {
867
- exp.content = varName;
868
- exp.ast = null;
869
- } else if (exp.content.includes(content)) {
870
- exp.content = exp.content.replace(new RegExp(escapeRegExp(content), "g"), varName);
871
- exp.ast = parseExp(context, exp.content);
1042
+ }
1043
+ }
1044
+ const repeatedExpressions = [...seenExp].sort(([contentA], [contentB]) => contentB.length - contentA.length);
1045
+ for (const [content, { count, first }] of repeatedExpressions) if (count > 1) {
1046
+ const removedDeclarations = [];
1047
+ for (let i = varDeclarations.length - 1; i >= 0; i--) {
1048
+ const item = varDeclarations[i];
1049
+ if (!item.exps || !item.seenCount) continue;
1050
+ if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) {
1051
+ removedDeclarations.push({
1052
+ name: item.name,
1053
+ rawName: item.rawName
1054
+ });
1055
+ reservedNames.delete(item.name);
1056
+ varDeclarations.splice(i, 1);
1057
+ }
1058
+ }
1059
+ const value = (0, _vue_shared.extend)({}, getProcessedExpression(first, expressionReplacements));
1060
+ const restorePlan = [];
1061
+ for (const { name, rawName } of removedDeclarations) restorePlan.push(...findIdentifierReplacements(value, name, rawName));
1062
+ if (restorePlan.length) {
1063
+ value.content = applyContentReplacements(value.content, restorePlan);
1064
+ if (value.ast) value.ast = parseExp(context, value.content);
1065
+ }
1066
+ const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
1067
+ declarations.push({
1068
+ name: varName,
1069
+ value
1070
+ });
1071
+ for (const exp of expressions) {
1072
+ const processed = getProcessedExpression(exp, expressionReplacements);
1073
+ if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null);
1074
+ else if (processed.content.includes(content)) {
1075
+ const replacements = findContentReplacements(processed, content, varName);
1076
+ if (replacements.length) {
1077
+ const replacedContent = applyContentReplacements(processed.content, replacements);
1078
+ setExpressionReplacement(expressionReplacements, exp, replacedContent, parseExp(context, replacedContent));
872
1079
  }
873
- });
1080
+ }
874
1081
  }
875
- });
1082
+ }
876
1083
  return declarations;
877
1084
  }
1085
+ function canCacheExpression(processed, vars, updatedVariable) {
1086
+ if (!processed.ast || processed.ast.type === "Identifier") return false;
1087
+ for (const { name } of vars) if (updatedVariable.has(name) || (0, _vue_shared.isGloballyAllowed)(name)) return false;
1088
+ return true;
1089
+ }
1090
+ function getExpressionVariables(expressionRecords, exp) {
1091
+ var _expressionRecords$ge2;
1092
+ return ((_expressionRecords$ge2 = expressionRecords.get(exp)) === null || _expressionRecords$ge2 === void 0 ? void 0 : _expressionRecords$ge2.variables) || [];
1093
+ }
1094
+ function queueContentReplacement(replacementPlan, exp, replacement) {
1095
+ const replacements = replacementPlan.get(exp);
1096
+ if (replacements) replacements.push(replacement);
1097
+ else replacementPlan.set(exp, [replacement]);
1098
+ }
1099
+ function applyReplacementPlan(context, expressionReplacements, replacementPlan) {
1100
+ for (const [exp, replacements] of replacementPlan) {
1101
+ if (!replacements.length) continue;
1102
+ const content = applyContentReplacements(getProcessedExpression(exp, expressionReplacements).content, replacements);
1103
+ setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content));
1104
+ }
1105
+ }
1106
+ function findContentReplacements(exp, content, replacement) {
1107
+ const identifiers = getIdentifierRanges(exp);
1108
+ if (!identifiers.length) return [];
1109
+ const replacements = [];
1110
+ let searchStart = 0;
1111
+ let start = exp.content.indexOf(content, searchStart);
1112
+ while (start !== -1) {
1113
+ const end = start + content.length;
1114
+ let canReplace = false;
1115
+ for (const identifier of identifiers) {
1116
+ if (start >= identifier.end || end <= identifier.start) continue;
1117
+ if (start > identifier.start || end < identifier.end) {
1118
+ canReplace = false;
1119
+ break;
1120
+ }
1121
+ canReplace = true;
1122
+ }
1123
+ if (canReplace) {
1124
+ replacements.push({
1125
+ start,
1126
+ end,
1127
+ content: replacement
1128
+ });
1129
+ searchStart = end;
1130
+ } else searchStart = start + 1;
1131
+ start = exp.content.indexOf(content, searchStart);
1132
+ }
1133
+ return replacements;
1134
+ }
1135
+ function findIdentifierReplacements(exp, name, replacement) {
1136
+ const replacements = [];
1137
+ for (const { start, end } of getIdentifierRanges(exp)) if (exp.content.slice(start, end) === name) replacements.push({
1138
+ start,
1139
+ end,
1140
+ content: replacement
1141
+ });
1142
+ return replacements;
1143
+ }
1144
+ function getIdentifierRanges(exp) {
1145
+ if (!exp.ast || typeof exp.ast !== "object") return [];
1146
+ const identifiers = [];
1147
+ (0, _vue_compiler_dom.walkIdentifiers)(exp.ast, (id) => {
1148
+ identifiers.push({
1149
+ start: id.start - 1,
1150
+ end: id.end - 1
1151
+ });
1152
+ }, false);
1153
+ return identifiers;
1154
+ }
1155
+ function applyContentReplacements(content, replacements) {
1156
+ replacements.sort((a, b) => b.start - a.start).forEach(({ start, end, content: replacement }) => {
1157
+ content = content.slice(0, start) + replacement + content.slice(end);
1158
+ });
1159
+ return content;
1160
+ }
878
1161
  function genDeclarations(declarations, context, shouldDeclare) {
879
1162
  const [frag, push] = buildCodeFragment();
880
1163
  const ids = Object.create(null);
@@ -902,13 +1185,8 @@ function genDeclarations(declarations, context, shouldDeclare) {
902
1185
  varNames: [...varNames]
903
1186
  };
904
1187
  }
905
- function escapeRegExp(string) {
906
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
907
- }
908
1188
  function parseExp(context, content) {
909
- const plugins = context.options.expressionPlugins;
910
- const options = { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] };
911
- return (0, _babel_parser.parseExpression)(`(${content})`, options);
1189
+ return (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
912
1190
  }
913
1191
  function genVarName(exp) {
914
1192
  return `${exp.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/_+$/, "")}`;
@@ -949,22 +1227,31 @@ const isMemberExpression$3 = (node) => {
949
1227
  function genSetEvent(oper, context) {
950
1228
  const { helper } = context;
951
1229
  const { element, key, keyOverride, value, modifiers, delegate, effect } = oper;
952
- const name = genName();
953
- const handler = [
954
- `${context.helper("createInvoker")}(`,
955
- ...genEventHandler(context, [value], modifiers),
956
- `)`
957
- ];
958
- const eventOptions = genEventOptions();
1230
+ let handler;
959
1231
  if (delegate) {
960
1232
  context.delegates.add(key.content);
961
1233
  if (!context.block.operation.some(isSameDelegateEvent)) return [
962
1234
  NEWLINE,
963
1235
  `n${element}.$evt${key.content} = `,
964
- ...handler
1236
+ ...genDirectHandler()
965
1237
  ];
966
1238
  }
967
- return [NEWLINE, ...genCall(helper(delegate ? "delegate" : "on"), `n${element}`, name, handler, eventOptions)];
1239
+ const name = genName();
1240
+ const eventOptions = genEventOptions();
1241
+ return [NEWLINE, ...genCall(helper(effect ? "onBinding" : delegate ? "delegate" : "on"), `n${element}`, name, genHandler(), eventOptions)];
1242
+ function genHandler() {
1243
+ return handler || (handler = genEventHandler(context, [value], modifiers));
1244
+ }
1245
+ function genInvoker() {
1246
+ return [
1247
+ `${helper("createInvoker")}(`,
1248
+ ...genHandler(),
1249
+ `)`
1250
+ ];
1251
+ }
1252
+ function genDirectHandler() {
1253
+ return modifiers.keys.length || modifiers.nonKeys.length ? genEventHandler(context, [value], modifiers, { modifierHelper: "vapor" }) : genInvoker();
1254
+ }
968
1255
  function genName() {
969
1256
  const expr = genExpression(key, context);
970
1257
  if (keyOverride) {
@@ -984,8 +1271,8 @@ function genSetEvent(oper, context) {
984
1271
  }
985
1272
  function genEventOptions() {
986
1273
  let { options } = modifiers;
987
- if (!options.length && !effect) return;
988
- return genMulti(DELIMITERS_OBJECT_NEWLINE, effect && ["effect: true"], ...options.map((option) => [`${option}: true`]));
1274
+ if (!options.length) return;
1275
+ return genMulti(DELIMITERS_OBJECT_NEWLINE, ...options.map((option) => [`${option}: true`]));
989
1276
  }
990
1277
  function isSameDelegateEvent(op) {
991
1278
  if (op.type === 6 && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true;
@@ -998,7 +1285,9 @@ function genSetDynamicEvents(oper, context) {
998
1285
  function genEventHandler(context, values, modifiers = {
999
1286
  nonKeys: [],
1000
1287
  keys: []
1001
- }, asComponentProp = false, extraWrap = false) {
1288
+ }, options = {}) {
1289
+ const { asComponentProp = false, extraWrap = false, modifierHelper = "runtime" } = options;
1290
+ const useVaporModifierHelper = modifierHelper === "vapor";
1002
1291
  let handlerExp = [];
1003
1292
  if (values) {
1004
1293
  values.forEach((value, index) => {
@@ -1039,16 +1328,16 @@ function genEventHandler(context, values, modifiers = {
1039
1328
  }
1040
1329
  if (handlerExp.length === 0) handlerExp = ["() => {}"];
1041
1330
  const { keys, nonKeys } = modifiers;
1042
- if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys);
1043
- if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys);
1331
+ if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys, useVaporModifierHelper && !keys.length);
1332
+ if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys, useVaporModifierHelper);
1044
1333
  if (extraWrap) handlerExp.unshift(`() => `);
1045
1334
  return handlerExp;
1046
1335
  }
1047
- function genWithModifiers(context, handler, nonKeys) {
1048
- return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys));
1336
+ function genWithModifiers(context, handler, nonKeys, useVaporHelper = false) {
1337
+ return genCall(context.helper(useVaporHelper ? "withVaporModifiers" : "withModifiers"), handler, JSON.stringify(nonKeys));
1049
1338
  }
1050
- function genWithKeys(context, handler, keys) {
1051
- return genCall(context.helper("withKeys"), handler, JSON.stringify(keys));
1339
+ function genWithKeys(context, handler, keys, useVaporHelper = false) {
1340
+ return genCall(context.helper(useVaporHelper ? "withVaporKeys" : "withKeys"), handler, JSON.stringify(keys));
1052
1341
  }
1053
1342
  function isConstantBinding(value, context) {
1054
1343
  if (value.ast === null) {
@@ -1059,7 +1348,7 @@ function isConstantBinding(value, context) {
1059
1348
  //#region packages/compiler-vapor/src/generators/for.ts
1060
1349
  function genFor(oper, context) {
1061
1350
  const { helper } = context;
1062
- const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper;
1351
+ const { source, value, key, index, render, keyProp, once, id, component, onlyChild, slotRoot } = oper;
1063
1352
  const rawValue = value && value.content;
1064
1353
  const rawKey = key && key.content;
1065
1354
  const rawIndex = index && index.content;
@@ -1086,16 +1375,12 @@ function genFor(oper, context) {
1086
1375
  idMap[rawIndex] = `${indexVar}.value`;
1087
1376
  idMap[indexVar] = null;
1088
1377
  }
1089
- const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
1378
+ const { selectorPatterns, keyOnlyBindingPatterns, skippedEffectIndexes } = matchPatterns(render, keyProp, idMap, context);
1090
1379
  const selectorDeclarations = [];
1091
- const selectorSetup = [];
1380
+ const selectorName = (i) => selectorPatterns.length > 1 ? `_selector${id}_${i}` : `_selector${id}`;
1092
1381
  for (let i = 0; i < selectorPatterns.length; i++) {
1093
1382
  const { selector } = selectorPatterns[i];
1094
- const selectorName = `_selector${id}_${i}`;
1095
- selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
1096
- if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
1097
- selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)]));
1098
- if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}");
1383
+ selectorDeclarations.push(`const ${selectorName(i)} = `, ...genCall(helper("createSelector"), [`() => `, ...genExpression(selector, context)]), NEWLINE);
1099
1384
  }
1100
1385
  const blockFn = context.withId(() => {
1101
1386
  const frag = [];
@@ -1104,27 +1389,27 @@ function genFor(oper, context) {
1104
1389
  const patternFrag = [];
1105
1390
  for (let i = 0; i < selectorPatterns.length; i++) {
1106
1391
  const { effect } = selectorPatterns[i];
1107
- patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START);
1392
+ patternFrag.push(NEWLINE, `${selectorName(i)}(`, ...genExpression(keyProp, context), `, () => {`, INDENT_START);
1108
1393
  for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context));
1109
1394
  patternFrag.push(INDENT_END, NEWLINE, `})`);
1110
1395
  }
1111
1396
  for (const { effect } of keyOnlyBindingPatterns) for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context));
1112
1397
  return patternFrag;
1113
- }));
1398
+ }, skippedEffectIndexes));
1114
1399
  else frag.push(...genBlockContent(render, context));
1115
1400
  frag.push(INDENT_END, NEWLINE, "}");
1116
1401
  return frag;
1117
1402
  }, idMap);
1118
1403
  exitScope();
1119
- let flags = 0;
1120
- if (onlyChild) flags |= 1;
1121
- if (component) flags |= 2;
1122
- if (once) flags |= 4;
1404
+ const flags = genForFlags(onlyChild, component, isFragmentBlock(render), !component && isSingleNodeBlock(render), once, slotRoot);
1405
+ const onResetCalls = [];
1406
+ for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`);
1123
1407
  return [
1124
1408
  NEWLINE,
1125
1409
  ...selectorDeclarations,
1126
1410
  `const n${id} = `,
1127
- ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0)
1411
+ ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags),
1412
+ ...onResetCalls
1128
1413
  ];
1129
1414
  function genCallback(expr) {
1130
1415
  if (!expr) return false;
@@ -1148,13 +1433,58 @@ function genFor(oper, context) {
1148
1433
  return idMap;
1149
1434
  }
1150
1435
  }
1151
- function parseValueDestructure(value, context) {
1152
- const map = /* @__PURE__ */ new Map();
1153
- if (value) {
1154
- const rawValue = value.content;
1155
- if (value.ast) (0, _vue_compiler_dom.walkIdentifiers)(value.ast, (id, _, parentStack, ___, isLocal) => {
1156
- if (isLocal) {
1157
- let path = "";
1436
+ function genForFlags(onlyChild, component, isFragment, isSingleNode, once, slotRoot) {
1437
+ let flags = 0;
1438
+ const names = [];
1439
+ if (onlyChild) {
1440
+ flags |= 1;
1441
+ names.push("FAST_REMOVE");
1442
+ }
1443
+ if (component) {
1444
+ flags |= 2;
1445
+ names.push("IS_COMPONENT");
1446
+ }
1447
+ if (isFragment) {
1448
+ flags |= 16;
1449
+ names.push("IS_FRAGMENT");
1450
+ }
1451
+ if (isSingleNode) {
1452
+ flags |= 8;
1453
+ names.push("IS_SINGLE_NODE");
1454
+ }
1455
+ if (once) {
1456
+ flags |= 4;
1457
+ names.push("ONCE");
1458
+ }
1459
+ if (slotRoot) {
1460
+ flags |= 32;
1461
+ names.push("SLOT_ROOT");
1462
+ }
1463
+ if (!flags) return;
1464
+ return `${flags} /* ${names.join(", ")} */`;
1465
+ }
1466
+ function isSingleNodeBlock(block) {
1467
+ const child = getSingleReturnedChild(block);
1468
+ return !!child && child.template != null;
1469
+ }
1470
+ function isFragmentBlock(block) {
1471
+ const child = getSingleReturnedChild(block);
1472
+ const operation = child && child.operation;
1473
+ if (!operation) return false;
1474
+ return operation.type === 13 || operation.type === 16 || operation.type === 17 || operation.type === 15 && !operation.once || operation.type === 12 && !!operation.dynamic && !operation.dynamic.isStatic;
1475
+ }
1476
+ function getSingleReturnedChild(block) {
1477
+ if (block.returns.length !== 1) return;
1478
+ const id = block.returns[0];
1479
+ for (const child of block.dynamic.children) if (child.id === id) return child;
1480
+ }
1481
+ function parseValueDestructure(value, context) {
1482
+ const map = /* @__PURE__ */ new Map();
1483
+ if (value) {
1484
+ const rawValue = value.content;
1485
+ if (value.ast) (0, _vue_compiler_dom.walkIdentifiers)(value.ast, (id, _, parentStack, ___, isLocal) => {
1486
+ if (isLocal) {
1487
+ let path = "";
1158
1488
  let isDynamic = false;
1159
1489
  let helper;
1160
1490
  let helperArgs;
@@ -1183,7 +1513,7 @@ function parseValueDestructure(value, context) {
1183
1513
  if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
1184
1514
  isDynamic = true;
1185
1515
  helper = context.helper("getDefaultValue");
1186
- helperArgs = rawValue.slice(child.right.start - 1, child.right.end - 1);
1516
+ helperArgs = `() => (${rawValue.slice(child.right.start - 1, child.right.end - 1)})`;
1187
1517
  }
1188
1518
  }
1189
1519
  map.set(id.name, {
@@ -1210,34 +1540,44 @@ function buildDestructureIdMap(idToPathMap, baseAccessor, plugins) {
1210
1540
  }
1211
1541
  if (pathInfo.dynamic) {
1212
1542
  const node = idMap[id] = (0, _vue_compiler_dom.createSimpleExpression)(path);
1213
- node.ast = (0, _babel_parser.parseExpression)(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] });
1543
+ node.ast = (0, _babel_parser.parseExpression)(`(${path})`, getParserOptions(plugins));
1214
1544
  } else idMap[id] = path;
1215
1545
  } else idMap[id] = path;
1216
1546
  });
1217
1547
  return idMap;
1218
1548
  }
1219
- function matchPatterns(render, keyProp, idMap) {
1549
+ function matchPatterns(render, keyProp, idMap, context) {
1220
1550
  const selectorPatterns = [];
1221
1551
  const keyOnlyBindingPatterns = [];
1222
- render.effect = render.effect.filter((effect) => {
1223
- if (keyProp !== void 0) {
1224
- const selector = matchSelectorPattern(effect, keyProp.content, idMap);
1225
- if (selector) {
1226
- selectorPatterns.push(selector);
1227
- return false;
1228
- }
1229
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
1230
- if (keyOnly) {
1231
- keyOnlyBindingPatterns.push(keyOnly);
1232
- return false;
1233
- }
1552
+ let skippedEffectIndexes;
1553
+ if (keyProp === void 0) return {
1554
+ keyOnlyBindingPatterns,
1555
+ selectorPatterns,
1556
+ skippedEffectIndexes
1557
+ };
1558
+ for (let index = 0; index < render.effect.length; index++) {
1559
+ const effect = render.effect[index];
1560
+ const selector = matchSelectorPattern(effect, keyProp.content, idMap, context);
1561
+ if (selector) {
1562
+ selectorPatterns.push(selector);
1563
+ skipEffect(index);
1564
+ continue;
1234
1565
  }
1235
- return true;
1236
- });
1566
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
1567
+ if (keyOnly) {
1568
+ keyOnlyBindingPatterns.push(keyOnly);
1569
+ skipEffect(index);
1570
+ }
1571
+ }
1237
1572
  return {
1238
1573
  keyOnlyBindingPatterns,
1239
- selectorPatterns
1574
+ selectorPatterns,
1575
+ skippedEffectIndexes
1240
1576
  };
1577
+ function skipEffect(index) {
1578
+ if (!skippedEffectIndexes) skippedEffectIndexes = /* @__PURE__ */ new Set();
1579
+ skippedEffectIndexes.add(index);
1580
+ }
1241
1581
  }
1242
1582
  function matchKeyOnlyBindingPattern(effect, key) {
1243
1583
  if (effect.expressions.length === 1) {
@@ -1247,7 +1587,7 @@ function matchKeyOnlyBindingPattern(effect, key) {
1247
1587
  }
1248
1588
  }
1249
1589
  }
1250
- function matchSelectorPattern(effect, key, idMap) {
1590
+ function matchSelectorPattern(effect, key, idMap, context) {
1251
1591
  if (effect.expressions.length === 1) {
1252
1592
  const { ast, content } = effect.expressions[0];
1253
1593
  if (typeof ast === "object" && ast) {
@@ -1272,17 +1612,11 @@ function matchSelectorPattern(effect, key, idMap) {
1272
1612
  }, false);
1273
1613
  if (!hasExtraId) {
1274
1614
  const name = content.slice(selector.start - 1, selector.end - 1);
1615
+ const selectorExpression = (0, _vue_compiler_dom.createSimpleExpression)(name, false, selector.loc);
1616
+ selectorExpression.ast = (0, _babel_parser.parseExpression)(`(${name})`, getParserOptions(context.options.expressionPlugins));
1275
1617
  return {
1276
1618
  effect,
1277
- selector: {
1278
- content: name,
1279
- ast: (0, _vue_shared.extend)({}, selector, {
1280
- start: 1,
1281
- end: name.length + 1
1282
- }),
1283
- loc: selector.loc,
1284
- isStatic: false
1285
- }
1619
+ selector: selectorExpression
1286
1620
  };
1287
1621
  }
1288
1622
  }
@@ -1323,8 +1657,9 @@ function genSetHtml(oper, context) {
1323
1657
  //#region packages/compiler-vapor/src/generators/if.ts
1324
1658
  function genIf(oper, context, isNested = false) {
1325
1659
  const { helper } = context;
1326
- const { condition, positive, negative, once, index, blockShape } = oper;
1660
+ const { condition, positive, negative, once, slotRoot, index, blockShape } = oper;
1327
1661
  const [frag, push] = buildCodeFragment();
1662
+ const flags = genIfFlags(blockShape, once, slotRoot, negative ? index : void 0);
1328
1663
  const conditionExpr = [
1329
1664
  "() => (",
1330
1665
  ...genExpression(condition, context),
@@ -1335,15 +1670,44 @@ function genIf(oper, context, isNested = false) {
1335
1670
  if (negative) if (negative.type === 1) negativeArg = genBlock(negative, context);
1336
1671
  else negativeArg = ["() => ", ...genIf(negative, context, true)];
1337
1672
  if (!isNested) push(NEWLINE, `const n${oper.id} = `);
1338
- push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, String(blockShape), once && "true", index !== void 0 && negative && String(index)));
1673
+ push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, flags));
1339
1674
  return frag;
1340
1675
  }
1676
+ function genIfFlags(blockShape, once, slotRoot, index) {
1677
+ let flags = blockShape;
1678
+ if (slotRoot) flags |= 128;
1679
+ if (once) flags |= 16;
1680
+ else if (index !== void 0) flags |= index + 1 << 8;
1681
+ if (flags === 1) return false;
1682
+ return `${flags} /* ${genIfFlagNames(once, slotRoot, index, blockShape)} */`;
1683
+ }
1684
+ function genIfFlagNames(once, slotRoot, index, blockShape) {
1685
+ const names = [`TRUE_${genBlockShapeName(blockShape)}`];
1686
+ const falseShape = blockShape >> 2;
1687
+ const hasFalseBranch = (falseShape & 3) !== 0;
1688
+ if (hasFalseBranch) names.push(`FALSE_${genBlockShapeName(falseShape)}`);
1689
+ if (blockShape & 32) names.push("TRUE_NO_SCOPE");
1690
+ if (hasFalseBranch && blockShape & 64) names.push("FALSE_NO_SCOPE");
1691
+ if (once) names.push("ONCE");
1692
+ if (slotRoot) names.push("SLOT_ROOT");
1693
+ if (!once && index !== void 0) names.push(`KEYED_INDEX_${index}`);
1694
+ return names.join(", ");
1695
+ }
1696
+ function genBlockShapeName(flags) {
1697
+ switch (flags & 3) {
1698
+ case 0: return "EMPTY";
1699
+ case 1: return "SINGLE_ROOT";
1700
+ case 2: return "MULTI_ROOT";
1701
+ }
1702
+ return "UNKNOWN";
1703
+ }
1341
1704
  //#endregion
1342
1705
  //#region packages/compiler-vapor/src/generators/prop.ts
1343
1706
  const helpers = {
1344
1707
  setText: { name: "setText" },
1345
1708
  setHtml: { name: "setHtml" },
1346
1709
  setClass: { name: "setClass" },
1710
+ setClassName: { name: "setClassName" },
1347
1711
  setStyle: { name: "setStyle" },
1348
1712
  setValue: { name: "setValue" },
1349
1713
  setAttr: {
@@ -1363,9 +1727,133 @@ function genSetProp(oper, context) {
1363
1727
  const { helper } = context;
1364
1728
  const { prop: { key, values, modifier }, tag } = oper;
1365
1729
  const resolvedHelper = getRuntimeHelper(tag, key.content, modifier);
1730
+ if (key.content === "class" && !resolvedHelper.isSVG && resolvedHelper.name === "setClass") {
1731
+ const className = genSetClassName(oper, context);
1732
+ if (className) return className;
1733
+ }
1366
1734
  const propValue = genPropValue(values, context);
1367
1735
  return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue, resolvedHelper.isSVG && "true")];
1368
1736
  }
1737
+ const MAX_CLASS_NAME_ENTRIES = 31;
1738
+ function genSetClassName(oper, context) {
1739
+ const info = resolveClassName(oper.prop.values, context);
1740
+ if (!info) return;
1741
+ const { helper } = context;
1742
+ const flags = genClassFlags(info.entries, context);
1743
+ const classFragments = info.entries.map((entry) => JSON.stringify(!info.prefix && info.entries.length === 1 ? entry.className : ` ${entry.className}`));
1744
+ const fragments = classFragments.length === 1 ? classFragments[0] : genMulti(DELIMITERS_ARRAY, ...classFragments);
1745
+ return [NEWLINE, ...genCall([helper("setClassName"), "\"\""], `n${oper.element}`, flags, fragments, info.prefix && JSON.stringify(info.prefix), info.suffix && JSON.stringify(info.suffix))];
1746
+ }
1747
+ function resolveClassName(values, context) {
1748
+ let prefix = "";
1749
+ let suffix = "";
1750
+ const entries = [];
1751
+ let sawDynamic = false;
1752
+ let sawSuffix = false;
1753
+ for (const rawValue of values) {
1754
+ const value = context.getExpressionReplacement(rawValue);
1755
+ const staticValue = getLiteralExpressionValue(value, true);
1756
+ if (staticValue != null) {
1757
+ const normalized = (0, _vue_shared.normalizeClass)(staticValue);
1758
+ if (normalized) if (sawSuffix) suffix = appendClass$1(suffix, normalized);
1759
+ else if (sawDynamic) {
1760
+ sawSuffix = true;
1761
+ suffix = appendClass$1(suffix, normalized);
1762
+ } else prefix = appendClass$1(prefix, normalized);
1763
+ continue;
1764
+ }
1765
+ const ast = value.ast;
1766
+ if (!ast || sawSuffix) return;
1767
+ sawDynamic = true;
1768
+ if (ast.type === "ObjectExpression") {
1769
+ if (!resolveObjectClassName(value, ast, entries, context)) return;
1770
+ } else if (ast.type === "ConditionalExpression") {
1771
+ if (!resolveConditionalClassName(value, ast, entries, context)) return;
1772
+ } else return;
1773
+ }
1774
+ return entries.length && entries.length <= MAX_CLASS_NAME_ENTRIES ? {
1775
+ prefix,
1776
+ suffix,
1777
+ entries
1778
+ } : void 0;
1779
+ }
1780
+ function resolveObjectClassName(source, ast, entries, context) {
1781
+ for (const prop of ast.properties) {
1782
+ if (prop.type !== "ObjectProperty" || prop.computed) return false;
1783
+ const rawClassName = getObjectPropertyName$1(prop);
1784
+ if (rawClassName == null) return false;
1785
+ const className = (0, _vue_shared.normalizeClass)(rawClassName);
1786
+ if (!className) continue;
1787
+ const value = getBooleanValue(prop.value);
1788
+ entries.push({
1789
+ className,
1790
+ value,
1791
+ condition: value == null ? createSubExpression(source, prop.value, context) : void 0
1792
+ });
1793
+ }
1794
+ return true;
1795
+ }
1796
+ function resolveConditionalClassName(source, ast, entries, context) {
1797
+ const consequent = getStringClassValue(ast.consequent);
1798
+ const alternate = getStringClassValue(ast.alternate);
1799
+ if (consequent && alternate === "") {
1800
+ entries.push({
1801
+ className: consequent,
1802
+ condition: createSubExpression(source, ast.test, context)
1803
+ });
1804
+ return true;
1805
+ } else if (alternate && consequent === "") {
1806
+ entries.push({
1807
+ className: alternate,
1808
+ condition: createSubExpression(source, ast.test, context),
1809
+ negate: true
1810
+ });
1811
+ return true;
1812
+ }
1813
+ return false;
1814
+ }
1815
+ function genClassFlags(entries, context) {
1816
+ const values = [];
1817
+ entries.forEach((entry, index) => {
1818
+ if (index) values.push(" | ");
1819
+ const bit = 1 << index;
1820
+ if (entry.value != null) {
1821
+ values.push(entry.value ? String(bit) : "0");
1822
+ return;
1823
+ }
1824
+ values.push("(", ...genExpression(entry.condition, context), entry.negate ? ` ? 0 : ${bit}` : ` ? ${bit} : 0`, ")");
1825
+ });
1826
+ return values;
1827
+ }
1828
+ function appendClass$1(base, value) {
1829
+ return base ? value ? `${base} ${value}` : base : value;
1830
+ }
1831
+ function getObjectPropertyName$1(prop) {
1832
+ const key = prop.key;
1833
+ if (key.type === "Identifier") return key.name;
1834
+ else if (key.type === "StringLiteral") return key.value;
1835
+ else if (key.type === "NumericLiteral") return String(key.value);
1836
+ }
1837
+ function getStringClassValue(node) {
1838
+ if (node.type === "StringLiteral") return (0, _vue_shared.normalizeClass)(node.value);
1839
+ else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return (0, _vue_shared.normalizeClass)(node.quasis[0].value.cooked || "");
1840
+ else if (node.type === "NullLiteral" || node.type === "BooleanLiteral" && !node.value) return "";
1841
+ }
1842
+ function getBooleanValue(node) {
1843
+ if (node.type === "BooleanLiteral") return node.value;
1844
+ }
1845
+ function createSubExpression(source, node, context) {
1846
+ const start = node.start == null ? 0 : node.start - 1;
1847
+ const end = node.end == null ? source.content.length : node.end - 1;
1848
+ const content = source.content.slice(start, end);
1849
+ const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
1850
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
1851
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
1852
+ source: content
1853
+ });
1854
+ expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
1855
+ return expression;
1856
+ }
1369
1857
  function genDynamicProps$1(oper, context) {
1370
1858
  const { helper } = context;
1371
1859
  const isSVG = (0, _vue_shared.isSVGTag)(oper.tag);
@@ -1394,7 +1882,12 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1394
1882
  if (runtimeCamelize) {
1395
1883
  key.push(" || \"\"");
1396
1884
  key = genCall(helper("camelize"), key);
1397
- }
1885
+ } else if (modifier) key = [
1886
+ "(",
1887
+ ...key,
1888
+ " || \"\"",
1889
+ ")"
1890
+ ];
1398
1891
  if (handler) key = genCall(helper("toHandlerKey"), key);
1399
1892
  return [
1400
1893
  "[",
@@ -1432,8 +1925,23 @@ function getSpecialHelper(keyName, tagName, isSVG) {
1432
1925
  const setTemplateRefIdent = `_setTemplateRef`;
1433
1926
  function genSetTemplateRef(oper, context) {
1434
1927
  const [refValue, refKey] = genRefValue(oper.value, context);
1928
+ if (context.staticTemplateRefHelperCandidate === oper) return genSetStaticTemplateRef(oper, refValue, refKey, context);
1929
+ context.needsTemplateRefSetter = true;
1435
1930
  return [NEWLINE, ...genCall(setTemplateRefIdent, `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
1436
1931
  }
1932
+ function genSetStaticTemplateRef(oper, refValue, refKey, context) {
1933
+ return [NEWLINE, ...genCall(context.helper("setStaticTemplateRef"), `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
1934
+ }
1935
+ function genSetTemplateRefBinding(oper, context) {
1936
+ const [refValue, refKey] = genRefValue(oper.value, context);
1937
+ const setter = context.inSlotBlock && setTemplateRefIdent;
1938
+ if (context.inSlotBlock) context.needsTemplateRefSetter = true;
1939
+ return [NEWLINE, ...genCall([context.helper("setTemplateRefBinding"), "undefined"], `n${oper.element}`, ["() => ", ...refValue], ...setter || oper.refFor || refKey ? [
1940
+ setter,
1941
+ oper.refFor && "true",
1942
+ refKey
1943
+ ] : [])];
1944
+ }
1437
1945
  function genRefValue(value, context) {
1438
1946
  if (value && context.options.inline) {
1439
1947
  const binding = context.options.bindingMetadata[value.content];
@@ -1463,17 +1971,17 @@ function genGetTextChild(oper, context) {
1463
1971
  //#endregion
1464
1972
  //#region packages/compiler-vapor/src/generators/vShow.ts
1465
1973
  function genVShow(oper, context) {
1466
- const { deferred, element } = oper;
1467
- return [
1468
- NEWLINE,
1469
- deferred ? `deferredApplyVShows.push(() => ` : void 0,
1470
- ...genCall(context.helper("applyVShow"), `n${element}`, [
1471
- `() => (`,
1472
- ...genExpression(oper.dir.exp, context),
1473
- `)`
1474
- ]),
1475
- deferred ? `)` : void 0
1476
- ];
1974
+ const { element } = oper;
1975
+ return [NEWLINE, ...genCall(context.helper("applyVShow"), `n${element}`, [
1976
+ `() => (`,
1977
+ ...genExpression(oper.dir.exp, context),
1978
+ `)`
1979
+ ])];
1980
+ }
1981
+ //#endregion
1982
+ //#region packages/compiler-vapor/src/generators/modifier.ts
1983
+ function genDirectiveModifiers(modifiers) {
1984
+ return modifiers.map((value) => `${(0, _vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", ");
1477
1985
  }
1478
1986
  //#endregion
1479
1987
  //#region packages/compiler-vapor/src/generators/vModel.ts
@@ -1490,7 +1998,7 @@ function genVModel(oper, context) {
1490
1998
  `() => (`,
1491
1999
  ...genExpression(exp, context),
1492
2000
  `)`
1493
- ], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : void 0)];
2001
+ ], genModelHandler(exp, context), modifiers.length ? `{ ${genDirectiveModifiers(modifiers.map((e) => e.content))} }` : void 0)];
1494
2002
  }
1495
2003
  function genModelHandler(exp, context) {
1496
2004
  return [
@@ -1532,25 +2040,31 @@ function genCustomDirectives(opers, context) {
1532
2040
  return genMulti(DELIMITERS_ARRAY.concat("void 0"), directiveVar, value, argument, modifiers);
1533
2041
  }
1534
2042
  }
1535
- function genDirectiveModifiers(modifiers) {
1536
- return modifiers.map((value) => `${(0, _vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", ");
1537
- }
1538
2043
  function filterCustomDirectives(id, operations) {
1539
2044
  return operations.filter((oper) => oper.type === 14 && oper.element === id && !oper.builtin);
1540
2045
  }
1541
2046
  //#endregion
1542
2047
  //#region packages/compiler-vapor/src/generators/component.ts
2048
+ function genStaticModifierPropKey(name) {
2049
+ const key = (0, _vue_shared.getModifierPropName)(name);
2050
+ return [(0, _vue_compiler_dom.isSimpleIdentifier)(key) ? key : JSON.stringify(key)];
2051
+ }
1543
2052
  function genCreateComponent(operation, context) {
1544
2053
  const { helper } = context;
2054
+ const singleUseAssetComponentNames = context.singleUseAssetComponentNames;
2055
+ const useAssetComponentHelper = operation.asset && !operation.dynamic && context.block === context.ir.block && !!singleUseAssetComponentNames && singleUseAssetComponentNames.has(operation.tag);
2056
+ const maybeSelfReference = useAssetComponentHelper && operation.tag.endsWith("__self");
1545
2057
  const tag = genTag();
1546
- const { root, props, slots, once } = operation;
2058
+ const { root, props, slots, once, slotRoot } = operation;
2059
+ const isRuntimeDynamicComponent = !!(operation.dynamic && !operation.dynamic.isStatic);
2060
+ const dynamicComponentFlags = isRuntimeDynamicComponent ? genDynamicComponentFlags(root, once, slotRoot) : false;
1547
2061
  const rawSlots = genRawSlots(slots, context);
1548
2062
  const [ids, handlers] = processInlineHandlers(props, context);
1549
- const rawProps = context.withId(() => genRawProps(props, context), ids);
2063
+ const rawProps = context.withId(() => genRawProps(props, context, true), ids);
1550
2064
  return [
1551
2065
  NEWLINE,
1552
2066
  ...handlers.reduce((acc, { name, value }) => {
1553
- const handler = genEventHandler(context, [value], void 0, false, false);
2067
+ const handler = genEventHandler(context, [value]);
1554
2068
  return [
1555
2069
  ...acc,
1556
2070
  `const ${name} = `,
@@ -1559,18 +2073,21 @@ function genCreateComponent(operation, context) {
1559
2073
  ];
1560
2074
  }, []),
1561
2075
  `const n${operation.id} = `,
1562
- ...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.isCustomElement ? helper("createPlainElement") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
2076
+ ...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags : root ? "true" : false, isRuntimeDynamicComponent ? false : once && "true", isRuntimeDynamicComponent ? false : maybeSelfReference && "true"),
1563
2077
  ...genDirectivesForElement(operation.id, context)
1564
2078
  ];
1565
2079
  function genTag() {
1566
- if (operation.isCustomElement) return JSON.stringify(operation.tag);
2080
+ if (operation.useCreateElement) return JSON.stringify(operation.tag);
1567
2081
  else if (operation.dynamic) if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context));
1568
2082
  else return [
1569
2083
  "() => (",
1570
2084
  ...genExpression(operation.dynamic, context),
1571
2085
  ")"
1572
2086
  ];
1573
- else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
2087
+ else if (useAssetComponentHelper) {
2088
+ const name = maybeSelfReference ? operation.tag.slice(0, -6) : operation.tag;
2089
+ return JSON.stringify(name);
2090
+ } else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
1574
2091
  else {
1575
2092
  const { tag } = operation;
1576
2093
  const builtInTag = isBuiltInComponent(tag);
@@ -1582,6 +2099,24 @@ function genCreateComponent(operation, context) {
1582
2099
  }
1583
2100
  }
1584
2101
  }
2102
+ function genDynamicComponentFlags(root, once, slotRoot) {
2103
+ let flags = 0;
2104
+ const names = [];
2105
+ if (root) {
2106
+ flags |= 1;
2107
+ names.push("SINGLE_ROOT");
2108
+ }
2109
+ if (once) {
2110
+ flags |= 2;
2111
+ names.push("ONCE");
2112
+ }
2113
+ if (slotRoot) {
2114
+ flags |= 4;
2115
+ names.push("SLOT_ROOT");
2116
+ }
2117
+ if (!flags) return false;
2118
+ return `${flags} /* ${names.join(", ")} */`;
2119
+ }
1585
2120
  function getUniqueHandlerName(context, name) {
1586
2121
  const { seenInlineHandlerNames } = context;
1587
2122
  name = genVarName(name);
@@ -1610,14 +2145,14 @@ function processInlineHandlers(props, context) {
1610
2145
  }
1611
2146
  return [ids, handlers];
1612
2147
  }
1613
- function genRawProps(props, context) {
2148
+ function genRawProps(props, context, directStaticLiteralProps = false) {
1614
2149
  const staticProps = props[0];
1615
2150
  if ((0, _vue_shared.isArray)(staticProps)) {
1616
2151
  if (!staticProps.length && props.length === 1) return;
1617
- return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context));
1618
- } else if (props.length) return genStaticProps([], context, genDynamicProps(props, context));
2152
+ return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context, directStaticLiteralProps), directStaticLiteralProps);
2153
+ } else if (props.length) return genStaticProps([], context, genDynamicProps(props, context, directStaticLiteralProps), directStaticLiteralProps);
1619
2154
  }
1620
- function genStaticProps(props, context, dynamicProps) {
2155
+ function genStaticProps(props, context, dynamicProps, directStaticLiteralProps = false) {
1621
2156
  const args = [];
1622
2157
  const handlerGroups = /* @__PURE__ */ new Map();
1623
2158
  const ensureHandlerGroup = (keyName, keyFrag) => {
@@ -1650,11 +2185,11 @@ function genStaticProps(props, context, dynamicProps) {
1650
2185
  continue;
1651
2186
  }
1652
2187
  const keyFrag = genPropKey(prop, context);
1653
- 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, false));
1654
- else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, true, false));
2188
+ 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 }));
2189
+ else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, { asComponentProp: true }));
1655
2190
  continue;
1656
2191
  }
1657
- args.push(genProp(prop, context, true));
2192
+ args.push(genProp(prop, context, true, true, directStaticLiteralProps && isDirectStaticLiteralProp(prop, context)));
1658
2193
  if (prop.model) {
1659
2194
  if (prop.key.isStatic) {
1660
2195
  const keyName = `onUpdate:${(0, _vue_shared.camelize)(prop.key.content)}`;
@@ -1673,13 +2208,13 @@ function genStaticProps(props, context, dynamicProps) {
1673
2208
  }
1674
2209
  const { key, modelModifiers } = prop;
1675
2210
  if (modelModifiers && modelModifiers.length) {
1676
- const modifiersKey = key.isStatic ? [(0, _vue_shared.getModifierPropName)(key.content)] : [
2211
+ const modifiersKey = key.isStatic ? genStaticModifierPropKey(key.content) : [
1677
2212
  "[",
1678
2213
  ...genExpression(key, context),
1679
2214
  " + \"Modifiers\"]"
1680
2215
  ];
1681
2216
  const modifiersVal = genDirectiveModifiers(modelModifiers);
1682
- args.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
2217
+ args.push([...modifiersKey, directStaticLiteralProps ? `: { ${modifiersVal} }` : `: () => ({ ${modifiersVal} })`]);
1683
2218
  }
1684
2219
  }
1685
2220
  }
@@ -1694,13 +2229,13 @@ function genStaticProps(props, context, dynamicProps) {
1694
2229
  if (dynamicProps) args.push([`$: `, ...dynamicProps]);
1695
2230
  return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args);
1696
2231
  }
1697
- function genDynamicProps(props, context) {
2232
+ function genDynamicProps(props, context, directStaticLiteralProps = false) {
1698
2233
  const { helper } = context;
1699
2234
  const frags = [];
1700
2235
  for (const p of props) {
1701
2236
  let expr;
1702
2237
  if ((0, _vue_shared.isArray)(p)) {
1703
- if (p.length) frags.push(genStaticProps(p, context));
2238
+ if (p.length) frags.push(genStaticProps(p, context, void 0, directStaticLiteralProps));
1704
2239
  continue;
1705
2240
  } else if (p.kind === 1) if (p.model) {
1706
2241
  const entries = [genProp(p, context)];
@@ -1711,21 +2246,21 @@ function genDynamicProps(props, context) {
1711
2246
  ];
1712
2247
  entries.push([
1713
2248
  ...updateKey,
1714
- ": () => ",
2249
+ ": ",
1715
2250
  ...genModelHandler(p.values[0], context)
1716
2251
  ]);
1717
2252
  const { modelModifiers } = p;
1718
2253
  if (modelModifiers && modelModifiers.length) {
1719
- const modifiersKey = p.key.isStatic ? [(0, _vue_shared.getModifierPropName)(p.key.content)] : [
2254
+ const modifiersKey = p.key.isStatic ? genStaticModifierPropKey(p.key.content) : [
1720
2255
  "[",
1721
2256
  ...genExpression(p.key, context),
1722
2257
  " + \"Modifiers\"]"
1723
2258
  ];
1724
2259
  const modifiersVal = genDirectiveModifiers(modelModifiers);
1725
- entries.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
2260
+ entries.push([...modifiersKey, `: { ${modifiersVal} }`]);
1726
2261
  }
1727
2262
  expr = genMulti(DELIMITERS_OBJECT_NEWLINE, ...entries);
1728
- } else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context));
2263
+ } else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context, false, false));
1729
2264
  else {
1730
2265
  expr = genExpression(p.value, context);
1731
2266
  if (p.handler) expr = genCall(helper("toHandlers"), expr);
@@ -1738,27 +2273,79 @@ function genDynamicProps(props, context) {
1738
2273
  }
1739
2274
  if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags);
1740
2275
  }
1741
- function genProp(prop, context, isStatic) {
2276
+ function genProp(prop, context, isStatic, wrapHandler = true, directStaticLiteral = false) {
1742
2277
  const values = genPropValue(prop.values, context);
1743
2278
  return [
1744
2279
  ...genPropKey(prop, context),
1745
2280
  ": ",
1746
- ...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, true, true) : isStatic ? [
2281
+ ...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, {
2282
+ asComponentProp: true,
2283
+ extraWrap: wrapHandler
2284
+ }) : isStatic ? directStaticLiteral ? values : [
1747
2285
  "() => (",
1748
2286
  ...values,
1749
2287
  ")"
1750
2288
  ] : values
1751
2289
  ];
1752
2290
  }
2291
+ /**
2292
+ * Static literal values are safe to emit directly because reading them cannot
2293
+ * touch reactive state. Keep handlers, v-model values, and dynamic expressions
2294
+ * as getter sources to preserve lazy access and merge semantics.
2295
+ */
2296
+ function isDirectStaticLiteralProp(prop, context) {
2297
+ return prop.key.isStatic && prop.values.length === 1 && !prop.handler && !prop.model && isDirectConstantValue(prop.values[0], context);
2298
+ }
2299
+ function isDirectConstantValue(value, context) {
2300
+ value = context.getExpressionReplacement(value);
2301
+ if (value.isStatic) return true;
2302
+ const ast = value.ast;
2303
+ if (ast === null) return value.content === "true" || value.content === "false" || value.content === "null" || value.content === "undefined";
2304
+ if (!ast) return false;
2305
+ return isDirectConstantAst(ast);
2306
+ }
2307
+ function isDirectConstantAst(node) {
2308
+ switch (node.type) {
2309
+ case "StringLiteral":
2310
+ case "NumericLiteral":
2311
+ case "BooleanLiteral":
2312
+ case "NullLiteral":
2313
+ case "BigIntLiteral": return true;
2314
+ case "Identifier": return node.name === "undefined";
2315
+ case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
2316
+ case "ArrayExpression": return node.elements.every((element) => element === null || element.type !== "SpreadElement" && isDirectConstantAst(element));
2317
+ case "ObjectExpression": return node.properties.every((prop) => prop.type === "ObjectProperty" && !prop.computed && isDirectConstantAst(prop.value));
2318
+ }
2319
+ return false;
2320
+ }
2321
+ function isDirectTemplateConstantAst(node) {
2322
+ switch (node.type) {
2323
+ case "StringLiteral":
2324
+ case "NumericLiteral":
2325
+ case "BooleanLiteral":
2326
+ case "NullLiteral":
2327
+ case "BigIntLiteral": return true;
2328
+ case "Identifier": return node.name === "undefined";
2329
+ case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
2330
+ }
2331
+ return false;
2332
+ }
1753
2333
  function genRawSlots(slots, context) {
1754
2334
  if (!slots.length) return;
1755
2335
  const staticSlots = slots[0];
1756
- if (staticSlots.slotType === 0) return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
1757
- else return genStaticSlots({
2336
+ if (staticSlots.slotType === 0) {
2337
+ const defaultSlot = getSingleDefaultSlot(staticSlots);
2338
+ if (defaultSlot && slots.length === 1) return genSlotBlockWithProps(defaultSlot, context);
2339
+ return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
2340
+ } else return genStaticSlots({
1758
2341
  slotType: 0,
1759
2342
  slots: {}
1760
2343
  }, context, slots);
1761
2344
  }
2345
+ function getSingleDefaultSlot({ slots }) {
2346
+ const names = Object.keys(slots);
2347
+ return names.length === 1 && names[0] === "default" ? slots.default : void 0;
2348
+ }
1762
2349
  function genStaticSlots({ slots }, context, dynamicSlots) {
1763
2350
  const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]);
1764
2351
  if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]);
@@ -1780,15 +2367,16 @@ function genDynamicSlot(slot, context, withFunction = false) {
1780
2367
  frag = genConditionalSlot(slot, context);
1781
2368
  break;
1782
2369
  }
1783
- return withFunction ? [
2370
+ if (!withFunction) return frag;
2371
+ return [
1784
2372
  "() => (",
1785
2373
  ...frag,
1786
2374
  ")"
1787
- ] : frag;
2375
+ ];
1788
2376
  }
1789
2377
  function genBasicDynamicSlot(slot, context) {
1790
2378
  const { name, fn } = slot;
1791
- return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]);
2379
+ return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context, false)]);
1792
2380
  }
1793
2381
  function genLoopSlot(slot, context) {
1794
2382
  const { name, fn, loop } = slot;
@@ -1800,7 +2388,7 @@ function genLoopSlot(slot, context) {
1800
2388
  if (rawValue) idMap[rawValue] = rawValue;
1801
2389
  if (rawKey) idMap[rawKey] = rawKey;
1802
2390
  if (rawIndex) idMap[rawIndex] = rawIndex;
1803
- const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]);
2391
+ const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context, false), idMap)]);
1804
2392
  return [...genCall(context.helper("createForSlots"), genExpression(source, context), [
1805
2393
  ...genMulti([
1806
2394
  "(",
@@ -1826,11 +2414,11 @@ function genConditionalSlot(slot, context) {
1826
2414
  INDENT_END
1827
2415
  ];
1828
2416
  }
1829
- function genSlotBlockWithProps(oper, context) {
2417
+ function genSlotBlockWithProps(oper, context, emitNonStableFlag = true) {
1830
2418
  let propsName;
1831
2419
  let exitScope;
1832
2420
  let depth;
1833
- const { props, node } = oper;
2421
+ const { props } = oper;
1834
2422
  const idToPathMap = props ? parseValueDestructure(props, context) : /* @__PURE__ */ new Map();
1835
2423
  if (props) if (props.ast) {
1836
2424
  [depth, exitScope] = context.enterScope();
@@ -1838,79 +2426,86 @@ function genSlotBlockWithProps(oper, context) {
1838
2426
  } else propsName = props.content;
1839
2427
  const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {};
1840
2428
  if (propsName) idMap[propsName] = null;
2429
+ const exitSlotBlock = context.enterSlotBlock();
2430
+ const hasStableRoot = hasStableSlotRoot(oper, context);
2431
+ if (!hasStableRoot) markSlotRootOperations(oper);
1841
2432
  let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap);
2433
+ if (emitNonStableFlag && !hasStableRoot) blockFn = genCall(context.helper("extend"), blockFn, [`{ _: ${genSlotFlags$1(8)} }`]);
2434
+ exitSlotBlock();
1842
2435
  exitScope && exitScope();
1843
- if (node.type === 1) {
1844
- if (needsVaporCtx(oper)) blockFn = [
1845
- `${context.helper("withVaporCtx")}(`,
1846
- ...blockFn,
1847
- `)`
1848
- ];
1849
- }
1850
2436
  return blockFn;
1851
2437
  }
1852
- /**
1853
- * Check if a slot block needs withVaporCtx wrapper.
1854
- * Returns true if the block contains:
1855
- * - Component creation (needs scopeId inheritance)
1856
- * - Slot outlet (needs rawSlots from slot owner)
1857
- */
1858
- function needsVaporCtx(block) {
1859
- return hasComponentOrSlotInBlock(block);
1860
- }
1861
- function hasComponentOrSlotInBlock(block) {
1862
- if (hasComponentOrSlotInOperations(block.operation)) return true;
1863
- return hasComponentOrSlotInDynamic(block.dynamic);
1864
- }
1865
- function hasComponentOrSlotInDynamic(dynamic) {
1866
- if (dynamic.operation) {
1867
- const type = dynamic.operation.type;
1868
- if (type === 12 || type === 13) return true;
1869
- if (type === 15) {
1870
- if (hasComponentOrSlotInIf(dynamic.operation)) return true;
2438
+ function genSlotFlags$1(flags) {
2439
+ const names = [];
2440
+ if (flags & 1) names.push("NO_SLOTTED");
2441
+ if (flags & 2) names.push("ONCE");
2442
+ if (flags & 4) names.push("SLOT_ROOT");
2443
+ if (flags & 8) names.push("NON_STABLE");
2444
+ return `${flags} /* ${names.join(", ")} */`;
2445
+ }
2446
+ const commentOnlyTemplateRE = /^(?:<!--[\s\S]*?-->)+$/;
2447
+ function hasStableSlotRoot(block, context) {
2448
+ let hasValidRoot = false;
2449
+ for (let i = 0; i < block.returns.length; i++) {
2450
+ const id = block.returns[i];
2451
+ const child = findReturnedDynamic$1(block, id);
2452
+ const operation = child && child.operation;
2453
+ if (!operation) {
2454
+ if (child && isStableTemplateSlotRoot(child, context)) hasValidRoot = true;
2455
+ continue;
1871
2456
  }
1872
- if (type === 16) {
1873
- if (hasComponentOrSlotInBlock(dynamic.operation.render)) return true;
2457
+ switch (operation.type) {
2458
+ case 12:
2459
+ if (!operation.dynamic || operation.dynamic.isStatic) {
2460
+ hasValidRoot = true;
2461
+ continue;
2462
+ }
2463
+ continue;
2464
+ case 17:
2465
+ if (hasStableSlotRoot(operation.block, context)) {
2466
+ hasValidRoot = true;
2467
+ continue;
2468
+ }
2469
+ continue;
2470
+ default: continue;
1874
2471
  }
1875
2472
  }
1876
- for (const child of dynamic.children) if (hasComponentOrSlotInDynamic(child)) return true;
1877
- return false;
1878
- }
1879
- function hasComponentOrSlotInOperations(operations) {
1880
- for (const op of operations) switch (op.type) {
1881
- case 12:
1882
- case 13: return true;
1883
- case 15:
1884
- if (hasComponentOrSlotInIf(op)) return true;
1885
- break;
1886
- case 16:
1887
- if (hasComponentOrSlotInBlock(op.render)) return true;
1888
- break;
1889
- }
1890
- return false;
2473
+ return hasValidRoot;
1891
2474
  }
1892
- function hasComponentOrSlotInIf(node) {
1893
- if (hasComponentOrSlotInBlock(node.positive)) return true;
1894
- if (node.negative) if ("positive" in node.negative) return hasComponentOrSlotInIf(node.negative);
1895
- else return hasComponentOrSlotInBlock(node.negative);
1896
- return false;
2475
+ function isStableTemplateSlotRoot(child, context) {
2476
+ if (child.template == null) return false;
2477
+ const content = context.ir.template.entries[child.template].content;
2478
+ return content !== "" && !commentOnlyTemplateRE.test(content.trim());
1897
2479
  }
1898
2480
  //#endregion
1899
2481
  //#region packages/compiler-vapor/src/generators/slotOutlet.ts
1900
2482
  function genSlotOutlet(oper, context) {
1901
2483
  const { helper } = context;
1902
- const { id, name, fallback, noSlotted, once } = oper;
2484
+ const { id, name, fallback, flags } = oper;
1903
2485
  const [frag, push] = buildCodeFragment();
1904
- const nameExpr = name.isStatic ? genExpression(name, context) : [
2486
+ let fallbackArg;
2487
+ if (fallback) {
2488
+ if (context.inSlotBlock) markSlotRootOperations(fallback);
2489
+ fallbackArg = genBlock(fallback, context);
2490
+ }
2491
+ const createSlot = helper("createSlot");
2492
+ const rawPropsArg = genRawProps(oper.props, context, true);
2493
+ const nameArg = name.isStatic && name.content === "default" && !rawPropsArg && !fallbackArg && !flags ? void 0 : name.isStatic ? genExpression(name, context) : [
1905
2494
  "() => (",
1906
2495
  ...genExpression(name, context),
1907
2496
  ")"
1908
2497
  ];
1909
- let fallbackArg;
1910
- if (fallback) fallbackArg = genBlock(fallback, context);
1911
- push(NEWLINE, `const n${id} = `, ...genCall(helper("createSlot"), nameExpr, genRawProps(oper.props, context) || "null", fallbackArg, noSlotted && "true", once && "true"));
2498
+ push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, genSlotFlags(flags)));
1912
2499
  return frag;
1913
2500
  }
2501
+ function genSlotFlags(flags) {
2502
+ if (!flags) return;
2503
+ const names = [];
2504
+ if (flags & 1) names.push("NO_SLOTTED");
2505
+ if (flags & 2) names.push("ONCE");
2506
+ if (flags & 4) names.push("SLOT_ROOT");
2507
+ return `${flags} /* ${names.join(", ")} */`;
2508
+ }
1914
2509
  //#endregion
1915
2510
  //#region packages/compiler-vapor/src/generators/key.ts
1916
2511
  function genKey(oper, context) {
@@ -1968,28 +2563,35 @@ function genEffects(effects, context, genExtraFrag) {
1968
2563
  const [frag, push, unshift] = buildCodeFragment();
1969
2564
  const shouldDeclare = genExtraFrag === void 0;
1970
2565
  let operationsCount = 0;
1971
- const { ids, frag: declarationFrags, varNames } = processExpressions(context, expressions, shouldDeclare);
1972
- push(...declarationFrags);
1973
- for (let i = 0; i < effects.length; i++) {
1974
- const effect = effects[i];
1975
- operationsCount += effect.operations.length;
1976
- const frags = context.withId(() => genEffect(effect, context), ids);
1977
- i > 0 && push(NEWLINE);
1978
- if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
1979
- push(...frags);
1980
- }
1981
- if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
1982
- unshift(`{`, INDENT_START, NEWLINE);
1983
- push(INDENT_END, NEWLINE, "}");
1984
- if (!effects.length) unshift(NEWLINE);
1985
- }
1986
- if (effects.length) {
1987
- unshift(NEWLINE, `${helper("renderEffect")}(() => `);
1988
- push(`)`);
1989
- }
1990
- if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
1991
- if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
1992
- return frag;
2566
+ const { ids, frag: declarationFrags, varNames, expressionReplacements } = processExpressions(context, expressions, shouldDeclare);
2567
+ if (shouldDeclare && !declarationFrags.length && !varNames.length) {
2568
+ const effect = effects.length === 1 ? effects[0] : void 0;
2569
+ const operation = effect && effect.operations.length === 1 ? effect.operations[0] : void 0;
2570
+ if (operation && operation.type === 9 && operation.effect && !operation.refFor) return context.withExpressionReplacements(expressionReplacements, () => context.withId(() => genSetTemplateRefBinding(operation, context), ids));
2571
+ }
2572
+ return context.withExpressionReplacements(expressionReplacements, () => {
2573
+ push(...declarationFrags);
2574
+ for (let i = 0; i < effects.length; i++) {
2575
+ const effect = effects[i];
2576
+ operationsCount += effect.operations.length;
2577
+ const frags = context.withId(() => genEffect(effect, context), ids);
2578
+ i > 0 && push(NEWLINE);
2579
+ if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
2580
+ push(...frags);
2581
+ }
2582
+ if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
2583
+ unshift(`{`, INDENT_START, NEWLINE);
2584
+ push(INDENT_END, NEWLINE, "}");
2585
+ if (!effects.length) unshift(NEWLINE);
2586
+ }
2587
+ if (effects.length) {
2588
+ unshift(NEWLINE, `${helper("renderEffect")}(() => `);
2589
+ push(`)`);
2590
+ }
2591
+ if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
2592
+ if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
2593
+ return frag;
2594
+ });
1993
2595
  }
1994
2596
  function genEffect({ operations }, context) {
1995
2597
  const [frag, push] = buildCodeFragment();
@@ -1999,21 +2601,24 @@ function genEffect({ operations }, context) {
1999
2601
  return frag;
2000
2602
  }
2001
2603
  function genInsertionState(operation, context) {
2002
- const { parent, anchor, logicalIndex, append, last } = operation;
2003
- return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${parent}`, anchor == null ? void 0 : anchor === -1 ? `0` : append ? "null" : `n${anchor}`, logicalIndex !== void 0 ? String(logicalIndex) : void 0, last && "true")];
2604
+ const { parent, anchor, logicalIndex, append } = operation;
2605
+ const isPrepend = anchor === -1;
2606
+ return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${parent}`, anchor == null ? void 0 : isPrepend ? `0` : append ? "null" : `n${anchor}`, logicalIndex !== void 0 && (!isPrepend || logicalIndex !== 0) ? String(logicalIndex) : void 0)];
2004
2607
  }
2005
2608
  //#endregion
2006
2609
  //#region packages/compiler-vapor/src/generators/template.ts
2007
- function genTemplates(templates, rootIndexes, context) {
2610
+ function genTemplates(templates, context) {
2008
2611
  const result = [];
2009
- let i = 0;
2010
- templates.forEach((ns, template) => {
2011
- result.push(`const ${context.tName(i)} = ${context.helper("template")}(${JSON.stringify(template).replace(IMPORT_EXPR_RE, `" + $1 + "`)}${rootIndexes.has(i) ? ", true" : ns ? ", false" : ""}${ns ? `, ${ns}` : ""})\n`);
2012
- i++;
2612
+ templates.forEach(({ content, ns, root, static: isStatic }, i) => {
2613
+ let args = JSON.stringify(content).replace(IMPORT_EXPR_RE, `" + $1 + "`);
2614
+ const flags = (root ? 1 : 0) | (isStatic ? 2 : 0);
2615
+ if (flags || ns) args += `, ${flags}`;
2616
+ if (ns) args += `, ${ns}`;
2617
+ result.push(`const ${context.tName(i)} = ${context.helper("template")}(${args})\n`);
2013
2618
  });
2014
2619
  return result.join("");
2015
2620
  }
2016
- function genSelf(dynamic, context) {
2621
+ function genSelf(dynamic, context, flushBeforeDynamic) {
2017
2622
  const [frag, push] = buildCodeFragment();
2018
2623
  const { id, template, operation, hasDynamicChild } = dynamic;
2019
2624
  if (id !== void 0 && template !== void 0) {
@@ -2021,46 +2626,145 @@ function genSelf(dynamic, context) {
2021
2626
  push(...genDirectivesForElement(id, context));
2022
2627
  }
2023
2628
  if (operation) push(...genOperationWithInsertionState(operation, context));
2024
- if (hasDynamicChild) push(...genChildren(dynamic, context, push, `n${id}`));
2629
+ if (hasDynamicChild) push(...genChildren(dynamic, context, push, `n${id}`, flushBeforeDynamic));
2025
2630
  return frag;
2026
2631
  }
2027
- function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2028
- const { helper } = context;
2632
+ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flushBeforeDynamic) {
2029
2633
  const [frag, push] = buildCodeFragment();
2030
2634
  const { children } = dynamic;
2031
2635
  let offset = 0;
2636
+ /**
2637
+ * `reusable` means the previous access target is a p* cursor that can be
2638
+ * reassigned by the next lookup. Referenced n* variables must stay stable.
2639
+ */
2032
2640
  let prev;
2033
2641
  for (const [index, child] of children.entries()) {
2034
2642
  if (child.flags & 2) offset--;
2035
2643
  if (child.flags & 4 && child.template != null) {
2036
- push(...genSelf(child, context));
2644
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2645
+ push(...genSelf(child, context, flushBeforeDynamic));
2037
2646
  continue;
2038
2647
  }
2039
2648
  const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2040
2649
  if (id === void 0 && !child.hasDynamicChild) {
2041
- push(...genSelf(child, context));
2650
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2651
+ push(...genSelf(child, context, flushBeforeDynamic));
2042
2652
  continue;
2043
2653
  }
2044
2654
  const elementIndex = index + offset;
2045
2655
  const logicalIndex = child.logicalIndex !== void 0 ? String(child.logicalIndex) : void 0;
2046
- const variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
2047
- pushBlock(NEWLINE, `const ${variable} = `);
2048
- if (prev) if (elementIndex - prev[1] === 1) pushBlock(...genCall(helper("next"), prev[0], logicalIndex));
2049
- else pushBlock(...genCall(helper("nthChild"), from, String(elementIndex), logicalIndex));
2050
- else if (elementIndex === 0) pushBlock(...genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0));
2051
- else {
2052
- let init = genCall(helper("child"), from);
2053
- if (elementIndex === 1) init = genCall(helper("next"), init, logicalIndex);
2054
- else if (elementIndex > 1) init = genCall(helper("nthChild"), from, String(elementIndex), logicalIndex);
2055
- pushBlock(...init);
2656
+ const inlinePlaceholder = id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6);
2657
+ const accessPath = genAccessPath(context, from, child, elementIndex, logicalIndex, prev);
2658
+ if (inlinePlaceholder) {
2659
+ if (prev && prev[2]) {
2660
+ push(...genChildren(child, context, pushBlock, [
2661
+ "(",
2662
+ prev[0],
2663
+ " = ",
2664
+ ...accessPath,
2665
+ ")"
2666
+ ], flushBeforeDynamic));
2667
+ prev = [
2668
+ prev[0],
2669
+ elementIndex,
2670
+ true
2671
+ ];
2672
+ continue;
2673
+ }
2674
+ if (!hasAdjacentFollowingAccessChild(children, index, elementIndex, offset)) {
2675
+ push(...genChildren(child, context, pushBlock, accessPath, flushBeforeDynamic));
2676
+ continue;
2677
+ }
2678
+ }
2679
+ let variable;
2680
+ if (id === void 0 && prev && prev[2]) {
2681
+ variable = prev[0];
2682
+ pushBlock(NEWLINE, `${variable} = `, ...accessPath);
2683
+ } else {
2684
+ variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
2685
+ pushBlock(NEWLINE, id === void 0 ? `let ${variable} = ` : `const ${variable} = `, ...accessPath);
2686
+ }
2687
+ if (id === child.anchor && !child.hasDynamicChild) {
2688
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2689
+ push(...genSelf(child, context, flushBeforeDynamic));
2056
2690
  }
2057
- if (id === child.anchor && !child.hasDynamicChild) push(...genSelf(child, context));
2058
2691
  if (id !== void 0) push(...genDirectivesForElement(id, context));
2059
- prev = [variable, elementIndex];
2060
- push(...genChildren(child, context, pushBlock, variable));
2692
+ prev = [
2693
+ variable,
2694
+ elementIndex,
2695
+ id === void 0
2696
+ ];
2697
+ push(...genChildren(child, context, pushBlock, variable, flushBeforeDynamic));
2061
2698
  }
2062
2699
  return frag;
2063
2700
  }
2701
+ /**
2702
+ * Build one DOM lookup path while preserving the fast sibling walk:
2703
+ * adjacent nodes use _next(prev), otherwise fall back to _nthChild(parent).
2704
+ */
2705
+ function genAccessPath({ helper }, from, child, elementIndex, logicalIndex, prev) {
2706
+ if (prev) return elementIndex - prev[1] === 1 ? genCall(helper("next"), prev[0], logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
2707
+ if (elementIndex === 0) return genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0);
2708
+ const firstChild = genCall(helper("child"), from);
2709
+ return elementIndex === 1 ? genCall(helper("next"), firstChild, logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
2710
+ }
2711
+ /**
2712
+ * Only inline a placeholder when materializing it would not save a parent
2713
+ * lookup. If its child tree needs the parent more than once, keep p* so the
2714
+ * generated code does not duplicate _child/_nthChild work.
2715
+ */
2716
+ function canInlinePlaceholder(dynamic) {
2717
+ return dynamic.hasDynamicChild === true && countParentAccessUsages(dynamic) === 1;
2718
+ }
2719
+ /**
2720
+ * A following access can reuse the current placeholder cursor only when it is
2721
+ * the next DOM sibling. Gapped siblings need _nthChild(parent, index) instead.
2722
+ */
2723
+ function hasAdjacentFollowingAccessChild(children, index, elementIndex, offset) {
2724
+ let futureOffset = offset;
2725
+ for (let i = index + 1; i < children.length; i++) {
2726
+ const child = children[i];
2727
+ if (child.flags & 2) futureOffset--;
2728
+ if (!(child.flags & 4 && child.template != null) && (!!(child.flags & 1) || child.hasDynamicChild)) return i + futureOffset - elementIndex === 1;
2729
+ }
2730
+ return false;
2731
+ }
2732
+ /**
2733
+ * Mirrors genChildren's traversal closely enough to count how many emitted
2734
+ * access paths would start from this placeholder's parent. This is the guard
2735
+ * that keeps inline placeholders from duplicating parent lookups.
2736
+ */
2737
+ function countParentAccessUsages(dynamic) {
2738
+ let usages = 0;
2739
+ let offset = 0;
2740
+ let prev;
2741
+ for (const [index, child] of dynamic.children.entries()) {
2742
+ if (child.flags & 2) offset--;
2743
+ if (child.flags & 4 && child.template != null) continue;
2744
+ const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2745
+ if (id === void 0 && !child.hasDynamicChild) continue;
2746
+ const elementIndex = index + offset;
2747
+ const usesParent = !prev || elementIndex - prev[0] !== 1;
2748
+ if (id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6)) {
2749
+ if (prev && prev[1]) {
2750
+ if (usesParent) usages++;
2751
+ prev = [elementIndex, true];
2752
+ continue;
2753
+ }
2754
+ if (!hasAdjacentFollowingAccessChild(dynamic.children, index, elementIndex, offset)) {
2755
+ if (usesParent) usages++;
2756
+ continue;
2757
+ }
2758
+ }
2759
+ if (usesParent) usages++;
2760
+ prev = [elementIndex, id === void 0];
2761
+ }
2762
+ return usages;
2763
+ }
2764
+ function genNthChild(nthChild, from, elementIndex, logicalIndex) {
2765
+ const index = String(elementIndex);
2766
+ return genCall(nthChild, from, index, logicalIndex === index ? void 0 : logicalIndex);
2767
+ }
2064
2768
  //#endregion
2065
2769
  //#region packages/compiler-vapor/src/generators/block.ts
2066
2770
  function genBlock(oper, context, args = [], root) {
@@ -2075,12 +2779,16 @@ function genBlock(oper, context, args = [], root) {
2075
2779
  "}"
2076
2780
  ];
2077
2781
  }
2078
- function genBlockContent(block, context, root, genEffectsExtraFrag) {
2782
+ function genBlockContent(block, context, root, genEffectsExtraFrag, skippedEffectIndexes) {
2079
2783
  const [frag, push] = buildCodeFragment();
2080
2784
  const { dynamic, effect, operation, returns } = block;
2081
2785
  const resetBlock = context.enterBlock(block);
2786
+ const singleUseAssetComponentNames = root ? collectSingleUseAssetComponents(block) : void 0;
2787
+ const prevSingleUseAssetComponentNames = context.singleUseAssetComponentNames;
2788
+ if (singleUseAssetComponentNames) context.singleUseAssetComponentNames = singleUseAssetComponentNames;
2082
2789
  if (root) {
2083
2790
  for (let name of context.ir.component) {
2791
+ if (singleUseAssetComponentNames && singleUseAssetComponentNames.has(name)) continue;
2084
2792
  const id = (0, _vue_compiler_dom.toValidAssetId)(name, "component");
2085
2793
  const maybeSelfReference = name.endsWith("__self");
2086
2794
  if (maybeSelfReference) name = name.slice(0, -6);
@@ -2088,24 +2796,167 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2088
2796
  }
2089
2797
  genResolveAssets("directive", "resolveDirective");
2090
2798
  }
2091
- for (const child of dynamic.children) push(...genSelf(child, context));
2092
- for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`));
2093
- push(...genOperations(operation, context));
2094
- push(...genEffects(effect, context, genEffectsExtraFrag));
2095
- if (root && context.ir.hasDeferredVShow) push(NEWLINE, `deferredApplyVShows.forEach(fn => fn())`);
2799
+ let operationIndex = 0;
2800
+ let effectIndex = 0;
2801
+ const flushPendingOperations = (operationEnd, effectEnd, push) => {
2802
+ while (operationIndex < operationEnd) {
2803
+ push(...genOperationWithInsertionState(operation[operationIndex], context));
2804
+ operationIndex++;
2805
+ }
2806
+ if (effectIndex < effectEnd) {
2807
+ push(...genEffectRange(effectIndex, effectEnd));
2808
+ effectIndex = effectEnd;
2809
+ }
2810
+ };
2811
+ const flushBeforeDynamic = (dynamic, push) => {
2812
+ const operation = dynamic.operation;
2813
+ if (operation && isBlockOperation(operation) && operation.operationIndex !== void 0 && operation.effectIndex !== void 0) flushPendingOperations(operation.operationIndex, operation.effectIndex, push);
2814
+ };
2815
+ for (const child of dynamic.children) {
2816
+ flushBeforeDynamic(child, push);
2817
+ push(...genSelf(child, context, flushBeforeDynamic));
2818
+ }
2819
+ for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`, flushBeforeDynamic));
2820
+ if (operationIndex < operation.length) push(...genOperations(operation.slice(operationIndex), context));
2821
+ if (effectIndex < effect.length) push(...genEffectRange(effectIndex, effect.length, genEffectsExtraFrag));
2822
+ else if (genEffectsExtraFrag) push(...genEffects([], context, genEffectsExtraFrag));
2096
2823
  push(NEWLINE, `return `);
2097
2824
  const returnNodes = returns.map((n) => `n${n}`);
2098
- push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"]);
2825
+ push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "[]"]);
2099
2826
  resetBlock();
2827
+ context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames;
2100
2828
  return frag;
2829
+ function genEffectRange(start, end, genExtraFrag) {
2830
+ if (!skippedEffectIndexes) return genEffects(effect.slice(start, end), context, genExtraFrag);
2831
+ const effects = [];
2832
+ for (let i = start; i < end; i++) if (!skippedEffectIndexes.has(i)) effects.push(effect[i]);
2833
+ if (effects.length || genExtraFrag) return genEffects(effects, context, genExtraFrag);
2834
+ return [];
2835
+ }
2101
2836
  function genResolveAssets(kind, helper) {
2102
2837
  for (const name of context.ir[kind]) push(NEWLINE, `const ${(0, _vue_compiler_dom.toValidAssetId)(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
2103
2838
  }
2104
2839
  }
2840
+ function markSlotRootOperations(block) {
2841
+ for (let i = 0; i < block.returns.length; i++) {
2842
+ const child = findReturnedDynamic$1(block, block.returns[i]);
2843
+ const operation = child && child.operation;
2844
+ if (!operation) continue;
2845
+ if (operation.type === 15) markSlotRootIf(operation);
2846
+ else if (operation.type === 16) markSlotRootFor(operation);
2847
+ else if (operation.type === 12) markSlotRootComponent(operation);
2848
+ }
2849
+ }
2850
+ function markSlotRootIf(operation) {
2851
+ if (!operation.once) operation.slotRoot = true;
2852
+ markSlotRootOperations(operation.positive);
2853
+ const negative = operation.negative;
2854
+ if (!negative) return;
2855
+ if (negative.type === 15) markSlotRootIf(negative);
2856
+ else markSlotRootOperations(negative);
2857
+ }
2858
+ function markSlotRootFor(operation) {
2859
+ if (!operation.once) operation.slotRoot = true;
2860
+ markSlotRootOperations(operation.render);
2861
+ }
2862
+ function markSlotRootComponent(operation) {
2863
+ if (!operation.once && operation.dynamic && !operation.dynamic.isStatic) operation.slotRoot = true;
2864
+ }
2865
+ function findReturnedDynamic$1(block, id) {
2866
+ for (let i = 0; i < block.dynamic.children.length; i++) {
2867
+ const child = block.dynamic.children[i];
2868
+ if (child.id === id) return child;
2869
+ }
2870
+ }
2871
+ function collectSingleUseAssetComponents(block) {
2872
+ const usageMap = /* @__PURE__ */ new Map();
2873
+ const seenOperations = /* @__PURE__ */ new Set();
2874
+ visitBlock(block, true);
2875
+ const names = /* @__PURE__ */ new Set();
2876
+ for (const [name, usage] of usageMap) if (usage.count === 1 && usage.root) names.add(name);
2877
+ return names;
2878
+ function visitBlock(block, rootCandidate) {
2879
+ visitDynamic(block.dynamic, rootCandidate);
2880
+ for (const operation of block.operation) visitOperation(operation, rootCandidate);
2881
+ for (const effect of block.effect) for (const operation of effect.operations) visitOperation(operation, false);
2882
+ }
2883
+ function visitDynamic(dynamic, rootCandidate) {
2884
+ if (dynamic.operation) visitOperation(dynamic.operation, rootCandidate);
2885
+ for (const child of dynamic.children) visitDynamic(child, rootCandidate);
2886
+ }
2887
+ function visitOperation(operation, rootCandidate) {
2888
+ if (seenOperations.has(operation)) return;
2889
+ seenOperations.add(operation);
2890
+ if (operation.type === 12) {
2891
+ if (operation.asset) {
2892
+ const usage = usageMap.get(operation.tag) || {
2893
+ count: 0,
2894
+ root: false
2895
+ };
2896
+ usage.count++;
2897
+ if (rootCandidate) usage.root = true;
2898
+ usageMap.set(operation.tag, usage);
2899
+ }
2900
+ visitSlots(operation.slots);
2901
+ return;
2902
+ }
2903
+ switch (operation.type) {
2904
+ case 15:
2905
+ visitBlock(operation.positive, false);
2906
+ if (operation.negative) if (operation.negative.type === 15) visitOperation(operation.negative, false);
2907
+ else visitBlock(operation.negative, false);
2908
+ break;
2909
+ case 16:
2910
+ visitBlock(operation.render, false);
2911
+ break;
2912
+ case 17:
2913
+ visitBlock(operation.block, false);
2914
+ break;
2915
+ case 13:
2916
+ if (operation.fallback) visitBlock(operation.fallback, false);
2917
+ break;
2918
+ }
2919
+ }
2920
+ function visitSlots(slots) {
2921
+ for (const slot of slots) switch (slot.slotType) {
2922
+ case 0:
2923
+ for (const name in slot.slots) visitBlock(slot.slots[name], false);
2924
+ break;
2925
+ case 1:
2926
+ case 2:
2927
+ visitBlock(slot.fn, false);
2928
+ break;
2929
+ case 3:
2930
+ visitSlots([slot.positive]);
2931
+ if (slot.negative) visitSlots([slot.negative]);
2932
+ break;
2933
+ }
2934
+ }
2935
+ }
2105
2936
  //#endregion
2106
2937
  //#region packages/compiler-vapor/src/generate.ts
2107
2938
  const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/;
2939
+ const helperNameAliases = {
2940
+ withVaporKeys: "withKeys",
2941
+ withVaporModifiers: "withModifiers"
2942
+ };
2108
2943
  var CodegenContext = class {
2944
+ withExpressionReplacements(map, fn) {
2945
+ if (map.size === 0) return fn();
2946
+ this.expressionReplacements.unshift(map);
2947
+ try {
2948
+ return fn();
2949
+ } finally {
2950
+ (0, _vue_shared.remove)(this.expressionReplacements, map);
2951
+ }
2952
+ }
2953
+ getExpressionReplacement(node) {
2954
+ for (const map of this.expressionReplacements) {
2955
+ const replacement = map.get(node);
2956
+ if (replacement) return replacement;
2957
+ }
2958
+ return node;
2959
+ }
2109
2960
  withId(fn, map) {
2110
2961
  const { identifiers } = this;
2111
2962
  const ids = Object.keys(map);
@@ -2122,9 +2973,19 @@ var CodegenContext = class {
2122
2973
  this.block = block;
2123
2974
  return () => this.block = parent;
2124
2975
  }
2976
+ enterSlotBlock() {
2977
+ const parent = this.inSlotBlock;
2978
+ this.inSlotBlock = true;
2979
+ return () => this.inSlotBlock = parent;
2980
+ }
2125
2981
  enterScope() {
2126
2982
  return [this.scopeLevel++, () => this.scopeLevel--];
2127
2983
  }
2984
+ isHelperNameAvailable(name) {
2985
+ if (this.bindingNames.has(name)) return false;
2986
+ for (const alias of this.helpers.values()) if (alias === name) return false;
2987
+ return true;
2988
+ }
2128
2989
  initNextIdMap() {
2129
2990
  if (this.bindingNames.size === 0) return;
2130
2991
  const map = /* @__PURE__ */ new Map();
@@ -2159,26 +3020,36 @@ var CodegenContext = class {
2159
3020
  this.ir = ir;
2160
3021
  this.bindingNames = /* @__PURE__ */ new Set();
2161
3022
  this.helpers = /* @__PURE__ */ new Map();
3023
+ this.needsTemplateRefSetter = false;
3024
+ this.inSlotBlock = false;
2162
3025
  this.helper = (name) => {
2163
3026
  if (this.helpers.has(name)) return this.helpers.get(name);
2164
- const base = `_${name}`;
2165
- if (this.bindingNames.size === 0 || !this.bindingNames.has(base)) {
3027
+ const base = `_${helperNameAliases[name] || name}`;
3028
+ if (this.isHelperNameAvailable(base)) {
2166
3029
  this.helpers.set(name, base);
2167
3030
  return base;
2168
3031
  }
2169
- const alias = `${base}${getNextId(this.nextIdMap.get(base), 1)}`;
2170
- this.helpers.set(name, alias);
2171
- return alias;
3032
+ const map = this.nextIdMap.get(base);
3033
+ let next = 1;
3034
+ while (true) {
3035
+ const alias = `${base}${getNextId(map, next)}`;
3036
+ if (this.isHelperNameAvailable(alias)) {
3037
+ this.helpers.set(name, alias);
3038
+ return alias;
3039
+ }
3040
+ next++;
3041
+ }
2172
3042
  };
2173
3043
  this.delegates = /* @__PURE__ */ new Set();
2174
3044
  this.identifiers = Object.create(null);
3045
+ this.expressionReplacements = [];
2175
3046
  this.seenInlineHandlerNames = Object.create(null);
2176
3047
  this.scopeLevel = 0;
2177
3048
  this.templateVars = /* @__PURE__ */ new Map();
2178
3049
  this.nextIdMap = /* @__PURE__ */ new Map();
2179
3050
  this.lastIdMap = /* @__PURE__ */ new Map();
2180
3051
  this.lastTIndex = -1;
2181
- this.options = (0, _vue_shared.extend)({
3052
+ const defaultOptions = {
2182
3053
  mode: "module",
2183
3054
  prefixIdentifiers: true,
2184
3055
  sourceMap: false,
@@ -2193,10 +3064,12 @@ var CodegenContext = class {
2193
3064
  inline: false,
2194
3065
  bindingMetadata: {},
2195
3066
  expressionPlugins: []
2196
- }, options);
3067
+ };
3068
+ this.options = (0, _vue_shared.extend)(defaultOptions, options);
2197
3069
  this.block = ir.block;
2198
3070
  this.bindingNames = new Set(this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []);
2199
3071
  this.initNextIdMap();
3072
+ this.staticTemplateRefHelperCandidate = getStaticTemplateRefHelperCandidate(ir.block);
2200
3073
  }
2201
3074
  };
2202
3075
  function generate(ir, options = {}) {
@@ -2209,13 +3082,15 @@ function generate(ir, options = {}) {
2209
3082
  const signature = (options.isTS ? args.map((arg) => `${arg}: any`) : args).join(", ");
2210
3083
  if (!inline) push(NEWLINE, `export function ${functionName}(${signature}) {`);
2211
3084
  push(INDENT_START);
2212
- if (ir.hasTemplateRef) push(NEWLINE, `const ${setTemplateRefIdent} = ${context.helper("createTemplateRefSetter")}()`);
2213
- if (ir.hasDeferredVShow) push(NEWLINE, `const deferredApplyVShows = []`);
2214
- push(...genBlockContent(ir.block, context, true));
3085
+ const templateRefSetterHelper = ir.hasTemplateRef ? context.helper("createTemplateRefSetter") : void 0;
3086
+ const body = genBlockContent(ir.block, context, true);
3087
+ if (context.needsTemplateRefSetter) push(NEWLINE, `const ${setTemplateRefIdent} = ${templateRefSetterHelper}()`);
3088
+ else if (templateRefSetterHelper) context.helpers.delete("createTemplateRefSetter");
3089
+ push(...body);
2215
3090
  push(INDENT_END, NEWLINE);
2216
3091
  if (!inline) push("}");
2217
3092
  const delegates = genDelegates(context);
2218
- const templates = genTemplates(ir.template, ir.rootTemplateIndexes, context);
3093
+ const templates = genTemplates(ir.template.entries, context);
2219
3094
  const preamble = genHelperImports(context) + genAssetImports(context) + templates + delegates;
2220
3095
  const newlineCount = [...preamble].filter((c) => c === "\n").length;
2221
3096
  if (newlineCount && !inline) frag.unshift(...new Array(newlineCount).fill(LF));
@@ -2246,89 +3121,21 @@ function genAssetImports({ ir }) {
2246
3121
  }
2247
3122
  return imports;
2248
3123
  }
3124
+ function getStaticTemplateRefHelperCandidate(block) {
3125
+ if (block.operation.length !== 1) return;
3126
+ const operation = block.operation[0];
3127
+ if (operation.type === 9 && !operation.effect && !operation.refFor && operation.value.isStatic) return operation;
3128
+ }
2249
3129
  //#endregion
2250
- //#region packages/compiler-vapor/src/transforms/transformChildren.ts
2251
- const transformChildren = (node, context) => {
2252
- const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
2253
- if (!isFragment && node.type !== 1) return;
2254
- for (const [i, child] of node.children.entries()) {
2255
- const childContext = context.create(child, i);
2256
- transformNode(childContext);
2257
- const childDynamic = childContext.dynamic;
2258
- if (isFragment) {
2259
- childContext.reference();
2260
- childContext.registerTemplate();
2261
- if (!(childDynamic.flags & 2) || childDynamic.flags & 4) context.block.returns.push(childContext.dynamic.id);
2262
- } else context.childrenTemplate.push(childContext.template);
2263
- if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) context.dynamic.hasDynamicChild = true;
2264
- context.dynamic.children[i] = childDynamic;
2265
- }
2266
- if (!isFragment) processDynamicChildren(context);
2267
- };
2268
- function processDynamicChildren(context) {
2269
- let prevDynamics = [];
2270
- let staticCount = 0;
2271
- let dynamicCount = 0;
2272
- let lastInsertionChild;
2273
- const children = context.dynamic.children;
2274
- let logicalIndex = 0;
2275
- for (const [index, child] of children.entries()) {
2276
- if (child.flags & 4) {
2277
- child.logicalIndex = logicalIndex;
2278
- prevDynamics.push(lastInsertionChild = child);
2279
- logicalIndex++;
2280
- }
2281
- if (!(child.flags & 2)) {
2282
- child.logicalIndex = logicalIndex;
2283
- if (prevDynamics.length) {
2284
- if (staticCount) {
2285
- context.childrenTemplate[index - prevDynamics.length] = `<!>`;
2286
- prevDynamics[0].flags -= 2;
2287
- const anchor = prevDynamics[0].anchor = context.increaseId();
2288
- registerInsertion(prevDynamics, context, anchor);
2289
- } else registerInsertion(prevDynamics, context, -1);
2290
- dynamicCount += prevDynamics.length;
2291
- prevDynamics = [];
2292
- }
2293
- staticCount++;
2294
- logicalIndex++;
2295
- }
3130
+ //#region packages/compiler-vapor/src/transforms/vBind.ts
3131
+ function normalizeBindShorthand(arg, context) {
3132
+ if (arg.type !== 4 || !arg.isStatic) {
3133
+ context.options.onError((0, _vue_compiler_dom.createCompilerError)(53, arg.loc));
3134
+ return (0, _vue_compiler_dom.createSimpleExpression)("", true, arg.loc);
2296
3135
  }
2297
- if (prevDynamics.length) registerInsertion(prevDynamics, context, dynamicCount + staticCount, true);
2298
- if (lastInsertionChild && lastInsertionChild.operation) lastInsertionChild.operation.last = true;
2299
- }
2300
- function registerInsertion(dynamics, context, anchor, append) {
2301
- for (const child of dynamics) {
2302
- const logicalIndex = child.logicalIndex;
2303
- if (child.template != null) context.registerOperation({
2304
- type: 10,
2305
- elements: dynamics.map((child) => child.id),
2306
- parent: context.reference(),
2307
- anchor: append ? void 0 : anchor
2308
- });
2309
- else if (child.operation && isBlockOperation(child.operation)) {
2310
- child.operation.parent = context.reference();
2311
- child.operation.anchor = anchor;
2312
- child.operation.logicalIndex = logicalIndex;
2313
- child.operation.append = append;
2314
- }
2315
- }
2316
- }
2317
- //#endregion
2318
- //#region packages/compiler-vapor/src/transforms/vOnce.ts
2319
- const transformVOnce = (node, context) => {
2320
- if (node.type === 1 && (0, _vue_compiler_dom.findDir)(node, "once", true)) context.inVOnce = true;
2321
- };
2322
- //#endregion
2323
- //#region packages/compiler-vapor/src/transforms/vBind.ts
2324
- function normalizeBindShorthand(arg, context) {
2325
- if (arg.type !== 4 || !arg.isStatic) {
2326
- context.options.onError((0, _vue_compiler_dom.createCompilerError)(53, arg.loc));
2327
- return (0, _vue_compiler_dom.createSimpleExpression)("", true, arg.loc);
2328
- }
2329
- const exp = (0, _vue_compiler_dom.createSimpleExpression)((0, _vue_shared.camelize)(arg.content), false, arg.loc);
2330
- exp.ast = null;
2331
- return exp;
3136
+ const exp = (0, _vue_compiler_dom.createSimpleExpression)((0, _vue_shared.camelize)(arg.content), false, arg.loc);
3137
+ exp.ast = null;
3138
+ return exp;
2332
3139
  }
2333
3140
  const transformVBind = (dir, node, context) => {
2334
3141
  const { loc, modifiers } = dir;
@@ -2356,11 +3163,36 @@ const transformVBind = (dir, node, context) => {
2356
3163
  };
2357
3164
  };
2358
3165
  //#endregion
3166
+ //#region packages/compiler-vapor/src/transforms/vHtml.ts
3167
+ function ignoreVHtmlChildren(node, context, clear) {
3168
+ if (!node.children.length) return;
3169
+ const dir = (0, _vue_compiler_dom.findDir)(node, "html");
3170
+ if (!dir) return;
3171
+ context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(55, dir.loc));
3172
+ if (clear === "node") node.children.length = 0;
3173
+ else context.childrenTemplate.length = 0;
3174
+ }
3175
+ const transformVHtml = (dir, node, context) => {
3176
+ let { exp, loc } = dir;
3177
+ if (!exp) {
3178
+ context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(54, loc));
3179
+ exp = EMPTY_EXPRESSION;
3180
+ }
3181
+ ignoreVHtmlChildren(node, context, "template");
3182
+ context.registerEffect([exp], {
3183
+ type: 8,
3184
+ element: context.reference(),
3185
+ value: exp,
3186
+ isComponent: node.tagType === 1
3187
+ });
3188
+ };
3189
+ //#endregion
2359
3190
  //#region packages/compiler-vapor/src/transforms/transformElement.ts
2360
3191
  const isReservedProp = /* @__PURE__ */ (0, _vue_shared.makeMap)(",key,ref,ref_for,ref_key,");
2361
3192
  const transformElement = (node, context) => {
2362
3193
  let effectIndex = context.block.effect.length;
2363
3194
  const getEffectIndex = () => effectIndex++;
3195
+ if (node.type === 1 && node.children.length) ignoreVHtmlChildren(node, context, "node");
2364
3196
  let parentSlots;
2365
3197
  if (node.type === 1 && (node.tagType === 1 || context.options.isCustomElement(node.tag))) {
2366
3198
  parentSlots = context.slots;
@@ -2369,13 +3201,13 @@ const transformElement = (node, context) => {
2369
3201
  return function postTransformElement() {
2370
3202
  ({node} = context);
2371
3203
  if (!(node.type === 1 && (node.tagType === 0 || node.tagType === 1))) return;
2372
- const isCustomElement = !!context.options.isCustomElement(node.tag);
2373
- const isComponent = node.tagType === 1 || isCustomElement;
3204
+ const useCreateElement = shouldUseCreateElement(node, context);
3205
+ const isComponent = node.tagType === 1 || useCreateElement;
2374
3206
  const isDynamicComponent = isComponentTag(node.tag);
2375
3207
  const staticKey = resolveStaticKey(node, context, isComponent);
2376
3208
  const propsResult = buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex);
2377
- const singleRoot = isSingleRoot(context);
2378
- if (isComponent) transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, isCustomElement);
3209
+ const singleRoot = context.isSingleRoot;
3210
+ if (isComponent) transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement);
2379
3211
  else transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, context.root === context.effectiveParent || canOmitEndTag(node, context));
2380
3212
  if (parentSlots) context.slots = parentSlots;
2381
3213
  };
@@ -2384,26 +3216,40 @@ function canOmitEndTag(node, context) {
2384
3216
  const { block, parent } = context;
2385
3217
  if (!parent) return false;
2386
3218
  if (block !== parent.block) return true;
3219
+ if (context.templateCloseTags && (context.templateCloseTags.has(node.tag) || (0, _vue_shared.isAlwaysCloseTag)(node.tag) || (0, _vue_shared.isFormattingTag)(node.tag)) || context.templateCloseBlocks && (0, _vue_shared.isBlockTag)(node.tag)) return false;
2387
3220
  if ((0, _vue_shared.isAlwaysCloseTag)(node.tag) && !context.isOnRightmostPath) return false;
2388
3221
  if ((0, _vue_shared.isFormattingTag)(node.tag) || parent.node.type === 1 && node.tag === parent.node.tag) return context.isOnRightmostPath;
2389
- if ((0, _vue_shared.isBlockTag)(node.tag) && context.hasInlineAncestorNeedingClose) return false;
2390
3222
  return context.isLastEffectiveChild;
2391
3223
  }
2392
- function isSingleRoot(context) {
2393
- if (context.inVFor) return false;
2394
- let { parent } = context;
2395
- if (parent && !((0, _vue_compiler_dom.hasSingleChild)(parent.node) || (0, _vue_compiler_dom.isSingleIfBlock)(parent.node))) return false;
2396
- while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2397
- parent = parent.parent;
2398
- if (!((0, _vue_compiler_dom.hasSingleChild)(parent.node) || (0, _vue_compiler_dom.isSingleIfBlock)(parent.node))) return false;
2399
- }
2400
- return context.root === parent;
3224
+ function getChildTemplateCloseState(context) {
3225
+ const { node } = context;
3226
+ if (node.type !== 1 || node.tagType !== 0 || shouldUseCreateElement(node, context)) return;
3227
+ const inSameTemplateAsParent = isInSameTemplateAsParent(context);
3228
+ const inheritedTags = inSameTemplateAsParent ? context.templateCloseTags : void 0;
3229
+ const inheritedBlocks = inSameTemplateAsParent && context.templateCloseBlocks;
3230
+ if (context.root === context.effectiveParent || canOmitEndTag(node, context) || (0, _vue_shared.isVoidTag)(node.tag)) return inheritedTags || inheritedBlocks ? {
3231
+ tags: inheritedTags,
3232
+ blocks: inheritedBlocks
3233
+ } : void 0;
3234
+ const tags = new Set(inheritedTags);
3235
+ tags.add(node.tag);
3236
+ return {
3237
+ tags,
3238
+ blocks: inheritedBlocks || (0, _vue_shared.isInlineTag)(node.tag)
3239
+ };
3240
+ }
3241
+ function isInSameTemplateAsParent(context) {
3242
+ const { parent, node, block } = context;
3243
+ if (!parent || block !== parent.block) return false;
3244
+ const parentNode = parent.node;
3245
+ if (parentNode.type !== 1 || parentNode.tagType !== 0) return false;
3246
+ return !shouldUseCreateElement(parentNode, parent) && (0, _vue_compiler_dom.isValidHTMLNesting)(parentNode.tag, node.tag);
2401
3247
  }
2402
- function transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, isCustomElement) {
3248
+ function transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement) {
2403
3249
  const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
2404
3250
  let { tag } = node;
2405
3251
  let asset = true;
2406
- if (!dynamicComponent && !isCustomElement) {
3252
+ if (!dynamicComponent && !useCreateElement) {
2407
3253
  const fromSetup = resolveSetupReference(tag, context);
2408
3254
  if (fromSetup) {
2409
3255
  tag = fromSetup;
@@ -2432,6 +3278,7 @@ function transformComponentElement(node, propsResult, staticKey, singleRoot, con
2432
3278
  context.dynamic.operation = {
2433
3279
  type: 12,
2434
3280
  id,
3281
+ ...context.effectBoundary(),
2435
3282
  tag,
2436
3283
  props: propsResult[0] ? propsResult[1] : [propsResult[1]],
2437
3284
  asset,
@@ -2439,7 +3286,7 @@ function transformComponentElement(node, propsResult, staticKey, singleRoot, con
2439
3286
  slots: [...context.slots],
2440
3287
  once: context.inVOnce,
2441
3288
  dynamic: dynamicComponent,
2442
- isCustomElement
3289
+ useCreateElement
2443
3290
  };
2444
3291
  if (staticKey) context.registerOperation(createSetBlockKey(id, staticKey));
2445
3292
  context.slots = [];
@@ -2459,13 +3306,13 @@ function resolveSetupReference(name, context) {
2459
3306
  }
2460
3307
  const dynamicKeys = ["indeterminate"];
2461
3308
  const NEEDS_QUOTES_RE = /[\s"'`=<>]/;
3309
+ const UNSAFE_ATTR_NAME_RE = /[\u0000-\u0020"'<=/>]/;
2462
3310
  function transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, omitEndTag) {
2463
3311
  const { tag } = node;
2464
3312
  const { scopeId } = context.options;
2465
3313
  let template = "";
2466
3314
  template += `<${tag}`;
2467
3315
  if (scopeId) template += ` ${scopeId}`;
2468
- const dynamicProps = [];
2469
3316
  if (propsResult[0]) {
2470
3317
  const [, dynamicArgs, expressions] = propsResult;
2471
3318
  context.registerEffect(expressions, {
@@ -2476,32 +3323,40 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
2476
3323
  }, getEffectIndex);
2477
3324
  } else {
2478
3325
  let prevWasQuoted = false;
3326
+ const appendTemplateProp = (key, value = "", generated = false) => {
3327
+ if (!prevWasQuoted) template += ` `;
3328
+ template += key;
3329
+ if (value) {
3330
+ const escapedValue = generated ? escapeGeneratedAttrValue(value) : value.replace(/"/g, "&quot;");
3331
+ template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${escapedValue}"` : `=${escapedValue}`;
3332
+ } else prevWasQuoted = false;
3333
+ };
2479
3334
  for (const prop of propsResult[1]) {
2480
3335
  const { key, values } = prop;
2481
- if (context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
3336
+ const canStringifyAttrName = key.isStatic && !UNSAFE_ATTR_NAME_RE.test(key.content);
3337
+ let foldedValue;
3338
+ if (canStringifyAttrName && context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
2482
3339
  if (!prevWasQuoted) template += ` `;
2483
3340
  template += `${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
2484
3341
  prevWasQuoted = true;
2485
- } else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
2486
- if (!prevWasQuoted) template += ` `;
3342
+ } else if (canStringifyAttrName && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
2487
3343
  const value = values[0].content === "''" ? "" : values[0].content;
2488
- template += key.content;
2489
- if (value) template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${value.replace(/"/g, "&quot;")}"` : `=${value}`;
2490
- else prevWasQuoted = false;
2491
- } else {
2492
- dynamicProps.push(key.content);
2493
- context.registerEffect(values, {
2494
- type: 3,
2495
- element: context.reference(),
2496
- prop,
2497
- tag
2498
- }, getEffectIndex);
2499
- }
3344
+ appendTemplateProp(key.content, value);
3345
+ } else if (canStringifyAttrName && !prop.modifier && (0, _vue_shared.isBooleanAttr)(key.content) && (foldedValue = foldBooleanAttrValue(values)) != null) {
3346
+ if (foldedValue) appendTemplateProp(key.content);
3347
+ } else if (canStringifyAttrName && !prop.modifier && hasBoundValue(values) && (foldedValue = key.content === "class" ? foldClassValues(values) : key.content === "style" ? foldStyleValues(values) : void 0) != null) {
3348
+ if (foldedValue) appendTemplateProp(key.content, foldedValue, true);
3349
+ } else context.registerEffect(values, {
3350
+ type: 3,
3351
+ element: context.reference(),
3352
+ prop,
3353
+ tag
3354
+ }, getEffectIndex);
2500
3355
  }
2501
3356
  }
2502
3357
  template += `>` + context.childrenTemplate.join("");
2503
3358
  if (!(0, _vue_shared.isVoidTag)(tag) && !omitEndTag) template += `</${tag}>`;
2504
- if (singleRoot) context.ir.rootTemplateIndexes.add(context.ir.template.size);
3359
+ context.templateRoot = singleRoot;
2505
3360
  if (context.parent && context.parent.node.type === 1 && !(0, _vue_compiler_dom.isValidHTMLNesting)(context.parent.node.tag, tag)) {
2506
3361
  context.reference();
2507
3362
  context.dynamic.template = context.pushTemplate(template);
@@ -2509,6 +3364,123 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
2509
3364
  } else context.template += template;
2510
3365
  if (staticKey) context.registerOperation(createSetBlockKey(context.reference(), staticKey));
2511
3366
  }
3367
+ function escapeGeneratedAttrValue(value) {
3368
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
3369
+ }
3370
+ function foldBooleanAttrValue(values) {
3371
+ if (values.length !== 1) return;
3372
+ const evaluated = evaluateConstantExpression(values[0]);
3373
+ if (!evaluated) return;
3374
+ const value = evaluated.value;
3375
+ if (value === true || value === false || value == null) return (0, _vue_shared.includeBooleanAttr)(value);
3376
+ }
3377
+ function foldStyleValues(values) {
3378
+ const evaluatedValues = [];
3379
+ for (const value of values) {
3380
+ const evaluated = evaluateConstantExpression(value);
3381
+ if (!evaluated || !isStaticStyleValue(evaluated.value)) return;
3382
+ evaluatedValues.push(evaluated.value);
3383
+ }
3384
+ return (0, _vue_shared.stringifyStyle)((0, _vue_shared.normalizeStyle)(evaluatedValues.length === 1 ? evaluatedValues[0] : evaluatedValues));
3385
+ }
3386
+ function isStaticStyleValue(value) {
3387
+ if (typeof value === "string") return true;
3388
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
3389
+ for (const key in value) {
3390
+ const propValue = value[key];
3391
+ if (!isSafeStylePropertyName(key) || !isSafeStylePropertyValue(propValue)) return false;
3392
+ }
3393
+ return true;
3394
+ }
3395
+ function isSafeStylePropertyName(key) {
3396
+ return !!key && !/[;:]/.test(key);
3397
+ }
3398
+ function isSafeStylePropertyValue(value) {
3399
+ return typeof value === "number" || typeof value === "string" && !value.includes(";");
3400
+ }
3401
+ function hasBoundValue(values) {
3402
+ return values.some((value) => !value.isStatic && value.content !== "''");
3403
+ }
3404
+ function foldClassValues(values) {
3405
+ let templateValue = "";
3406
+ let changed = false;
3407
+ for (const value of values) {
3408
+ const evaluated = evaluateConstantExpression(value);
3409
+ if (evaluated) {
3410
+ const normalized = (0, _vue_shared.normalizeClass)(evaluated.value);
3411
+ if (normalized) templateValue = appendClass(templateValue, normalized);
3412
+ else changed = true;
3413
+ continue;
3414
+ }
3415
+ return;
3416
+ }
3417
+ return changed || templateValue ? templateValue : void 0;
3418
+ }
3419
+ function appendClass(base, value) {
3420
+ return base ? value ? `${base} ${value}` : base : value;
3421
+ }
3422
+ function getObjectPropertyName(prop) {
3423
+ const key = prop.key;
3424
+ if (key.type === "Identifier") return key.name;
3425
+ else if (key.type === "StringLiteral") return key.value;
3426
+ else if (key.type === "NumericLiteral") return String(key.value);
3427
+ }
3428
+ function evaluateConstantExpression(node) {
3429
+ if (node.isStatic) return { value: node.content };
3430
+ const ast = node.ast;
3431
+ if (ast === null) {
3432
+ if (node.content === "true") return { value: true };
3433
+ else if (node.content === "false") return { value: false };
3434
+ else if (node.content === "null") return { value: null };
3435
+ else if (node.content === "undefined") return { value: void 0 };
3436
+ }
3437
+ if (!ast) return;
3438
+ return evaluateConstantAst(ast);
3439
+ }
3440
+ function evaluateConstantAst(node) {
3441
+ switch (node.type) {
3442
+ case "StringLiteral": return { value: node.value };
3443
+ case "NumericLiteral": return { value: node.value };
3444
+ case "BooleanLiteral": return { value: node.value };
3445
+ case "NullLiteral": return { value: null };
3446
+ case "Identifier": return node.name === "undefined" ? { value: void 0 } : void 0;
3447
+ case "UnaryExpression":
3448
+ if (node.operator === "void") return { value: void 0 };
3449
+ else if (node.operator === "-") {
3450
+ const value = evaluateConstantAst(node.argument);
3451
+ return value && typeof value.value === "number" ? { value: -value.value } : void 0;
3452
+ }
3453
+ return;
3454
+ case "TemplateLiteral": return evaluateTemplateLiteral(node);
3455
+ case "ObjectExpression": return evaluateObjectExpression(node);
3456
+ }
3457
+ }
3458
+ function evaluateTemplateLiteral(node) {
3459
+ if (node.type !== "TemplateLiteral") return;
3460
+ let value = "";
3461
+ for (const [index, quasi] of node.quasis.entries()) {
3462
+ value += quasi.value.cooked || "";
3463
+ const expression = node.expressions[index];
3464
+ if (expression) {
3465
+ const evaluated = evaluateConstantAst(expression);
3466
+ if (!evaluated) return;
3467
+ value += evaluated.value;
3468
+ }
3469
+ }
3470
+ return { value };
3471
+ }
3472
+ function evaluateObjectExpression(node) {
3473
+ const value = {};
3474
+ for (const prop of node.properties) {
3475
+ if (prop.type !== "ObjectProperty" || prop.computed) return;
3476
+ const key = getObjectPropertyName(prop);
3477
+ if (key == null) return;
3478
+ const evaluated = evaluateConstantAst(prop.value);
3479
+ if (!evaluated) return;
3480
+ value[key] = evaluated.value;
3481
+ }
3482
+ return { value };
3483
+ }
2512
3484
  function resolveStaticKey(node, context, isComponent) {
2513
3485
  const keyProp = findProp$1(node, "key", false, true);
2514
3486
  if (!keyProp) return;
@@ -2535,27 +3507,42 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
2535
3507
  results = [];
2536
3508
  }
2537
3509
  }
3510
+ function pushStaticObjectLiteralProps(props) {
3511
+ if (dynamicArgs.length) {
3512
+ pushMergeArg();
3513
+ dynamicArgs.push(props);
3514
+ } else results.push(...props.map(toDirectiveResult));
3515
+ }
2538
3516
  for (const prop of props) {
2539
3517
  if (prop.type === 7 && !prop.arg) {
2540
3518
  if (prop.name === "bind") {
2541
3519
  if (prop.exp) {
2542
- dynamicExpr.push(prop.exp);
2543
- pushMergeArg();
2544
- dynamicArgs.push({
2545
- kind: 0,
2546
- value: prop.exp
2547
- });
3520
+ const objectLiteralProps = isComponent ? resolveComponentObjectLiteralBindProps(prop.exp, context, props, prop) : resolveNativeObjectLiteralBindProps(prop.exp, context, props, prop);
3521
+ if (objectLiteralProps) if (isComponent) pushStaticObjectLiteralProps(objectLiteralProps);
3522
+ else results.push(...objectLiteralProps.map(toDirectiveResult));
3523
+ else {
3524
+ dynamicExpr.push(prop.exp);
3525
+ pushMergeArg();
3526
+ dynamicArgs.push({
3527
+ kind: 0,
3528
+ value: prop.exp
3529
+ });
3530
+ }
2548
3531
  } else context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, prop.loc));
2549
3532
  continue;
2550
3533
  } else if (prop.name === "on") {
2551
3534
  if (prop.exp) if (isComponent) {
2552
- dynamicExpr.push(prop.exp);
2553
- pushMergeArg();
2554
- dynamicArgs.push({
2555
- kind: 0,
2556
- value: prop.exp,
2557
- handler: true
2558
- });
3535
+ const objectLiteralProps = resolveComponentObjectLiteralOnProps(prop.exp, context, props, prop);
3536
+ if (objectLiteralProps) pushStaticObjectLiteralProps(objectLiteralProps);
3537
+ else {
3538
+ dynamicExpr.push(prop.exp);
3539
+ pushMergeArg();
3540
+ dynamicArgs.push({
3541
+ kind: 0,
3542
+ value: prop.exp,
3543
+ handler: true
3544
+ });
3545
+ }
2559
3546
  } else context.registerEffect([prop.exp], {
2560
3547
  type: 7,
2561
3548
  element: context.reference(),
@@ -2585,6 +3572,151 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
2585
3572
  }
2586
3573
  return [false, dedupeProperties(results)];
2587
3574
  }
3575
+ function resolveObjectLiteralProps(exp, context, keyTransform, isValidKey) {
3576
+ const ast = exp.ast;
3577
+ if (!ast || ast.type !== "ObjectExpression") return;
3578
+ const props = [];
3579
+ const knownKeys = /* @__PURE__ */ new Set();
3580
+ for (const property of ast.properties) {
3581
+ if (property.type !== "ObjectProperty" || property.computed) return;
3582
+ let key = getObjectPropertyName(property);
3583
+ if (key == null || key === "__proto__") return;
3584
+ if (isValidKey && !isValidKey(key)) return;
3585
+ if (keyTransform) key = keyTransform(key);
3586
+ if (knownKeys.has(key)) return;
3587
+ knownKeys.add(key);
3588
+ props.push({
3589
+ key: (0, _vue_compiler_dom.createSimpleExpression)(key, true),
3590
+ values: [resolveExpression(createObjectBindSubExpression(exp, property.value, context), true)]
3591
+ });
3592
+ }
3593
+ return props;
3594
+ }
3595
+ function resolveComponentObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
3596
+ const props = resolveObjectLiteralProps(exp, context, void 0, isSafeObjectLiteralBindKey);
3597
+ if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3598
+ return props;
3599
+ }
3600
+ function resolveNativeObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
3601
+ const props = resolveObjectLiteralProps(exp, context, void 0, isSafeNativeObjectLiteralBindKey);
3602
+ if (!props || hasNativeObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3603
+ return props;
3604
+ }
3605
+ function resolveComponentObjectLiteralOnProps(exp, context, nodeProps, currentProp) {
3606
+ const props = resolveObjectLiteralProps(exp, context, _vue_shared.toHandlerKey);
3607
+ if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3608
+ return props;
3609
+ }
3610
+ function isSafeNativeObjectLiteralBindKey(key) {
3611
+ return key !== "" && !UNSAFE_ATTR_NAME_RE.test(key) && isSafeObjectLiteralBindKey(key) && !(0, _vue_shared.isOn)(key) && key.charCodeAt(0) !== 46 && key.charCodeAt(0) !== 94;
3612
+ }
3613
+ function isSafeObjectLiteralBindKey(key) {
3614
+ return !isReservedProp(key);
3615
+ }
3616
+ function hasComponentObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
3617
+ const keys = createComponentConflictKeySet(objectLiteralProps.map((prop) => prop.key.content));
3618
+ for (const prop of props) {
3619
+ if (prop === currentProp) continue;
3620
+ let key;
3621
+ if (prop.type === 6) key = prop.name;
3622
+ else if (prop.name === "bind") {
3623
+ if (!prop.arg) {
3624
+ const bindKeys = getObjectLiteralKeys(prop.exp);
3625
+ if (bindKeys && hasComponentKeyOverlap(keys, bindKeys)) return true;
3626
+ continue;
3627
+ }
3628
+ key = getStaticBindKey(prop);
3629
+ } else if (prop.name === "on") key = getStaticHandlerKey(prop);
3630
+ else if (prop.name === "model") {
3631
+ if (hasComponentModelKey(keys, prop)) return true;
3632
+ }
3633
+ if (key && hasComponentKey(keys, key)) return true;
3634
+ }
3635
+ return false;
3636
+ }
3637
+ function hasComponentModelKey(keys, prop) {
3638
+ const { arg } = prop;
3639
+ if (arg && (arg.type !== 4 || !arg.isStatic)) return true;
3640
+ const key = arg ? arg.content : "modelValue";
3641
+ return hasComponentKey(keys, key) || hasComponentKey(keys, `onUpdate:${(0, _vue_shared.camelize)(key)}`) || prop.modifiers.length > 0 && hasComponentKey(keys, (0, _vue_shared.getModifierPropName)(key));
3642
+ }
3643
+ function hasNativeObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
3644
+ const keys = new Set(objectLiteralProps.map((prop) => prop.key.content));
3645
+ for (const prop of props) {
3646
+ if (prop === currentProp) continue;
3647
+ let key;
3648
+ if (prop.type === 6) key = prop.name;
3649
+ else if (prop.name === "bind") {
3650
+ if (!prop.arg) return true;
3651
+ key = getStaticBindKey(prop);
3652
+ if (!key) return true;
3653
+ }
3654
+ if (key && keys.has(key)) return true;
3655
+ }
3656
+ return false;
3657
+ }
3658
+ function getStaticBindKey(prop) {
3659
+ const { arg } = prop;
3660
+ if (!arg || arg.type !== 4 || !arg.isStatic) return;
3661
+ let key = arg.content;
3662
+ if (isReservedProp(key)) return;
3663
+ if (prop.modifiers.some((modifier) => modifier.content === "camel")) key = (0, _vue_shared.camelize)(key);
3664
+ return key;
3665
+ }
3666
+ function getStaticHandlerKey(prop) {
3667
+ const { arg } = prop;
3668
+ if (!arg || arg.type !== 4 || !arg.isStatic) return;
3669
+ let key = arg.content;
3670
+ if (key.startsWith("vue:")) key = `vnode-${key.slice(4)}`;
3671
+ const { nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(`on${key}`, prop.modifiers, null, prop.loc);
3672
+ if (key.toLowerCase() === "click") {
3673
+ if (nonKeyModifiers.includes("middle")) key = "mouseup";
3674
+ if (nonKeyModifiers.includes("right")) key = "contextmenu";
3675
+ }
3676
+ key = (0, _vue_shared.toHandlerKey)((0, _vue_shared.camelize)(key));
3677
+ const optionPostfix = eventOptionModifiers.map(_vue_shared.capitalize).join("");
3678
+ if (optionPostfix) key += optionPostfix;
3679
+ return key;
3680
+ }
3681
+ function getObjectLiteralKeys(exp) {
3682
+ const ast = exp && exp.ast;
3683
+ if (!ast || ast.type !== "ObjectExpression") return;
3684
+ const keys = /* @__PURE__ */ new Set();
3685
+ for (const property of ast.properties) {
3686
+ if (property.type !== "ObjectProperty" || property.computed) return;
3687
+ const key = getObjectPropertyName(property);
3688
+ if (key == null) return;
3689
+ keys.add(key);
3690
+ }
3691
+ return keys;
3692
+ }
3693
+ function createComponentConflictKeySet(keys) {
3694
+ const normalized = /* @__PURE__ */ new Set();
3695
+ for (const key of keys) {
3696
+ normalized.add(key);
3697
+ normalized.add((0, _vue_shared.camelize)(key));
3698
+ }
3699
+ return normalized;
3700
+ }
3701
+ function hasComponentKey(keys, key) {
3702
+ return keys.has(key) || keys.has((0, _vue_shared.camelize)(key));
3703
+ }
3704
+ function hasComponentKeyOverlap(left, right) {
3705
+ for (const key of right) if (hasComponentKey(left, key)) return true;
3706
+ return false;
3707
+ }
3708
+ function createObjectBindSubExpression(source, node, context) {
3709
+ const start = node.start == null ? 0 : node.start - 1;
3710
+ const end = node.end == null ? source.content.length : node.end - 1;
3711
+ const content = source.content.slice(start, end);
3712
+ const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
3713
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
3714
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
3715
+ source: content
3716
+ });
3717
+ expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
3718
+ return expression;
3719
+ }
2588
3720
  function transformProp(prop, node, context) {
2589
3721
  let { name } = prop;
2590
3722
  if (prop.type === 6) {
@@ -2635,6 +3767,12 @@ function resolveDirectiveResult(prop) {
2635
3767
  values: [prop.value]
2636
3768
  });
2637
3769
  }
3770
+ function toDirectiveResult(prop) {
3771
+ return (0, _vue_shared.extend)({}, prop, {
3772
+ values: void 0,
3773
+ value: prop.values[0]
3774
+ });
3775
+ }
2638
3776
  function mergePropValues(existing, incoming) {
2639
3777
  const newValues = incoming.values;
2640
3778
  existing.values.push(...newValues);
@@ -2642,24 +3780,88 @@ function mergePropValues(existing, incoming) {
2642
3780
  function isComponentTag(tag) {
2643
3781
  return tag === "component" || tag === "Component";
2644
3782
  }
3783
+ function shouldUseCreateElement(node, context) {
3784
+ return context.options.isCustomElement(node.tag) || node.tagType === 0 && node.tag === "template";
3785
+ }
2645
3786
  //#endregion
2646
- //#region packages/compiler-vapor/src/transforms/vHtml.ts
2647
- const transformVHtml = (dir, node, context) => {
2648
- let { exp, loc } = dir;
2649
- if (!exp) {
2650
- context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(54, loc));
2651
- exp = EMPTY_EXPRESSION;
3787
+ //#region packages/compiler-vapor/src/transforms/transformChildren.ts
3788
+ const transformChildren = (node, context) => {
3789
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3790
+ if (!isFragment && node.type !== 1) return;
3791
+ const useCreateElement = node.type === 1 && shouldUseCreateElement(node, context);
3792
+ const childTemplateCloseState = !isFragment && !useCreateElement ? getChildTemplateCloseState(context) : void 0;
3793
+ for (const [i, child] of node.children.entries()) {
3794
+ const childContext = context.create(child, i);
3795
+ const isInSameTemplate = childTemplateCloseState && child.type === 1 && child.tagType === 0 && isInSameTemplateAsParent(childContext);
3796
+ childContext.templateCloseTags = isInSameTemplate ? childTemplateCloseState.tags : void 0;
3797
+ childContext.templateCloseBlocks = isInSameTemplate ? childTemplateCloseState.blocks : false;
3798
+ transformNode(childContext);
3799
+ const childDynamic = childContext.dynamic;
3800
+ if (isFragment) {
3801
+ childContext.reference();
3802
+ childContext.registerTemplate();
3803
+ if (!(childDynamic.flags & 2) || childDynamic.flags & 4) context.block.returns.push(childContext.dynamic.id);
3804
+ } else if (useCreateElement) {
3805
+ if (childContext.template !== "" || childDynamic.template != null || childDynamic.id !== void 0 || childDynamic.operation !== void 0 || childDynamic.hasDynamicChild === true) {
3806
+ childContext.reference();
3807
+ childContext.registerTemplate();
3808
+ childDynamic.flags |= 6;
3809
+ }
3810
+ } else context.childrenTemplate.push(childContext.template);
3811
+ if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) context.dynamic.hasDynamicChild = true;
3812
+ context.dynamic.children[i] = childDynamic;
2652
3813
  }
2653
- if (node.children.length) {
2654
- context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(55, loc));
2655
- context.childrenTemplate.length = 0;
3814
+ if (!isFragment) processDynamicChildren(context);
3815
+ };
3816
+ function processDynamicChildren(context) {
3817
+ let prevDynamics = [];
3818
+ let staticCount = 0;
3819
+ const children = context.dynamic.children;
3820
+ let logicalIndex = 0;
3821
+ for (const [index, child] of children.entries()) {
3822
+ if (child.flags & 4) {
3823
+ child.logicalIndex = logicalIndex;
3824
+ prevDynamics.push(child);
3825
+ logicalIndex++;
3826
+ }
3827
+ if (!(child.flags & 2)) {
3828
+ child.logicalIndex = logicalIndex;
3829
+ if (prevDynamics.length) {
3830
+ if (staticCount) {
3831
+ context.childrenTemplate[index - prevDynamics.length] = `<!>`;
3832
+ prevDynamics[0].flags -= 2;
3833
+ const anchor = prevDynamics[0].anchor = context.increaseId();
3834
+ registerInsertion(prevDynamics, context, anchor);
3835
+ } else registerInsertion(prevDynamics, context, -1);
3836
+ prevDynamics = [];
3837
+ }
3838
+ staticCount++;
3839
+ logicalIndex++;
3840
+ }
2656
3841
  }
2657
- context.registerEffect([exp], {
2658
- type: 8,
2659
- element: context.reference(),
2660
- value: exp,
2661
- isComponent: node.tagType === 1
2662
- });
3842
+ if (prevDynamics.length) registerInsertion(prevDynamics, context, prevDynamics[0].logicalIndex, true);
3843
+ }
3844
+ function registerInsertion(dynamics, context, anchor, append) {
3845
+ for (const child of dynamics) {
3846
+ const logicalIndex = child.logicalIndex;
3847
+ if (child.template != null) context.registerOperation({
3848
+ type: 10,
3849
+ elements: dynamics.map((child) => child.id),
3850
+ parent: context.reference(),
3851
+ anchor: append ? void 0 : anchor
3852
+ });
3853
+ else if (child.operation && isBlockOperation(child.operation)) {
3854
+ child.operation.parent = context.reference();
3855
+ child.operation.anchor = anchor;
3856
+ child.operation.logicalIndex = logicalIndex;
3857
+ child.operation.append = append;
3858
+ }
3859
+ }
3860
+ }
3861
+ //#endregion
3862
+ //#region packages/compiler-vapor/src/transforms/vOnce.ts
3863
+ const transformVOnce = (node, context) => {
3864
+ if (node.type === 1 && (0, _vue_compiler_dom.findDir)(node, "once", true)) context.inVOnce = true;
2663
3865
  };
2664
3866
  //#endregion
2665
3867
  //#region packages/shared/src/makeMap.ts
@@ -2682,6 +3884,147 @@ function makeMap$1(str) {
2682
3884
  */
2683
3885
  const isVoidTag = /* @__PURE__ */ makeMap$1("area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr");
2684
3886
  //#endregion
3887
+ //#region packages/compiler-vapor/src/transforms/transformText.ts
3888
+ const seen = /* @__PURE__ */ new WeakMap();
3889
+ function markNonTemplate(node, context) {
3890
+ let seenNodes = seen.get(context.root);
3891
+ if (!seenNodes) {
3892
+ seenNodes = /* @__PURE__ */ new WeakSet();
3893
+ seen.set(context.root, seenNodes);
3894
+ }
3895
+ seenNodes.add(node);
3896
+ }
3897
+ const transformText = (node, context) => {
3898
+ if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
3899
+ if (seen.get(context.root).has(node)) {
3900
+ context.dynamic.flags |= 2;
3901
+ return;
3902
+ }
3903
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3904
+ if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
3905
+ let hasInterp = false;
3906
+ let isAllTextLike = true;
3907
+ for (const c of node.children) if (c.type === 5) hasInterp = true;
3908
+ else if (c.type !== 2) isAllTextLike = false;
3909
+ if (!isFragment && isAllTextLike && hasInterp) {
3910
+ const elementContext = context;
3911
+ if (shouldUseCreateElement(node, elementContext)) processCreateElementTextContainer(node.children, elementContext);
3912
+ else processTextContainer(node.children, elementContext);
3913
+ } else if (hasInterp) for (let i = 0; i < node.children.length; i++) {
3914
+ const c = node.children[i];
3915
+ const prev = node.children[i - 1];
3916
+ if (c.type === 5 && prev && prev.type === 2) markNonTemplate(prev, context);
3917
+ }
3918
+ } else if (node.type === 5) processInterpolation(context);
3919
+ else if (node.type === 2) {
3920
+ var _context$parent;
3921
+ const parent = (_context$parent = context.parent) === null || _context$parent === void 0 ? void 0 : _context$parent.node;
3922
+ if (parent && parent.type === 1 && shouldUseCreateElement(parent, context.parent) && node.content[0] === "<") {
3923
+ materializeLiteralTextNode((0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc), context);
3924
+ return;
3925
+ }
3926
+ const isRootText = !parent || parent.type === 0 || parent.type === 1 && (parent.tagType === 3 || parent.tagType === 1);
3927
+ context.template += isRootText ? node.content : (0, _vue_shared.escapeHtml)(node.content);
3928
+ }
3929
+ };
3930
+ function processInterpolation(context) {
3931
+ const parentNode = context.parent.node;
3932
+ const values = processTextLikeChildren(collectAdjacentText(context), context);
3933
+ if (values.length === 0 && parentNode.type !== 0) return;
3934
+ const literalValues = values.map((v) => getLiteralExpressionValue(v));
3935
+ if (literalValues.every((v) => v != null) && parentNode.type !== 0) {
3936
+ const text = literalValues.join("");
3937
+ if (parentNode.type === 1 && shouldUseCreateElement(parentNode, context.parent) && text[0] === "<") {
3938
+ materializeLiteralTextNode((0, _vue_compiler_dom.createSimpleExpression)(text, true, context.node.loc), context);
3939
+ return;
3940
+ }
3941
+ const isElementChild = parentNode.type === 1 && parentNode.tagType === 0;
3942
+ context.template += isElementChild ? (0, _vue_shared.escapeHtml)(text) : text;
3943
+ return;
3944
+ }
3945
+ context.template += " ";
3946
+ const id = context.reference();
3947
+ if (values.length === 0) return;
3948
+ context.registerEffect(values, {
3949
+ type: 5,
3950
+ element: id,
3951
+ values
3952
+ });
3953
+ }
3954
+ function collectAdjacentText(context) {
3955
+ const children = context.parent.node.children;
3956
+ const nodes = [];
3957
+ const prev = children[context.index - 1];
3958
+ let index = prev && prev.type === 2 ? context.index - 1 : context.index;
3959
+ for (; index < children.length; index++) {
3960
+ const child = children[index];
3961
+ if (!isTextLike(child)) break;
3962
+ nodes.push(child);
3963
+ }
3964
+ return nodes;
3965
+ }
3966
+ function processTextContainer(children, context) {
3967
+ const values = processTextLikeChildren(children, context);
3968
+ const literals = values.map((value) => getLiteralExpressionValue(value));
3969
+ if (literals.every((l) => l != null)) context.childrenTemplate = literals.map((l) => (0, _vue_shared.escapeHtml)(String(l)));
3970
+ else {
3971
+ context.childrenTemplate = [" "];
3972
+ context.registerOperation({
3973
+ type: 18,
3974
+ parent: context.reference()
3975
+ });
3976
+ context.registerEffect(values, {
3977
+ type: 5,
3978
+ element: context.reference(),
3979
+ values,
3980
+ generated: true
3981
+ });
3982
+ }
3983
+ }
3984
+ function registerSyntheticTextChild(context, template, values) {
3985
+ const id = context.increaseId();
3986
+ context.dynamic.children[context.node.children.length] = {
3987
+ id,
3988
+ flags: 6,
3989
+ children: [],
3990
+ template: context.pushTemplate(template)
3991
+ };
3992
+ context.dynamic.hasDynamicChild = true;
3993
+ if (values && values.length) context.registerEffect(values, {
3994
+ type: 5,
3995
+ element: id,
3996
+ values
3997
+ });
3998
+ return id;
3999
+ }
4000
+ function processCreateElementTextContainer(children, context) {
4001
+ registerSyntheticTextChild(context, "", processTextLikeChildren(children, context));
4002
+ }
4003
+ function materializeLiteralTextNode(value, context) {
4004
+ const id = context.reference();
4005
+ context.dynamic.flags |= 6;
4006
+ context.dynamic.template = context.pushTemplate("");
4007
+ context.registerEffect([value], {
4008
+ type: 5,
4009
+ element: id,
4010
+ values: [value]
4011
+ });
4012
+ }
4013
+ function processTextLikeChildren(nodes, context) {
4014
+ const exps = [];
4015
+ for (const node of nodes) {
4016
+ let exp;
4017
+ markNonTemplate(node, context);
4018
+ if (node.type === 2) exp = (0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc);
4019
+ else exp = node.content;
4020
+ if (exp.content) exps.push(exp);
4021
+ }
4022
+ return exps;
4023
+ }
4024
+ function isTextLike(node) {
4025
+ return node.type === 5 || node.type === 2;
4026
+ }
4027
+ //#endregion
2685
4028
  //#region packages/compiler-vapor/src/transforms/vText.ts
2686
4029
  const transformVText = (dir, node, context) => {
2687
4030
  let { exp, loc } = dir;
@@ -2692,22 +4035,41 @@ const transformVText = (dir, node, context) => {
2692
4035
  if (node.children.length) {
2693
4036
  context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(57, loc));
2694
4037
  context.childrenTemplate.length = 0;
4038
+ for (const child of node.children) markNonTemplate(child, context);
2695
4039
  }
2696
4040
  if (isVoidTag(context.node.tag)) return;
2697
4041
  const literal = getLiteralExpressionValue(exp);
2698
- if (literal != null) context.childrenTemplate = [String(literal)];
2699
- else {
2700
- context.childrenTemplate = [" "];
2701
- const isComponent = node.tagType === 1;
2702
- if (!isComponent) context.registerOperation({
2703
- type: 18,
4042
+ const useCreateElement = shouldUseCreateElement(context.node, context);
4043
+ if (literal != null) if (useCreateElement) {
4044
+ const id = registerSyntheticTextChild(context, "", [exp]);
4045
+ context.registerOperation({
4046
+ type: 10,
4047
+ elements: [id],
2704
4048
  parent: context.reference()
2705
4049
  });
4050
+ } else context.childrenTemplate = [String(literal)];
4051
+ else {
4052
+ const isComponent = node.tagType === 1;
4053
+ let id;
4054
+ if (useCreateElement) {
4055
+ id = registerSyntheticTextChild(context, "");
4056
+ context.registerOperation({
4057
+ type: 10,
4058
+ elements: [id],
4059
+ parent: context.reference()
4060
+ });
4061
+ } else if (!isComponent) {
4062
+ context.childrenTemplate = [" "];
4063
+ context.registerOperation({
4064
+ type: 18,
4065
+ parent: context.reference()
4066
+ });
4067
+ }
2706
4068
  context.registerEffect([exp], {
2707
4069
  type: 5,
2708
- element: context.reference(),
4070
+ element: useCreateElement ? id : context.reference(),
2709
4071
  values: [exp],
2710
- generated: true,
4072
+ generated: !useCreateElement,
2711
4073
  isComponent
2712
4074
  });
2713
4075
  }
@@ -2721,15 +4083,14 @@ const transformVOn = (dir, node, context) => {
2721
4083
  const isSlotOutlet = node.tag === "slot";
2722
4084
  if (!exp && !modifiers.length) context.options.onError((0, _vue_compiler_dom.createCompilerError)(35, loc));
2723
4085
  arg = resolveExpression(arg);
4086
+ if (arg.isStatic && arg.content.startsWith("vue:")) arg = (0, _vue_shared.extend)({}, arg, { content: `vnode-${arg.content.slice(4)}` });
2724
4087
  const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(arg.isStatic ? `on${arg.content}` : arg, modifiers, null, loc);
2725
4088
  let keyOverride;
2726
4089
  const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
2727
- if (nonKeyModifiers.includes("middle")) {
2728
- if (keyOverride) {}
2729
- if (!isStaticClick && !arg.isStatic) keyOverride = ["click", "mouseup"];
2730
- }
2731
4090
  if (nonKeyModifiers.includes("right")) {
2732
4091
  if (!isStaticClick && !arg.isStatic) keyOverride = ["click", "contextmenu"];
4092
+ } else if (nonKeyModifiers.includes("middle")) {
4093
+ if (!isStaticClick && !arg.isStatic) keyOverride = ["click", "mouseup"];
2733
4094
  }
2734
4095
  arg = normalizeStaticEventArg(arg, nonKeyModifiers);
2735
4096
  if (keyModifiers.length && (0, _vue_compiler_dom.isStaticExp)(arg) && !(0, _vue_compiler_dom.isKeyboardEvent)(`on${arg.content.toLowerCase()}`)) keyModifiers.length = 0;
@@ -2743,7 +4104,7 @@ const transformVOn = (dir, node, context) => {
2743
4104
  options: eventOptionModifiers
2744
4105
  }
2745
4106
  };
2746
- const delegate = arg.isStatic && !eventOptionModifiers.length && !hasStopHandlerForStaticEvent(node, arg.content) && delegatedEvents(arg.content);
4107
+ const delegate = context.options.eventDelegation && arg.isStatic && !eventOptionModifiers.length && !hasStopHandlerForStaticEvent(node, arg.content) && delegatedEvents(arg.content);
2747
4108
  const operation = {
2748
4109
  type: 6,
2749
4110
  element: context.reference(),
@@ -2764,8 +4125,8 @@ function normalizeStaticEventArg(arg, nonKeyModifiers) {
2764
4125
  if (!arg.isStatic) return arg;
2765
4126
  let normalized = arg;
2766
4127
  const isStaticClick = arg.content.toLowerCase() === "click";
2767
- if (nonKeyModifiers.includes("middle") && isStaticClick) normalized = (0, _vue_shared.extend)({}, normalized, { content: "mouseup" });
2768
4128
  if (nonKeyModifiers.includes("right") && isStaticClick) normalized = (0, _vue_shared.extend)({}, normalized, { content: "contextmenu" });
4129
+ else if (nonKeyModifiers.includes("middle") && isStaticClick) normalized = (0, _vue_shared.extend)({}, normalized, { content: "mouseup" });
2769
4130
  return normalized;
2770
4131
  }
2771
4132
  function hasStopHandlerForStaticEvent(node, eventName) {
@@ -2789,19 +4150,12 @@ const transformVShow = (dir, node, context) => {
2789
4150
  context.options.onError((0, _vue_compiler_dom.createCompilerError)(36, loc));
2790
4151
  return;
2791
4152
  }
2792
- let shouldDeferred = false;
2793
- const parentNode = context.parent && context.parent.node;
2794
- if (parentNode && parentNode.type === 1) {
2795
- shouldDeferred = !!(isTransitionTag(parentNode.tag) && findProp$1(parentNode, "appear", false, true));
2796
- if (shouldDeferred) context.ir.hasDeferredVShow = true;
2797
- }
2798
4153
  context.registerOperation({
2799
4154
  type: 14,
2800
4155
  element: context.reference(),
2801
4156
  dir,
2802
4157
  name: "show",
2803
- builtin: true,
2804
- deferred: shouldDeferred
4158
+ builtin: true
2805
4159
  });
2806
4160
  };
2807
4161
  //#endregion
@@ -2827,96 +4181,6 @@ const transformTemplateRef = (node, context) => {
2827
4181
  };
2828
4182
  };
2829
4183
  //#endregion
2830
- //#region packages/compiler-vapor/src/transforms/transformText.ts
2831
- const seen = /* @__PURE__ */ new WeakMap();
2832
- function markNonTemplate(node, context) {
2833
- seen.get(context.root).add(node);
2834
- }
2835
- const transformText = (node, context) => {
2836
- if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
2837
- if (seen.get(context.root).has(node)) {
2838
- context.dynamic.flags |= 2;
2839
- return;
2840
- }
2841
- const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
2842
- if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
2843
- let hasInterp = false;
2844
- let isAllTextLike = true;
2845
- for (const c of node.children) if (c.type === 5) hasInterp = true;
2846
- else if (c.type !== 2) isAllTextLike = false;
2847
- if (!isFragment && isAllTextLike && hasInterp) processTextContainer(node.children, context);
2848
- else if (hasInterp) for (let i = 0; i < node.children.length; i++) {
2849
- const c = node.children[i];
2850
- const prev = node.children[i - 1];
2851
- if (c.type === 5 && prev && prev.type === 2) markNonTemplate(prev, context);
2852
- }
2853
- } else if (node.type === 5) processInterpolation(context);
2854
- else if (node.type === 2) {
2855
- var _context$parent;
2856
- const parent = (_context$parent = context.parent) === null || _context$parent === void 0 ? void 0 : _context$parent.node;
2857
- const isRootText = !parent || parent.type === 0 || parent.type === 1 && (parent.tagType === 3 || parent.tagType === 1);
2858
- context.template += isRootText ? node.content : (0, _vue_shared.escapeHtml)(node.content);
2859
- }
2860
- };
2861
- function processInterpolation(context) {
2862
- const parentNode = context.parent.node;
2863
- const children = parentNode.children;
2864
- const nexts = children.slice(context.index);
2865
- const idx = nexts.findIndex((n) => !isTextLike(n));
2866
- const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
2867
- const prev = children[context.index - 1];
2868
- if (prev && prev.type === 2) nodes.unshift(prev);
2869
- const values = processTextLikeChildren(nodes, context);
2870
- if (values.length === 0 && parentNode.type !== 0) return;
2871
- const literalValues = values.map((v) => getLiteralExpressionValue(v));
2872
- if (literalValues.every((v) => v != null) && parentNode.type !== 0) {
2873
- const text = literalValues.join("");
2874
- const isElementChild = parentNode.type === 1 && parentNode.tagType === 0;
2875
- context.template += isElementChild ? (0, _vue_shared.escapeHtml)(text) : text;
2876
- return;
2877
- }
2878
- context.template += " ";
2879
- const id = context.reference();
2880
- if (values.length === 0) return;
2881
- context.registerEffect(values, {
2882
- type: 5,
2883
- element: id,
2884
- values
2885
- });
2886
- }
2887
- function processTextContainer(children, context) {
2888
- const values = processTextLikeChildren(children, context);
2889
- const literals = values.map((value) => getLiteralExpressionValue(value));
2890
- if (literals.every((l) => l != null)) context.childrenTemplate = literals.map((l) => (0, _vue_shared.escapeHtml)(String(l)));
2891
- else {
2892
- context.childrenTemplate = [" "];
2893
- context.registerOperation({
2894
- type: 18,
2895
- parent: context.reference()
2896
- });
2897
- context.registerEffect(values, {
2898
- type: 5,
2899
- element: context.reference(),
2900
- values,
2901
- generated: true
2902
- });
2903
- }
2904
- }
2905
- function processTextLikeChildren(nodes, context) {
2906
- const exps = [];
2907
- for (const node of nodes) {
2908
- let exp;
2909
- markNonTemplate(node, context);
2910
- if (node.type === 2) exp = (0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc);
2911
- else exp = node.content;
2912
- if (exp.content) exps.push(exp);
2913
- }
2914
- return exps;
2915
- }
2916
- function isTextLike(node) {
2917
- return node.type === 5 || node.type === 2;
2918
- }
2919
- //#endregion
2920
4184
  //#region packages/compiler-vapor/src/transforms/vModel.ts
2921
4185
  const transformVModel = (dir, node, context) => {
2922
4186
  const { exp, arg } = dir;
@@ -3026,6 +4290,8 @@ function processIf(node, dir, context) {
3026
4290
  dir.exp = (0, _vue_compiler_dom.createSimpleExpression)(`true`, false, loc);
3027
4291
  }
3028
4292
  context.dynamic.flags |= 2;
4293
+ const forceMultiRoot = shouldForceMultiRoot(context);
4294
+ const allowNoScope = context.block === context.root.block;
3029
4295
  if (dir.name === "if") {
3030
4296
  const id = context.reference();
3031
4297
  context.dynamic.flags |= 4;
@@ -3035,7 +4301,8 @@ function processIf(node, dir, context) {
3035
4301
  context.dynamic.operation = {
3036
4302
  type: 15,
3037
4303
  id,
3038
- blockShape: encodeIfBlockShape(branch),
4304
+ ...context.effectBoundary(),
4305
+ blockShape: encodeIfBlockShape(branch, forceMultiRoot, void 0, allowNoScope),
3039
4306
  condition: dir.exp,
3040
4307
  positive: branch,
3041
4308
  index: context.root.nextIfIndex(),
@@ -3059,11 +4326,14 @@ function processIf(node, dir, context) {
3059
4326
  }
3060
4327
  while (lastIfNode.negative && lastIfNode.negative.type === 15) lastIfNode = lastIfNode.negative;
3061
4328
  if (dir.name === "else-if" && lastIfNode.negative) context.options.onError((0, _vue_compiler_dom.createCompilerError)(30, node.loc));
3062
- if (context.root.comment.length) {
3063
- node = wrapTemplate(node, ["else-if", "else"]);
3064
- context.node = node = (0, _vue_shared.extend)({}, node, { children: [...context.comment, ...node.children] });
4329
+ const comments = context.comment;
4330
+ if (comments.length) {
4331
+ if (!isInTransition(context)) {
4332
+ node = wrapTemplate(node, ["else-if", "else"]);
4333
+ context.node = node = (0, _vue_shared.extend)({}, node, { children: [...comments, ...node.children] });
4334
+ }
4335
+ comments.length = 0;
3065
4336
  }
3066
- context.root.comment = [];
3067
4337
  const [branch, onExit] = createIfBranch(node, context);
3068
4338
  if (dir.name === "else") lastIfNode.negative = branch;
3069
4339
  else lastIfNode.negative = {
@@ -3077,8 +4347,8 @@ function processIf(node, dir, context) {
3077
4347
  };
3078
4348
  return () => {
3079
4349
  onExit();
3080
- if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive);
3081
- lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, lastIfNode.negative);
4350
+ if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot, void 0, allowNoScope);
4351
+ lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative, allowNoScope);
3082
4352
  };
3083
4353
  }
3084
4354
  }
@@ -3093,13 +4363,42 @@ function createIfBranch(node, context) {
3093
4363
  context.reference();
3094
4364
  return [branch, exitBlock];
3095
4365
  }
3096
- function encodeIfBlockShape(positive, negative) {
3097
- return getBlockShape(positive) | getNegativeBlockShape(negative) << 2;
4366
+ function encodeIfBlockShape(positive, forceMultiRoot = false, negative, allowNoScope = true) {
4367
+ if (forceMultiRoot) return 10;
4368
+ const positiveNoScope = allowNoScope && canSkipIfBranchScope(positive);
4369
+ const negativeNoScope = allowNoScope && negative && negative.type !== 15 && canSkipIfBranchScope(negative);
4370
+ return getBlockShape(positive) | getNegativeIfBranchShape(negative) << 2 | (positiveNoScope ? 32 : 0) | (negativeNoScope ? 64 : 0);
3098
4371
  }
3099
- function getNegativeBlockShape(negative) {
4372
+ function getNegativeIfBranchShape(negative) {
3100
4373
  if (!negative) return 0;
3101
4374
  return negative.type === 15 ? 1 : getBlockShape(negative);
3102
4375
  }
4376
+ function canSkipIfBranchScope(block) {
4377
+ if (block.effect.length || block.operation.length) return false;
4378
+ if (!isStaticBranch(block.node)) return false;
4379
+ if (block.returns.length === 0 || block.dynamic.children.length !== block.returns.length) return false;
4380
+ return block.returns.every((id) => {
4381
+ const returned = findReturnedDynamic(block, id);
4382
+ return !!(returned && returned.template != null && !returned.operation && !returned.hasDynamicChild && !(returned.flags & 6));
4383
+ });
4384
+ }
4385
+ function findReturnedDynamic(block, id) {
4386
+ return block.dynamic.children.find((child) => child.id === id);
4387
+ }
4388
+ function isStaticBranch(node) {
4389
+ if (node.type !== 1 || node.tagType !== 3 || node.children.length === 0) return false;
4390
+ return node.children.every((child) => isStaticTemplateNode(child));
4391
+ }
4392
+ function isStaticTemplateNode(node) {
4393
+ if (node.type === 2 || node.type === 3) return true;
4394
+ if (node.type !== 1 || node.tagType !== 0) return false;
4395
+ for (const prop of node.props) if (prop.type === 7 || prop.name === "ref") return false;
4396
+ return node.children.every((child) => isStaticTemplateNode(child));
4397
+ }
4398
+ function shouldForceMultiRoot(context) {
4399
+ const parent = context.parent && context.parent.node;
4400
+ return !!parent && parent.type === 1 && parent.tagType === 3 && parent.props.some((prop) => prop.type === 7 && prop.name === "for");
4401
+ }
3103
4402
  //#endregion
3104
4403
  //#region packages/compiler-vapor/src/transforms/vFor.ts
3105
4404
  const transformVFor = createStructuralDirectiveTransform("for", processFor);
@@ -3130,6 +4429,7 @@ function processFor(node, dir, context) {
3130
4429
  context.dynamic.operation = {
3131
4430
  type: 16,
3132
4431
  id,
4432
+ ...context.effectBoundary(),
3133
4433
  source,
3134
4434
  value,
3135
4435
  key,
@@ -3179,14 +4479,17 @@ const transformSlotOutlet = (node, context) => {
3179
4479
  }
3180
4480
  return () => {
3181
4481
  exitBlock && exitBlock();
4482
+ let flags = 0;
4483
+ if (context.options.scopeId && !context.options.slotted) flags |= 1;
4484
+ if (context.inVOnce) flags |= 2;
3182
4485
  context.dynamic.operation = {
3183
4486
  type: 13,
3184
4487
  id,
4488
+ ...context.effectBoundary(),
3185
4489
  name: slotName,
3186
4490
  props: irProps,
3187
4491
  fallback,
3188
- noSlotted: !!(context.options.scopeId && !context.options.slotted),
3189
- once: context.inVOnce
4492
+ flags
3190
4493
  };
3191
4494
  };
3192
4495
  };
@@ -3208,7 +4511,7 @@ function createFallback(node, context) {
3208
4511
  //#region packages/compiler-vapor/src/transforms/vSlot.ts
3209
4512
  const transformVSlot = (node, context) => {
3210
4513
  if (node.type !== 1) return;
3211
- const dir = findDir$2(node, "slot", true);
4514
+ const dir = findDir$4(node, "slot", true);
3212
4515
  const { tagType, children } = node;
3213
4516
  const { parent } = context;
3214
4517
  const isComponent = tagType === 1;
@@ -3259,9 +4562,9 @@ function transformTemplateSlot(node, dir, context) {
3259
4562
  const resolvedArg = dir.arg && resolveExpression(dir.arg);
3260
4563
  let arg = resolvedArg;
3261
4564
  if (!arg) arg = (0, _vue_compiler_dom.createSimpleExpression)("default", true);
3262
- const vFor = findDir$2(node, "for");
3263
- const vIf = findDir$2(node, "if");
3264
- const vElse = findDir$2(node, /^else(-if)?$/, true);
4565
+ const vFor = findDir$4(node, "for");
4566
+ const vIf = findDir$4(node, "if");
4567
+ const vElse = findDir$4(node, /^else(-if)?$/, true);
3265
4568
  const { slots } = context;
3266
4569
  const [block, onExit] = createSlotBlock(node, dir, context);
3267
4570
  if (!vFor && !vIf && !vElse) {
@@ -3279,7 +4582,7 @@ function transformTemplateSlot(node, dir, context) {
3279
4582
  });
3280
4583
  else if (vElse) {
3281
4584
  const vIfSlot = slots[slots.length - 1];
3282
- if (vIfSlot.slotType === 3) {
4585
+ if (vIfSlot && vIfSlot.slotType === 3) {
3283
4586
  let ifNode = vIfSlot;
3284
4587
  while (ifNode.negative && ifNode.negative.slotType === 3) ifNode = ifNode.negative;
3285
4588
  const negative = vElse.exp ? {
@@ -3342,7 +4645,7 @@ function isNonWhitespaceContent(node) {
3342
4645
  return !!node.content.trim();
3343
4646
  }
3344
4647
  function isSlotTemplateChild(node) {
3345
- return node.type === 1 && (0, _vue_compiler_dom.isTemplateNode)(node) && !!findDir$2(node, "slot", true);
4648
+ return node.type === 1 && (0, _vue_compiler_dom.isTemplateNode)(node) && !!findDir$4(node, "slot", true);
3346
4649
  }
3347
4650
  //#endregion
3348
4651
  //#region packages/compiler-vapor/src/transforms/transformTransition.ts
@@ -3355,17 +4658,17 @@ function hasMultipleChildren(node) {
3355
4658
  const children = node.children = node.children.filter((c) => c.type !== 3 && !(c.type === 2 && !c.content.trim()));
3356
4659
  const first = children[0];
3357
4660
  if (children.length === 1 && first.type === 1) {
3358
- if (findDir$2(first, "for")) return true;
4661
+ if (findDir$4(first, "for")) return true;
3359
4662
  if ((0, _vue_compiler_dom.isTemplateNode)(first)) return hasMultipleChildren(first);
3360
4663
  }
3361
- const hasElse = (node) => findDir$2(node, "else-if") || findDir$2(node, "else", true);
3362
- if (children.length > 0 && children.every((c, index) => c.type === 1 && (!(0, _vue_compiler_dom.isTemplateNode)(c) || !hasMultipleChildren(c)) && !findDir$2(c, "for") && (index === 0 ? findDir$2(c, "if") : hasElse(c)))) return false;
4664
+ const hasElse = (node) => findDir$4(node, "else-if") || findDir$4(node, "else", true);
4665
+ if (children.length > 0 && children.every((c, index) => c.type === 1 && (!(0, _vue_compiler_dom.isTemplateNode)(c) || !hasMultipleChildren(c)) && !findDir$4(c, "for") && (index === 0 ? findDir$4(c, "if") : hasElse(c)))) return false;
3363
4666
  return children.length !== 1;
3364
4667
  }
3365
4668
  //#endregion
3366
4669
  //#region packages/compiler-vapor/src/transforms/transformKey.ts
3367
4670
  const transformKey = (node, context) => {
3368
- if (node.type !== 1 || context.inVOnce || findDir$2(node, "for")) return;
4671
+ if (node.type !== 1 || context.inVOnce || findDir$4(node, "for")) return;
3369
4672
  const dir = findProp$1(node, "key", true, true);
3370
4673
  if (!dir || dir.type === 6) return;
3371
4674
  let value;
@@ -3381,6 +4684,7 @@ const transformKey = (node, context) => {
3381
4684
  context.dynamic.operation = {
3382
4685
  type: 17,
3383
4686
  id,
4687
+ ...context.effectBoundary(),
3384
4688
  value,
3385
4689
  block
3386
4690
  };
@@ -3448,6 +4752,7 @@ exports.DynamicFlag = DynamicFlag;
3448
4752
  exports.IRDynamicPropsKind = IRDynamicPropsKind;
3449
4753
  exports.IRNodeTypes = IRNodeTypes;
3450
4754
  exports.IRSlotType = IRSlotType;
4755
+ exports.TemplateRegistry = TemplateRegistry;
3451
4756
  exports.VaporErrorCodes = VaporErrorCodes;
3452
4757
  exports.VaporErrorMessages = VaporErrorMessages;
3453
4758
  exports.buildCodeFragment = buildCodeFragment;