@vue/compiler-ssr 3.2.47 → 3.3.0-alpha.10

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.
@@ -25,1250 +25,1256 @@ const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
25
25
  const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
26
26
  const SSR_GET_DIRECTIVE_PROPS = Symbol(`ssrGetDirectiveProps`);
27
27
  const ssrHelpers = {
28
- [SSR_INTERPOLATE]: `ssrInterpolate`,
29
- [SSR_RENDER_VNODE]: `ssrRenderVNode`,
30
- [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
31
- [SSR_RENDER_SLOT]: `ssrRenderSlot`,
32
- [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
33
- [SSR_RENDER_CLASS]: `ssrRenderClass`,
34
- [SSR_RENDER_STYLE]: `ssrRenderStyle`,
35
- [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
36
- [SSR_RENDER_ATTR]: `ssrRenderAttr`,
37
- [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
38
- [SSR_RENDER_LIST]: `ssrRenderList`,
39
- [SSR_INCLUDE_BOOLEAN_ATTR]: `ssrIncludeBooleanAttr`,
40
- [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
41
- [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
42
- [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
43
- [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
44
- [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
45
- [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
46
- [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
28
+ [SSR_INTERPOLATE]: `ssrInterpolate`,
29
+ [SSR_RENDER_VNODE]: `ssrRenderVNode`,
30
+ [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
31
+ [SSR_RENDER_SLOT]: `ssrRenderSlot`,
32
+ [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
33
+ [SSR_RENDER_CLASS]: `ssrRenderClass`,
34
+ [SSR_RENDER_STYLE]: `ssrRenderStyle`,
35
+ [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
36
+ [SSR_RENDER_ATTR]: `ssrRenderAttr`,
37
+ [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
38
+ [SSR_RENDER_LIST]: `ssrRenderList`,
39
+ [SSR_INCLUDE_BOOLEAN_ATTR]: `ssrIncludeBooleanAttr`,
40
+ [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
41
+ [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
42
+ [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
43
+ [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
44
+ [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
45
+ [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
46
+ [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
47
47
  };
48
- // Note: these are helpers imported from @vue/server-renderer
49
- // make sure the names match!
50
48
  compilerDom.registerRuntimeHelpers(ssrHelpers);
51
49
 
52
- // Plugin for the first transform pass, which simply constructs the AST node
53
- const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(/^(if|else|else-if)$/, compilerDom.processIf);
54
- // This is called during the 2nd transform pass to construct the SSR-specific
55
- // codegen nodes.
50
+ const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(
51
+ /^(if|else|else-if)$/,
52
+ compilerDom.processIf
53
+ );
56
54
  function ssrProcessIf(node, context, disableNestedFragments = false) {
57
- const [rootBranch] = node.branches;
58
- const ifStatement = compilerDom.createIfStatement(rootBranch.condition, processIfBranch(rootBranch, context, disableNestedFragments));
59
- context.pushStatement(ifStatement);
60
- let currentIf = ifStatement;
61
- for (let i = 1; i < node.branches.length; i++) {
62
- const branch = node.branches[i];
63
- const branchBlockStatement = processIfBranch(branch, context, disableNestedFragments);
64
- if (branch.condition) {
65
- // else-if
66
- currentIf = currentIf.alternate = compilerDom.createIfStatement(branch.condition, branchBlockStatement);
67
- }
68
- else {
69
- // else
70
- currentIf.alternate = branchBlockStatement;
71
- }
72
- }
73
- if (!currentIf.alternate) {
74
- currentIf.alternate = compilerDom.createBlockStatement([
75
- compilerDom.createCallExpression(`_push`, ['`<!---->`'])
76
- ]);
55
+ const [rootBranch] = node.branches;
56
+ const ifStatement = compilerDom.createIfStatement(
57
+ rootBranch.condition,
58
+ processIfBranch(rootBranch, context, disableNestedFragments)
59
+ );
60
+ context.pushStatement(ifStatement);
61
+ let currentIf = ifStatement;
62
+ for (let i = 1; i < node.branches.length; i++) {
63
+ const branch = node.branches[i];
64
+ const branchBlockStatement = processIfBranch(
65
+ branch,
66
+ context,
67
+ disableNestedFragments
68
+ );
69
+ if (branch.condition) {
70
+ currentIf = currentIf.alternate = compilerDom.createIfStatement(
71
+ branch.condition,
72
+ branchBlockStatement
73
+ );
74
+ } else {
75
+ currentIf.alternate = branchBlockStatement;
77
76
  }
77
+ }
78
+ if (!currentIf.alternate) {
79
+ currentIf.alternate = compilerDom.createBlockStatement([
80
+ compilerDom.createCallExpression(`_push`, ["`<!---->`"])
81
+ ]);
82
+ }
78
83
  }
79
84
  function processIfBranch(branch, context, disableNestedFragments = false) {
80
- const { children } = branch;
81
- const needFragmentWrapper = !disableNestedFragments &&
82
- (children.length !== 1 || children[0].type !== 1 /* NodeTypes.ELEMENT */) &&
83
- // optimize away nested fragments when the only child is a ForNode
84
- !(children.length === 1 && children[0].type === 11 /* NodeTypes.FOR */);
85
- return processChildrenAsStatement(branch, context, needFragmentWrapper);
85
+ const { children } = branch;
86
+ const needFragmentWrapper = !disableNestedFragments && (children.length !== 1 || children[0].type !== 1) && // optimize away nested fragments when the only child is a ForNode
87
+ !(children.length === 1 && children[0].type === 11);
88
+ return processChildrenAsStatement(branch, context, needFragmentWrapper);
86
89
  }
87
90
 
88
- // Plugin for the first transform pass, which simply constructs the AST node
89
- const ssrTransformFor = compilerDom.createStructuralDirectiveTransform('for', compilerDom.processFor);
90
- // This is called during the 2nd transform pass to construct the SSR-specific
91
- // codegen nodes.
91
+ const ssrTransformFor = compilerDom.createStructuralDirectiveTransform(
92
+ "for",
93
+ compilerDom.processFor
94
+ );
92
95
  function ssrProcessFor(node, context, disableNestedFragments = false) {
93
- const needFragmentWrapper = !disableNestedFragments &&
94
- (node.children.length !== 1 || node.children[0].type !== 1 /* NodeTypes.ELEMENT */);
95
- const renderLoop = compilerDom.createFunctionExpression(compilerDom.createForLoopParams(node.parseResult));
96
- renderLoop.body = processChildrenAsStatement(node, context, needFragmentWrapper);
97
- // v-for always renders a fragment unless explicitly disabled
98
- if (!disableNestedFragments) {
99
- context.pushStringPart(`<!--[-->`);
100
- }
101
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_LIST), [
102
- node.source,
103
- renderLoop
104
- ]));
105
- if (!disableNestedFragments) {
106
- context.pushStringPart(`<!--]-->`);
107
- }
96
+ const needFragmentWrapper = !disableNestedFragments && (node.children.length !== 1 || node.children[0].type !== 1);
97
+ const renderLoop = compilerDom.createFunctionExpression(
98
+ compilerDom.createForLoopParams(node.parseResult)
99
+ );
100
+ renderLoop.body = processChildrenAsStatement(
101
+ node,
102
+ context,
103
+ needFragmentWrapper
104
+ );
105
+ if (!disableNestedFragments) {
106
+ context.pushStringPart(`<!--[-->`);
107
+ }
108
+ context.pushStatement(
109
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_LIST), [
110
+ node.source,
111
+ renderLoop
112
+ ])
113
+ );
114
+ if (!disableNestedFragments) {
115
+ context.pushStringPart(`<!--]-->`);
116
+ }
108
117
  }
109
118
 
110
119
  const ssrTransformSlotOutlet = (node, context) => {
111
- if (compilerDom.isSlotOutlet(node)) {
112
- const { slotName, slotProps } = compilerDom.processSlotOutlet(node, context);
113
- const args = [
114
- `_ctx.$slots`,
115
- slotName,
116
- slotProps || `{}`,
117
- // fallback content placeholder. will be replaced in the process phase
118
- `null`,
119
- `_push`,
120
- `_parent`
121
- ];
122
- // inject slot scope id if current template uses :slotted
123
- if (context.scopeId && context.slotted !== false) {
124
- args.push(`"${context.scopeId}-s"`);
125
- }
126
- let method = SSR_RENDER_SLOT;
127
- // #3989
128
- // check if this is a single slot inside a transition wrapper - since
129
- // transition will unwrap the slot fragment into a single vnode at runtime,
130
- // we need to avoid rendering the slot as a fragment.
131
- const parent = context.parent;
132
- if (parent &&
133
- parent.type === 1 /* NodeTypes.ELEMENT */ &&
134
- parent.tagType === 1 /* ElementTypes.COMPONENT */ &&
135
- compilerDom.resolveComponentType(parent, context, true) === compilerDom.TRANSITION &&
136
- parent.children.filter(c => c.type === 1 /* NodeTypes.ELEMENT */).length === 1) {
137
- method = SSR_RENDER_SLOT_INNER;
138
- if (!(context.scopeId && context.slotted !== false)) {
139
- args.push('null');
140
- }
141
- args.push('true');
142
- }
143
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
120
+ if (compilerDom.isSlotOutlet(node)) {
121
+ const { slotName, slotProps } = compilerDom.processSlotOutlet(node, context);
122
+ const args = [
123
+ `_ctx.$slots`,
124
+ slotName,
125
+ slotProps || `{}`,
126
+ // fallback content placeholder. will be replaced in the process phase
127
+ `null`,
128
+ `_push`,
129
+ `_parent`
130
+ ];
131
+ if (context.scopeId && context.slotted !== false) {
132
+ args.push(`"${context.scopeId}-s"`);
133
+ }
134
+ let method = SSR_RENDER_SLOT;
135
+ const parent = context.parent;
136
+ if (parent && parent.type === 1 && parent.tagType === 1 && compilerDom.resolveComponentType(parent, context, true) === compilerDom.TRANSITION && parent.children.filter((c) => c.type === 1).length === 1) {
137
+ method = SSR_RENDER_SLOT_INNER;
138
+ if (!(context.scopeId && context.slotted !== false)) {
139
+ args.push("null");
140
+ }
141
+ args.push("true");
144
142
  }
143
+ node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
144
+ }
145
145
  };
146
146
  function ssrProcessSlotOutlet(node, context) {
147
- const renderCall = node.ssrCodegenNode;
148
- // has fallback content
149
- if (node.children.length) {
150
- const fallbackRenderFn = compilerDom.createFunctionExpression([]);
151
- fallbackRenderFn.body = processChildrenAsStatement(node, context);
152
- // _renderSlot(slots, name, props, fallback, ...)
153
- renderCall.arguments[3] = fallbackRenderFn;
154
- }
155
- // Forwarded <slot/>. Merge slot scope ids
156
- if (context.withSlotScopeId) {
157
- const slotScopeId = renderCall.arguments[6];
158
- renderCall.arguments[6] = slotScopeId
159
- ? `${slotScopeId} + _scopeId`
160
- : `_scopeId`;
161
- }
162
- context.pushStatement(node.ssrCodegenNode);
147
+ const renderCall = node.ssrCodegenNode;
148
+ if (node.children.length) {
149
+ const fallbackRenderFn = compilerDom.createFunctionExpression([]);
150
+ fallbackRenderFn.body = processChildrenAsStatement(node, context);
151
+ renderCall.arguments[3] = fallbackRenderFn;
152
+ }
153
+ if (context.withSlotScopeId) {
154
+ const slotScopeId = renderCall.arguments[6];
155
+ renderCall.arguments[6] = slotScopeId ? `${slotScopeId} + _scopeId` : `_scopeId`;
156
+ }
157
+ context.pushStatement(node.ssrCodegenNode);
163
158
  }
164
159
 
165
160
  function createSSRCompilerError(code, loc) {
166
- return compilerDom.createCompilerError(code, loc, SSRErrorMessages);
161
+ return compilerDom.createCompilerError(code, loc, SSRErrorMessages);
167
162
  }
168
163
  const SSRErrorMessages = {
169
- [62 /* SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME */]: `Unsafe attribute name for SSR.`,
170
- [63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */]: `Missing the 'to' prop on teleport element.`,
171
- [64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */]: `Invalid AST node during SSR transform.`
164
+ [62]: `Unsafe attribute name for SSR.`,
165
+ [63]: `Missing the 'to' prop on teleport element.`,
166
+ [64]: `Invalid AST node during SSR transform.`
172
167
  };
173
168
 
174
- // Note: this is a 2nd-pass codegen transform.
175
169
  function ssrProcessTeleport(node, context) {
176
- const targetProp = compilerDom.findProp(node, 'to');
177
- if (!targetProp) {
178
- context.onError(createSSRCompilerError(63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */, node.loc));
179
- return;
180
- }
181
- let target;
182
- if (targetProp.type === 6 /* NodeTypes.ATTRIBUTE */) {
183
- target =
184
- targetProp.value && compilerDom.createSimpleExpression(targetProp.value.content, true);
185
- }
186
- else {
187
- target = targetProp.exp;
188
- }
189
- if (!target) {
190
- context.onError(createSSRCompilerError(63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */, targetProp.loc));
191
- return;
192
- }
193
- const disabledProp = compilerDom.findProp(node, 'disabled', false, true /* allow empty */);
194
- const disabled = disabledProp
195
- ? disabledProp.type === 6 /* NodeTypes.ATTRIBUTE */
196
- ? `true`
197
- : disabledProp.exp || `false`
198
- : `false`;
199
- const contentRenderFn = compilerDom.createFunctionExpression([`_push`], undefined, // Body is added later
200
- true, // newline
201
- false, // isSlot
202
- node.loc);
203
- contentRenderFn.body = processChildrenAsStatement(node, context);
204
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
205
- `_push`,
206
- contentRenderFn,
207
- target,
208
- disabled,
209
- `_parent`
210
- ]));
170
+ const targetProp = compilerDom.findProp(node, "to");
171
+ if (!targetProp) {
172
+ context.onError(
173
+ createSSRCompilerError(63, node.loc)
174
+ );
175
+ return;
176
+ }
177
+ let target;
178
+ if (targetProp.type === 6) {
179
+ target = targetProp.value && compilerDom.createSimpleExpression(targetProp.value.content, true);
180
+ } else {
181
+ target = targetProp.exp;
182
+ }
183
+ if (!target) {
184
+ context.onError(
185
+ createSSRCompilerError(
186
+ 63,
187
+ targetProp.loc
188
+ )
189
+ );
190
+ return;
191
+ }
192
+ const disabledProp = compilerDom.findProp(
193
+ node,
194
+ "disabled",
195
+ false,
196
+ true
197
+ /* allow empty */
198
+ );
199
+ const disabled = disabledProp ? disabledProp.type === 6 ? `true` : disabledProp.exp || `false` : `false`;
200
+ const contentRenderFn = compilerDom.createFunctionExpression(
201
+ [`_push`],
202
+ void 0,
203
+ // Body is added later
204
+ true,
205
+ // newline
206
+ false,
207
+ // isSlot
208
+ node.loc
209
+ );
210
+ contentRenderFn.body = processChildrenAsStatement(node, context);
211
+ context.pushStatement(
212
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
213
+ `_push`,
214
+ contentRenderFn,
215
+ target,
216
+ disabled,
217
+ `_parent`
218
+ ])
219
+ );
211
220
  }
212
221
 
213
- const wipMap$2 = new WeakMap();
214
- // phase 1
222
+ const wipMap$2 = /* @__PURE__ */ new WeakMap();
215
223
  function ssrTransformSuspense(node, context) {
216
- return () => {
217
- if (node.children.length) {
218
- const wipEntry = {
219
- slotsExp: null,
220
- wipSlots: []
221
- };
222
- wipMap$2.set(node, wipEntry);
223
- wipEntry.slotsExp = compilerDom.buildSlots(node, context, (_props, children, loc) => {
224
- const fn = compilerDom.createFunctionExpression([], undefined, // no return, assign body later
225
- true, // newline
226
- false, // suspense slots are not treated as normal slots
227
- loc);
228
- wipEntry.wipSlots.push({
229
- fn,
230
- children
231
- });
232
- return fn;
233
- }).slots;
234
- }
235
- };
224
+ return () => {
225
+ if (node.children.length) {
226
+ const wipEntry = {
227
+ slotsExp: null,
228
+ // to be immediately set
229
+ wipSlots: []
230
+ };
231
+ wipMap$2.set(node, wipEntry);
232
+ wipEntry.slotsExp = compilerDom.buildSlots(node, context, (_props, children, loc) => {
233
+ const fn = compilerDom.createFunctionExpression(
234
+ [],
235
+ void 0,
236
+ // no return, assign body later
237
+ true,
238
+ // newline
239
+ false,
240
+ // suspense slots are not treated as normal slots
241
+ loc
242
+ );
243
+ wipEntry.wipSlots.push({
244
+ fn,
245
+ children
246
+ });
247
+ return fn;
248
+ }).slots;
249
+ }
250
+ };
236
251
  }
237
- // phase 2
238
252
  function ssrProcessSuspense(node, context) {
239
- // complete wip slots with ssr code
240
- const wipEntry = wipMap$2.get(node);
241
- if (!wipEntry) {
242
- return;
243
- }
244
- const { slotsExp, wipSlots } = wipEntry;
245
- for (let i = 0; i < wipSlots.length; i++) {
246
- const slot = wipSlots[i];
247
- slot.fn.body = processChildrenAsStatement(slot, context);
248
- }
249
- // _push(ssrRenderSuspense(slots))
250
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
251
- `_push`,
252
- slotsExp
253
- ]));
253
+ const wipEntry = wipMap$2.get(node);
254
+ if (!wipEntry) {
255
+ return;
256
+ }
257
+ const { slotsExp, wipSlots } = wipEntry;
258
+ for (let i = 0; i < wipSlots.length; i++) {
259
+ const slot = wipSlots[i];
260
+ slot.fn.body = processChildrenAsStatement(slot, context);
261
+ }
262
+ context.pushStatement(
263
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
264
+ `_push`,
265
+ slotsExp
266
+ ])
267
+ );
254
268
  }
255
269
 
256
- // for directives with children overwrite (e.g. v-html & v-text), we need to
257
- // store the raw children so that they can be added in the 2nd pass.
258
- const rawChildrenMap = new WeakMap();
270
+ const rawChildrenMap = /* @__PURE__ */ new WeakMap();
259
271
  const ssrTransformElement = (node, context) => {
260
- if (node.type !== 1 /* NodeTypes.ELEMENT */ ||
261
- node.tagType !== 0 /* ElementTypes.ELEMENT */) {
262
- return;
263
- }
264
- return function ssrPostTransformElement() {
265
- // element
266
- // generate the template literal representing the open tag.
267
- const openTag = [`<${node.tag}`];
268
- // some tags need to be passed to runtime for special checks
269
- const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
270
- // v-bind="obj", v-bind:[key] and custom directives can potentially
271
- // overwrite other static attrs and can affect final rendering result,
272
- // so when they are present we need to bail out to full `renderAttrs`
273
- const hasDynamicVBind = compilerDom.hasDynamicKeyVBind(node);
274
- const hasCustomDir = node.props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && !shared.isBuiltInDirective(p.name));
275
- const needMergeProps = hasDynamicVBind || hasCustomDir;
276
- if (needMergeProps) {
277
- const { props, directives } = compilerDom.buildProps(node, context, node.props, false /* isComponent */, false /* isDynamicComponent */, true /* ssr */);
278
- if (props || directives.length) {
279
- const mergedProps = buildSSRProps(props, directives, context);
280
- const propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [mergedProps]);
281
- if (node.tag === 'textarea') {
282
- const existingText = node.children[0];
283
- // If interpolation, this is dynamic <textarea> content, potentially
284
- // injected by v-model and takes higher priority than v-bind value
285
- if (!existingText || existingText.type !== 5 /* NodeTypes.INTERPOLATION */) {
286
- // <textarea> with dynamic v-bind. We don't know if the final props
287
- // will contain .value, so we will have to do something special:
288
- // assign the merged props to a temp variable, and check whether
289
- // it contains value (if yes, render is as children).
290
- const tempId = `_temp${context.temps++}`;
291
- propsExp.arguments = [
292
- compilerDom.createAssignmentExpression(compilerDom.createSimpleExpression(tempId, false), mergedProps)
293
- ];
294
- rawChildrenMap.set(node, compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
295
- compilerDom.createConditionalExpression(compilerDom.createSimpleExpression(`"value" in ${tempId}`, false), compilerDom.createSimpleExpression(`${tempId}.value`, false), compilerDom.createSimpleExpression(existingText ? existingText.content : ``, true), false)
296
- ]));
297
- }
298
- }
299
- else if (node.tag === 'input') {
300
- // <input v-bind="obj" v-model>
301
- // we need to determine the props to render for the dynamic v-model
302
- // and merge it with the v-bind expression.
303
- const vModel = findVModel(node);
304
- if (vModel) {
305
- // 1. save the props (san v-model) in a temp variable
306
- const tempId = `_temp${context.temps++}`;
307
- const tempExp = compilerDom.createSimpleExpression(tempId, false);
308
- propsExp.arguments = [
309
- compilerDom.createSequenceExpression([
310
- compilerDom.createAssignmentExpression(tempExp, mergedProps),
311
- compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), [
312
- tempExp,
313
- compilerDom.createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
314
- tempExp,
315
- vModel.exp // model
316
- ])
317
- ])
318
- ])
319
- ];
320
- }
321
- }
322
- if (needTagForRuntime) {
323
- propsExp.arguments.push(`"${node.tag}"`);
324
- }
325
- openTag.push(propsExp);
326
- }
272
+ if (node.type !== 1 || node.tagType !== 0) {
273
+ return;
274
+ }
275
+ return function ssrPostTransformElement() {
276
+ const openTag = [`<${node.tag}`];
277
+ const needTagForRuntime = node.tag === "textarea" || node.tag.indexOf("-") > 0;
278
+ const hasDynamicVBind = compilerDom.hasDynamicKeyVBind(node);
279
+ const hasCustomDir = node.props.some(
280
+ (p) => p.type === 7 && !shared.isBuiltInDirective(p.name)
281
+ );
282
+ const needMergeProps = hasDynamicVBind || hasCustomDir;
283
+ if (needMergeProps) {
284
+ const { props, directives } = compilerDom.buildProps(
285
+ node,
286
+ context,
287
+ node.props,
288
+ false,
289
+ false,
290
+ true
291
+ /* ssr */
292
+ );
293
+ if (props || directives.length) {
294
+ const mergedProps = buildSSRProps(props, directives, context);
295
+ const propsExp = compilerDom.createCallExpression(
296
+ context.helper(SSR_RENDER_ATTRS),
297
+ [mergedProps]
298
+ );
299
+ if (node.tag === "textarea") {
300
+ const existingText = node.children[0];
301
+ if (!existingText || existingText.type !== 5) {
302
+ const tempId = `_temp${context.temps++}`;
303
+ propsExp.arguments = [
304
+ compilerDom.createAssignmentExpression(
305
+ compilerDom.createSimpleExpression(tempId, false),
306
+ mergedProps
307
+ )
308
+ ];
309
+ rawChildrenMap.set(
310
+ node,
311
+ compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
312
+ compilerDom.createConditionalExpression(
313
+ compilerDom.createSimpleExpression(`"value" in ${tempId}`, false),
314
+ compilerDom.createSimpleExpression(`${tempId}.value`, false),
315
+ compilerDom.createSimpleExpression(
316
+ existingText ? existingText.content : ``,
317
+ true
318
+ ),
319
+ false
320
+ )
321
+ ])
322
+ );
323
+ }
324
+ } else if (node.tag === "input") {
325
+ const vModel = findVModel(node);
326
+ if (vModel) {
327
+ const tempId = `_temp${context.temps++}`;
328
+ const tempExp = compilerDom.createSimpleExpression(tempId, false);
329
+ propsExp.arguments = [
330
+ compilerDom.createSequenceExpression([
331
+ compilerDom.createAssignmentExpression(tempExp, mergedProps),
332
+ compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), [
333
+ tempExp,
334
+ compilerDom.createCallExpression(
335
+ context.helper(SSR_GET_DYNAMIC_MODEL_PROPS),
336
+ [
337
+ tempExp,
338
+ // existing props
339
+ vModel.exp
340
+ // model
341
+ ]
342
+ )
343
+ ])
344
+ ])
345
+ ];
346
+ }
327
347
  }
328
- // book keeping static/dynamic class merging.
329
- let dynamicClassBinding = undefined;
330
- let staticClassBinding = undefined;
331
- // all style bindings are converted to dynamic by transformStyle.
332
- // but we need to make sure to merge them.
333
- let dynamicStyleBinding = undefined;
334
- for (let i = 0; i < node.props.length; i++) {
335
- const prop = node.props[i];
336
- // ignore true-value/false-value on input
337
- if (node.tag === 'input' && isTrueFalseValue(prop)) {
338
- continue;
348
+ if (needTagForRuntime) {
349
+ propsExp.arguments.push(`"${node.tag}"`);
350
+ }
351
+ openTag.push(propsExp);
352
+ }
353
+ }
354
+ let dynamicClassBinding = void 0;
355
+ let staticClassBinding = void 0;
356
+ let dynamicStyleBinding = void 0;
357
+ for (let i = 0; i < node.props.length; i++) {
358
+ const prop = node.props[i];
359
+ if (node.tag === "input" && isTrueFalseValue(prop)) {
360
+ continue;
361
+ }
362
+ if (prop.type === 7) {
363
+ if (prop.name === "html" && prop.exp) {
364
+ rawChildrenMap.set(node, prop.exp);
365
+ } else if (prop.name === "text" && prop.exp) {
366
+ node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
367
+ } else if (prop.name === "slot") {
368
+ context.onError(
369
+ compilerDom.createCompilerError(40, prop.loc)
370
+ );
371
+ } else if (isTextareaWithValue(node, prop) && prop.exp) {
372
+ if (!needMergeProps) {
373
+ node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
374
+ }
375
+ } else if (!needMergeProps && prop.name !== "on") {
376
+ const directiveTransform = context.directiveTransforms[prop.name];
377
+ if (directiveTransform) {
378
+ const { props, ssrTagParts } = directiveTransform(
379
+ prop,
380
+ node,
381
+ context
382
+ );
383
+ if (ssrTagParts) {
384
+ openTag.push(...ssrTagParts);
339
385
  }
340
- // special cases with children override
341
- if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
342
- if (prop.name === 'html' && prop.exp) {
343
- rawChildrenMap.set(node, prop.exp);
386
+ for (let j = 0; j < props.length; j++) {
387
+ const { key, value } = props[j];
388
+ if (compilerDom.isStaticExp(key)) {
389
+ let attrName = key.content;
390
+ if (attrName === "key" || attrName === "ref") {
391
+ continue;
344
392
  }
345
- else if (prop.name === 'text' && prop.exp) {
346
- node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
347
- }
348
- else if (prop.name === 'slot') {
349
- context.onError(compilerDom.createCompilerError(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, prop.loc));
350
- }
351
- else if (isTextareaWithValue(node, prop) && prop.exp) {
352
- if (!needMergeProps) {
353
- node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
354
- }
355
- }
356
- else if (!needMergeProps && prop.name !== 'on') {
357
- // Directive transforms.
358
- const directiveTransform = context.directiveTransforms[prop.name];
359
- if (directiveTransform) {
360
- const { props, ssrTagParts } = directiveTransform(prop, node, context);
361
- if (ssrTagParts) {
362
- openTag.push(...ssrTagParts);
363
- }
364
- for (let j = 0; j < props.length; j++) {
365
- const { key, value } = props[j];
366
- if (compilerDom.isStaticExp(key)) {
367
- let attrName = key.content;
368
- // static key attr
369
- if (attrName === 'key' || attrName === 'ref') {
370
- continue;
371
- }
372
- if (attrName === 'class') {
373
- openTag.push(` class="`, (dynamicClassBinding = compilerDom.createCallExpression(context.helper(SSR_RENDER_CLASS), [value])), `"`);
374
- }
375
- else if (attrName === 'style') {
376
- if (dynamicStyleBinding) {
377
- // already has style binding, merge into it.
378
- mergeCall(dynamicStyleBinding, value);
379
- }
380
- else {
381
- openTag.push(` style="`, (dynamicStyleBinding = compilerDom.createCallExpression(context.helper(SSR_RENDER_STYLE), [value])), `"`);
382
- }
383
- }
384
- else {
385
- attrName =
386
- node.tag.indexOf('-') > 0
387
- ? attrName // preserve raw name on custom elements
388
- : shared.propsToAttrMap[attrName] || attrName.toLowerCase();
389
- if (shared.isBooleanAttr(attrName)) {
390
- openTag.push(compilerDom.createConditionalExpression(compilerDom.createCallExpression(context.helper(SSR_INCLUDE_BOOLEAN_ATTR), [value]), compilerDom.createSimpleExpression(' ' + attrName, true), compilerDom.createSimpleExpression('', true), false /* no newline */));
391
- }
392
- else if (shared.isSSRSafeAttrName(attrName)) {
393
- openTag.push(compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTR), [
394
- key,
395
- value
396
- ]));
397
- }
398
- else {
399
- context.onError(createSSRCompilerError(62 /* SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME */, key.loc));
400
- }
401
- }
402
- }
403
- else {
404
- // dynamic key attr
405
- // this branch is only encountered for custom directive
406
- // transforms that returns properties with dynamic keys
407
- const args = [key, value];
408
- if (needTagForRuntime) {
409
- args.push(`"${node.tag}"`);
410
- }
411
- openTag.push(compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_ATTR), args));
412
- }
413
- }
414
- }
415
- }
416
- }
417
- else {
418
- // special case: value on <textarea>
419
- if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
420
- rawChildrenMap.set(node, shared.escapeHtml(prop.value.content));
393
+ if (attrName === "class") {
394
+ openTag.push(
395
+ ` class="`,
396
+ dynamicClassBinding = compilerDom.createCallExpression(
397
+ context.helper(SSR_RENDER_CLASS),
398
+ [value]
399
+ ),
400
+ `"`
401
+ );
402
+ } else if (attrName === "style") {
403
+ if (dynamicStyleBinding) {
404
+ mergeCall(dynamicStyleBinding, value);
405
+ } else {
406
+ openTag.push(
407
+ ` style="`,
408
+ dynamicStyleBinding = compilerDom.createCallExpression(
409
+ context.helper(SSR_RENDER_STYLE),
410
+ [value]
411
+ ),
412
+ `"`
413
+ );
414
+ }
415
+ } else {
416
+ attrName = node.tag.indexOf("-") > 0 ? attrName : shared.propsToAttrMap[attrName] || attrName.toLowerCase();
417
+ if (shared.isBooleanAttr(attrName)) {
418
+ openTag.push(
419
+ compilerDom.createConditionalExpression(
420
+ compilerDom.createCallExpression(
421
+ context.helper(SSR_INCLUDE_BOOLEAN_ATTR),
422
+ [value]
423
+ ),
424
+ compilerDom.createSimpleExpression(" " + attrName, true),
425
+ compilerDom.createSimpleExpression("", true),
426
+ false
427
+ /* no newline */
428
+ )
429
+ );
430
+ } else if (shared.isSSRSafeAttrName(attrName)) {
431
+ openTag.push(
432
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTR), [
433
+ key,
434
+ value
435
+ ])
436
+ );
437
+ } else {
438
+ context.onError(
439
+ createSSRCompilerError(
440
+ 62,
441
+ key.loc
442
+ )
443
+ );
444
+ }
421
445
  }
422
- else if (!needMergeProps) {
423
- if (prop.name === 'key' || prop.name === 'ref') {
424
- continue;
425
- }
426
- // static prop
427
- if (prop.name === 'class' && prop.value) {
428
- staticClassBinding = JSON.stringify(prop.value.content);
429
- }
430
- openTag.push(` ${prop.name}` +
431
- (prop.value ? `="${shared.escapeHtml(prop.value.content)}"` : ``));
446
+ } else {
447
+ const args = [key, value];
448
+ if (needTagForRuntime) {
449
+ args.push(`"${node.tag}"`);
432
450
  }
451
+ openTag.push(
452
+ compilerDom.createCallExpression(
453
+ context.helper(SSR_RENDER_DYNAMIC_ATTR),
454
+ args
455
+ )
456
+ );
457
+ }
433
458
  }
459
+ }
434
460
  }
435
- // handle co-existence of dynamic + static class bindings
436
- if (dynamicClassBinding && staticClassBinding) {
437
- mergeCall(dynamicClassBinding, staticClassBinding);
438
- removeStaticBinding(openTag, 'class');
439
- }
440
- if (context.scopeId) {
441
- openTag.push(` ${context.scopeId}`);
461
+ } else {
462
+ if (node.tag === "textarea" && prop.name === "value" && prop.value) {
463
+ rawChildrenMap.set(node, shared.escapeHtml(prop.value.content));
464
+ } else if (!needMergeProps) {
465
+ if (prop.name === "key" || prop.name === "ref") {
466
+ continue;
467
+ }
468
+ if (prop.name === "class" && prop.value) {
469
+ staticClassBinding = JSON.stringify(prop.value.content);
470
+ }
471
+ openTag.push(
472
+ ` ${prop.name}` + (prop.value ? `="${shared.escapeHtml(prop.value.content)}"` : ``)
473
+ );
442
474
  }
443
- node.ssrCodegenNode = compilerDom.createTemplateLiteral(openTag);
444
- };
475
+ }
476
+ }
477
+ if (dynamicClassBinding && staticClassBinding) {
478
+ mergeCall(dynamicClassBinding, staticClassBinding);
479
+ removeStaticBinding(openTag, "class");
480
+ }
481
+ if (context.scopeId) {
482
+ openTag.push(` ${context.scopeId}`);
483
+ }
484
+ node.ssrCodegenNode = compilerDom.createTemplateLiteral(openTag);
485
+ };
445
486
  };
446
487
  function buildSSRProps(props, directives, context) {
447
- let mergePropsArgs = [];
448
- if (props) {
449
- if (props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
450
- // already a mergeProps call
451
- mergePropsArgs = props.arguments;
452
- }
453
- else {
454
- mergePropsArgs.push(props);
455
- }
488
+ let mergePropsArgs = [];
489
+ if (props) {
490
+ if (props.type === 14) {
491
+ mergePropsArgs = props.arguments;
492
+ } else {
493
+ mergePropsArgs.push(props);
456
494
  }
457
- if (directives.length) {
458
- for (const dir of directives) {
459
- mergePropsArgs.push(compilerDom.createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
460
- `_ctx`,
461
- ...compilerDom.buildDirectiveArgs(dir, context).elements
462
- ]));
463
- }
495
+ }
496
+ if (directives.length) {
497
+ for (const dir of directives) {
498
+ mergePropsArgs.push(
499
+ compilerDom.createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
500
+ `_ctx`,
501
+ ...compilerDom.buildDirectiveArgs(dir, context).elements
502
+ ])
503
+ );
464
504
  }
465
- return mergePropsArgs.length > 1
466
- ? compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), mergePropsArgs)
467
- : mergePropsArgs[0];
505
+ }
506
+ return mergePropsArgs.length > 1 ? compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), mergePropsArgs) : mergePropsArgs[0];
468
507
  }
469
508
  function isTrueFalseValue(prop) {
470
- if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
471
- return (prop.name === 'bind' &&
472
- prop.arg &&
473
- compilerDom.isStaticExp(prop.arg) &&
474
- (prop.arg.content === 'true-value' || prop.arg.content === 'false-value'));
475
- }
476
- else {
477
- return prop.name === 'true-value' || prop.name === 'false-value';
478
- }
509
+ if (prop.type === 7) {
510
+ return prop.name === "bind" && prop.arg && compilerDom.isStaticExp(prop.arg) && (prop.arg.content === "true-value" || prop.arg.content === "false-value");
511
+ } else {
512
+ return prop.name === "true-value" || prop.name === "false-value";
513
+ }
479
514
  }
480
515
  function isTextareaWithValue(node, prop) {
481
- return !!(node.tag === 'textarea' &&
482
- prop.name === 'bind' &&
483
- compilerDom.isStaticArgOf(prop.arg, 'value'));
516
+ return !!(node.tag === "textarea" && prop.name === "bind" && compilerDom.isStaticArgOf(prop.arg, "value"));
484
517
  }
485
518
  function mergeCall(call, arg) {
486
- const existing = call.arguments[0];
487
- if (existing.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */) {
488
- existing.elements.push(arg);
489
- }
490
- else {
491
- call.arguments[0] = compilerDom.createArrayExpression([existing, arg]);
492
- }
519
+ const existing = call.arguments[0];
520
+ if (existing.type === 17) {
521
+ existing.elements.push(arg);
522
+ } else {
523
+ call.arguments[0] = compilerDom.createArrayExpression([existing, arg]);
524
+ }
493
525
  }
494
526
  function removeStaticBinding(tag, binding) {
495
- const regExp = new RegExp(`^ ${binding}=".+"$`);
496
- const i = tag.findIndex(e => typeof e === 'string' && regExp.test(e));
497
- if (i > -1) {
498
- tag.splice(i, 1);
499
- }
527
+ const regExp = new RegExp(`^ ${binding}=".+"$`);
528
+ const i = tag.findIndex((e) => typeof e === "string" && regExp.test(e));
529
+ if (i > -1) {
530
+ tag.splice(i, 1);
531
+ }
500
532
  }
501
533
  function findVModel(node) {
502
- return node.props.find(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'model' && p.exp);
534
+ return node.props.find(
535
+ (p) => p.type === 7 && p.name === "model" && p.exp
536
+ );
503
537
  }
504
538
  function ssrProcessElement(node, context) {
505
- const isVoidTag = context.options.isVoidTag || shared.NO;
506
- const elementsToAdd = node.ssrCodegenNode.elements;
507
- for (let j = 0; j < elementsToAdd.length; j++) {
508
- context.pushStringPart(elementsToAdd[j]);
509
- }
510
- // Handle slot scopeId
511
- if (context.withSlotScopeId) {
512
- context.pushStringPart(compilerDom.createSimpleExpression(`_scopeId`, false));
513
- }
514
- // close open tag
515
- context.pushStringPart(`>`);
516
- const rawChildren = rawChildrenMap.get(node);
517
- if (rawChildren) {
518
- context.pushStringPart(rawChildren);
519
- }
520
- else if (node.children.length) {
521
- processChildren(node, context);
522
- }
523
- if (!isVoidTag(node.tag)) {
524
- // push closing tag
525
- context.pushStringPart(`</${node.tag}>`);
526
- }
539
+ const isVoidTag = context.options.isVoidTag || shared.NO;
540
+ const elementsToAdd = node.ssrCodegenNode.elements;
541
+ for (let j = 0; j < elementsToAdd.length; j++) {
542
+ context.pushStringPart(elementsToAdd[j]);
543
+ }
544
+ if (context.withSlotScopeId) {
545
+ context.pushStringPart(compilerDom.createSimpleExpression(`_scopeId`, false));
546
+ }
547
+ context.pushStringPart(`>`);
548
+ const rawChildren = rawChildrenMap.get(node);
549
+ if (rawChildren) {
550
+ context.pushStringPart(rawChildren);
551
+ } else if (node.children.length) {
552
+ processChildren(node, context);
553
+ }
554
+ if (!isVoidTag(node.tag)) {
555
+ context.pushStringPart(`</${node.tag}>`);
556
+ }
527
557
  }
528
558
 
529
- const wipMap$1 = new WeakMap();
530
- // phase 1: build props
559
+ const wipMap$1 = /* @__PURE__ */ new WeakMap();
531
560
  function ssrTransformTransitionGroup(node, context) {
532
- return () => {
533
- const tag = compilerDom.findProp(node, 'tag');
534
- if (tag) {
535
- const otherProps = node.props.filter(p => p !== tag);
536
- const { props, directives } = compilerDom.buildProps(node, context, otherProps, true /* isComponent */, false /* isDynamicComponent */, true /* ssr (skip event listeners) */);
537
- let propsExp = null;
538
- if (props || directives.length) {
539
- propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
540
- buildSSRProps(props, directives, context)
541
- ]);
542
- }
543
- wipMap$1.set(node, {
544
- tag,
545
- propsExp
546
- });
547
- }
548
- };
561
+ return () => {
562
+ const tag = compilerDom.findProp(node, "tag");
563
+ if (tag) {
564
+ const otherProps = node.props.filter((p) => p !== tag);
565
+ const { props, directives } = compilerDom.buildProps(
566
+ node,
567
+ context,
568
+ otherProps,
569
+ true,
570
+ false,
571
+ true
572
+ /* ssr (skip event listeners) */
573
+ );
574
+ let propsExp = null;
575
+ if (props || directives.length) {
576
+ propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
577
+ buildSSRProps(props, directives, context)
578
+ ]);
579
+ }
580
+ wipMap$1.set(node, {
581
+ tag,
582
+ propsExp
583
+ });
584
+ }
585
+ };
549
586
  }
550
- // phase 2: process children
551
587
  function ssrProcessTransitionGroup(node, context) {
552
- const entry = wipMap$1.get(node);
553
- if (entry) {
554
- const { tag, propsExp } = entry;
555
- if (tag.type === 7 /* NodeTypes.DIRECTIVE */) {
556
- // dynamic :tag
557
- context.pushStringPart(`<`);
558
- context.pushStringPart(tag.exp);
559
- if (propsExp) {
560
- context.pushStringPart(propsExp);
561
- }
562
- context.pushStringPart(`>`);
563
- processChildren(node, context, false,
564
- /**
565
- * TransitionGroup has the special runtime behavior of flattening and
566
- * concatenating all children into a single fragment (in order for them to
567
- * be patched using the same key map) so we need to account for that here
568
- * by disabling nested fragment wrappers from being generated.
569
- */
570
- true);
571
- context.pushStringPart(`</`);
572
- context.pushStringPart(tag.exp);
573
- context.pushStringPart(`>`);
574
- }
575
- else {
576
- // static tag
577
- context.pushStringPart(`<${tag.value.content}`);
578
- if (propsExp) {
579
- context.pushStringPart(propsExp);
580
- }
581
- context.pushStringPart(`>`);
582
- processChildren(node, context, false, true);
583
- context.pushStringPart(`</${tag.value.content}>`);
584
- }
585
- }
586
- else {
587
- // fragment
588
- processChildren(node, context, true, true);
588
+ const entry = wipMap$1.get(node);
589
+ if (entry) {
590
+ const { tag, propsExp } = entry;
591
+ if (tag.type === 7) {
592
+ context.pushStringPart(`<`);
593
+ context.pushStringPart(tag.exp);
594
+ if (propsExp) {
595
+ context.pushStringPart(propsExp);
596
+ }
597
+ context.pushStringPart(`>`);
598
+ processChildren(
599
+ node,
600
+ context,
601
+ false,
602
+ /**
603
+ * TransitionGroup has the special runtime behavior of flattening and
604
+ * concatenating all children into a single fragment (in order for them to
605
+ * be patched using the same key map) so we need to account for that here
606
+ * by disabling nested fragment wrappers from being generated.
607
+ */
608
+ true
609
+ );
610
+ context.pushStringPart(`</`);
611
+ context.pushStringPart(tag.exp);
612
+ context.pushStringPart(`>`);
613
+ } else {
614
+ context.pushStringPart(`<${tag.value.content}`);
615
+ if (propsExp) {
616
+ context.pushStringPart(propsExp);
617
+ }
618
+ context.pushStringPart(`>`);
619
+ processChildren(node, context, false, true);
620
+ context.pushStringPart(`</${tag.value.content}>`);
589
621
  }
622
+ } else {
623
+ processChildren(node, context, true, true);
624
+ }
590
625
  }
591
626
 
592
- // We need to construct the slot functions in the 1st pass to ensure proper
593
- // scope tracking, but the children of each slot cannot be processed until
594
- // the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
595
- // pass and complete them in the 2nd pass.
596
- const wipMap = new WeakMap();
627
+ const wipMap = /* @__PURE__ */ new WeakMap();
597
628
  const WIP_SLOT = Symbol();
598
- const componentTypeMap = new WeakMap();
599
- // ssr component transform is done in two phases:
600
- // In phase 1. we use `buildSlot` to analyze the children of the component into
601
- // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
602
- // the core transform context).
603
- // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
604
- // nodes.
629
+ const componentTypeMap = /* @__PURE__ */ new WeakMap();
605
630
  const ssrTransformComponent = (node, context) => {
606
- if (node.type !== 1 /* NodeTypes.ELEMENT */ ||
607
- node.tagType !== 1 /* ElementTypes.COMPONENT */) {
608
- return;
631
+ if (node.type !== 1 || node.tagType !== 1) {
632
+ return;
633
+ }
634
+ const component = compilerDom.resolveComponentType(
635
+ node,
636
+ context,
637
+ true
638
+ /* ssr */
639
+ );
640
+ const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
641
+ componentTypeMap.set(node, component);
642
+ if (shared.isSymbol(component)) {
643
+ if (component === compilerDom.SUSPENSE) {
644
+ return ssrTransformSuspense(node, context);
609
645
  }
610
- const component = compilerDom.resolveComponentType(node, context, true /* ssr */);
611
- const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
612
- componentTypeMap.set(node, component);
613
- if (shared.isSymbol(component)) {
614
- if (component === compilerDom.SUSPENSE) {
615
- return ssrTransformSuspense(node, context);
616
- }
617
- if (component === compilerDom.TRANSITION_GROUP) {
618
- return ssrTransformTransitionGroup(node, context);
619
- }
620
- return; // other built-in components: fallthrough
646
+ if (component === compilerDom.TRANSITION_GROUP) {
647
+ return ssrTransformTransitionGroup(node, context);
621
648
  }
622
- // Build the fallback vnode-based branch for the component's slots.
623
- // We need to clone the node into a fresh copy and use the buildSlots' logic
624
- // to get access to the children of each slot. We then compile them with
625
- // a child transform pipeline using vnode-based transforms (instead of ssr-
626
- // based ones), and save the result branch (a ReturnStatement) in an array.
627
- // The branch is retrieved when processing slots again in ssr mode.
628
- const vnodeBranches = [];
629
- const clonedNode = clone(node);
630
- return function ssrPostTransformComponent() {
631
- // Using the cloned node, build the normal VNode-based branches (for
632
- // fallback in case the child is render-fn based). Store them in an array
633
- // for later use.
634
- if (clonedNode.children.length) {
635
- compilerDom.buildSlots(clonedNode, context, (props, children) => {
636
- vnodeBranches.push(createVNodeSlotBranch(props, children, context));
637
- return compilerDom.createFunctionExpression(undefined);
638
- });
639
- }
640
- let propsExp = `null`;
641
- if (node.props.length) {
642
- // note we are not passing ssr: true here because for components, v-on
643
- // handlers should still be passed
644
- const { props, directives } = compilerDom.buildProps(node, context, undefined, true, isDynamicComponent);
645
- if (props || directives.length) {
646
- propsExp = buildSSRProps(props, directives, context);
647
- }
648
- }
649
- const wipEntries = [];
650
- wipMap.set(node, wipEntries);
651
- const buildSSRSlotFn = (props, children, loc) => {
652
- const param0 = (props && compilerDom.stringifyExpression(props)) || `_`;
653
- const fn = compilerDom.createFunctionExpression([param0, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
654
- true, // newline
655
- true, // isSlot
656
- loc);
657
- wipEntries.push({
658
- type: WIP_SLOT,
659
- fn,
660
- children,
661
- // also collect the corresponding vnode branch built earlier
662
- vnodeBranch: vnodeBranches[wipEntries.length]
663
- });
664
- return fn;
665
- };
666
- const slots = node.children.length
667
- ? compilerDom.buildSlots(node, context, buildSSRSlotFn).slots
668
- : `null`;
669
- if (typeof component !== 'string') {
670
- // dynamic component that resolved to a `resolveDynamicComponent` call
671
- // expression - since the resolved result may be a plain element (string)
672
- // or a VNode, handle it with `renderVNode`.
673
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(SSR_RENDER_VNODE), [
674
- `_push`,
675
- compilerDom.createCallExpression(context.helper(compilerDom.CREATE_VNODE), [
676
- component,
677
- propsExp,
678
- slots
679
- ]),
680
- `_parent`
681
- ]);
682
- }
683
- else {
684
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, propsExp, slots, `_parent`]);
685
- }
649
+ return;
650
+ }
651
+ const vnodeBranches = [];
652
+ const clonedNode = clone(node);
653
+ return function ssrPostTransformComponent() {
654
+ if (clonedNode.children.length) {
655
+ compilerDom.buildSlots(clonedNode, context, (props, children) => {
656
+ vnodeBranches.push(createVNodeSlotBranch(props, children, context));
657
+ return compilerDom.createFunctionExpression(void 0);
658
+ });
659
+ }
660
+ let propsExp = `null`;
661
+ if (node.props.length) {
662
+ const { props, directives } = compilerDom.buildProps(
663
+ node,
664
+ context,
665
+ void 0,
666
+ true,
667
+ isDynamicComponent
668
+ );
669
+ if (props || directives.length) {
670
+ propsExp = buildSSRProps(props, directives, context);
671
+ }
672
+ }
673
+ const wipEntries = [];
674
+ wipMap.set(node, wipEntries);
675
+ const buildSSRSlotFn = (props, children, loc) => {
676
+ const param0 = props && compilerDom.stringifyExpression(props) || `_`;
677
+ const fn = compilerDom.createFunctionExpression(
678
+ [param0, `_push`, `_parent`, `_scopeId`],
679
+ void 0,
680
+ // no return, assign body later
681
+ true,
682
+ // newline
683
+ true,
684
+ // isSlot
685
+ loc
686
+ );
687
+ wipEntries.push({
688
+ type: WIP_SLOT,
689
+ fn,
690
+ children,
691
+ // also collect the corresponding vnode branch built earlier
692
+ vnodeBranch: vnodeBranches[wipEntries.length]
693
+ });
694
+ return fn;
686
695
  };
696
+ const slots = node.children.length ? compilerDom.buildSlots(node, context, buildSSRSlotFn).slots : `null`;
697
+ if (typeof component !== "string") {
698
+ node.ssrCodegenNode = compilerDom.createCallExpression(
699
+ context.helper(SSR_RENDER_VNODE),
700
+ [
701
+ `_push`,
702
+ compilerDom.createCallExpression(context.helper(compilerDom.CREATE_VNODE), [
703
+ component,
704
+ propsExp,
705
+ slots
706
+ ]),
707
+ `_parent`
708
+ ]
709
+ );
710
+ } else {
711
+ node.ssrCodegenNode = compilerDom.createCallExpression(
712
+ context.helper(SSR_RENDER_COMPONENT),
713
+ [component, propsExp, slots, `_parent`]
714
+ );
715
+ }
716
+ };
687
717
  };
688
718
  function ssrProcessComponent(node, context, parent) {
689
- const component = componentTypeMap.get(node);
690
- if (!node.ssrCodegenNode) {
691
- // this is a built-in component that fell-through.
692
- if (component === compilerDom.TELEPORT) {
693
- return ssrProcessTeleport(node, context);
694
- }
695
- else if (component === compilerDom.SUSPENSE) {
696
- return ssrProcessSuspense(node, context);
697
- }
698
- else if (component === compilerDom.TRANSITION_GROUP) {
699
- return ssrProcessTransitionGroup(node, context);
700
- }
701
- else {
702
- // real fall-through: Transition / KeepAlive
703
- // just render its children.
704
- // #5352: if is at root level of a slot, push an empty string.
705
- // this does not affect the final output, but avoids all-comment slot
706
- // content of being treated as empty by ssrRenderSlot().
707
- if (parent.type === WIP_SLOT) {
708
- context.pushStringPart(``);
709
- }
710
- // #5351: filter out comment children inside transition
711
- if (component === compilerDom.TRANSITION) {
712
- node.children = node.children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */);
713
- }
714
- processChildren(node, context);
715
- }
719
+ const component = componentTypeMap.get(node);
720
+ if (!node.ssrCodegenNode) {
721
+ if (component === compilerDom.TELEPORT) {
722
+ return ssrProcessTeleport(node, context);
723
+ } else if (component === compilerDom.SUSPENSE) {
724
+ return ssrProcessSuspense(node, context);
725
+ } else if (component === compilerDom.TRANSITION_GROUP) {
726
+ return ssrProcessTransitionGroup(node, context);
727
+ } else {
728
+ if (parent.type === WIP_SLOT) {
729
+ context.pushStringPart(``);
730
+ }
731
+ if (component === compilerDom.TRANSITION) {
732
+ node.children = node.children.filter((c) => c.type !== 3);
733
+ }
734
+ processChildren(node, context);
716
735
  }
717
- else {
718
- // finish up slot function expressions from the 1st pass.
719
- const wipEntries = wipMap.get(node) || [];
720
- for (let i = 0; i < wipEntries.length; i++) {
721
- const { fn, vnodeBranch } = wipEntries[i];
722
- // For each slot, we generate two branches: one SSR-optimized branch and
723
- // one normal vnode-based branch. The branches are taken based on the
724
- // presence of the 2nd `_push` argument (which is only present if the slot
725
- // is called by `_ssrRenderSlot`.
726
- fn.body = compilerDom.createIfStatement(compilerDom.createSimpleExpression(`_push`, false), processChildrenAsStatement(wipEntries[i], context, false, true /* withSlotScopeId */), vnodeBranch);
727
- }
728
- // component is inside a slot, inherit slot scope Id
729
- if (context.withSlotScopeId) {
730
- node.ssrCodegenNode.arguments.push(`_scopeId`);
731
- }
732
- if (typeof component === 'string') {
733
- // static component
734
- context.pushStatement(compilerDom.createCallExpression(`_push`, [node.ssrCodegenNode]));
735
- }
736
- else {
737
- // dynamic component (`resolveDynamicComponent` call)
738
- // the codegen node is a `renderVNode` call
739
- context.pushStatement(node.ssrCodegenNode);
740
- }
736
+ } else {
737
+ const wipEntries = wipMap.get(node) || [];
738
+ for (let i = 0; i < wipEntries.length; i++) {
739
+ const { fn, vnodeBranch } = wipEntries[i];
740
+ fn.body = compilerDom.createIfStatement(
741
+ compilerDom.createSimpleExpression(`_push`, false),
742
+ processChildrenAsStatement(
743
+ wipEntries[i],
744
+ context,
745
+ false,
746
+ true
747
+ /* withSlotScopeId */
748
+ ),
749
+ vnodeBranch
750
+ );
741
751
  }
752
+ if (context.withSlotScopeId) {
753
+ node.ssrCodegenNode.arguments.push(`_scopeId`);
754
+ }
755
+ if (typeof component === "string") {
756
+ context.pushStatement(
757
+ compilerDom.createCallExpression(`_push`, [node.ssrCodegenNode])
758
+ );
759
+ } else {
760
+ context.pushStatement(node.ssrCodegenNode);
761
+ }
762
+ }
742
763
  }
743
- const rawOptionsMap = new WeakMap();
764
+ const rawOptionsMap = /* @__PURE__ */ new WeakMap();
744
765
  const [baseNodeTransforms, baseDirectiveTransforms] = compilerDom.getBaseTransformPreset(true);
745
766
  const vnodeNodeTransforms = [...baseNodeTransforms, ...compilerDom.DOMNodeTransforms];
746
767
  const vnodeDirectiveTransforms = {
747
- ...baseDirectiveTransforms,
748
- ...compilerDom.DOMDirectiveTransforms
768
+ ...baseDirectiveTransforms,
769
+ ...compilerDom.DOMDirectiveTransforms
749
770
  };
750
771
  function createVNodeSlotBranch(props, children, parentContext) {
751
- // apply a sub-transform using vnode-based transforms.
752
- const rawOptions = rawOptionsMap.get(parentContext.root);
753
- const subOptions = {
754
- ...rawOptions,
755
- // overwrite with vnode-based transforms
756
- nodeTransforms: [
757
- ...vnodeNodeTransforms,
758
- ...(rawOptions.nodeTransforms || [])
759
- ],
760
- directiveTransforms: {
761
- ...vnodeDirectiveTransforms,
762
- ...(rawOptions.directiveTransforms || {})
763
- }
764
- };
765
- // wrap the children with a wrapper template for proper children treatment.
766
- const wrapperNode = {
767
- type: 1 /* NodeTypes.ELEMENT */,
768
- ns: 0 /* Namespaces.HTML */,
769
- tag: 'template',
770
- tagType: 3 /* ElementTypes.TEMPLATE */,
771
- isSelfClosing: false,
772
- // important: provide v-slot="props" on the wrapper for proper
773
- // scope analysis
774
- props: [
775
- {
776
- type: 7 /* NodeTypes.DIRECTIVE */,
777
- name: 'slot',
778
- exp: props,
779
- arg: undefined,
780
- modifiers: [],
781
- loc: compilerDom.locStub
782
- }
783
- ],
784
- children,
785
- loc: compilerDom.locStub,
786
- codegenNode: undefined
787
- };
788
- subTransform(wrapperNode, subOptions, parentContext);
789
- return compilerDom.createReturnStatement(children);
772
+ const rawOptions = rawOptionsMap.get(parentContext.root);
773
+ const subOptions = {
774
+ ...rawOptions,
775
+ // overwrite with vnode-based transforms
776
+ nodeTransforms: [
777
+ ...vnodeNodeTransforms,
778
+ ...rawOptions.nodeTransforms || []
779
+ ],
780
+ directiveTransforms: {
781
+ ...vnodeDirectiveTransforms,
782
+ ...rawOptions.directiveTransforms || {}
783
+ }
784
+ };
785
+ const wrapperNode = {
786
+ type: 1,
787
+ ns: 0,
788
+ tag: "template",
789
+ tagType: 3,
790
+ isSelfClosing: false,
791
+ // important: provide v-slot="props" on the wrapper for proper
792
+ // scope analysis
793
+ props: [
794
+ {
795
+ type: 7,
796
+ name: "slot",
797
+ exp: props,
798
+ arg: void 0,
799
+ modifiers: [],
800
+ loc: compilerDom.locStub
801
+ }
802
+ ],
803
+ children,
804
+ loc: compilerDom.locStub,
805
+ codegenNode: void 0
806
+ };
807
+ subTransform(wrapperNode, subOptions, parentContext);
808
+ return compilerDom.createReturnStatement(children);
790
809
  }
791
810
  function subTransform(node, options, parentContext) {
792
- const childRoot = compilerDom.createRoot([node]);
793
- const childContext = compilerDom.createTransformContext(childRoot, options);
794
- // this sub transform is for vnode fallback branch so it should be handled
795
- // like normal render functions
796
- childContext.ssr = false;
797
- // inherit parent scope analysis state
798
- childContext.scopes = { ...parentContext.scopes };
799
- childContext.identifiers = { ...parentContext.identifiers };
800
- childContext.imports = parentContext.imports;
801
- // traverse
802
- compilerDom.traverseNode(childRoot, childContext);
803
- ['helpers', 'components', 'directives'].forEach(key => {
804
- childContext[key].forEach((value, helperKey) => {
805
- if (key === 'helpers') {
806
- const parentCount = parentContext.helpers.get(helperKey);
807
- if (parentCount === undefined) {
808
- parentContext.helpers.set(helperKey, value);
809
- }
810
- else {
811
- parentContext.helpers.set(helperKey, value + parentCount);
812
- }
813
- }
814
- else {
815
- parentContext[key].add(value);
816
- }
817
- });
811
+ const childRoot = compilerDom.createRoot([node]);
812
+ const childContext = compilerDom.createTransformContext(childRoot, options);
813
+ childContext.ssr = false;
814
+ childContext.scopes = { ...parentContext.scopes };
815
+ childContext.identifiers = { ...parentContext.identifiers };
816
+ childContext.imports = parentContext.imports;
817
+ compilerDom.traverseNode(childRoot, childContext);
818
+ ["helpers", "components", "directives"].forEach((key) => {
819
+ childContext[key].forEach((value, helperKey) => {
820
+ if (key === "helpers") {
821
+ const parentCount = parentContext.helpers.get(helperKey);
822
+ if (parentCount === void 0) {
823
+ parentContext.helpers.set(helperKey, value);
824
+ } else {
825
+ parentContext.helpers.set(helperKey, value + parentCount);
826
+ }
827
+ } else {
828
+ parentContext[key].add(value);
829
+ }
818
830
  });
819
- // imports/hoists are not merged because:
820
- // - imports are only used for asset urls and should be consistent between
821
- // node/client branches
822
- // - hoists are not enabled for the client branch here
831
+ });
823
832
  }
824
833
  function clone(v) {
825
- if (shared.isArray(v)) {
826
- return v.map(clone);
827
- }
828
- else if (shared.isObject(v)) {
829
- const res = {};
830
- for (const key in v) {
831
- res[key] = clone(v[key]);
832
- }
833
- return res;
834
- }
835
- else {
836
- return v;
834
+ if (shared.isArray(v)) {
835
+ return v.map(clone);
836
+ } else if (shared.isObject(v)) {
837
+ const res = {};
838
+ for (const key in v) {
839
+ res[key] = clone(v[key]);
837
840
  }
841
+ return res;
842
+ } else {
843
+ return v;
844
+ }
838
845
  }
839
846
 
840
- // Because SSR codegen output is completely different from client-side output
841
- // (e.g. multiple elements can be concatenated into a single template literal
842
- // instead of each getting a corresponding call), we need to apply an extra
843
- // transform pass to convert the template AST into a fresh JS AST before
844
- // passing it to codegen.
845
847
  function ssrCodegenTransform(ast, options) {
846
- const context = createSSRTransformContext(ast, options);
847
- // inject SFC <style> CSS variables
848
- // we do this instead of inlining the expression to ensure the vars are
849
- // only resolved once per render
850
- if (options.ssrCssVars) {
851
- const cssContext = compilerDom.createTransformContext(compilerDom.createRoot([]), options);
852
- const varsExp = compilerDom.processExpression(compilerDom.createSimpleExpression(options.ssrCssVars, false), cssContext);
853
- context.body.push(compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`]));
854
- Array.from(cssContext.helpers.keys()).forEach(helper => {
855
- ast.helpers.add(helper);
856
- });
857
- }
858
- const isFragment = ast.children.length > 1 && ast.children.some(c => !compilerDom.isText(c));
859
- processChildren(ast, context, isFragment);
860
- ast.codegenNode = compilerDom.createBlockStatement(context.body);
861
- // Finalize helpers.
862
- // We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
863
- ast.ssrHelpers = Array.from(new Set([
864
- ...Array.from(ast.helpers).filter(h => h in ssrHelpers),
865
- ...context.helpers
866
- ]));
867
- ast.helpers = new Set(Array.from(ast.helpers).filter(h => !(h in ssrHelpers)));
848
+ const context = createSSRTransformContext(ast, options);
849
+ if (options.ssrCssVars) {
850
+ const cssContext = compilerDom.createTransformContext(compilerDom.createRoot([]), options);
851
+ const varsExp = compilerDom.processExpression(
852
+ compilerDom.createSimpleExpression(options.ssrCssVars, false),
853
+ cssContext
854
+ );
855
+ context.body.push(
856
+ compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`])
857
+ );
858
+ Array.from(cssContext.helpers.keys()).forEach((helper) => {
859
+ ast.helpers.add(helper);
860
+ });
861
+ }
862
+ const isFragment = ast.children.length > 1 && ast.children.some((c) => !compilerDom.isText(c));
863
+ processChildren(ast, context, isFragment);
864
+ ast.codegenNode = compilerDom.createBlockStatement(context.body);
865
+ ast.ssrHelpers = Array.from(
866
+ /* @__PURE__ */ new Set([
867
+ ...Array.from(ast.helpers).filter((h) => h in ssrHelpers),
868
+ ...context.helpers
869
+ ])
870
+ );
871
+ ast.helpers = new Set(Array.from(ast.helpers).filter((h) => !(h in ssrHelpers)));
868
872
  }
869
- function createSSRTransformContext(root, options, helpers = new Set(), withSlotScopeId = false) {
870
- const body = [];
871
- let currentString = null;
872
- return {
873
- root,
874
- options,
875
- body,
876
- helpers,
877
- withSlotScopeId,
878
- onError: options.onError ||
879
- (e => {
880
- throw e;
881
- }),
882
- helper(name) {
883
- helpers.add(name);
884
- return name;
885
- },
886
- pushStringPart(part) {
887
- if (!currentString) {
888
- const currentCall = compilerDom.createCallExpression(`_push`);
889
- body.push(currentCall);
890
- currentString = compilerDom.createTemplateLiteral([]);
891
- currentCall.arguments.push(currentString);
892
- }
893
- const bufferedElements = currentString.elements;
894
- const lastItem = bufferedElements[bufferedElements.length - 1];
895
- if (shared.isString(part) && shared.isString(lastItem)) {
896
- bufferedElements[bufferedElements.length - 1] += part;
897
- }
898
- else {
899
- bufferedElements.push(part);
900
- }
901
- },
902
- pushStatement(statement) {
903
- // close current string
904
- currentString = null;
905
- body.push(statement);
906
- }
907
- };
873
+ function createSSRTransformContext(root, options, helpers = /* @__PURE__ */ new Set(), withSlotScopeId = false) {
874
+ const body = [];
875
+ let currentString = null;
876
+ return {
877
+ root,
878
+ options,
879
+ body,
880
+ helpers,
881
+ withSlotScopeId,
882
+ onError: options.onError || ((e) => {
883
+ throw e;
884
+ }),
885
+ helper(name) {
886
+ helpers.add(name);
887
+ return name;
888
+ },
889
+ pushStringPart(part) {
890
+ if (!currentString) {
891
+ const currentCall = compilerDom.createCallExpression(`_push`);
892
+ body.push(currentCall);
893
+ currentString = compilerDom.createTemplateLiteral([]);
894
+ currentCall.arguments.push(currentString);
895
+ }
896
+ const bufferedElements = currentString.elements;
897
+ const lastItem = bufferedElements[bufferedElements.length - 1];
898
+ if (shared.isString(part) && shared.isString(lastItem)) {
899
+ bufferedElements[bufferedElements.length - 1] += part;
900
+ } else {
901
+ bufferedElements.push(part);
902
+ }
903
+ },
904
+ pushStatement(statement) {
905
+ currentString = null;
906
+ body.push(statement);
907
+ }
908
+ };
908
909
  }
909
910
  function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
910
- // ensure child inherits parent helpers
911
- return createSSRTransformContext(parent.root, parent.options, parent.helpers, withSlotScopeId);
911
+ return createSSRTransformContext(
912
+ parent.root,
913
+ parent.options,
914
+ parent.helpers,
915
+ withSlotScopeId
916
+ );
912
917
  }
913
918
  function processChildren(parent, context, asFragment = false, disableNestedFragments = false) {
914
- if (asFragment) {
915
- context.pushStringPart(`<!--[-->`);
916
- }
917
- const { children } = parent;
918
- for (let i = 0; i < children.length; i++) {
919
- const child = children[i];
920
- switch (child.type) {
921
- case 1 /* NodeTypes.ELEMENT */:
922
- switch (child.tagType) {
923
- case 0 /* ElementTypes.ELEMENT */:
924
- ssrProcessElement(child, context);
925
- break;
926
- case 1 /* ElementTypes.COMPONENT */:
927
- ssrProcessComponent(child, context, parent);
928
- break;
929
- case 2 /* ElementTypes.SLOT */:
930
- ssrProcessSlotOutlet(child, context);
931
- break;
932
- case 3 /* ElementTypes.TEMPLATE */:
933
- // TODO
934
- break;
935
- default:
936
- context.onError(createSSRCompilerError(64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */, child.loc));
937
- // make sure we exhaust all possible types
938
- const exhaustiveCheck = child;
939
- return exhaustiveCheck;
940
- }
941
- break;
942
- case 2 /* NodeTypes.TEXT */:
943
- context.pushStringPart(shared.escapeHtml(child.content));
944
- break;
945
- case 3 /* NodeTypes.COMMENT */:
946
- // no need to escape comment here because the AST can only
947
- // contain valid comments.
948
- context.pushStringPart(`<!--${child.content}-->`);
949
- break;
950
- case 5 /* NodeTypes.INTERPOLATION */:
951
- context.pushStringPart(compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [child.content]));
952
- break;
953
- case 9 /* NodeTypes.IF */:
954
- ssrProcessIf(child, context, disableNestedFragments);
955
- break;
956
- case 11 /* NodeTypes.FOR */:
957
- ssrProcessFor(child, context, disableNestedFragments);
958
- break;
959
- case 10 /* NodeTypes.IF_BRANCH */:
960
- // no-op - handled by ssrProcessIf
961
- break;
962
- case 12 /* NodeTypes.TEXT_CALL */:
963
- case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
964
- // no-op - these two types can never appear as template child node since
965
- // `transformText` is not used during SSR compile.
966
- break;
967
- default:
968
- context.onError(createSSRCompilerError(64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */, child.loc));
969
- // make sure we exhaust all possible types
970
- const exhaustiveCheck = child;
971
- return exhaustiveCheck;
919
+ if (asFragment) {
920
+ context.pushStringPart(`<!--[-->`);
921
+ }
922
+ const { children } = parent;
923
+ for (let i = 0; i < children.length; i++) {
924
+ const child = children[i];
925
+ switch (child.type) {
926
+ case 1:
927
+ switch (child.tagType) {
928
+ case 0:
929
+ ssrProcessElement(child, context);
930
+ break;
931
+ case 1:
932
+ ssrProcessComponent(child, context, parent);
933
+ break;
934
+ case 2:
935
+ ssrProcessSlotOutlet(child, context);
936
+ break;
937
+ case 3:
938
+ break;
939
+ default:
940
+ context.onError(
941
+ createSSRCompilerError(
942
+ 64,
943
+ child.loc
944
+ )
945
+ );
946
+ const exhaustiveCheck2 = child;
947
+ return exhaustiveCheck2;
972
948
  }
949
+ break;
950
+ case 2:
951
+ context.pushStringPart(shared.escapeHtml(child.content));
952
+ break;
953
+ case 3:
954
+ context.pushStringPart(`<!--${child.content}-->`);
955
+ break;
956
+ case 5:
957
+ context.pushStringPart(
958
+ compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [child.content])
959
+ );
960
+ break;
961
+ case 9:
962
+ ssrProcessIf(child, context, disableNestedFragments);
963
+ break;
964
+ case 11:
965
+ ssrProcessFor(child, context, disableNestedFragments);
966
+ break;
967
+ case 10:
968
+ break;
969
+ case 12:
970
+ case 8:
971
+ break;
972
+ default:
973
+ context.onError(
974
+ createSSRCompilerError(
975
+ 64,
976
+ child.loc
977
+ )
978
+ );
979
+ const exhaustiveCheck = child;
980
+ return exhaustiveCheck;
973
981
  }
974
- if (asFragment) {
975
- context.pushStringPart(`<!--]-->`);
976
- }
982
+ }
983
+ if (asFragment) {
984
+ context.pushStringPart(`<!--]-->`);
985
+ }
977
986
  }
978
987
  function processChildrenAsStatement(parent, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
979
- const childContext = createChildContext(parentContext, withSlotScopeId);
980
- processChildren(parent, childContext, asFragment);
981
- return compilerDom.createBlockStatement(childContext.body);
988
+ const childContext = createChildContext(parentContext, withSlotScopeId);
989
+ processChildren(parent, childContext, asFragment);
990
+ return compilerDom.createBlockStatement(childContext.body);
982
991
  }
983
992
 
984
993
  const ssrTransformModel = (dir, node, context) => {
985
- const model = dir.exp;
986
- function checkDuplicatedValue() {
987
- const value = compilerDom.findProp(node, 'value');
988
- if (value) {
989
- context.onError(compilerDom.createDOMCompilerError(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
990
- }
994
+ const model = dir.exp;
995
+ function checkDuplicatedValue() {
996
+ const value = compilerDom.findProp(node, "value");
997
+ if (value) {
998
+ context.onError(
999
+ compilerDom.createDOMCompilerError(
1000
+ 58,
1001
+ value.loc
1002
+ )
1003
+ );
991
1004
  }
992
- if (node.tagType === 0 /* ElementTypes.ELEMENT */) {
993
- const res = { props: [] };
994
- const defaultProps = [
995
- // default value binding for text type inputs
996
- compilerDom.createObjectProperty(`value`, model)
997
- ];
998
- if (node.tag === 'input') {
999
- const type = compilerDom.findProp(node, 'type');
1000
- if (type) {
1001
- const value = findValueBinding(node);
1002
- if (type.type === 7 /* NodeTypes.DIRECTIVE */) {
1003
- // dynamic type
1004
- res.ssrTagParts = [
1005
- compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
1006
- type.exp,
1007
- model,
1008
- value
1009
- ])
1010
- ];
1011
- }
1012
- else if (type.value) {
1013
- // static type
1014
- switch (type.value.content) {
1015
- case 'radio':
1016
- res.props = [
1017
- compilerDom.createObjectProperty(`checked`, compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1018
- model,
1019
- value
1020
- ]))
1021
- ];
1022
- break;
1023
- case 'checkbox':
1024
- const trueValueBinding = compilerDom.findProp(node, 'true-value');
1025
- if (trueValueBinding) {
1026
- const trueValue = trueValueBinding.type === 6 /* NodeTypes.ATTRIBUTE */
1027
- ? JSON.stringify(trueValueBinding.value.content)
1028
- : trueValueBinding.exp;
1029
- res.props = [
1030
- compilerDom.createObjectProperty(`checked`, compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1031
- model,
1032
- trueValue
1033
- ]))
1034
- ];
1035
- }
1036
- else {
1037
- res.props = [
1038
- compilerDom.createObjectProperty(`checked`, compilerDom.createConditionalExpression(compilerDom.createCallExpression(`Array.isArray`, [model]), compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1039
- model,
1040
- value
1041
- ]), model))
1042
- ];
1043
- }
1044
- break;
1045
- case 'file':
1046
- context.onError(compilerDom.createDOMCompilerError(57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
1047
- break;
1048
- default:
1049
- checkDuplicatedValue();
1050
- res.props = defaultProps;
1051
- break;
1052
- }
1053
- }
1054
- }
1055
- else if (compilerDom.hasDynamicKeyVBind(node)) ;
1056
- else {
1057
- // text type
1058
- checkDuplicatedValue();
1059
- res.props = defaultProps;
1060
- }
1061
- }
1062
- else if (node.tag === 'textarea') {
1063
- checkDuplicatedValue();
1064
- node.children = [compilerDom.createInterpolation(model, model.loc)];
1065
- }
1066
- else if (node.tag === 'select') ;
1067
- else {
1068
- context.onError(compilerDom.createDOMCompilerError(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
1005
+ }
1006
+ if (node.tagType === 0) {
1007
+ const res = { props: [] };
1008
+ const defaultProps = [
1009
+ // default value binding for text type inputs
1010
+ compilerDom.createObjectProperty(`value`, model)
1011
+ ];
1012
+ if (node.tag === "input") {
1013
+ const type = compilerDom.findProp(node, "type");
1014
+ if (type) {
1015
+ const value = findValueBinding(node);
1016
+ if (type.type === 7) {
1017
+ res.ssrTagParts = [
1018
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
1019
+ type.exp,
1020
+ model,
1021
+ value
1022
+ ])
1023
+ ];
1024
+ } else if (type.value) {
1025
+ switch (type.value.content) {
1026
+ case "radio":
1027
+ res.props = [
1028
+ compilerDom.createObjectProperty(
1029
+ `checked`,
1030
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1031
+ model,
1032
+ value
1033
+ ])
1034
+ )
1035
+ ];
1036
+ break;
1037
+ case "checkbox":
1038
+ const trueValueBinding = compilerDom.findProp(node, "true-value");
1039
+ if (trueValueBinding) {
1040
+ const trueValue = trueValueBinding.type === 6 ? JSON.stringify(trueValueBinding.value.content) : trueValueBinding.exp;
1041
+ res.props = [
1042
+ compilerDom.createObjectProperty(
1043
+ `checked`,
1044
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1045
+ model,
1046
+ trueValue
1047
+ ])
1048
+ )
1049
+ ];
1050
+ } else {
1051
+ res.props = [
1052
+ compilerDom.createObjectProperty(
1053
+ `checked`,
1054
+ compilerDom.createConditionalExpression(
1055
+ compilerDom.createCallExpression(`Array.isArray`, [model]),
1056
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1057
+ model,
1058
+ value
1059
+ ]),
1060
+ model
1061
+ )
1062
+ )
1063
+ ];
1064
+ }
1065
+ break;
1066
+ case "file":
1067
+ context.onError(
1068
+ compilerDom.createDOMCompilerError(
1069
+ 57,
1070
+ dir.loc
1071
+ )
1072
+ );
1073
+ break;
1074
+ default:
1075
+ checkDuplicatedValue();
1076
+ res.props = defaultProps;
1077
+ break;
1078
+ }
1069
1079
  }
1070
- return res;
1071
- }
1072
- else {
1073
- // component v-model
1074
- return compilerDom.transformModel(dir, node, context);
1080
+ } else if (compilerDom.hasDynamicKeyVBind(node)) ; else {
1081
+ checkDuplicatedValue();
1082
+ res.props = defaultProps;
1083
+ }
1084
+ } else if (node.tag === "textarea") {
1085
+ checkDuplicatedValue();
1086
+ node.children = [compilerDom.createInterpolation(model, model.loc)];
1087
+ } else if (node.tag === "select") ; else {
1088
+ context.onError(
1089
+ compilerDom.createDOMCompilerError(
1090
+ 55,
1091
+ dir.loc
1092
+ )
1093
+ );
1075
1094
  }
1095
+ return res;
1096
+ } else {
1097
+ return compilerDom.transformModel(dir, node, context);
1098
+ }
1076
1099
  };
1077
1100
  function findValueBinding(node) {
1078
- const valueBinding = compilerDom.findProp(node, 'value');
1079
- return valueBinding
1080
- ? valueBinding.type === 7 /* NodeTypes.DIRECTIVE */
1081
- ? valueBinding.exp
1082
- : compilerDom.createSimpleExpression(valueBinding.value.content, true)
1083
- : compilerDom.createSimpleExpression(`null`, false);
1101
+ const valueBinding = compilerDom.findProp(node, "value");
1102
+ return valueBinding ? valueBinding.type === 7 ? valueBinding.exp : compilerDom.createSimpleExpression(valueBinding.value.content, true) : compilerDom.createSimpleExpression(`null`, false);
1084
1103
  }
1085
1104
 
1086
1105
  const ssrTransformShow = (dir, node, context) => {
1087
- if (!dir.exp) {
1088
- context.onError(compilerDom.createDOMCompilerError(59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */));
1089
- }
1090
- return {
1091
- props: [
1092
- compilerDom.createObjectProperty(`style`, compilerDom.createConditionalExpression(dir.exp, compilerDom.createSimpleExpression(`null`, false), compilerDom.createObjectExpression([
1093
- compilerDom.createObjectProperty(`display`, compilerDom.createSimpleExpression(`none`, true))
1094
- ]), false /* no newline */))
1095
- ]
1096
- };
1106
+ if (!dir.exp) {
1107
+ context.onError(
1108
+ compilerDom.createDOMCompilerError(59)
1109
+ );
1110
+ }
1111
+ return {
1112
+ props: [
1113
+ compilerDom.createObjectProperty(
1114
+ `style`,
1115
+ compilerDom.createConditionalExpression(
1116
+ dir.exp,
1117
+ compilerDom.createSimpleExpression(`null`, false),
1118
+ compilerDom.createObjectExpression([
1119
+ compilerDom.createObjectProperty(
1120
+ `display`,
1121
+ compilerDom.createSimpleExpression(`none`, true)
1122
+ )
1123
+ ]),
1124
+ false
1125
+ /* no newline */
1126
+ )
1127
+ )
1128
+ ]
1129
+ };
1097
1130
  };
1098
1131
 
1099
- const filterChild = (node) => node.children.filter(n => n.type !== 3 /* NodeTypes.COMMENT */);
1132
+ const filterChild = (node) => node.children.filter((n) => n.type !== 3);
1100
1133
  const hasSingleChild = (node) => filterChild(node).length === 1;
1101
1134
  const ssrInjectFallthroughAttrs = (node, context) => {
1102
- // _attrs is provided as a function argument.
1103
- // mark it as a known identifier so that it doesn't get prefixed by
1104
- // transformExpression.
1105
- if (node.type === 0 /* NodeTypes.ROOT */) {
1106
- context.identifiers._attrs = 1;
1107
- }
1108
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1109
- node.tagType === 1 /* ElementTypes.COMPONENT */ &&
1110
- (compilerDom.isBuiltInType(node.tag, 'Transition') ||
1111
- compilerDom.isBuiltInType(node.tag, 'KeepAlive'))) {
1112
- const rootChildren = filterChild(context.root);
1113
- if (rootChildren.length === 1 && rootChildren[0] === node) {
1114
- if (hasSingleChild(node)) {
1115
- injectFallthroughAttrs(node.children[0]);
1116
- }
1117
- return;
1118
- }
1119
- }
1120
- const parent = context.parent;
1121
- if (!parent || parent.type !== 0 /* NodeTypes.ROOT */) {
1122
- return;
1123
- }
1124
- if (node.type === 10 /* NodeTypes.IF_BRANCH */ && hasSingleChild(node)) {
1125
- // detect cases where the parent v-if is not the only root level node
1126
- let hasEncounteredIf = false;
1127
- for (const c of filterChild(parent)) {
1128
- if (c.type === 9 /* NodeTypes.IF */ ||
1129
- (c.type === 1 /* NodeTypes.ELEMENT */ && compilerDom.findDir(c, 'if'))) {
1130
- // multiple root v-if
1131
- if (hasEncounteredIf)
1132
- return;
1133
- hasEncounteredIf = true;
1134
- }
1135
- else if (
1136
- // node before v-if
1137
- !hasEncounteredIf ||
1138
- // non else nodes
1139
- !(c.type === 1 /* NodeTypes.ELEMENT */ && compilerDom.findDir(c, /else/, true))) {
1140
- return;
1141
- }
1142
- }
1135
+ if (node.type === 0) {
1136
+ context.identifiers._attrs = 1;
1137
+ }
1138
+ if (node.type === 1 && node.tagType === 1 && (compilerDom.isBuiltInType(node.tag, "Transition") || compilerDom.isBuiltInType(node.tag, "KeepAlive"))) {
1139
+ const rootChildren = filterChild(context.root);
1140
+ if (rootChildren.length === 1 && rootChildren[0] === node) {
1141
+ if (hasSingleChild(node)) {
1143
1142
  injectFallthroughAttrs(node.children[0]);
1143
+ }
1144
+ return;
1144
1145
  }
1145
- else if (hasSingleChild(parent)) {
1146
- injectFallthroughAttrs(node);
1146
+ }
1147
+ const parent = context.parent;
1148
+ if (!parent || parent.type !== 0) {
1149
+ return;
1150
+ }
1151
+ if (node.type === 10 && hasSingleChild(node)) {
1152
+ let hasEncounteredIf = false;
1153
+ for (const c of filterChild(parent)) {
1154
+ if (c.type === 9 || c.type === 1 && compilerDom.findDir(c, "if")) {
1155
+ if (hasEncounteredIf)
1156
+ return;
1157
+ hasEncounteredIf = true;
1158
+ } else if (
1159
+ // node before v-if
1160
+ !hasEncounteredIf || // non else nodes
1161
+ !(c.type === 1 && compilerDom.findDir(c, /else/, true))
1162
+ ) {
1163
+ return;
1164
+ }
1147
1165
  }
1166
+ injectFallthroughAttrs(node.children[0]);
1167
+ } else if (hasSingleChild(parent)) {
1168
+ injectFallthroughAttrs(node);
1169
+ }
1148
1170
  };
1149
1171
  function injectFallthroughAttrs(node) {
1150
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1151
- (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
1152
- node.tagType === 1 /* ElementTypes.COMPONENT */) &&
1153
- !compilerDom.findDir(node, 'for')) {
1154
- node.props.push({
1155
- type: 7 /* NodeTypes.DIRECTIVE */,
1156
- name: 'bind',
1157
- arg: undefined,
1158
- exp: compilerDom.createSimpleExpression(`_attrs`, false),
1159
- modifiers: [],
1160
- loc: compilerDom.locStub
1161
- });
1162
- }
1172
+ if (node.type === 1 && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1173
+ node.props.push({
1174
+ type: 7,
1175
+ name: "bind",
1176
+ arg: void 0,
1177
+ exp: compilerDom.createSimpleExpression(`_attrs`, false),
1178
+ modifiers: [],
1179
+ loc: compilerDom.locStub
1180
+ });
1181
+ }
1163
1182
  }
1164
1183
 
1165
1184
  const ssrInjectCssVars = (node, context) => {
1166
- if (!context.ssrCssVars) {
1167
- return;
1168
- }
1169
- // _cssVars is initialized once per render function
1170
- // the code is injected in ssrCodegenTransform when creating the
1171
- // ssr transform context
1172
- if (node.type === 0 /* NodeTypes.ROOT */) {
1173
- context.identifiers._cssVars = 1;
1174
- }
1175
- const parent = context.parent;
1176
- if (!parent || parent.type !== 0 /* NodeTypes.ROOT */) {
1177
- return;
1178
- }
1179
- if (node.type === 10 /* NodeTypes.IF_BRANCH */) {
1180
- for (const child of node.children) {
1181
- injectCssVars(child);
1182
- }
1183
- }
1184
- else {
1185
- injectCssVars(node);
1185
+ if (!context.ssrCssVars) {
1186
+ return;
1187
+ }
1188
+ if (node.type === 0) {
1189
+ context.identifiers._cssVars = 1;
1190
+ }
1191
+ const parent = context.parent;
1192
+ if (!parent || parent.type !== 0) {
1193
+ return;
1194
+ }
1195
+ if (node.type === 10) {
1196
+ for (const child of node.children) {
1197
+ injectCssVars(child);
1186
1198
  }
1199
+ } else {
1200
+ injectCssVars(node);
1201
+ }
1187
1202
  };
1188
1203
  function injectCssVars(node) {
1189
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1190
- (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
1191
- node.tagType === 1 /* ElementTypes.COMPONENT */) &&
1192
- !compilerDom.findDir(node, 'for')) {
1193
- if (compilerDom.isBuiltInType(node.tag, 'Suspense')) {
1194
- for (const child of node.children) {
1195
- if (child.type === 1 /* NodeTypes.ELEMENT */ &&
1196
- child.tagType === 3 /* ElementTypes.TEMPLATE */) {
1197
- // suspense slot
1198
- child.children.forEach(injectCssVars);
1199
- }
1200
- else {
1201
- injectCssVars(child);
1202
- }
1203
- }
1204
- }
1205
- else {
1206
- node.props.push({
1207
- type: 7 /* NodeTypes.DIRECTIVE */,
1208
- name: 'bind',
1209
- arg: undefined,
1210
- exp: compilerDom.createSimpleExpression(`_cssVars`, false),
1211
- modifiers: [],
1212
- loc: compilerDom.locStub
1213
- });
1204
+ if (node.type === 1 && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1205
+ if (compilerDom.isBuiltInType(node.tag, "Suspense")) {
1206
+ for (const child of node.children) {
1207
+ if (child.type === 1 && child.tagType === 3) {
1208
+ child.children.forEach(injectCssVars);
1209
+ } else {
1210
+ injectCssVars(child);
1214
1211
  }
1212
+ }
1213
+ } else {
1214
+ node.props.push({
1215
+ type: 7,
1216
+ name: "bind",
1217
+ arg: void 0,
1218
+ exp: compilerDom.createSimpleExpression(`_cssVars`, false),
1219
+ modifiers: [],
1220
+ loc: compilerDom.locStub
1221
+ });
1215
1222
  }
1223
+ }
1216
1224
  }
1217
1225
 
1218
1226
  function compile(template, options = {}) {
1219
- options = {
1220
- ...options,
1221
- // apply DOM-specific parsing options
1222
- ...compilerDom.parserOptions,
1223
- ssr: true,
1224
- inSSR: true,
1225
- scopeId: options.mode === 'function' ? null : options.scopeId,
1226
- // always prefix since compiler-ssr doesn't have size concern
1227
- prefixIdentifiers: true,
1228
- // disable optimizations that are unnecessary for ssr
1229
- cacheHandlers: false,
1230
- hoistStatic: false
1231
- };
1232
- const ast = compilerDom.baseParse(template, options);
1233
- // Save raw options for AST. This is needed when performing sub-transforms
1234
- // on slot vnode branches.
1235
- rawOptionsMap.set(ast, options);
1236
- compilerDom.transform(ast, {
1237
- ...options,
1238
- hoistStatic: false,
1239
- nodeTransforms: [
1240
- ssrTransformIf,
1241
- ssrTransformFor,
1242
- compilerDom.trackVForSlotScopes,
1243
- compilerDom.transformExpression,
1244
- ssrTransformSlotOutlet,
1245
- ssrInjectFallthroughAttrs,
1246
- ssrInjectCssVars,
1247
- ssrTransformElement,
1248
- ssrTransformComponent,
1249
- compilerDom.trackSlotScopes,
1250
- compilerDom.transformStyle,
1251
- ...(options.nodeTransforms || []) // user transforms
1252
- ],
1253
- directiveTransforms: {
1254
- // reusing core v-bind
1255
- bind: compilerDom.transformBind,
1256
- on: compilerDom.transformOn,
1257
- // model and show has dedicated SSR handling
1258
- model: ssrTransformModel,
1259
- show: ssrTransformShow,
1260
- // the following are ignored during SSR
1261
- // on: noopDirectiveTransform,
1262
- cloak: compilerDom.noopDirectiveTransform,
1263
- once: compilerDom.noopDirectiveTransform,
1264
- memo: compilerDom.noopDirectiveTransform,
1265
- ...(options.directiveTransforms || {}) // user transforms
1266
- }
1267
- });
1268
- // traverse the template AST and convert into SSR codegen AST
1269
- // by replacing ast.codegenNode.
1270
- ssrCodegenTransform(ast, options);
1271
- return compilerDom.generate(ast, options);
1227
+ options = {
1228
+ ...options,
1229
+ // apply DOM-specific parsing options
1230
+ ...compilerDom.parserOptions,
1231
+ ssr: true,
1232
+ inSSR: true,
1233
+ scopeId: options.mode === "function" ? null : options.scopeId,
1234
+ // always prefix since compiler-ssr doesn't have size concern
1235
+ prefixIdentifiers: true,
1236
+ // disable optimizations that are unnecessary for ssr
1237
+ cacheHandlers: false,
1238
+ hoistStatic: false
1239
+ };
1240
+ const ast = compilerDom.baseParse(template, options);
1241
+ rawOptionsMap.set(ast, options);
1242
+ compilerDom.transform(ast, {
1243
+ ...options,
1244
+ hoistStatic: false,
1245
+ nodeTransforms: [
1246
+ ssrTransformIf,
1247
+ ssrTransformFor,
1248
+ compilerDom.trackVForSlotScopes,
1249
+ compilerDom.transformExpression,
1250
+ ssrTransformSlotOutlet,
1251
+ ssrInjectFallthroughAttrs,
1252
+ ssrInjectCssVars,
1253
+ ssrTransformElement,
1254
+ ssrTransformComponent,
1255
+ compilerDom.trackSlotScopes,
1256
+ compilerDom.transformStyle,
1257
+ ...options.nodeTransforms || []
1258
+ // user transforms
1259
+ ],
1260
+ directiveTransforms: {
1261
+ // reusing core v-bind
1262
+ bind: compilerDom.transformBind,
1263
+ on: compilerDom.transformOn,
1264
+ // model and show has dedicated SSR handling
1265
+ model: ssrTransformModel,
1266
+ show: ssrTransformShow,
1267
+ // the following are ignored during SSR
1268
+ // on: noopDirectiveTransform,
1269
+ cloak: compilerDom.noopDirectiveTransform,
1270
+ once: compilerDom.noopDirectiveTransform,
1271
+ memo: compilerDom.noopDirectiveTransform,
1272
+ ...options.directiveTransforms || {}
1273
+ // user transforms
1274
+ }
1275
+ });
1276
+ ssrCodegenTransform(ast, options);
1277
+ return compilerDom.generate(ast, options);
1272
1278
  }
1273
1279
 
1274
1280
  exports.compile = compile;