@vue-jsx-vapor/compiler 2.6.4 → 2.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,63 @@
1
1
  import { parse, parseExpression } from "@babel/parser";
2
- import { NOOP, camelize, canSetValueDirectly, capitalize, extend, isArray, isBuiltInDirective, isGloballyAllowed, isHTMLTag, isSVGTag, isString, isVoidTag, makeMap, remove, shouldSetAsAttr, toHandlerKey } from "@vue/shared";
3
- import { DOMErrorCodes, ErrorCodes, NewlineType, NodeTypes, TS_NODE_TYPES, advancePositionWithClone, advancePositionWithMutation, createCompilerError, createDOMCompilerError, createSimpleExpression, defaultOnError, defaultOnWarn, isConstantNode, isFnExpression, isLiteralWhitelisted, isMemberExpression, isSimpleIdentifier, isStaticProperty, isValidHTMLNesting, locStub, resolveModifiers, toValidAssetId, unwrapTSNode, walkIdentifiers } from "@vue/compiler-dom";
4
- import { walkAST, walkIdentifiers as walkIdentifiers$1 } from "ast-kit";
5
- import { isNodesEquivalent, jsxClosingFragment, jsxExpressionContainer, jsxFragment, jsxOpeningFragment } from "@babel/types";
2
+ import { NOOP, camelize, canSetValueDirectly, capitalize, escapeHtml, extend, isArray, isBuiltInDirective, isGloballyAllowed, isHTMLTag, isSVGTag, isString, isVoidTag, makeMap, remove, shouldSetAsAttr, toHandlerKey } from "@vue/shared";
6
3
  import { SourceMapGenerator } from "source-map-js";
4
+ import { walkAST, walkIdentifiers } from "ast-kit";
7
5
 
6
+ //#region src/utils/error.ts
7
+ let ErrorCodes = /* @__PURE__ */ function(ErrorCodes$1) {
8
+ ErrorCodes$1[ErrorCodes$1["X_V_IF_NO_EXPRESSION"] = 28] = "X_V_IF_NO_EXPRESSION";
9
+ ErrorCodes$1[ErrorCodes$1["X_V_ELSE_NO_ADJACENT_IF"] = 30] = "X_V_ELSE_NO_ADJACENT_IF";
10
+ ErrorCodes$1[ErrorCodes$1["X_V_FOR_NO_EXPRESSION"] = 31] = "X_V_FOR_NO_EXPRESSION";
11
+ ErrorCodes$1[ErrorCodes$1["X_V_FOR_MALFORMED_EXPRESSION"] = 32] = "X_V_FOR_MALFORMED_EXPRESSION";
12
+ ErrorCodes$1[ErrorCodes$1["X_V_ON_NO_EXPRESSION"] = 35] = "X_V_ON_NO_EXPRESSION";
13
+ ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MIXED_SLOT_USAGE"] = 37] = "X_V_SLOT_MIXED_SLOT_USAGE";
14
+ ErrorCodes$1[ErrorCodes$1["X_V_SLOT_DUPLICATE_SLOT_NAMES"] = 38] = "X_V_SLOT_DUPLICATE_SLOT_NAMES";
15
+ ErrorCodes$1[ErrorCodes$1["X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN"] = 39] = "X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN";
16
+ ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MISPLACED"] = 40] = "X_V_SLOT_MISPLACED";
17
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_NO_EXPRESSION"] = 41] = "X_V_MODEL_NO_EXPRESSION";
18
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_MALFORMED_EXPRESSION"] = 42] = "X_V_MODEL_MALFORMED_EXPRESSION";
19
+ ErrorCodes$1[ErrorCodes$1["X_V_HTML_NO_EXPRESSION"] = 53] = "X_V_HTML_NO_EXPRESSION";
20
+ ErrorCodes$1[ErrorCodes$1["X_V_HTML_WITH_CHILDREN"] = 54] = "X_V_HTML_WITH_CHILDREN";
21
+ ErrorCodes$1[ErrorCodes$1["X_V_TEXT_NO_EXPRESSION"] = 55] = "X_V_TEXT_NO_EXPRESSION";
22
+ ErrorCodes$1[ErrorCodes$1["X_V_TEXT_WITH_CHILDREN"] = 56] = "X_V_TEXT_WITH_CHILDREN";
23
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_INVALID_ELEMENT"] = 57] = "X_V_MODEL_ON_INVALID_ELEMENT";
24
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ARG_ON_ELEMENT"] = 58] = "X_V_MODEL_ARG_ON_ELEMENT";
25
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_FILE_INPUT_ELEMENT"] = 59] = "X_V_MODEL_ON_FILE_INPUT_ELEMENT";
26
+ ErrorCodes$1[ErrorCodes$1["X_V_MODEL_UNNECESSARY_VALUE"] = 60] = "X_V_MODEL_UNNECESSARY_VALUE";
27
+ ErrorCodes$1[ErrorCodes$1["X_V_SHOW_NO_EXPRESSION"] = 61] = "X_V_SHOW_NO_EXPRESSION";
28
+ return ErrorCodes$1;
29
+ }({});
30
+ const errorMessages = {
31
+ [ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
32
+ [ErrorCodes.X_V_ELSE_NO_ADJACENT_IF]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
33
+ [ErrorCodes.X_V_FOR_NO_EXPRESSION]: `v-for is missing expression.`,
34
+ [ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
35
+ [ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`,
36
+ [ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE]: "Mixed v-slot usage on both the component and nested <template>. When there are multiple named slots, all slots should use <template> syntax to avoid scope ambiguity.",
37
+ [ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES]: `Duplicate slot names found. `,
38
+ [ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN]: "Extraneous children found when component already has explicitly named default slot. These children will be ignored.",
39
+ [ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
40
+ [ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
41
+ [ErrorCodes.X_V_SLOT_MISPLACED]: `v-slot can only be used on components or <template> tags.`,
42
+ [ErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing expression.`,
43
+ [ErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`,
44
+ [ErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`,
45
+ [ErrorCodes.X_V_TEXT_WITH_CHILDREN]: `v-text will override element children.`,
46
+ [ErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`,
47
+ [ErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
48
+ [ErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
49
+ [ErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
50
+ [ErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`
51
+ };
52
+ function createCompilerError(code, loc, messages, additionalMessage) {
53
+ const msg = (messages || errorMessages)[code] + (additionalMessage || ``);
54
+ const error = new SyntaxError(String(msg));
55
+ error.code = code;
56
+ error.loc = loc;
57
+ return error;
58
+ }
59
+
60
+ //#endregion
8
61
  //#region src/ir/component.ts
9
62
  let IRDynamicPropsKind = /* @__PURE__ */ function(IRDynamicPropsKind$1) {
10
63
  IRDynamicPropsKind$1[IRDynamicPropsKind$1["EXPRESSION"] = 0] = "EXPRESSION";
@@ -67,62 +120,104 @@ function isBlockOperation(op) {
67
120
  }
68
121
 
69
122
  //#endregion
70
- //#region src/transforms/utils.ts
71
- function newDynamic() {
72
- return {
73
- flags: DynamicFlag.REFERENCED,
74
- children: []
75
- };
76
- }
77
- function newBlock(node) {
78
- return {
79
- type: 1,
80
- node,
81
- dynamic: newDynamic(),
82
- effect: [],
83
- operation: [],
84
- returns: [],
85
- tempId: 0
86
- };
123
+ //#region src/utils/ast.ts
124
+ function findProp(expression, key) {
125
+ if (expression?.type === "JSXElement") for (const attr of expression.openingElement.attributes) {
126
+ const name = attr.type === "JSXAttribute" && (attr.name.type === "JSXIdentifier" ? attr.name.name : attr.name.type === "JSXNamespacedName" ? attr.name.namespace.name : "").split("_")[0];
127
+ if (name && (isString(key) ? name === key : key.test(name))) return attr;
128
+ }
87
129
  }
88
- function createBranch(node, context, isVFor) {
89
- context.node = node = wrapFragment(node);
90
- const branch = newBlock(node);
91
- const exitBlock = context.enterBlock(branch, isVFor);
92
- context.reference();
93
- return [branch, exitBlock];
130
+ const TS_NODE_TYPES = [
131
+ "TSAsExpression",
132
+ "TSTypeAssertion",
133
+ "TSNonNullExpression",
134
+ "TSInstantiationExpression",
135
+ "TSSatisfiesExpression"
136
+ ];
137
+ function unwrapTSNode(node) {
138
+ if (TS_NODE_TYPES.includes(node.type)) return unwrapTSNode(node.expression);
139
+ else return node;
94
140
  }
95
- function wrapFragment(node) {
96
- if (node.type === "JSXFragment" || isTemplate(node)) return node;
97
- return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), [node.type === "JSXElement" ? node : jsxExpressionContainer(node)]);
141
+ function isJSXComponent(node) {
142
+ if (node.type !== "JSXElement") return false;
143
+ const { openingElement } = node;
144
+ if (openingElement.name.type === "JSXIdentifier") {
145
+ const name = openingElement.name.name;
146
+ return !isHTMLTag(name) && !isSVGTag(name);
147
+ } else return openingElement.name.type === "JSXMemberExpression";
98
148
  }
99
- const EMPTY_EXPRESSION = createSimpleExpression("", true);
100
- const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node);
101
-
102
- //#endregion
103
- //#region src/utils.ts
104
- function propToExpression(prop, context) {
105
- return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
149
+ function isMemberExpression(exp) {
150
+ if (!exp.ast) return;
151
+ const ret = unwrapTSNode(exp.ast);
152
+ return ret.type === "MemberExpression" || ret.type === "OptionalMemberExpression" || ret.type === "Identifier" && ret.name !== "undefined";
106
153
  }
107
- function isConstantExpression(exp) {
108
- return isLiteralWhitelisted(exp.content) || isGloballyAllowed(exp.content) || getLiteralExpressionValue(exp) !== null;
154
+ function isTemplate(node) {
155
+ if (node.type === "JSXElement" && node.openingElement.name.type === "JSXIdentifier") return node.openingElement.name.name === "template";
109
156
  }
110
- function getLiteralExpressionValue(exp) {
111
- if (exp.ast) {
112
- if ([
113
- "StringLiteral",
114
- "NumericLiteral",
115
- "BigIntLiteral"
116
- ].includes(exp.ast.type)) return exp.ast.value;
117
- else if (exp.ast.type === "TemplateLiteral" && exp.ast.expressions.length === 0) return exp.ast.quasis[0].value.cooked;
157
+ function isStaticNode(node) {
158
+ node = unwrapTSNode(node);
159
+ switch (node.type) {
160
+ case "UnaryExpression": return isStaticNode(node.argument);
161
+ case "LogicalExpression":
162
+ case "BinaryExpression": return isStaticNode(node.left) && isStaticNode(node.right);
163
+ case "ConditionalExpression": return isStaticNode(node.test) && isStaticNode(node.consequent) && isStaticNode(node.alternate);
164
+ case "SequenceExpression":
165
+ case "TemplateLiteral": return node.expressions.every((expr) => isStaticNode(expr));
166
+ case "ParenthesizedExpression": return isStaticNode(node.expression);
167
+ case "StringLiteral":
168
+ case "NumericLiteral":
169
+ case "BooleanLiteral":
170
+ case "NullLiteral":
171
+ case "BigIntLiteral": return true;
172
+ }
173
+ return false;
174
+ }
175
+ function isConstantNode(node) {
176
+ if (isStaticNode(node)) return true;
177
+ node = unwrapTSNode(node);
178
+ switch (node.type) {
179
+ case "Identifier": return node.name === "undefined" || isGloballyAllowed(node.name);
180
+ case "RegExpLiteral": return true;
181
+ case "ObjectExpression": return node.properties.every((prop) => {
182
+ if (prop.type === "ObjectMethod") return false;
183
+ if (prop.type === "SpreadElement") return isConstantNode(prop.argument);
184
+ return (!prop.computed || isConstantNode(prop.key)) && isConstantNode(prop.value);
185
+ });
186
+ case "ArrayExpression": return node.elements.every((element) => {
187
+ if (element === null) return true;
188
+ if (element.type === "SpreadElement") return isConstantNode(element.argument);
189
+ return isConstantNode(element);
190
+ });
118
191
  }
119
- return exp.isStatic ? exp.content : null;
192
+ return false;
120
193
  }
121
- const isConstant = (node) => {
122
- if (!node) return false;
123
- if (node.type === "Identifier") return node.name === "undefined" || isGloballyAllowed(node.name);
124
- return isConstantNode(node, {});
194
+ const isFnExpression = (exp) => {
195
+ try {
196
+ if (!exp.ast) return false;
197
+ let ret = exp.ast;
198
+ if (ret.type === "Program") {
199
+ ret = ret.body[0];
200
+ if (ret.type === "ExpressionStatement") ret = ret.expression;
201
+ }
202
+ ret = unwrapTSNode(ret);
203
+ return ret.type === "FunctionExpression" || ret.type === "ArrowFunctionExpression";
204
+ } catch {
205
+ return false;
206
+ }
125
207
  };
208
+ const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node);
209
+ const isStaticProperty = (node) => !!node && (node.type === "ObjectProperty" || node.type === "ObjectMethod") && !node.computed;
210
+ const nonIdentifierRE = /^$|^\d|[^$\w\u00A0-\uFFFF]/;
211
+ const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
212
+ function getTextLikeValue(node, excludeNumber) {
213
+ node = node.type === "JSXExpressionContainer" ? node.expression : node;
214
+ if (node.type === "StringLiteral") return node.value;
215
+ else if (!excludeNumber && (node.type === "NumericLiteral" || node.type === "BigIntLiteral")) return String(node.value);
216
+ else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return node.quasis[0].value.cooked;
217
+ }
218
+
219
+ //#endregion
220
+ //#region src/utils/text.ts
126
221
  const EMPTY_TEXT_REGEX = /^[\t\v\f \u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[\n\r]\s*$/;
127
222
  const START_EMPTY_TEXT_REGEX = /^\s*[\n\r]/;
128
223
  const END_EMPTY_TEXT_REGEX = /[\n\r]\s*$/;
@@ -136,59 +231,61 @@ function resolveJSXText(node) {
136
231
  function isEmptyText(node) {
137
232
  return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(String(node.extra?.raw)) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression";
138
233
  }
139
- function resolveSimpleExpressionNode(exp) {
140
- if (!exp.isStatic) {
141
- const value = getLiteralExpressionValue(exp);
142
- if (value !== null) return createSimpleExpression(String(value), true, exp.loc);
234
+ function getText(node, content) {
235
+ return content.ir.source.slice(node.start, node.end);
236
+ }
237
+
238
+ //#endregion
239
+ //#region src/utils/expression.ts
240
+ const locStub = {
241
+ start: {
242
+ line: 1,
243
+ column: 0,
244
+ index: 0
245
+ },
246
+ end: {
247
+ line: 1,
248
+ column: 0,
249
+ index: 0
250
+ },
251
+ filename: "",
252
+ identifierName: void 0
253
+ };
254
+ function createSimpleExpression(content, isStatic = false, ast) {
255
+ return {
256
+ loc: ast ? ast.loc : locStub,
257
+ content,
258
+ isStatic,
259
+ ast
260
+ };
261
+ }
262
+ const isLiteralWhitelisted = /* @__PURE__ */ makeMap("true,false,null,this");
263
+ function isConstantExpression(exp) {
264
+ return isLiteralWhitelisted(exp.content) || isGloballyAllowed(exp.content) || getLiteralExpressionValue(exp) !== null;
265
+ }
266
+ function getLiteralExpressionValue(exp) {
267
+ if (exp.ast) {
268
+ const res = getTextLikeValue(exp.ast);
269
+ if (res != null) return res;
143
270
  }
144
- return exp;
271
+ return exp.isStatic ? exp.content : null;
145
272
  }
146
- function resolveExpression(node, context, effect = false) {
147
- if (!node) return createSimpleExpression("", true);
273
+ const EMPTY_EXPRESSION = createSimpleExpression("", true);
274
+ function resolveExpression(node, context) {
275
+ if (!node) return EMPTY_EXPRESSION;
148
276
  node = unwrapTSNode(node.type === "JSXExpressionContainer" ? node.expression : node);
149
277
  const isStatic = node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier";
150
- let source = node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end);
151
- const location = node.loc;
152
- if (source && !isStatic && effect && !isConstant(node)) {
153
- source = `() => (${source})`;
154
- node._offset = 7;
155
- }
156
- return resolveSimpleExpression(source, isStatic, location, isStatic ? void 0 : node);
157
- }
158
- function resolveSimpleExpression(source, isStatic, location, ast) {
159
- const result = createSimpleExpression(source, isStatic, resolveLocation(location, source));
160
- result.ast = ast ?? null;
161
- return result;
162
- }
163
- function resolveLocation(location, context) {
164
- return location ? {
165
- start: {
166
- line: location.start.line,
167
- column: location.start.column + 1,
168
- offset: location.start.index
169
- },
170
- end: {
171
- line: location.end.line,
172
- column: location.end.column + 1,
173
- offset: location.end.index
174
- },
175
- source: isString(context) ? context : context.ir.source.slice(location.start.index, location.end.index)
176
- } : {
177
- start: {
178
- line: 1,
179
- column: 1,
180
- offset: 0
181
- },
182
- end: {
183
- line: 1,
184
- column: 1,
185
- offset: 0
186
- },
187
- source: ""
188
- };
278
+ const source = node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end);
279
+ return createSimpleExpression(source, isStatic, node);
189
280
  }
281
+ function propToExpression(prop, context) {
282
+ return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
283
+ }
284
+
285
+ //#endregion
286
+ //#region src/utils/directive.ts
190
287
  const namespaceRE = /^(?:\$([\w-]+)\$)?([\w-]+)?/;
191
- function resolveDirective(node, context, withFn = false) {
288
+ function resolveDirective(node, context) {
192
289
  const { value, name } = node;
193
290
  let nameString = name.type === "JSXNamespacedName" ? name.namespace.name : name.type === "JSXIdentifier" ? name.name : "";
194
291
  const isDirective = nameString.startsWith("v-");
@@ -208,48 +305,73 @@ function resolveDirective(node, context, withFn = false) {
208
305
  } else if (modifierString) [argString, ...modifiers] = modifierString.split("_");
209
306
  }
210
307
  }
211
- const arg = isDirective ? argString && name.type === "JSXNamespacedName" ? resolveSimpleExpression(argString, isStatic, name.name.loc) : void 0 : resolveSimpleExpression(nameString, true, name.loc);
212
- const exp = value ? withFn && value.type === "JSXExpressionContainer" ? resolveExpressionWithFn(value.expression, context) : resolveExpression(value, context) : void 0;
308
+ const arg = isDirective ? argString && name.type === "JSXNamespacedName" ? createSimpleExpression(argString, isStatic, name.name) : void 0 : createSimpleExpression(nameString, true, name);
309
+ const exp = value ? resolveExpression(value, context) : void 0;
213
310
  return {
214
- type: NodeTypes.DIRECTIVE,
215
311
  name: isDirective ? nameString.slice(2) : "bind",
216
312
  rawName: getText(name, context),
217
313
  exp,
218
314
  arg,
219
- loc: resolveLocation(node.loc, context),
315
+ loc: node.loc,
220
316
  modifiers: modifiers.map((modifier) => createSimpleExpression(modifier))
221
317
  };
222
318
  }
223
- function resolveExpressionWithFn(node, context) {
224
- const text = getText(node, context);
225
- return node.type === "Identifier" ? resolveSimpleExpression(text, false, node.loc) : resolveSimpleExpression(text, false, node.loc, parseExpression(`(${text})=>{}`, { plugins: context.options.expressionPlugins }));
226
- }
227
- function isJSXComponent(node) {
228
- if (node.type !== "JSXElement") return false;
229
- const { openingElement } = node;
230
- if (openingElement.name.type === "JSXIdentifier") {
231
- const name = openingElement.name.name;
232
- return !isHTMLTag(name) && !isSVGTag(name);
233
- } else return openingElement.name.type === "JSXMemberExpression";
319
+
320
+ //#endregion
321
+ //#region src/utils/transform.ts
322
+ function newDynamic() {
323
+ return {
324
+ flags: DynamicFlag.REFERENCED,
325
+ children: []
326
+ };
234
327
  }
235
- function findProp(expression, key) {
236
- if (expression?.type === "JSXElement") for (const attr of expression.openingElement.attributes) {
237
- const name = attr.type === "JSXAttribute" && (attr.name.type === "JSXIdentifier" ? attr.name.name : attr.name.type === "JSXNamespacedName" ? attr.name.namespace.name : "").split("_")[0];
238
- if (name && (isString(key) ? name === key : key.test(name))) return attr;
239
- }
328
+ function newBlock(node) {
329
+ return {
330
+ type: 1,
331
+ node,
332
+ dynamic: newDynamic(),
333
+ effect: [],
334
+ operation: [],
335
+ returns: [],
336
+ tempId: 0
337
+ };
240
338
  }
241
- function getText(node, content) {
242
- return content.ir.source.slice(node.start, node.end);
339
+ function createBranch(node, context, isVFor) {
340
+ context.node = node = wrapFragment(node);
341
+ const branch = newBlock(node);
342
+ const exitBlock = context.enterBlock(branch, isVFor);
343
+ context.reference();
344
+ return [branch, exitBlock];
243
345
  }
244
- function isTemplate(node) {
245
- if (node.type === "JSXElement" && node.openingElement.name.type === "JSXIdentifier") return node.openingElement.name.name === "template";
346
+ function wrapFragment(node) {
347
+ if (node.type === "JSXFragment" || isTemplate(node)) return node;
348
+ return {
349
+ type: "JSXFragment",
350
+ openingFragment: { type: "JSXOpeningFragment" },
351
+ closingFragment: { type: "JSXClosingFragment" },
352
+ children: [node.type === "JSXElement" ? node : {
353
+ type: "JSXExpressionContainer",
354
+ expression: node
355
+ }]
356
+ };
246
357
  }
247
358
 
248
359
  //#endregion
249
- //#region src/generators/utils.ts
360
+ //#region src/utils/generate.ts
250
361
  const NEWLINE = Symbol(`newline`);
251
362
  const INDENT_START = Symbol(`indent start`);
252
363
  const INDENT_END = Symbol(`indent end`);
364
+ let NewlineType = /* @__PURE__ */ function(NewlineType$1) {
365
+ /** Start with `\n` */
366
+ NewlineType$1[NewlineType$1["Start"] = 0] = "Start";
367
+ /** Ends with `\n` */
368
+ NewlineType$1[NewlineType$1["End"] = -1] = "End";
369
+ /** No `\n` included */
370
+ NewlineType$1[NewlineType$1["None"] = -2] = "None";
371
+ /** Don't know, calc it */
372
+ NewlineType$1[NewlineType$1["Unknown"] = -3] = "Unknown";
373
+ return NewlineType$1;
374
+ }({});
253
375
  function buildCodeFragment(...frag) {
254
376
  const push = frag.push.bind(frag);
255
377
  const unshift = frag.unshift.bind(frag);
@@ -335,8 +457,8 @@ function codeFragmentToString(code, context) {
335
457
  let codegen = "";
336
458
  const pos = {
337
459
  line: 1,
338
- column: 1,
339
- offset: 0
460
+ column: 0,
461
+ index: 0
340
462
  };
341
463
  let indentLevel = 0;
342
464
  for (let frag of code) {
@@ -356,7 +478,7 @@ function codeFragmentToString(code, context) {
356
478
  if (loc) addMapping(loc.start, name);
357
479
  if (newlineIndex === NewlineType.Unknown) advancePositionWithMutation(pos, code$1);
358
480
  else {
359
- pos.offset += code$1.length;
481
+ pos.index += code$1.length;
360
482
  if (newlineIndex === NewlineType.None) pos.column += code$1.length;
361
483
  else {
362
484
  if (newlineIndex === NewlineType.End) newlineIndex = code$1.length - 1;
@@ -373,7 +495,7 @@ function codeFragmentToString(code, context) {
373
495
  if (name !== null && !_names.has(name)) _names.add(name);
374
496
  _mappings.add({
375
497
  originalLine: loc.line,
376
- originalColumn: loc.column - 1,
498
+ originalColumn: loc.column,
377
499
  generatedLine: pos.line,
378
500
  generatedColumn: pos.column - 1,
379
501
  source: filename,
@@ -381,26 +503,238 @@ function codeFragmentToString(code, context) {
381
503
  });
382
504
  }
383
505
  }
506
+ function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
507
+ let linesCount = 0;
508
+ let lastNewLinePos = -1;
509
+ for (let i = 0; i < numberOfCharacters; i++) if (source.charCodeAt(i) === 10) {
510
+ linesCount++;
511
+ lastNewLinePos = i;
512
+ }
513
+ pos.index += numberOfCharacters;
514
+ pos.line += linesCount;
515
+ pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos;
516
+ return pos;
517
+ }
518
+ function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
519
+ return advancePositionWithMutation({
520
+ index: pos.index,
521
+ line: pos.line,
522
+ column: pos.column
523
+ }, source, numberOfCharacters);
524
+ }
525
+
526
+ //#endregion
527
+ //#region src/utils/dom.ts
528
+ /**
529
+ * Copied from https://github.com/MananTank/validate-html-nesting
530
+ * with ISC license
531
+ *
532
+ * To avoid runtime dependency on validate-html-nesting
533
+ * This file should not change very often in the original repo
534
+ * but we may need to keep it up-to-date from time to time.
535
+ */
536
+ /**
537
+ * returns true if given parent-child nesting is valid HTML
538
+ */
539
+ function isValidHTMLNesting(parent, child) {
540
+ if (parent === "template") return true;
541
+ if (parent in onlyValidChildren) return onlyValidChildren[parent].has(child);
542
+ if (child in onlyValidParents) return onlyValidParents[child].has(parent);
543
+ if (parent in knownInvalidChildren && knownInvalidChildren[parent].has(child)) return false;
544
+ if (child in knownInvalidParents && knownInvalidParents[child].has(parent)) return false;
545
+ return true;
546
+ }
547
+ const headings = new Set([
548
+ "h1",
549
+ "h2",
550
+ "h3",
551
+ "h4",
552
+ "h5",
553
+ "h6"
554
+ ]);
555
+ const emptySet = new Set([]);
556
+ /**
557
+ * maps element to set of elements that can be it's children, no other */
558
+ const onlyValidChildren = {
559
+ head: new Set([
560
+ "base",
561
+ "basefront",
562
+ "bgsound",
563
+ "link",
564
+ "meta",
565
+ "title",
566
+ "noscript",
567
+ "noframes",
568
+ "style",
569
+ "script",
570
+ "template"
571
+ ]),
572
+ optgroup: new Set(["option"]),
573
+ select: new Set([
574
+ "optgroup",
575
+ "option",
576
+ "hr"
577
+ ]),
578
+ table: new Set([
579
+ "caption",
580
+ "colgroup",
581
+ "tbody",
582
+ "tfoot",
583
+ "thead"
584
+ ]),
585
+ tr: new Set(["td", "th"]),
586
+ colgroup: new Set(["col"]),
587
+ tbody: new Set(["tr"]),
588
+ thead: new Set(["tr"]),
589
+ tfoot: new Set(["tr"]),
590
+ script: emptySet,
591
+ iframe: emptySet,
592
+ option: emptySet,
593
+ textarea: emptySet,
594
+ style: emptySet,
595
+ title: emptySet
596
+ };
597
+ /** maps elements to set of elements which can be it's parent, no other */
598
+ const onlyValidParents = {
599
+ html: emptySet,
600
+ body: new Set(["html"]),
601
+ head: new Set(["html"]),
602
+ td: new Set(["tr"]),
603
+ colgroup: new Set(["table"]),
604
+ caption: new Set(["table"]),
605
+ tbody: new Set(["table"]),
606
+ tfoot: new Set(["table"]),
607
+ col: new Set(["colgroup"]),
608
+ th: new Set(["tr"]),
609
+ thead: new Set(["table"]),
610
+ tr: new Set([
611
+ "tbody",
612
+ "thead",
613
+ "tfoot"
614
+ ]),
615
+ dd: new Set(["dl", "div"]),
616
+ dt: new Set(["dl", "div"]),
617
+ figcaption: new Set(["figure"]),
618
+ summary: new Set(["details"]),
619
+ area: new Set(["map"])
620
+ };
621
+ /** maps element to set of elements that can not be it's children, others can */
622
+ const knownInvalidChildren = {
623
+ p: new Set([
624
+ "address",
625
+ "article",
626
+ "aside",
627
+ "blockquote",
628
+ "center",
629
+ "details",
630
+ "dialog",
631
+ "dir",
632
+ "div",
633
+ "dl",
634
+ "fieldset",
635
+ "figure",
636
+ "footer",
637
+ "form",
638
+ "h1",
639
+ "h2",
640
+ "h3",
641
+ "h4",
642
+ "h5",
643
+ "h6",
644
+ "header",
645
+ "hgroup",
646
+ "hr",
647
+ "li",
648
+ "main",
649
+ "nav",
650
+ "menu",
651
+ "ol",
652
+ "p",
653
+ "pre",
654
+ "section",
655
+ "table",
656
+ "ul"
657
+ ]),
658
+ svg: new Set([
659
+ "b",
660
+ "blockquote",
661
+ "br",
662
+ "code",
663
+ "dd",
664
+ "div",
665
+ "dl",
666
+ "dt",
667
+ "em",
668
+ "embed",
669
+ "h1",
670
+ "h2",
671
+ "h3",
672
+ "h4",
673
+ "h5",
674
+ "h6",
675
+ "hr",
676
+ "i",
677
+ "img",
678
+ "li",
679
+ "menu",
680
+ "meta",
681
+ "ol",
682
+ "p",
683
+ "pre",
684
+ "ruby",
685
+ "s",
686
+ "small",
687
+ "span",
688
+ "strong",
689
+ "sub",
690
+ "sup",
691
+ "table",
692
+ "u",
693
+ "ul",
694
+ "var"
695
+ ])
696
+ };
697
+ /** maps element to set of elements that can not be it's parent, others can */
698
+ const knownInvalidParents = {
699
+ a: new Set(["a"]),
700
+ button: new Set(["button"]),
701
+ dd: new Set(["dd", "dt"]),
702
+ dt: new Set(["dd", "dt"]),
703
+ form: new Set(["form"]),
704
+ li: new Set(["li"]),
705
+ h1: headings,
706
+ h2: headings,
707
+ h3: headings,
708
+ h4: headings,
709
+ h5: headings,
710
+ h6: headings
711
+ };
712
+ function toValidAssetId(name, type) {
713
+ return `_${type}_${name.replaceAll(/\W/g, (searchValue, replaceValue) => {
714
+ return searchValue === "-" ? "_" : name.charCodeAt(replaceValue).toString();
715
+ })}`;
716
+ }
384
717
 
385
718
  //#endregion
386
719
  //#region src/generators/expression.ts
387
- function genExpression(node, context, assignment) {
388
- const { content, ast, isStatic, loc } = node;
720
+ function genExpression(node, context, assignment, needWrap = false) {
721
+ let { content, ast, isStatic, loc } = node;
722
+ if (needWrap) content = `() => (${content})`;
389
723
  if (isStatic) return [[
390
724
  JSON.stringify(content),
391
725
  NewlineType.None,
392
726
  loc
393
727
  ]];
394
- if (!node.content.trim() || ast === false || isConstantExpression(node)) return [[
728
+ if (!node.content.trim() || isConstantExpression(node)) return [[
395
729
  content,
396
730
  NewlineType.None,
397
731
  loc
398
732
  ], assignment && ` = ${assignment}`];
399
- if (ast === null) return genIdentifier(content, context, loc, assignment);
733
+ if (!ast) return genIdentifier(content, context, loc, assignment);
400
734
  const ids = [];
401
735
  const parentStackMap = /* @__PURE__ */ new Map();
402
736
  const parentStack = [];
403
- walkIdentifiers$1(ast, (id) => {
737
+ walkIdentifiers(ast, (id) => {
404
738
  ids.push(id);
405
739
  parentStackMap.set(id, parentStack.slice());
406
740
  }, false, parentStack);
@@ -408,7 +742,7 @@ function genExpression(node, context, assignment) {
408
742
  if (ids.length) {
409
743
  const [frag, push] = buildCodeFragment();
410
744
  const isTSNode = ast && TS_NODE_TYPES.includes(ast.type);
411
- const offset = (ast?.start ? ast.start - 1 : 0) - (ast._offset || 0);
745
+ const offset = (ast?.start ? ast.start - 1 : 0) - (needWrap ? 7 : 0);
412
746
  ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
413
747
  const start = id.start - 1 - offset;
414
748
  const end = id.end - 1 - offset;
@@ -424,7 +758,8 @@ function genExpression(node, context, assignment) {
424
758
  push(...genIdentifier(source, context, {
425
759
  start: advancePositionWithClone(node.loc.start, source, start),
426
760
  end: advancePositionWithClone(node.loc.start, source, end),
427
- source
761
+ filename: "",
762
+ identifierName: void 0
428
763
  }, hasMemberExpression ? void 0 : assignment, parent));
429
764
  if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end), NewlineType.Unknown]);
430
765
  });
@@ -487,7 +822,7 @@ function genVModel(oper, context) {
487
822
  }
488
823
  function genModelHandler(exp, context) {
489
824
  return [
490
- `${context.options.isTS ? `(_value: any)` : `_value`} => (`,
825
+ "_value => (",
491
826
  ...genExpression(exp, context, "_value"),
492
827
  ")"
493
828
  ];
@@ -528,7 +863,7 @@ function genCustomDirectives(opers, context) {
528
863
  const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems);
529
864
  return [NEWLINE, ...genCall(helper("withVaporDirectives"), element, directives)];
530
865
  function genDirectiveItem({ dir, name, asset }) {
531
- const directiveVar = asset ? toValidAssetId(name, "directive") : genExpression(extend(createSimpleExpression(name, false), { ast: null }), context);
866
+ const directiveVar = asset ? toValidAssetId(name, "directive") : genExpression(createSimpleExpression(name), context);
532
867
  const value = dir.exp && ["() => ", ...genExpression(dir.exp, context)];
533
868
  const argument = dir.arg && genExpression(dir.arg, context);
534
869
  const modifiers = !!dir.modifiers.length && [
@@ -598,22 +933,20 @@ function genEventHandler(context, value, modifiers = {
598
933
  keys: []
599
934
  }, extraWrap = false) {
600
935
  let handlerExp = [`() => {}`];
601
- if (value && value.content.trim()) if (isMemberExpression(value, context.options)) {
936
+ if (value && value.content.trim()) if (isMemberExpression(value)) {
602
937
  handlerExp = genExpression(value, context);
603
938
  if (!extraWrap) handlerExp = [
604
939
  `e => `,
605
940
  ...handlerExp,
606
941
  `(e)`
607
942
  ];
608
- } else if (isFnExpression(value, context.options)) handlerExp = genExpression(value, context);
943
+ } else if (isFnExpression(value)) handlerExp = genExpression(value, context);
609
944
  else {
610
- const referencesEvent = value.content.includes("$event");
611
945
  const hasMultipleStatements = value.content.includes(`;`);
612
- const expr = referencesEvent ? context.withId(() => genExpression(value, context), { $event: null }) : genExpression(value, context);
613
946
  handlerExp = [
614
- referencesEvent ? "$event => " : "() => ",
947
+ "() => ",
615
948
  hasMultipleStatements ? "{" : "(",
616
- ...expr,
949
+ ...genExpression(value, context),
617
950
  hasMultipleStatements ? "}" : ")"
618
951
  ];
619
952
  }
@@ -738,7 +1071,7 @@ function genCreateComponent(operation, context) {
738
1071
  ")"
739
1072
  ];
740
1073
  else if (operation.asset) return toValidAssetId(operation.tag, "component");
741
- else return genExpression(extend(createSimpleExpression(operation.tag, false), { ast: null }), context);
1074
+ else return genExpression(createSimpleExpression(operation.tag), context);
742
1075
  }
743
1076
  }
744
1077
  function genRawProps(props, context) {
@@ -907,8 +1240,8 @@ function genSlotBlockWithProps(oper, context) {
907
1240
  if (isDestructureAssignment = !!props.ast) {
908
1241
  [depth, exitScope] = context.enterScope();
909
1242
  propsName = `_slotProps${depth}`;
910
- walkIdentifiers$1(props.ast, (id, _, __, ___, isLocal) => {
911
- if (isLocal) idsOfProps.add(id.name);
1243
+ walkIdentifiers(props.ast, (id, _, __, isReference, isLocal) => {
1244
+ if (isReference && !isLocal) idsOfProps.add(id.name);
912
1245
  }, true);
913
1246
  } else idsOfProps.add(propsName = rawProps);
914
1247
  }
@@ -978,8 +1311,7 @@ function genFor(oper, context) {
978
1311
  }
979
1312
  if (pathInfo.dynamic) {
980
1313
  const node = idMap[id$1] = createSimpleExpression(path);
981
- const plugins = context.options.expressionPlugins;
982
- node.ast = parseExpression(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] });
1314
+ node.ast = parseExpression(`(${path})`, { plugins: context.options.expressionPlugins });
983
1315
  } else idMap[id$1] = path;
984
1316
  } else idMap[id$1] = path;
985
1317
  });
@@ -996,7 +1328,7 @@ function genFor(oper, context) {
996
1328
  idMap[rawIndex] = `${indexVar}.value`;
997
1329
  idMap[indexVar] = null;
998
1330
  }
999
- const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
1331
+ const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap, context.ir.source);
1000
1332
  const selectorDeclarations = [];
1001
1333
  const selectorSetup = [];
1002
1334
  for (const [i, { selector }] of selectorPatterns.entries()) {
@@ -1038,8 +1370,8 @@ function genFor(oper, context) {
1038
1370
  const map = /* @__PURE__ */ new Map();
1039
1371
  if (value) {
1040
1372
  rawValue = value && value.content;
1041
- if (value.ast) walkIdentifiers(value.ast, (id$1, _, parentStack, ___, isLocal) => {
1042
- if (isLocal) {
1373
+ if (value.ast && value.ast.type !== "Identifier") walkIdentifiers(value.ast, (id$1, _, parentStack, isReference, isLocal) => {
1374
+ if (isReference && !isLocal) {
1043
1375
  let path = "";
1044
1376
  let isDynamic = false;
1045
1377
  let helper$1;
@@ -1052,11 +1384,11 @@ function genFor(oper, context) {
1052
1384
  isDynamic = true;
1053
1385
  path += `[${value.content.slice(parent.key.start - 1, parent.key.end - 1)}]`;
1054
1386
  } else path += `.${parent.key.name}`;
1055
- else if (parent.type === "ArrayPattern") {
1387
+ else if (parent.type === "ArrayExpression") {
1056
1388
  const index$1 = parent.elements.indexOf(child);
1057
- if (child.type === "RestElement") path += `.slice(${index$1})`;
1389
+ if (child.type === "SpreadElement") path += `.slice(${index$1})`;
1058
1390
  else path += `[${index$1}]`;
1059
- } else if (parent.type === "ObjectPattern" && child.type === "RestElement") {
1391
+ } else if (parent.type === "ObjectExpression" && child.type === "SpreadElement") {
1060
1392
  helper$1 = context.helper("getRestElement");
1061
1393
  helperArgs = `[${parent.properties.filter((p) => p.type === "ObjectProperty").map((p) => {
1062
1394
  if (p.key.type === "StringLiteral") return JSON.stringify(p.key.value);
@@ -1066,11 +1398,6 @@ function genFor(oper, context) {
1066
1398
  } else return JSON.stringify(p.key.name);
1067
1399
  }).join(", ")}]`;
1068
1400
  }
1069
- if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
1070
- isDynamic = true;
1071
- helper$1 = context.helper("getDefaultValue");
1072
- helperArgs = value.content.slice(child.right.start - 1, child.right.end - 1);
1073
- }
1074
1401
  }
1075
1402
  map.set(id$1.name, {
1076
1403
  path,
@@ -1106,17 +1433,17 @@ function genFor(oper, context) {
1106
1433
  return idMap$1;
1107
1434
  }
1108
1435
  }
1109
- function matchPatterns(render, keyProp, idMap) {
1436
+ function matchPatterns(render, keyProp, idMap, source) {
1110
1437
  const selectorPatterns = [];
1111
1438
  const keyOnlyBindingPatterns = [];
1112
1439
  render.effect = render.effect.filter((effect) => {
1113
1440
  if (keyProp !== void 0) {
1114
- const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
1441
+ const selector = matchSelectorPattern(effect, keyProp.content, idMap, source);
1115
1442
  if (selector) {
1116
1443
  selectorPatterns.push(selector);
1117
1444
  return false;
1118
1445
  }
1119
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
1446
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content, source);
1120
1447
  if (keyOnly) {
1121
1448
  keyOnlyBindingPatterns.push(keyOnly);
1122
1449
  return false;
@@ -1129,37 +1456,37 @@ function matchPatterns(render, keyProp, idMap) {
1129
1456
  selectorPatterns
1130
1457
  };
1131
1458
  }
1132
- function matchKeyOnlyBindingPattern(effect, keyAst) {
1459
+ function matchKeyOnlyBindingPattern(effect, key, source) {
1133
1460
  if (effect.expressions.length === 1) {
1134
1461
  const ast = effect.expressions[0].ast;
1135
- if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, keyAst)) return { effect };
1462
+ if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, key, source)) return { effect };
1136
1463
  }
1137
1464
  }
1138
- function matchSelectorPattern(effect, keyAst, idMap) {
1465
+ function matchSelectorPattern(effect, key, idMap, source) {
1139
1466
  if (effect.expressions.length === 1) {
1140
1467
  const ast = effect.expressions[0].ast;
1141
- const offset = effect.expressions[0].loc.start.offset;
1468
+ const offset = effect.expressions[0].loc.start.index;
1142
1469
  if (typeof ast === "object" && ast) {
1143
1470
  const matcheds = [];
1144
1471
  walkAST(ast, { enter(node) {
1145
1472
  if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
1146
1473
  const { left, right } = node;
1147
1474
  for (const [a, b] of [[left, right], [right, left]]) {
1148
- const aIsKey = isKeyOnlyBinding(a, keyAst);
1149
- const bIsKey = isKeyOnlyBinding(b, keyAst);
1475
+ const aIsKey = isKeyOnlyBinding(a, key, source);
1476
+ const bIsKey = isKeyOnlyBinding(b, key, source);
1150
1477
  const bVars = analyzeVariableScopes(b, idMap);
1151
1478
  if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]);
1152
1479
  }
1153
1480
  }
1154
1481
  } });
1155
1482
  if (matcheds.length === 1) {
1156
- const [key, selector] = matcheds[0];
1483
+ const [key$1, selector] = matcheds[0];
1157
1484
  const content$1 = effect.expressions[0].content;
1158
1485
  let hasExtraId = false;
1159
1486
  const parentStackMap = /* @__PURE__ */ new Map();
1160
1487
  const parentStack = [];
1161
1488
  walkIdentifiers(ast, (id) => {
1162
- if (id.start !== key.start && id.start !== selector.start) hasExtraId = true;
1489
+ if (id.start !== key$1.start && id.start !== selector.start) hasExtraId = true;
1163
1490
  parentStackMap.set(id, parentStack.slice());
1164
1491
  }, false, parentStack);
1165
1492
  if (!hasExtraId) {
@@ -1180,12 +1507,12 @@ function matchSelectorPattern(effect, keyAst, idMap) {
1180
1507
  }
1181
1508
  }
1182
1509
  const content = effect.expressions[0].content;
1183
- if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && isConstant(ast.consequent) && isConstant(ast.alternate)) {
1510
+ if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && isConstantNode(ast.consequent) && isConstantNode(ast.alternate)) {
1184
1511
  const left = ast.test.left;
1185
1512
  const right = ast.test.right;
1186
1513
  for (const [a, b] of [[left, right], [right, left]]) {
1187
- const aIsKey = isKeyOnlyBinding(a, keyAst);
1188
- const bIsKey = isKeyOnlyBinding(b, keyAst);
1514
+ const aIsKey = isKeyOnlyBinding(a, key, source);
1515
+ const bIsKey = isKeyOnlyBinding(b, key, source);
1189
1516
  const bVars = analyzeVariableScopes(b, idMap);
1190
1517
  if (aIsKey && !bIsKey && !bVars.locals.length) return {
1191
1518
  effect,
@@ -1220,10 +1547,10 @@ function analyzeVariableScopes(ast, idMap) {
1220
1547
  locals
1221
1548
  };
1222
1549
  }
1223
- function isKeyOnlyBinding(expr, keyAst) {
1550
+ function isKeyOnlyBinding(expr, key, source) {
1224
1551
  let only = true;
1225
1552
  walkAST(expr, { enter(node) {
1226
- if (isNodesEquivalent(node, keyAst)) {
1553
+ if (source.slice(node.start, node.end) === key) {
1227
1554
  this.skip();
1228
1555
  return;
1229
1556
  }
@@ -1279,7 +1606,7 @@ function genDeclareOldRef(oper) {
1279
1606
  function genSetText(oper, context) {
1280
1607
  const { helper } = context;
1281
1608
  const { element, values, generated } = oper;
1282
- const texts = combineValues(values, context, true);
1609
+ const texts = combineValues(values, context, true, true);
1283
1610
  return [NEWLINE, ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)];
1284
1611
  }
1285
1612
  function genGetTextChild(oper, context) {
@@ -1287,21 +1614,22 @@ function genGetTextChild(oper, context) {
1287
1614
  }
1288
1615
  function genSetNodes(oper, context) {
1289
1616
  const { helper } = context;
1290
- const { element, values, generated } = oper;
1291
- return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context))];
1617
+ const { element, values, generated, once } = oper;
1618
+ return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context, once))];
1292
1619
  }
1293
1620
  function genCreateNodes(oper, context) {
1294
1621
  const { helper } = context;
1295
- const { id, values } = oper;
1622
+ const { id, values, once } = oper;
1296
1623
  return [
1297
1624
  NEWLINE,
1298
1625
  `const n${id} = `,
1299
- ...genCall(helper("createNodes"), values && combineValues(values, context))
1626
+ ...genCall(helper("createNodes"), values && combineValues(values, context, once))
1300
1627
  ];
1301
1628
  }
1302
- function combineValues(values, context, setText) {
1629
+ function combineValues(values, context, once, setText) {
1303
1630
  return values.flatMap((value, i) => {
1304
- let exp = genExpression(value, context);
1631
+ const { content, isStatic, ast } = value;
1632
+ let exp = genExpression(value, context, void 0, !once && !setText && !!content && !isStatic && !!ast && !isConstantNode(ast));
1305
1633
  if (setText && getLiteralExpressionValue(value) == null) exp = genCall(context.helper("toDisplayString"), exp);
1306
1634
  if (i > 0) exp.unshift(setText ? " + " : ", ");
1307
1635
  return exp;
@@ -1508,18 +1836,10 @@ var CodegenContext = class {
1508
1836
  constructor(ir, options) {
1509
1837
  this.ir = ir;
1510
1838
  const defaultOptions$1 = {
1511
- mode: "module",
1512
1839
  sourceMap: false,
1513
- filename: `template.vue.html`,
1514
- scopeId: null,
1515
- runtimeGlobalName: `Vue`,
1516
- runtimeModuleName: `vue`,
1517
- ssrRuntimeModuleName: "vue/server-renderer",
1518
- ssr: false,
1519
- isTS: false,
1520
- inSSR: false,
1521
- templates: [],
1522
- expressionPlugins: []
1840
+ filename: `index.jsx`,
1841
+ expressionPlugins: ["jsx"],
1842
+ templates: []
1523
1843
  };
1524
1844
  this.options = extend(defaultOptions$1, options);
1525
1845
  this.block = ir.block;
@@ -1550,26 +1870,18 @@ function generate(ir, options = {}) {
1550
1870
  //#region src/transform.ts
1551
1871
  const defaultOptions = {
1552
1872
  source: "",
1553
- filename: "",
1554
- hoistStatic: false,
1555
- hmr: false,
1556
- cacheHandlers: false,
1873
+ sourceMap: false,
1874
+ filename: "index.jsx",
1557
1875
  nodeTransforms: [],
1558
1876
  directiveTransforms: {},
1559
1877
  templates: [],
1560
- transformHoist: null,
1561
- isBuiltInComponent: NOOP,
1562
1878
  isCustomElement: NOOP,
1563
1879
  expressionPlugins: [],
1564
- scopeId: null,
1565
- slotted: true,
1566
- ssr: false,
1567
- inSSR: false,
1568
- ssrCssVars: ``,
1569
1880
  isTS: false,
1570
1881
  withFallback: false,
1571
- onError: defaultOnError,
1572
- onWarn: defaultOnWarn
1882
+ onError: (error) => {
1883
+ throw error;
1884
+ }
1573
1885
  };
1574
1886
  var TransformContext = class TransformContext {
1575
1887
  parent = null;
@@ -1582,7 +1894,6 @@ var TransformContext = class TransformContext {
1582
1894
  dynamic;
1583
1895
  inVOnce = false;
1584
1896
  inVFor = 0;
1585
- comment = [];
1586
1897
  component;
1587
1898
  directive;
1588
1899
  slots = [];
@@ -1635,7 +1946,7 @@ var TransformContext = class TransformContext {
1635
1946
  registerEffect(expressions, operation, getEffectIndex = () => this.block.effect.length, getOperationIndex = () => this.block.operation.length) {
1636
1947
  const operations = [operation].flat();
1637
1948
  expressions = expressions.filter((exp) => !isConstantExpression(exp));
1638
- if (this.inVOnce || expressions.length === 0 || expressions.every((e) => e.ast && isConstant(e.ast))) return this.registerOperation(operations, getOperationIndex);
1949
+ if (this.inVOnce || expressions.length === 0 || expressions.every((e) => e.ast && isConstantNode(e.ast))) return this.registerOperation(operations, getOperationIndex);
1639
1950
  this.block.effect.splice(getEffectIndex(), 0, {
1640
1951
  expressions,
1641
1952
  operations
@@ -1807,10 +2118,8 @@ function transformComponentElement(tag, propsResult, singleRoot, context) {
1807
2118
  context.slots = [];
1808
2119
  }
1809
2120
  function transformNativeElement(tag, propsResult, singleRoot, context, getEffectIndex, getOperationIndex) {
1810
- const { scopeId } = context.options;
1811
2121
  let template = "";
1812
2122
  template += `<${tag}`;
1813
- if (scopeId) template += ` ${scopeId}`;
1814
2123
  const dynamicProps = [];
1815
2124
  if (propsResult[0]) {
1816
2125
  const [, dynamicArgs, expressions] = propsResult;
@@ -1868,7 +2177,7 @@ function buildProps(node, context, isComponent) {
1868
2177
  });
1869
2178
  continue;
1870
2179
  }
1871
- const result = transformProp(prop, node, context);
2180
+ const result = transformProp(prop, node, isComponent, context);
1872
2181
  if (result) {
1873
2182
  dynamicExpr.push(result.key, result.value);
1874
2183
  if (isComponent && !result.key.isStatic) {
@@ -1888,15 +2197,16 @@ function buildProps(node, context, isComponent) {
1888
2197
  const irProps = dedupeProperties(results);
1889
2198
  return [false, irProps];
1890
2199
  }
1891
- function transformProp(prop, node, context) {
2200
+ function transformProp(prop, node, isComponent, context) {
1892
2201
  if (prop.type === "JSXSpreadAttribute") return;
1893
2202
  let name = prop.name.type === "JSXIdentifier" ? prop.name.name : prop.name.type === "JSXNamespacedName" ? prop.name.namespace.name : "";
1894
2203
  name = name.split("_")[0];
1895
- if (!isDirectiveRegex.test(name) && !isEventRegex.test(name) && (!prop.value || prop.value.type === "StringLiteral")) {
2204
+ let value;
2205
+ if (!isDirectiveRegex.test(name) && !isEventRegex.test(name) && (!prop.value || (value = getTextLikeValue(prop.value, isComponent)) != null)) {
1896
2206
  if (isReservedProp(name)) return;
1897
2207
  return {
1898
- key: resolveSimpleExpression(name, true, prop.name.loc),
1899
- value: prop.value && prop.value.type === "StringLiteral" ? resolveSimpleExpression(prop.value.value, true, prop.value.loc) : createSimpleExpression("true", false)
2208
+ key: createSimpleExpression(name, true, prop.name),
2209
+ value: prop.value ? createSimpleExpression(value, true, prop.value) : createSimpleExpression("true")
1900
2210
  };
1901
2211
  }
1902
2212
  name = isEventRegex.test(name) ? "on" : isDirectiveRegex.test(name) ? name.slice(2) : "bind";
@@ -1977,7 +2287,7 @@ function processConditionalExpression(node, context) {
1977
2287
  id,
1978
2288
  condition,
1979
2289
  positive: branch,
1980
- once: context.inVOnce || isConstant(test)
2290
+ once: context.inVOnce || isConstantNode(test)
1981
2291
  };
1982
2292
  return [() => {
1983
2293
  onExit();
@@ -2043,7 +2353,7 @@ const transformText = (node, context) => {
2043
2353
  else processInterpolation(context);
2044
2354
  else if (node.type === "JSXText") {
2045
2355
  const value = resolveJSXText(node);
2046
- if (value) context.template += value;
2356
+ if (value) context.template += escapeHtml(value);
2047
2357
  else context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
2048
2358
  }
2049
2359
  };
@@ -2064,6 +2374,7 @@ function processInterpolation(context) {
2064
2374
  if (isFragmentNode(parent) || findProp(parent, "v-slot")) context.registerOperation({
2065
2375
  type: IRNodeTypes.CREATE_NODES,
2066
2376
  id,
2377
+ once: context.inVOnce,
2067
2378
  values
2068
2379
  });
2069
2380
  else {
@@ -2071,6 +2382,7 @@ function processInterpolation(context) {
2071
2382
  context.registerOperation({
2072
2383
  type: IRNodeTypes.SET_NODES,
2073
2384
  element: id,
2385
+ once: context.inVOnce,
2074
2386
  values
2075
2387
  });
2076
2388
  }
@@ -2078,7 +2390,7 @@ function processInterpolation(context) {
2078
2390
  function processTextContainer(children, context) {
2079
2391
  const values = createTextLikeExpressions(children, context);
2080
2392
  const literals = values.map(getLiteralExpressionValue);
2081
- if (literals.every((l) => l != null)) context.childrenTemplate = literals.map((l) => String(l));
2393
+ if (literals.every((l) => l != null)) context.childrenTemplate = literals;
2082
2394
  else {
2083
2395
  context.childrenTemplate = [" "];
2084
2396
  context.registerOperation({
@@ -2088,6 +2400,7 @@ function processTextContainer(children, context) {
2088
2400
  context.registerOperation({
2089
2401
  type: IRNodeTypes.SET_NODES,
2090
2402
  element: context.reference(),
2403
+ once: context.inVOnce,
2091
2404
  values,
2092
2405
  generated: true
2093
2406
  });
@@ -2098,7 +2411,7 @@ function createTextLikeExpressions(nodes, context) {
2098
2411
  for (const node of nodes) {
2099
2412
  markNonTemplate(node, context);
2100
2413
  if (isEmptyText(node)) continue;
2101
- values.push(resolveExpression(node, context, !context.inVOnce));
2414
+ values.push(resolveExpression(node, context));
2102
2415
  }
2103
2416
  return values;
2104
2417
  }
@@ -2113,7 +2426,7 @@ const transformVBind = (dir, node, context) => {
2113
2426
  if (!loc || name.type === "JSXNamespacedName") return;
2114
2427
  const [nameString, ...modifiers] = name.name.split("_");
2115
2428
  const exp = resolveExpression(value, context);
2116
- let arg = resolveSimpleExpression(nameString, true, dir.name.loc);
2429
+ let arg = createSimpleExpression(nameString, true, dir.name);
2117
2430
  if (arg.isStatic && isReservedProp(arg.content)) return;
2118
2431
  let camel = false;
2119
2432
  if (modifiers.includes("camel")) if (arg.isStatic) arg = extend({}, arg, { content: camelize(arg.content) });
@@ -2133,12 +2446,12 @@ const transformVFor = createStructuralDirectiveTransform("for", processFor);
2133
2446
  function processFor(node, dir, context) {
2134
2447
  const { value, index, key, source } = getForParseResult(dir, context);
2135
2448
  if (!source) {
2136
- context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION, resolveLocation(dir.loc, context)));
2449
+ context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION, dir.loc));
2137
2450
  return;
2138
2451
  }
2139
2452
  const keyProp = findProp(node, "key");
2140
2453
  const keyProperty = keyProp && propToExpression(keyProp, context);
2141
- const isComponent = isJSXComponent(node);
2454
+ const isComponent = isJSXComponent(node) || isTemplateWithSingleComponent(node);
2142
2455
  const id = context.reference();
2143
2456
  context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT;
2144
2457
  const [render, exitBlock] = createBranch(node, context, true);
@@ -2155,7 +2468,7 @@ function processFor(node, dir, context) {
2155
2468
  index,
2156
2469
  keyProp: keyProperty,
2157
2470
  render,
2158
- once: context.inVOnce || !!(source.ast && isConstant(source.ast)),
2471
+ once: context.inVOnce || !!(source.ast && isConstantNode(source.ast)),
2159
2472
  component: isComponent,
2160
2473
  onlyChild: !!isOnlyChild
2161
2474
  };
@@ -2167,13 +2480,13 @@ function getForParseResult(dir, context) {
2167
2480
  if (dir.value.type === "JSXExpressionContainer" && dir.value.expression.type === "BinaryExpression") {
2168
2481
  if (dir.value.expression.left.type === "SequenceExpression") {
2169
2482
  const expressions = dir.value.expression.left.expressions;
2170
- value = expressions[0] && resolveExpressionWithFn(expressions[0], context);
2483
+ value = expressions[0] && resolveExpression(expressions[0], context);
2171
2484
  key = expressions[1] && resolveExpression(expressions[1], context);
2172
2485
  index = expressions[2] && resolveExpression(expressions[2], context);
2173
- } else value = resolveExpressionWithFn(dir.value.expression.left, context);
2486
+ } else value = resolveExpression(dir.value.expression.left, context);
2174
2487
  source = resolveExpression(dir.value.expression.right, context);
2175
2488
  }
2176
- } else context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_NO_EXPRESSION, resolveLocation(dir.loc, context)));
2489
+ } else context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_NO_EXPRESSION, dir.loc));
2177
2490
  return {
2178
2491
  value,
2179
2492
  index,
@@ -2181,18 +2494,21 @@ function getForParseResult(dir, context) {
2181
2494
  source
2182
2495
  };
2183
2496
  }
2497
+ function isTemplateWithSingleComponent(node) {
2498
+ const nonCommentChildren = node.children.filter((c) => !isEmptyText(c));
2499
+ return nonCommentChildren.length === 1 && isJSXComponent(nonCommentChildren[0]);
2500
+ }
2184
2501
 
2185
2502
  //#endregion
2186
2503
  //#region src/transforms/vHtml.ts
2187
2504
  const transformVHtml = (dir, node, context) => {
2188
2505
  let exp;
2189
- const loc = resolveLocation(dir.loc, context);
2190
2506
  if (!dir.value) {
2191
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_HTML_NO_EXPRESSION, loc));
2507
+ context.options.onError(createCompilerError(ErrorCodes.X_V_HTML_NO_EXPRESSION, dir.loc));
2192
2508
  exp = EMPTY_EXPRESSION;
2193
2509
  } else exp = resolveExpression(dir.value, context);
2194
2510
  if (node.children.length) {
2195
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_HTML_WITH_CHILDREN, loc));
2511
+ context.options.onError(createCompilerError(ErrorCodes.X_V_HTML_WITH_CHILDREN, dir.loc));
2196
2512
  context.childrenTemplate.length = 0;
2197
2513
  }
2198
2514
  context.registerEffect([exp], {
@@ -2213,9 +2529,8 @@ const transformedIfNode = /* @__PURE__ */ new WeakMap();
2213
2529
  function processIf(node, attribute, context) {
2214
2530
  const dir = resolveDirective(attribute, context);
2215
2531
  if (dir.name !== "else" && (!dir.exp || !dir.exp.content.trim())) {
2216
- const loc = dir.exp ? dir.exp.loc : resolveLocation(node.loc, context);
2217
2532
  context.options.onError(createCompilerError(ErrorCodes.X_V_IF_NO_EXPRESSION, dir.loc));
2218
- dir.exp = createSimpleExpression(`true`, false, loc);
2533
+ dir.exp = createSimpleExpression(`true`, false, dir.exp ? dir.exp.ast : node);
2219
2534
  }
2220
2535
  context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
2221
2536
  transformedIfNode.set(node, dir);
@@ -2230,7 +2545,7 @@ function processIf(node, attribute, context) {
2230
2545
  id,
2231
2546
  condition: dir.exp,
2232
2547
  positive: branch,
2233
- once: context.inVOnce || isConstant(attribute.value)
2548
+ once: context.inVOnce || isConstantNode(attribute.value)
2234
2549
  };
2235
2550
  };
2236
2551
  } else {
@@ -2245,12 +2560,11 @@ function processIf(node, attribute, context) {
2245
2560
  }
2246
2561
  }
2247
2562
  if (!siblingIf || !lastIfNode || lastIfNode.type !== IRNodeTypes.IF) {
2248
- context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, resolveLocation(node.loc, context)));
2563
+ context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
2249
2564
  return;
2250
2565
  }
2251
2566
  while (lastIfNode.negative && lastIfNode.negative.type === IRNodeTypes.IF) lastIfNode = lastIfNode.negative;
2252
- if (dir.name === "else-if" && lastIfNode.negative) context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, resolveLocation(node.loc, context)));
2253
- context.root.comment = [];
2567
+ if (dir.name === "else-if" && lastIfNode.negative) context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
2254
2568
  const [branch, onExit] = createBranch(node, context);
2255
2569
  if (dir.name === "else") lastIfNode.negative = branch;
2256
2570
  else lastIfNode.negative = {
@@ -2286,7 +2600,7 @@ const transformVModel = (_dir, node, context) => {
2286
2600
  return;
2287
2601
  }
2288
2602
  const expString = exp.content;
2289
- if (!expString.trim() || !isMemberExpression(exp, context.options)) {
2603
+ if (!expString.trim() || !isMemberExpression(exp)) {
2290
2604
  context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION, exp.loc));
2291
2605
  return;
2292
2606
  }
@@ -2297,7 +2611,7 @@ const transformVModel = (_dir, node, context) => {
2297
2611
  model: true,
2298
2612
  modelModifiers: dir.modifiers.map((m) => m.content)
2299
2613
  };
2300
- if (dir.arg) context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT, dir.arg.loc));
2614
+ if (dir.arg) context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ARG_ON_ELEMENT, dir.arg.loc));
2301
2615
  const tag = getText(node.openingElement.name, context);
2302
2616
  const isCustomElement = context.options.isCustomElement(tag);
2303
2617
  let modelType = "text";
@@ -2314,7 +2628,7 @@ const transformVModel = (_dir, node, context) => {
2314
2628
  break;
2315
2629
  case "file":
2316
2630
  modelType = void 0;
2317
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT, dir.loc));
2631
+ context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT, dir.loc));
2318
2632
  break;
2319
2633
  default:
2320
2634
  checkDuplicatedValue();
@@ -2324,7 +2638,7 @@ const transformVModel = (_dir, node, context) => {
2324
2638
  else checkDuplicatedValue();
2325
2639
  } else if (tag === "select") modelType = "select";
2326
2640
  else checkDuplicatedValue();
2327
- else context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT, dir.loc));
2641
+ else context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT, dir.loc));
2328
2642
  if (modelType) context.registerOperation({
2329
2643
  type: IRNodeTypes.DIRECTIVE,
2330
2644
  element: context.reference(),
@@ -2335,7 +2649,7 @@ const transformVModel = (_dir, node, context) => {
2335
2649
  });
2336
2650
  function checkDuplicatedValue() {
2337
2651
  const value = findProp(node, "value");
2338
- if (value && value.value?.type !== "StringLiteral") context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE, resolveLocation(value.loc, context)));
2652
+ if (value && value.value?.type !== "StringLiteral") context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_UNNECESSARY_VALUE, value.loc));
2339
2653
  }
2340
2654
  };
2341
2655
  function hasDynamicKeyVBind(node) {
@@ -2350,10 +2664,10 @@ const transformVOn = (dir, node, context) => {
2350
2664
  if (!name) return;
2351
2665
  const isComponent = isJSXComponent(node);
2352
2666
  const [nameString, ...modifiers] = context.ir.source.slice(name.start, name.end).replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
2353
- if (!value && !modifiers.length) context.options.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, resolveLocation(loc, context)));
2354
- let arg = resolveSimpleExpression(nameString, true, dir.name.loc);
2667
+ if (!value && !modifiers.length) context.options.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc));
2668
+ let arg = createSimpleExpression(nameString, true, dir.name);
2355
2669
  const exp = resolveExpression(dir.value, context);
2356
- const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(arg.isStatic ? `on${nameString}` : arg, modifiers.map((modifier) => createSimpleExpression(modifier)), null, resolveLocation(loc, context));
2670
+ const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(arg.isStatic ? `on${nameString}` : arg, modifiers.map((modifier) => createSimpleExpression(modifier)));
2357
2671
  let keyOverride;
2358
2672
  const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
2359
2673
  if (nonKeyModifiers.includes("middle")) {
@@ -2395,6 +2709,35 @@ const transformVOn = (dir, node, context) => {
2395
2709
  };
2396
2710
  context.registerEffect([arg], operation);
2397
2711
  };
2712
+ const isEventOptionModifier = /* @__PURE__ */ makeMap(`passive,once,capture`);
2713
+ const isNonKeyModifier = /* @__PURE__ */ makeMap("stop,prevent,self,ctrl,shift,alt,meta,exact,middle");
2714
+ const maybeKeyModifier = /* @__PURE__ */ makeMap("left,right");
2715
+ const isKeyboardEvent = /* @__PURE__ */ makeMap(`onkeyup,onkeydown,onkeypress`);
2716
+ const resolveModifiers = (key, modifiers) => {
2717
+ const keyModifiers = [];
2718
+ const nonKeyModifiers = [];
2719
+ const eventOptionModifiers = [];
2720
+ for (const modifier_ of modifiers) {
2721
+ const modifier = modifier_.content;
2722
+ if (isEventOptionModifier(modifier)) eventOptionModifiers.push(modifier);
2723
+ else {
2724
+ const keyString = isString(key) ? key : key.isStatic ? key.content : null;
2725
+ if (maybeKeyModifier(modifier)) if (keyString) if (isKeyboardEvent(keyString.toLowerCase())) keyModifiers.push(modifier);
2726
+ else nonKeyModifiers.push(modifier);
2727
+ else {
2728
+ keyModifiers.push(modifier);
2729
+ nonKeyModifiers.push(modifier);
2730
+ }
2731
+ else if (isNonKeyModifier(modifier)) nonKeyModifiers.push(modifier);
2732
+ else keyModifiers.push(modifier);
2733
+ }
2734
+ }
2735
+ return {
2736
+ keyModifiers,
2737
+ nonKeyModifiers,
2738
+ eventOptionModifiers
2739
+ };
2740
+ };
2398
2741
 
2399
2742
  //#endregion
2400
2743
  //#region src/transforms/vOnce.ts
@@ -2408,7 +2751,7 @@ const transformVShow = (_dir, node, context) => {
2408
2751
  const dir = resolveDirective(_dir, context);
2409
2752
  const { exp, loc } = dir;
2410
2753
  if (!exp) {
2411
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_SHOW_NO_EXPRESSION, loc));
2754
+ context.options.onError(createCompilerError(ErrorCodes.X_V_SHOW_NO_EXPRESSION, loc));
2412
2755
  return;
2413
2756
  }
2414
2757
  context.registerOperation({
@@ -2426,13 +2769,13 @@ const transformVSlot = (node, context) => {
2426
2769
  if (node.type !== "JSXElement") return;
2427
2770
  const { children } = node;
2428
2771
  const dir = findProp(node, "v-slot");
2429
- const resolvedDirective = dir ? resolveDirective(dir, context, true) : void 0;
2772
+ const resolvedDirective = dir ? resolveDirective(dir, context) : void 0;
2430
2773
  const { parent } = context;
2431
2774
  const isComponent = isJSXComponent(node);
2432
2775
  const isSlotTemplate = isTemplate(node) && parent && parent.node.type === "JSXElement" && isJSXComponent(parent.node);
2433
2776
  if (isComponent && children.length) return transformComponentSlot(node, resolvedDirective, context);
2434
2777
  else if (isSlotTemplate && resolvedDirective) return transformTemplateSlot(node, resolvedDirective, context);
2435
- else if (!isComponent && dir) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MISPLACED, resolveLocation(dir.loc, context)));
2778
+ else if (!isComponent && dir) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MISPLACED, dir.loc));
2436
2779
  };
2437
2780
  function transformComponentSlot(node, dir, context) {
2438
2781
  const { children } = node;
@@ -2447,7 +2790,7 @@ function transformComponentSlot(node, dir, context) {
2447
2790
  context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, dir.loc));
2448
2791
  return;
2449
2792
  }
2450
- if (nonSlotTemplateChildren.length) if (hasStaticSlot(slots, "default")) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN, resolveLocation(nonSlotTemplateChildren[0].loc, context)));
2793
+ if (nonSlotTemplateChildren.length) if (hasStaticSlot(slots, "default")) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN, nonSlotTemplateChildren[0].loc));
2451
2794
  else {
2452
2795
  registerSlot(slots, arg, block);
2453
2796
  context.slots = slots;
@@ -2458,7 +2801,7 @@ function transformComponentSlot(node, dir, context) {
2458
2801
  const elseIfRE = /^v-else(-if)?$/;
2459
2802
  function transformTemplateSlot(node, dir, context) {
2460
2803
  context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
2461
- const arg = dir.arg && resolveSimpleExpressionNode(dir.arg);
2804
+ const arg = dir.arg;
2462
2805
  const vFor = findProp(node, "v-for");
2463
2806
  const vIf = findProp(node, "v-if");
2464
2807
  const vElse = findProp(node, elseIfRE);
@@ -2557,18 +2900,17 @@ const transformVSlots = (dir, node, context) => {
2557
2900
  //#region src/transforms/vText.ts
2558
2901
  const transformVText = (dir, node, context) => {
2559
2902
  let exp;
2560
- const loc = resolveLocation(dir.loc, context);
2561
2903
  if (!dir.value) {
2562
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_TEXT_NO_EXPRESSION, loc));
2904
+ context.options.onError(createCompilerError(ErrorCodes.X_V_TEXT_NO_EXPRESSION, dir.loc));
2563
2905
  exp = EMPTY_EXPRESSION;
2564
2906
  } else exp = resolveExpression(dir.value, context);
2565
2907
  if (node.children.length) {
2566
- context.options.onError(createDOMCompilerError(DOMErrorCodes.X_V_TEXT_WITH_CHILDREN, loc));
2908
+ context.options.onError(createCompilerError(ErrorCodes.X_V_TEXT_WITH_CHILDREN, dir.loc));
2567
2909
  context.childrenTemplate.length = 0;
2568
2910
  }
2569
2911
  if (isVoidTag(getText(node.openingElement.name, context))) return;
2570
2912
  const literal = getLiteralExpressionValue(exp);
2571
- if (literal != null) context.childrenTemplate = [String(literal)];
2913
+ if (literal != null) context.childrenTemplate = [escapeHtml(String(literal))];
2572
2914
  else {
2573
2915
  context.childrenTemplate = [" "];
2574
2916
  context.registerOperation({