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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-vapor v3.6.0-alpha.3
2
+ * @vue/compiler-vapor v3.6.0-alpha.5
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -11,7 +11,6 @@ var compilerDom = require('@vue/compiler-dom');
11
11
  var shared = require('@vue/shared');
12
12
  var sourceMapJs = require('source-map-js');
13
13
  var parser = require('@babel/parser');
14
- var types = require('@babel/types');
15
14
  var estreeWalker = require('estree-walker');
16
15
 
17
16
  const newDynamic = () => ({
@@ -66,26 +65,45 @@ function isStaticExpression(node, bindings) {
66
65
  if (node.ast) {
67
66
  return compilerDom.isConstantNode(node.ast, bindings);
68
67
  } else if (node.ast === null) {
68
+ if (!node.isStatic && (node.content === "true" || node.content === "false")) {
69
+ return true;
70
+ }
69
71
  const type = bindings[node.content];
70
72
  return type === "literal-const";
71
73
  }
72
74
  return false;
73
75
  }
74
- function resolveExpression(exp) {
76
+ function resolveExpression(exp, isComponent) {
75
77
  if (!exp.isStatic) {
76
- const value = getLiteralExpressionValue(exp);
78
+ const value = getLiteralExpressionValue(exp, isComponent);
77
79
  if (value !== null) {
78
- return compilerDom.createSimpleExpression("" + value, true, exp.loc);
80
+ return compilerDom.createSimpleExpression(value, true, exp.loc);
79
81
  }
80
82
  }
81
83
  return exp;
82
84
  }
83
- function getLiteralExpressionValue(exp) {
85
+ function getLiteralExpressionValue(exp, excludeNumber) {
84
86
  if (exp.ast) {
85
87
  if (exp.ast.type === "StringLiteral") {
86
88
  return exp.ast.value;
87
- } else if (exp.ast.type === "TemplateLiteral" && exp.ast.expressions.length === 0) {
88
- return exp.ast.quasis[0].value.cooked;
89
+ } else if (!excludeNumber && (exp.ast.type === "NumericLiteral" || exp.ast.type === "BigIntLiteral")) {
90
+ return String(exp.ast.value);
91
+ } else if (exp.ast.type === "TemplateLiteral") {
92
+ let result = "";
93
+ for (const [index, quasi] of exp.ast.quasis.entries()) {
94
+ result += quasi.value.cooked;
95
+ if (exp.ast.expressions[index]) {
96
+ let expressionValue = getLiteralExpressionValue({
97
+ ast: exp.ast.expressions[index]
98
+ });
99
+ if (expressionValue == null) {
100
+ return null;
101
+ } else {
102
+ result += expressionValue;
103
+ }
104
+ }
105
+ }
106
+ return result;
89
107
  }
90
108
  }
91
109
  return exp.isStatic ? exp.content : null;
@@ -125,6 +143,7 @@ function isBuiltInComponent(tag) {
125
143
  }
126
144
  }
127
145
 
146
+ const generatedVarRE = /^[nxr](\d+)$/;
128
147
  class TransformContext {
129
148
  constructor(ir, node, options = {}) {
130
149
  this.ir = ir;
@@ -136,6 +155,7 @@ class TransformContext {
136
155
  this.template = "";
137
156
  this.childrenTemplate = [];
138
157
  this.dynamic = this.ir.block.dynamic;
158
+ this.imports = [];
139
159
  this.inVOnce = false;
140
160
  this.inVFor = 0;
141
161
  this.comment = [];
@@ -143,10 +163,16 @@ class TransformContext {
143
163
  this.directive = this.ir.directive;
144
164
  this.slots = [];
145
165
  this.globalId = 0;
146
- this.increaseId = () => this.globalId++;
166
+ this.nextIdMap = null;
167
+ this.increaseId = () => {
168
+ const id = getNextId(this.nextIdMap, this.globalId);
169
+ this.globalId = getNextId(this.nextIdMap, id + 1);
170
+ return id;
171
+ };
147
172
  this.options = shared.extend({}, defaultOptions, options);
148
173
  this.root = this;
149
174
  if (options.filename) this.selfName = compilerDom.getSelfName(options.filename);
175
+ this.initNextIdMap();
150
176
  }
151
177
  enterBlock(ir, isVFor = false) {
152
178
  const { block, template, dynamic, childrenTemplate, slots } = this;
@@ -166,18 +192,33 @@ class TransformContext {
166
192
  isVFor && this.inVFor--;
167
193
  };
168
194
  }
195
+ initNextIdMap() {
196
+ const binding = this.root.options.bindingMetadata;
197
+ if (!binding) return;
198
+ const keys = Object.keys(binding);
199
+ if (keys.length === 0) return;
200
+ const numbers = /* @__PURE__ */ new Set();
201
+ for (const name of keys) {
202
+ const m = generatedVarRE.exec(name);
203
+ if (m) numbers.add(Number(m[1]));
204
+ }
205
+ if (numbers.size === 0) return;
206
+ this.globalId = getNextId(this.nextIdMap = buildNextIdMap(numbers), 0);
207
+ }
169
208
  reference() {
170
209
  if (this.dynamic.id !== void 0) return this.dynamic.id;
171
210
  this.dynamic.flags |= 1;
172
211
  return this.dynamic.id = this.increaseId();
173
212
  }
174
213
  pushTemplate(content) {
175
- const existing = this.ir.template.findIndex(
176
- (template) => template === content
177
- );
178
- if (existing !== -1) return existing;
179
- this.ir.template.push(content);
180
- return this.ir.template.length - 1;
214
+ const existingIndex = this.ir.templateIndexMap.get(content);
215
+ if (existingIndex !== void 0) {
216
+ return existingIndex;
217
+ }
218
+ const newIndex = this.ir.template.size;
219
+ this.ir.template.set(content, this.node.ns);
220
+ this.ir.templateIndexMap.set(content, newIndex);
221
+ return newIndex;
181
222
  }
182
223
  registerTemplate() {
183
224
  if (!this.template) return -1;
@@ -239,7 +280,9 @@ function transform(node, options = {}) {
239
280
  type: 0,
240
281
  node,
241
282
  source: node.source,
242
- template: [],
283
+ template: /* @__PURE__ */ new Map(),
284
+ templateIndexMap: /* @__PURE__ */ new Map(),
285
+ rootTemplateIndexes: /* @__PURE__ */ new Set(),
243
286
  component: /* @__PURE__ */ new Set(),
244
287
  directive: /* @__PURE__ */ new Set(),
245
288
  block: newBlock(node),
@@ -247,6 +290,7 @@ function transform(node, options = {}) {
247
290
  };
248
291
  const context = new TransformContext(ir, node, options);
249
292
  transformNode(context);
293
+ ir.node.imports = context.imports;
250
294
  return ir;
251
295
  }
252
296
  function transformNode(context) {
@@ -300,7 +344,32 @@ function createStructuralDirectiveTransform(name, fn) {
300
344
  }
301
345
  };
302
346
  }
347
+ function buildNextIdMap(nums) {
348
+ const map = /* @__PURE__ */ new Map();
349
+ const arr = Array.from(new Set(nums)).sort((a, b) => a - b);
350
+ if (arr.length === 0) return map;
351
+ for (let i = 0; i < arr.length; i++) {
352
+ let start = arr[i];
353
+ let end = start;
354
+ while (i + 1 < arr.length && arr[i + 1] === end + 1) {
355
+ i++;
356
+ end = arr[i];
357
+ }
358
+ for (let v = start; v <= end; v++) map.set(v, end + 1);
359
+ }
360
+ return map;
361
+ }
362
+ function getNextId(map, n) {
363
+ if (map && map.has(n)) return map.get(n);
364
+ return n;
365
+ }
303
366
 
367
+ const IMPORT_EXP_START = "__IMPORT_EXP_START__";
368
+ const IMPORT_EXP_END = "__IMPORT_EXP_END__";
369
+ const IMPORT_EXPR_RE = new RegExp(
370
+ `${IMPORT_EXP_START}(.*?)${IMPORT_EXP_END}`,
371
+ "g"
372
+ );
304
373
  const NEWLINE = Symbol(`newline` );
305
374
  const LF = Symbol(`line feed` );
306
375
  const INDENT_START = Symbol(`indent start` );
@@ -543,15 +612,12 @@ function genExpression(node, context, assignment) {
543
612
  let hasMemberExpression = false;
544
613
  if (ids.length) {
545
614
  const [frag, push] = buildCodeFragment();
546
- const isTSNode = ast && compilerDom.TS_NODE_TYPES.includes(ast.type);
547
615
  ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
548
616
  const start = id.start - 1;
549
617
  const end = id.end - 1;
550
618
  const last = ids[i - 1];
551
- if (!(isTSNode && i === 0)) {
552
- const leadingText = content.slice(last ? last.end - 1 : 0, start);
553
- if (leadingText.length) push([leadingText, -3]);
554
- }
619
+ const leadingText = content.slice(last ? last.end - 1 : 0, start);
620
+ if (leadingText.length) push([leadingText, -3]);
555
621
  const source = content.slice(start, end);
556
622
  const parentStack2 = parentStackMap.get(id);
557
623
  const parent = parentStack2[parentStack2.length - 1];
@@ -571,7 +637,7 @@ function genExpression(node, context, assignment) {
571
637
  parentStack2
572
638
  )
573
639
  );
574
- if (i === ids.length - 1 && end < content.length && !isTSNode) {
640
+ if (i === ids.length - 1 && end < content.length) {
575
641
  push([content.slice(end), -3]);
576
642
  }
577
643
  });
@@ -713,8 +779,10 @@ function analyzeExpressions(expressions) {
713
779
  exp.ast === null && registerVariable(exp.content, exp, true);
714
780
  continue;
715
781
  }
782
+ const seenParents = /* @__PURE__ */ new Set();
716
783
  compilerDom.walkIdentifiers(exp.ast, (currentNode, parent, parentStack) => {
717
- if (parent && isMemberExpression(parent)) {
784
+ if (parent && isMemberExpression(parent) && !seenParents.has(parent)) {
785
+ seenParents.add(parent);
718
786
  const memberExp = extractMemberExpression(parent, (id) => {
719
787
  registerVariable(id.name, exp, true, {
720
788
  start: id.start,
@@ -816,7 +884,7 @@ function shouldDeclareVariable(name, expToVariableMap, exps) {
816
884
  }
817
885
  return true;
818
886
  }
819
- if (vars.some((v) => v.some((e) => first.includes(e)))) {
887
+ if (vars.every((v) => v.every((e, idx) => e === first[idx]))) {
820
888
  return false;
821
889
  }
822
890
  return true;
@@ -825,7 +893,9 @@ function processRepeatedExpressions(context, expressions, varDeclarations, updat
825
893
  const declarations = [];
826
894
  const seenExp = expressions.reduce(
827
895
  (acc, exp) => {
828
- const variables = expToVariableMap.get(exp).map((v) => v.name);
896
+ const vars = expToVariableMap.get(exp);
897
+ if (!vars) return acc;
898
+ const variables = vars.map((v) => v.name);
829
899
  if (exp.ast && exp.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v)))) {
830
900
  acc[exp.content] = (acc[exp.content] || 0) + 1;
831
901
  }
@@ -941,19 +1011,25 @@ function extractMemberExpression(exp, onIdentifier) {
941
1011
  const object = extractMemberExpression(exp.object, onIdentifier);
942
1012
  const prop = exp.computed ? `[${extractMemberExpression(exp.property, onIdentifier)}]` : `.${extractMemberExpression(exp.property, shared.NOOP)}`;
943
1013
  return `${object}${prop}`;
1014
+ case "TSNonNullExpression":
1015
+ return `${extractMemberExpression(exp.expression, onIdentifier)}`;
944
1016
  default:
945
1017
  return "";
946
1018
  }
947
1019
  }
948
1020
  const isMemberExpression = (node) => {
949
- return node.type === "MemberExpression" || node.type === "OptionalMemberExpression";
1021
+ return node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "TSNonNullExpression";
950
1022
  };
951
1023
 
952
1024
  function genSetEvent(oper, context) {
953
1025
  const { helper } = context;
954
1026
  const { element, key, keyOverride, value, modifiers, delegate, effect } = oper;
955
1027
  const name = genName();
956
- const handler = genEventHandler(context, value, modifiers);
1028
+ const handler = [
1029
+ `${context.helper("createInvoker")}(`,
1030
+ ...genEventHandler(context, value, modifiers),
1031
+ `)`
1032
+ ];
957
1033
  const eventOptions = genEventOptions();
958
1034
  if (delegate) {
959
1035
  context.delegates.add(key.content);
@@ -1014,7 +1090,14 @@ function genEventHandler(context, value, modifiers = { nonKeys: [], keys: [] },
1014
1090
  if (compilerDom.isMemberExpression(value, context.options)) {
1015
1091
  handlerExp = genExpression(value, context);
1016
1092
  if (!isConstantBinding(value, context) && !extraWrap) {
1017
- handlerExp = [`e => `, ...handlerExp, `(e)`];
1093
+ const isTSNode = value.ast && compilerDom.TS_NODE_TYPES.includes(value.ast.type);
1094
+ handlerExp = [
1095
+ `e => `,
1096
+ isTSNode ? "(" : "",
1097
+ ...handlerExp,
1098
+ isTSNode ? ")" : "",
1099
+ `(e)`
1100
+ ];
1018
1101
  }
1019
1102
  } else if (compilerDom.isFnExpression(value, context.options)) {
1020
1103
  handlerExp = genExpression(value, context);
@@ -1300,12 +1383,12 @@ function matchPatterns(render, keyProp, idMap) {
1300
1383
  const keyOnlyBindingPatterns = [];
1301
1384
  render.effect = render.effect.filter((effect) => {
1302
1385
  if (keyProp !== void 0) {
1303
- const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
1386
+ const selector = matchSelectorPattern(effect, keyProp.content, idMap);
1304
1387
  if (selector) {
1305
1388
  selectorPatterns.push(selector);
1306
1389
  return false;
1307
1390
  }
1308
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
1391
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
1309
1392
  if (keyOnly) {
1310
1393
  keyOnlyBindingPatterns.push(keyOnly);
1311
1394
  return false;
@@ -1318,19 +1401,19 @@ function matchPatterns(render, keyProp, idMap) {
1318
1401
  selectorPatterns
1319
1402
  };
1320
1403
  }
1321
- function matchKeyOnlyBindingPattern(effect, keyAst) {
1404
+ function matchKeyOnlyBindingPattern(effect, key) {
1322
1405
  if (effect.expressions.length === 1) {
1323
- const ast = effect.expressions[0].ast;
1406
+ const { ast, content } = effect.expressions[0];
1324
1407
  if (typeof ast === "object" && ast !== null) {
1325
- if (isKeyOnlyBinding(ast, keyAst)) {
1408
+ if (isKeyOnlyBinding(ast, key, content)) {
1326
1409
  return { effect };
1327
1410
  }
1328
1411
  }
1329
1412
  }
1330
1413
  }
1331
- function matchSelectorPattern(effect, keyAst, idMap) {
1414
+ function matchSelectorPattern(effect, key, idMap) {
1332
1415
  if (effect.expressions.length === 1) {
1333
- const ast = effect.expressions[0].ast;
1416
+ const { ast, content } = effect.expressions[0];
1334
1417
  if (typeof ast === "object" && ast) {
1335
1418
  const matcheds = [];
1336
1419
  estreeWalker.walk(ast, {
@@ -1341,10 +1424,10 @@ function matchSelectorPattern(effect, keyAst, idMap) {
1341
1424
  [left, right],
1342
1425
  [right, left]
1343
1426
  ]) {
1344
- const aIsKey = isKeyOnlyBinding(a, keyAst);
1345
- const bIsKey = isKeyOnlyBinding(b, keyAst);
1427
+ const aIsKey = isKeyOnlyBinding(a, key, content);
1428
+ const bIsKey = isKeyOnlyBinding(b, key, content);
1346
1429
  const bVars = analyzeVariableScopes(b, idMap);
1347
- if (aIsKey && !bIsKey && !bVars.locals.length) {
1430
+ if (aIsKey && !bIsKey && !bVars.length) {
1348
1431
  matcheds.push([a, b]);
1349
1432
  }
1350
1433
  }
@@ -1352,21 +1435,17 @@ function matchSelectorPattern(effect, keyAst, idMap) {
1352
1435
  }
1353
1436
  });
1354
1437
  if (matcheds.length === 1) {
1355
- const [key, selector] = matcheds[0];
1438
+ const [key2, selector] = matcheds[0];
1356
1439
  const content2 = effect.expressions[0].content;
1357
1440
  let hasExtraId = false;
1358
- const parentStackMap = /* @__PURE__ */ new Map();
1359
- const parentStack = [];
1360
1441
  compilerDom.walkIdentifiers(
1361
1442
  ast,
1362
1443
  (id) => {
1363
- if (id.start !== key.start && id.start !== selector.start) {
1444
+ if (id.start !== key2.start && id.start !== selector.start) {
1364
1445
  hasExtraId = true;
1365
1446
  }
1366
- parentStackMap.set(id, parentStack.slice());
1367
1447
  },
1368
- false,
1369
- parentStack
1448
+ false
1370
1449
  );
1371
1450
  if (!hasExtraId) {
1372
1451
  const name = content2.slice(selector.start - 1, selector.end - 1);
@@ -1386,47 +1465,17 @@ function matchSelectorPattern(effect, keyAst, idMap) {
1386
1465
  }
1387
1466
  }
1388
1467
  }
1389
- const content = effect.expressions[0].content;
1390
- if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && compilerDom.isStaticNode(ast.consequent) && compilerDom.isStaticNode(ast.alternate)) {
1391
- const left = ast.test.left;
1392
- const right = ast.test.right;
1393
- for (const [a, b] of [
1394
- [left, right],
1395
- [right, left]
1396
- ]) {
1397
- const aIsKey = isKeyOnlyBinding(a, keyAst);
1398
- const bIsKey = isKeyOnlyBinding(b, keyAst);
1399
- const bVars = analyzeVariableScopes(b, idMap);
1400
- if (aIsKey && !bIsKey && !bVars.locals.length) {
1401
- return {
1402
- effect,
1403
- // @ts-expect-error
1404
- selector: {
1405
- content: content.slice(b.start - 1, b.end - 1),
1406
- ast: b,
1407
- loc: b.loc,
1408
- isStatic: false
1409
- }
1410
- };
1411
- }
1412
- }
1413
- }
1414
1468
  }
1415
1469
  }
1416
1470
  function analyzeVariableScopes(ast, idMap) {
1417
- let globals = [];
1418
1471
  let locals = [];
1419
1472
  const ids = [];
1420
- const parentStackMap = /* @__PURE__ */ new Map();
1421
- const parentStack = [];
1422
1473
  compilerDom.walkIdentifiers(
1423
1474
  ast,
1424
1475
  (id) => {
1425
1476
  ids.push(id);
1426
- parentStackMap.set(id, parentStack.slice());
1427
1477
  },
1428
- false,
1429
- parentStack
1478
+ false
1430
1479
  );
1431
1480
  for (const id of ids) {
1432
1481
  if (shared.isGloballyAllowed(id.name)) {
@@ -1434,17 +1483,15 @@ function analyzeVariableScopes(ast, idMap) {
1434
1483
  }
1435
1484
  if (idMap[id.name]) {
1436
1485
  locals.push(id.name);
1437
- } else {
1438
- globals.push(id.name);
1439
1486
  }
1440
1487
  }
1441
- return { globals, locals };
1488
+ return locals;
1442
1489
  }
1443
- function isKeyOnlyBinding(expr, keyAst) {
1490
+ function isKeyOnlyBinding(expr, key, source) {
1444
1491
  let only = true;
1445
1492
  estreeWalker.walk(expr, {
1446
1493
  enter(node) {
1447
- if (types.isNodesEquivalent(node, keyAst)) {
1494
+ if (source.slice(node.start - 1, node.end - 1) === key) {
1448
1495
  this.skip();
1449
1496
  return;
1450
1497
  }
@@ -1509,7 +1556,8 @@ const helpers = {
1509
1556
  setValue: { name: "setValue" },
1510
1557
  setAttr: { name: "setAttr", needKey: true },
1511
1558
  setProp: { name: "setProp", needKey: true },
1512
- setDOMProp: { name: "setDOMProp", needKey: true }};
1559
+ setDOMProp: { name: "setDOMProp", needKey: true }
1560
+ };
1513
1561
  function genSetProp(oper, context) {
1514
1562
  const { helper } = context;
1515
1563
  const {
@@ -1524,12 +1572,14 @@ function genSetProp(oper, context) {
1524
1572
  [helper(resolvedHelper.name), null],
1525
1573
  `n${oper.element}`,
1526
1574
  resolvedHelper.needKey ? genExpression(key, context) : false,
1527
- propValue
1575
+ propValue,
1576
+ resolvedHelper.isSVG && "true"
1528
1577
  )
1529
1578
  ];
1530
1579
  }
1531
1580
  function genDynamicProps$1(oper, context) {
1532
1581
  const { helper } = context;
1582
+ const isSVG = shared.isSVGTag(oper.tag);
1533
1583
  const values = oper.props.map(
1534
1584
  (props) => Array.isArray(props) ? genLiteralObjectProps(props, context) : props.kind === 1 ? genLiteralObjectProps([props], context) : genExpression(props.value, context)
1535
1585
  );
@@ -1539,7 +1589,7 @@ function genDynamicProps$1(oper, context) {
1539
1589
  helper("setDynamicProps"),
1540
1590
  `n${oper.element}`,
1541
1591
  genMulti(DELIMITERS_ARRAY, ...values),
1542
- oper.root && "true"
1592
+ isSVG && "true"
1543
1593
  )
1544
1594
  ];
1545
1595
  }
@@ -1592,6 +1642,10 @@ function genPropValue(values, context) {
1592
1642
  }
1593
1643
  function getRuntimeHelper(tag, key, modifier) {
1594
1644
  const tagName = tag.toUpperCase();
1645
+ const isSVG = shared.isSVGTag(tag);
1646
+ if (isSVG) {
1647
+ return shared.extend({ isSVG: true }, helpers.setAttr);
1648
+ }
1595
1649
  if (modifier) {
1596
1650
  if (modifier === ".") {
1597
1651
  return getSpecialHelper(key, tagName) || helpers.setDOMProp;
@@ -1606,9 +1660,6 @@ function getRuntimeHelper(tag, key, modifier) {
1606
1660
  if (/aria[A-Z]/.test(key)) {
1607
1661
  return helpers.setDOMProp;
1608
1662
  }
1609
- if (shared.isSVGTag(tag)) {
1610
- return helpers.setAttr;
1611
- }
1612
1663
  if (shared.shouldSetAsAttr(tagName, key) || key.includes("-")) {
1613
1664
  return helpers.setAttr;
1614
1665
  }
@@ -1675,7 +1726,7 @@ function genSetText(oper, context) {
1675
1726
  function combineValues(values, context, jsx) {
1676
1727
  return values.flatMap((value, i) => {
1677
1728
  let exp = genExpression(value, context);
1678
- if (!jsx && getLiteralExpressionValue(value) == null) {
1729
+ if (!jsx && getLiteralExpressionValue(value, true) == null) {
1679
1730
  exp = genCall(context.helper("toDisplayString"), exp);
1680
1731
  }
1681
1732
  if (i > 0) {
@@ -1818,7 +1869,7 @@ function genCreateComponent(operation, context) {
1818
1869
  ...inlineHandlers,
1819
1870
  `const n${operation.id} = `,
1820
1871
  ...genCall(
1821
- operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"),
1872
+ operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.isCustomElement ? helper("createPlainElement") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"),
1822
1873
  tag,
1823
1874
  rawProps,
1824
1875
  rawSlots,
@@ -1828,7 +1879,9 @@ function genCreateComponent(operation, context) {
1828
1879
  ...genDirectivesForElement(operation.id, context)
1829
1880
  ];
1830
1881
  function genTag() {
1831
- if (operation.dynamic) {
1882
+ if (operation.isCustomElement) {
1883
+ return JSON.stringify(operation.tag);
1884
+ } else if (operation.dynamic) {
1832
1885
  if (operation.dynamic.isStatic) {
1833
1886
  return genCall(
1834
1887
  helper("resolveDynamicComponent"),
@@ -1955,7 +2008,7 @@ function genModelEvent(prop, context) {
1955
2008
  function genModelModifiers(prop, context) {
1956
2009
  const { key, modelModifiers } = prop;
1957
2010
  if (!modelModifiers || !modelModifiers.length) return [];
1958
- const modifiersKey = key.isStatic ? key.content === "modelValue" ? [`modelModifiers`] : [`${key.content}Modifiers`] : ["[", ...genExpression(key, context), ' + "Modifiers"]'];
2011
+ const modifiersKey = key.isStatic ? [shared.getModifierPropName(key.content)] : ["[", ...genExpression(key, context), ' + "Modifiers"]'];
1959
2012
  const modifiersVal = genDirectiveModifiers(modelModifiers);
1960
2013
  return [",", NEWLINE, ...modifiersKey, `: () => ({ ${modifiersVal} })`];
1961
2014
  }
@@ -2116,10 +2169,7 @@ function genSlotBlockWithProps(oper, context) {
2116
2169
  `}`
2117
2170
  ];
2118
2171
  }
2119
- if (node.type === 1 && // Not a real component
2120
- !isTeleportTag(node.tag) && // Needs to determine whether to activate/deactivate based on instance.parent being KeepAlive
2121
- !isKeepAliveTag(node.tag) && // Slot updates need to trigger TransitionGroup's onBeforeUpdate/onUpdated hook
2122
- !isTransitionGroupTag(node.tag)) {
2172
+ if (node.type === 1 && !isKeepAliveTag(node.tag)) {
2123
2173
  blockFn = [`${context.helper("withVaporCtx")}(`, ...blockFn, `)`];
2124
2174
  }
2125
2175
  return blockFn;
@@ -2142,8 +2192,6 @@ function genSlotOutlet(oper, context) {
2142
2192
  nameExpr,
2143
2193
  genRawProps(oper.props, context) || "null",
2144
2194
  fallbackArg,
2145
- noSlotted && "undefined",
2146
- // instance
2147
2195
  noSlotted && "true"
2148
2196
  // noSlotted
2149
2197
  )
@@ -2277,19 +2325,29 @@ function genInsertionState(operation, context) {
2277
2325
  ];
2278
2326
  }
2279
2327
 
2280
- function genTemplates(templates, rootIndex, { helper }) {
2281
- return templates.map(
2282
- (template, i) => `const t${i} = ${helper("template")}(${JSON.stringify(
2283
- template
2284
- )}${i === rootIndex ? ", true" : ""})
2328
+ function genTemplates(templates, rootIndexes, context) {
2329
+ const result = [];
2330
+ let i = 0;
2331
+ templates.forEach((ns, template) => {
2332
+ result.push(
2333
+ `const ${context.tName(i)} = ${context.helper("template")}(${JSON.stringify(
2334
+ template
2335
+ ).replace(
2336
+ // replace import expressions with string concatenation
2337
+ IMPORT_EXPR_RE,
2338
+ `" + $1 + "`
2339
+ )}${rootIndexes.has(i) ? ", true" : ns ? ", false" : ""}${ns ? `, ${ns}` : ""})
2285
2340
  `
2286
- ).join("");
2341
+ );
2342
+ i++;
2343
+ });
2344
+ return result.join("");
2287
2345
  }
2288
2346
  function genSelf(dynamic, context) {
2289
2347
  const [frag, push] = buildCodeFragment();
2290
2348
  const { id, template, operation, hasDynamicChild } = dynamic;
2291
2349
  if (id !== void 0 && template !== void 0) {
2292
- push(NEWLINE, `const n${id} = t${template}()`);
2350
+ push(NEWLINE, `const n${id} = ${context.tName(template)}()`);
2293
2351
  push(...genDirectivesForElement(id, context));
2294
2352
  }
2295
2353
  if (operation) {
@@ -2324,7 +2382,7 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2324
2382
  }
2325
2383
  const elementIndex = index + offset;
2326
2384
  const logicalIndex = elementIndex - ifBranchCount + prependCount;
2327
- const variable = id === void 0 ? `p${context.block.tempId++}` : `n${id}`;
2385
+ const variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
2328
2386
  pushBlock(NEWLINE, `const ${variable} = `);
2329
2387
  if (prev) {
2330
2388
  if (elementIndex - prev[1] === 1) {
@@ -2442,18 +2500,34 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2442
2500
  }
2443
2501
  }
2444
2502
 
2503
+ const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/;
2445
2504
  class CodegenContext {
2446
2505
  constructor(ir, options) {
2447
2506
  this.ir = ir;
2448
- this.helpers = /* @__PURE__ */ new Set([]);
2507
+ this.bindingNames = /* @__PURE__ */ new Set();
2508
+ this.helpers = /* @__PURE__ */ new Map();
2449
2509
  this.helper = (name) => {
2450
- this.helpers.add(name);
2451
- return `_${name}`;
2510
+ if (this.helpers.has(name)) {
2511
+ return this.helpers.get(name);
2512
+ }
2513
+ const base = `_${name}`;
2514
+ if (this.bindingNames.size === 0 || !this.bindingNames.has(base)) {
2515
+ this.helpers.set(name, base);
2516
+ return base;
2517
+ }
2518
+ const map = this.nextIdMap.get(base);
2519
+ const alias = `${base}${getNextId(map, 1)}`;
2520
+ this.helpers.set(name, alias);
2521
+ return alias;
2452
2522
  };
2453
2523
  this.delegates = /* @__PURE__ */ new Set();
2454
2524
  this.identifiers = /* @__PURE__ */ Object.create(null);
2455
2525
  this.seenInlineHandlerNames = /* @__PURE__ */ Object.create(null);
2456
2526
  this.scopeLevel = 0;
2527
+ this.templateVars = /* @__PURE__ */ new Map();
2528
+ this.nextIdMap = /* @__PURE__ */ new Map();
2529
+ this.lastIdMap = /* @__PURE__ */ new Map();
2530
+ this.lastTIndex = -1;
2457
2531
  const defaultOptions = {
2458
2532
  mode: "module",
2459
2533
  prefixIdentifiers: true,
@@ -2472,6 +2546,10 @@ class CodegenContext {
2472
2546
  };
2473
2547
  this.options = shared.extend(defaultOptions, options);
2474
2548
  this.block = ir.block;
2549
+ this.bindingNames = new Set(
2550
+ this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []
2551
+ );
2552
+ this.initNextIdMap();
2475
2553
  }
2476
2554
  withId(fn, map) {
2477
2555
  const { identifiers } = this;
@@ -2492,11 +2570,47 @@ class CodegenContext {
2492
2570
  enterScope() {
2493
2571
  return [this.scopeLevel++, () => this.scopeLevel--];
2494
2572
  }
2573
+ initNextIdMap() {
2574
+ if (this.bindingNames.size === 0) return;
2575
+ const map = /* @__PURE__ */ new Map();
2576
+ for (const name of this.bindingNames) {
2577
+ const m = idWithTrailingDigitsRE.exec(name);
2578
+ if (!m) continue;
2579
+ const prefix = m[1];
2580
+ const num = Number(m[2]);
2581
+ let set = map.get(prefix);
2582
+ if (!set) map.set(prefix, set = /* @__PURE__ */ new Set());
2583
+ set.add(num);
2584
+ }
2585
+ for (const [prefix, nums] of map) {
2586
+ this.nextIdMap.set(prefix, buildNextIdMap(nums));
2587
+ }
2588
+ }
2589
+ tName(i) {
2590
+ let name = this.templateVars.get(i);
2591
+ if (name) return name;
2592
+ const map = this.nextIdMap.get("t");
2593
+ let lastId = this.lastIdMap.get("t") || -1;
2594
+ for (let j = this.lastTIndex + 1; j <= i; j++) {
2595
+ this.templateVars.set(
2596
+ j,
2597
+ name = `t${lastId = getNextId(map, Math.max(j, lastId + 1))}`
2598
+ );
2599
+ }
2600
+ this.lastIdMap.set("t", lastId);
2601
+ this.lastTIndex = i;
2602
+ return name;
2603
+ }
2604
+ pName(i) {
2605
+ const map = this.nextIdMap.get("p");
2606
+ let lastId = this.lastIdMap.get("p") || -1;
2607
+ this.lastIdMap.set("p", lastId = getNextId(map, Math.max(i, lastId + 1)));
2608
+ return `p${lastId}`;
2609
+ }
2495
2610
  }
2496
2611
  function generate(ir, options = {}) {
2497
2612
  const [frag, push] = buildCodeFragment();
2498
2613
  const context = new CodegenContext(ir, options);
2499
- const { helpers } = context;
2500
2614
  const { inline, bindingMetadata } = options;
2501
2615
  const functionName = "render";
2502
2616
  const args = ["_ctx"];
@@ -2522,8 +2636,8 @@ function generate(ir, options = {}) {
2522
2636
  push("}");
2523
2637
  }
2524
2638
  const delegates = genDelegates(context);
2525
- const templates = genTemplates(ir.template, ir.rootTemplateIndex, context);
2526
- const imports = genHelperImports(context);
2639
+ const templates = genTemplates(ir.template, ir.rootTemplateIndexes, context);
2640
+ const imports = genHelperImports(context) + genAssetImports(context);
2527
2641
  const preamble = imports + templates + delegates;
2528
2642
  const newlineCount = [...preamble].filter((c) => c === "\n").length;
2529
2643
  if (newlineCount && !inline) {
@@ -2538,7 +2652,7 @@ function generate(ir, options = {}) {
2538
2652
  ast: ir,
2539
2653
  preamble,
2540
2654
  map: map && map.toJSON(),
2541
- helpers
2655
+ helpers: new Set(Array.from(context.helpers.keys()))
2542
2656
  };
2543
2657
  }
2544
2658
  function genDelegates({ delegates, helper }) {
@@ -2547,10 +2661,21 @@ function genDelegates({ delegates, helper }) {
2547
2661
  ...Array.from(delegates).map((v) => `"${v}"`)
2548
2662
  ).join("") + "\n" : "";
2549
2663
  }
2550
- function genHelperImports({ helpers, helper, options }) {
2664
+ function genHelperImports({ helpers, options }) {
2551
2665
  let imports = "";
2552
2666
  if (helpers.size) {
2553
- imports += `import { ${[...helpers].map((h) => `${h} as _${h}`).join(", ")} } from '${options.runtimeModuleName}';
2667
+ imports += `import { ${Array.from(helpers).map(([h, alias]) => `${h} as ${alias}`).join(", ")} } from '${options.runtimeModuleName}';
2668
+ `;
2669
+ }
2670
+ return imports;
2671
+ }
2672
+ function genAssetImports({ ir }) {
2673
+ const assetImports = ir.node.imports;
2674
+ let imports = "";
2675
+ for (const assetImport of assetImports) {
2676
+ const exp = assetImport.exp;
2677
+ const name = exp.content;
2678
+ imports += `import ${name} from '${assetImport.path}';
2554
2679
  `;
2555
2680
  }
2556
2681
  return imports;
@@ -2662,7 +2787,8 @@ const transformElement = (node, context) => {
2662
2787
  ({ node } = context);
2663
2788
  if (!(node.type === 1 && (node.tagType === 0 || node.tagType === 1)))
2664
2789
  return;
2665
- const isComponent = node.tagType === 1;
2790
+ const isCustomElement = !!context.options.isCustomElement(node.tag);
2791
+ const isComponent = node.tagType === 1 || isCustomElement;
2666
2792
  const isDynamicComponent = isComponentTag(node.tag);
2667
2793
  const propsResult = buildProps(
2668
2794
  node,
@@ -2671,18 +2797,15 @@ const transformElement = (node, context) => {
2671
2797
  isDynamicComponent,
2672
2798
  getEffectIndex
2673
2799
  );
2674
- let { parent } = context;
2675
- while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2676
- parent = parent.parent;
2677
- }
2678
- const singleRoot = context.root === parent && parent.node.children.filter((child) => child.type !== 3).length === 1;
2800
+ const singleRoot = isSingleRoot(context);
2679
2801
  if (isComponent) {
2680
2802
  transformComponentElement(
2681
2803
  node,
2682
2804
  propsResult,
2683
2805
  singleRoot,
2684
2806
  context,
2685
- isDynamicComponent
2807
+ isDynamicComponent,
2808
+ isCustomElement
2686
2809
  );
2687
2810
  } else {
2688
2811
  transformNativeElement(
@@ -2695,11 +2818,27 @@ const transformElement = (node, context) => {
2695
2818
  }
2696
2819
  };
2697
2820
  };
2698
- function transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent) {
2821
+ function isSingleRoot(context) {
2822
+ if (context.inVFor) {
2823
+ return false;
2824
+ }
2825
+ let { parent } = context;
2826
+ if (parent && !(compilerDom.hasSingleChild(parent.node) || compilerDom.isSingleIfBlock(parent.node))) {
2827
+ return false;
2828
+ }
2829
+ while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2830
+ parent = parent.parent;
2831
+ if (!(compilerDom.hasSingleChild(parent.node) || compilerDom.isSingleIfBlock(parent.node))) {
2832
+ return false;
2833
+ }
2834
+ }
2835
+ return context.root === parent;
2836
+ }
2837
+ function transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent, isCustomElement) {
2699
2838
  const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
2700
2839
  let { tag } = node;
2701
2840
  let asset = true;
2702
- if (!dynamicComponent) {
2841
+ if (!dynamicComponent && !isCustomElement) {
2703
2842
  const fromSetup = resolveSetupReference(tag, context);
2704
2843
  if (fromSetup) {
2705
2844
  tag = fromSetup;
@@ -2732,10 +2871,11 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2732
2871
  tag,
2733
2872
  props: propsResult[0] ? propsResult[1] : [propsResult[1]],
2734
2873
  asset,
2735
- root: singleRoot && !context.inVFor,
2874
+ root: singleRoot,
2736
2875
  slots: [...context.slots],
2737
2876
  once: context.inVOnce,
2738
- dynamic: dynamicComponent
2877
+ dynamic: dynamicComponent,
2878
+ isCustomElement
2739
2879
  };
2740
2880
  context.slots = [];
2741
2881
  }
@@ -2782,16 +2922,21 @@ function transformNativeElement(node, propsResult, singleRoot, context, getEffec
2782
2922
  type: 3,
2783
2923
  element: context.reference(),
2784
2924
  props: dynamicArgs,
2785
- root: singleRoot
2925
+ tag
2786
2926
  },
2787
2927
  getEffectIndex
2788
2928
  );
2789
2929
  } else {
2790
2930
  for (const prop of propsResult[1]) {
2791
2931
  const { key, values } = prop;
2792
- if (key.isStatic && values.length === 1 && values[0].isStatic && !dynamicKeys.includes(key.content)) {
2932
+ if (context.imports.some(
2933
+ (imported) => values[0].content.includes(imported.exp.content)
2934
+ )) {
2935
+ template += ` ${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
2936
+ } else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
2793
2937
  template += ` ${key.content}`;
2794
- if (values[0].content) template += `="${values[0].content}"`;
2938
+ if (values[0].content)
2939
+ template += `="${values[0].content === "''" ? "" : values[0].content}"`;
2795
2940
  } else {
2796
2941
  dynamicProps.push(key.content);
2797
2942
  context.registerEffect(
@@ -2800,7 +2945,6 @@ function transformNativeElement(node, propsResult, singleRoot, context, getEffec
2800
2945
  type: 2,
2801
2946
  element: context.reference(),
2802
2947
  prop,
2803
- root: singleRoot,
2804
2948
  tag
2805
2949
  },
2806
2950
  getEffectIndex
@@ -2813,7 +2957,7 @@ function transformNativeElement(node, propsResult, singleRoot, context, getEffec
2813
2957
  template += `</${tag}>`;
2814
2958
  }
2815
2959
  if (singleRoot) {
2816
- context.ir.rootTemplateIndex = context.ir.template.length;
2960
+ context.ir.rootTemplateIndexes.add(context.ir.template.size);
2817
2961
  }
2818
2962
  if (context.parent && context.parent.node.type === 1 && !compilerDom.isValidHTMLNesting(context.parent.node.tag, tag)) {
2819
2963
  context.reference();
@@ -3068,7 +3212,8 @@ const transformVBind = (dir, node, context) => {
3068
3212
  );
3069
3213
  exp = compilerDom.createSimpleExpression("", true, loc);
3070
3214
  }
3071
- exp = resolveExpression(exp);
3215
+ const isComponent = node.tagType === 1;
3216
+ exp = resolveExpression(exp, isComponent);
3072
3217
  arg = resolveExpression(arg);
3073
3218
  if (arg.isStatic && isReservedProp(arg.content)) return;
3074
3219
  let camel = false;
@@ -3274,30 +3419,18 @@ function processInterpolation(context) {
3274
3419
  }
3275
3420
  context.template += " ";
3276
3421
  const id = context.reference();
3277
- if (values.length === 0) {
3422
+ if (values.length === 0 || values.every((v) => getLiteralExpressionValue(v) != null) && parentNode.type !== 0) {
3278
3423
  return;
3279
3424
  }
3280
- const nonConstantExps = values.filter((v) => !isConstantExpression(v));
3281
- const isStatic = !nonConstantExps.length || nonConstantExps.every(
3282
- (e) => isStaticExpression(e, context.options.bindingMetadata)
3283
- ) || context.inVOnce;
3284
- if (isStatic) {
3285
- context.registerOperation({
3286
- type: 4,
3287
- element: id,
3288
- values
3289
- });
3290
- } else {
3291
- context.registerEffect(values, {
3292
- type: 4,
3293
- element: id,
3294
- values
3295
- });
3296
- }
3425
+ context.registerEffect(values, {
3426
+ type: 4,
3427
+ element: id,
3428
+ values
3429
+ });
3297
3430
  }
3298
3431
  function processTextContainer(children, context) {
3299
3432
  const values = processTextLikeChildren(children, context);
3300
- const literals = values.map(getLiteralExpressionValue);
3433
+ const literals = values.map((value) => getLiteralExpressionValue(value));
3301
3434
  if (literals.every((l) => l != null)) {
3302
3435
  context.childrenTemplate = literals.map((l) => shared.escapeHtml(String(l)));
3303
3436
  } else {
@@ -3550,7 +3683,7 @@ function processIf(node, dir, context) {
3550
3683
  id: -1,
3551
3684
  condition: dir.exp,
3552
3685
  positive: branch,
3553
- once: context.inVOnce
3686
+ once: context.inVOnce || isStaticExpression(dir.exp, context.options.bindingMetadata)
3554
3687
  };
3555
3688
  }
3556
3689
  return () => onExit();