source: node_modules/@vue/compiler-ssr/dist/compiler-ssr.cjs.js@ 3d60932

Last change on this file since 3d60932 was 57e58a3, checked in by ste08 <sjovanoska@…>, 4 months ago

Initial commit

  • Property mode set to 100644
File size: 44.7 KB
RevLine 
[57e58a3]1/**
2* @vue/compiler-ssr v3.5.13
3* (c) 2018-present Yuxi (Evan) You and Vue contributors
4* @license MIT
5**/
6'use strict';
7
8Object.defineProperty(exports, '__esModule', { value: true });
9
10var compilerDom = require('@vue/compiler-dom');
11var shared = require('@vue/shared');
12
13const SSR_INTERPOLATE = Symbol(`ssrInterpolate`);
14const SSR_RENDER_VNODE = Symbol(`ssrRenderVNode`);
15const SSR_RENDER_COMPONENT = Symbol(`ssrRenderComponent`);
16const SSR_RENDER_SLOT = Symbol(`ssrRenderSlot`);
17const SSR_RENDER_SLOT_INNER = Symbol(`ssrRenderSlotInner`);
18const SSR_RENDER_CLASS = Symbol(`ssrRenderClass`);
19const SSR_RENDER_STYLE = Symbol(`ssrRenderStyle`);
20const SSR_RENDER_ATTRS = Symbol(`ssrRenderAttrs`);
21const SSR_RENDER_ATTR = Symbol(`ssrRenderAttr`);
22const SSR_RENDER_DYNAMIC_ATTR = Symbol(`ssrRenderDynamicAttr`);
23const SSR_RENDER_LIST = Symbol(`ssrRenderList`);
24const SSR_INCLUDE_BOOLEAN_ATTR = Symbol(
25 `ssrIncludeBooleanAttr`
26);
27const SSR_LOOSE_EQUAL = Symbol(`ssrLooseEqual`);
28const SSR_LOOSE_CONTAIN = Symbol(`ssrLooseContain`);
29const SSR_RENDER_DYNAMIC_MODEL = Symbol(
30 `ssrRenderDynamicModel`
31);
32const SSR_GET_DYNAMIC_MODEL_PROPS = Symbol(
33 `ssrGetDynamicModelProps`
34);
35const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
36const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
37const SSR_GET_DIRECTIVE_PROPS = Symbol(`ssrGetDirectiveProps`);
38const ssrHelpers = {
39 [SSR_INTERPOLATE]: `ssrInterpolate`,
40 [SSR_RENDER_VNODE]: `ssrRenderVNode`,
41 [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
42 [SSR_RENDER_SLOT]: `ssrRenderSlot`,
43 [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
44 [SSR_RENDER_CLASS]: `ssrRenderClass`,
45 [SSR_RENDER_STYLE]: `ssrRenderStyle`,
46 [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
47 [SSR_RENDER_ATTR]: `ssrRenderAttr`,
48 [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
49 [SSR_RENDER_LIST]: `ssrRenderList`,
50 [SSR_INCLUDE_BOOLEAN_ATTR]: `ssrIncludeBooleanAttr`,
51 [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
52 [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
53 [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
54 [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
55 [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
56 [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
57 [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
58};
59compilerDom.registerRuntimeHelpers(ssrHelpers);
60
61const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(
62 /^(if|else|else-if)$/,
63 compilerDom.processIf
64);
65function ssrProcessIf(node, context, disableNestedFragments = false, disableComment = false) {
66 const [rootBranch] = node.branches;
67 const ifStatement = compilerDom.createIfStatement(
68 rootBranch.condition,
69 processIfBranch(rootBranch, context, disableNestedFragments)
70 );
71 context.pushStatement(ifStatement);
72 let currentIf = ifStatement;
73 for (let i = 1; i < node.branches.length; i++) {
74 const branch = node.branches[i];
75 const branchBlockStatement = processIfBranch(
76 branch,
77 context,
78 disableNestedFragments
79 );
80 if (branch.condition) {
81 currentIf = currentIf.alternate = compilerDom.createIfStatement(
82 branch.condition,
83 branchBlockStatement
84 );
85 } else {
86 currentIf.alternate = branchBlockStatement;
87 }
88 }
89 if (!currentIf.alternate && !disableComment) {
90 currentIf.alternate = compilerDom.createBlockStatement([
91 compilerDom.createCallExpression(`_push`, ["`<!---->`"])
92 ]);
93 }
94}
95function processIfBranch(branch, context, disableNestedFragments = false) {
96 const { children } = branch;
97 const needFragmentWrapper = !disableNestedFragments && (children.length !== 1 || children[0].type !== 1) && // optimize away nested fragments when the only child is a ForNode
98 !(children.length === 1 && children[0].type === 11);
99 return processChildrenAsStatement(branch, context, needFragmentWrapper);
100}
101
102const ssrTransformFor = compilerDom.createStructuralDirectiveTransform("for", compilerDom.processFor);
103function ssrProcessFor(node, context, disableNestedFragments = false) {
104 const needFragmentWrapper = !disableNestedFragments && (node.children.length !== 1 || node.children[0].type !== 1);
105 const renderLoop = compilerDom.createFunctionExpression(
106 compilerDom.createForLoopParams(node.parseResult)
107 );
108 renderLoop.body = processChildrenAsStatement(
109 node,
110 context,
111 needFragmentWrapper
112 );
113 if (!disableNestedFragments) {
114 context.pushStringPart(`<!--[-->`);
115 }
116 context.pushStatement(
117 compilerDom.createCallExpression(context.helper(SSR_RENDER_LIST), [
118 node.source,
119 renderLoop
120 ])
121 );
122 if (!disableNestedFragments) {
123 context.pushStringPart(`<!--]-->`);
124 }
125}
126
127const ssrTransformSlotOutlet = (node, context) => {
128 if (compilerDom.isSlotOutlet(node)) {
129 const { slotName, slotProps } = compilerDom.processSlotOutlet(node, context);
130 const args = [
131 `_ctx.$slots`,
132 slotName,
133 slotProps || `{}`,
134 // fallback content placeholder. will be replaced in the process phase
135 `null`,
136 `_push`,
137 `_parent`
138 ];
139 if (context.scopeId && context.slotted !== false) {
140 args.push(`"${context.scopeId}-s"`);
141 }
142 let method = SSR_RENDER_SLOT;
143 let parent = context.parent;
144 if (parent) {
145 const children = parent.children;
146 if (parent.type === 10) {
147 parent = context.grandParent;
148 }
149 let componentType;
150 if (parent.type === 1 && parent.tagType === 1 && ((componentType = compilerDom.resolveComponentType(parent, context, true)) === compilerDom.TRANSITION || componentType === compilerDom.TRANSITION_GROUP) && children.filter((c) => c.type === 1).length === 1) {
151 method = SSR_RENDER_SLOT_INNER;
152 if (!(context.scopeId && context.slotted !== false)) {
153 args.push("null");
154 }
155 args.push("true");
156 }
157 }
158 node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
159 }
160};
161function ssrProcessSlotOutlet(node, context) {
162 const renderCall = node.ssrCodegenNode;
163 if (node.children.length) {
164 const fallbackRenderFn = compilerDom.createFunctionExpression([]);
165 fallbackRenderFn.body = processChildrenAsStatement(node, context);
166 renderCall.arguments[3] = fallbackRenderFn;
167 }
168 if (context.withSlotScopeId) {
169 const slotScopeId = renderCall.arguments[6];
170 renderCall.arguments[6] = slotScopeId ? `${slotScopeId} + _scopeId` : `_scopeId`;
171 }
172 context.pushStatement(node.ssrCodegenNode);
173}
174
175function createSSRCompilerError(code, loc) {
176 return compilerDom.createCompilerError(code, loc, SSRErrorMessages);
177}
178const SSRErrorMessages = {
179 [65]: `Unsafe attribute name for SSR.`,
180 [66]: `Missing the 'to' prop on teleport element.`,
181 [67]: `Invalid AST node during SSR transform.`
182};
183
184function ssrProcessTeleport(node, context) {
185 const targetProp = compilerDom.findProp(node, "to");
186 if (!targetProp) {
187 context.onError(
188 createSSRCompilerError(66, node.loc)
189 );
190 return;
191 }
192 let target;
193 if (targetProp.type === 6) {
194 target = targetProp.value && compilerDom.createSimpleExpression(targetProp.value.content, true);
195 } else {
196 target = targetProp.exp;
197 }
198 if (!target) {
199 context.onError(
200 createSSRCompilerError(
201 66,
202 targetProp.loc
203 )
204 );
205 return;
206 }
207 const disabledProp = compilerDom.findProp(
208 node,
209 "disabled",
210 false,
211 true
212 /* allow empty */
213 );
214 const disabled = disabledProp ? disabledProp.type === 6 ? `true` : disabledProp.exp || `false` : `false`;
215 const contentRenderFn = compilerDom.createFunctionExpression(
216 [`_push`],
217 void 0,
218 // Body is added later
219 true,
220 // newline
221 false,
222 // isSlot
223 node.loc
224 );
225 contentRenderFn.body = processChildrenAsStatement(node, context);
226 context.pushStatement(
227 compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
228 `_push`,
229 contentRenderFn,
230 target,
231 disabled,
232 `_parent`
233 ])
234 );
235}
236
237const wipMap$3 = /* @__PURE__ */ new WeakMap();
238function ssrTransformSuspense(node, context) {
239 return () => {
240 if (node.children.length) {
241 const wipEntry = {
242 slotsExp: null,
243 // to be immediately set
244 wipSlots: []
245 };
246 wipMap$3.set(node, wipEntry);
247 wipEntry.slotsExp = compilerDom.buildSlots(
248 node,
249 context,
250 (_props, _vForExp, children, loc) => {
251 const fn = compilerDom.createFunctionExpression(
252 [],
253 void 0,
254 // no return, assign body later
255 true,
256 // newline
257 false,
258 // suspense slots are not treated as normal slots
259 loc
260 );
261 wipEntry.wipSlots.push({
262 fn,
263 children
264 });
265 return fn;
266 }
267 ).slots;
268 }
269 };
270}
271function ssrProcessSuspense(node, context) {
272 const wipEntry = wipMap$3.get(node);
273 if (!wipEntry) {
274 return;
275 }
276 const { slotsExp, wipSlots } = wipEntry;
277 for (let i = 0; i < wipSlots.length; i++) {
278 const slot = wipSlots[i];
279 slot.fn.body = processChildrenAsStatement(slot, context);
280 }
281 context.pushStatement(
282 compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
283 `_push`,
284 slotsExp
285 ])
286 );
287}
288
289const rawChildrenMap = /* @__PURE__ */ new WeakMap();
290const ssrTransformElement = (node, context) => {
291 if (node.type !== 1 || node.tagType !== 0) {
292 return;
293 }
294 return function ssrPostTransformElement() {
295 const openTag = [`<${node.tag}`];
296 const needTagForRuntime = node.tag === "textarea" || node.tag.indexOf("-") > 0;
297 const hasDynamicVBind = compilerDom.hasDynamicKeyVBind(node);
298 const hasCustomDir = node.props.some(
299 (p) => p.type === 7 && !shared.isBuiltInDirective(p.name)
300 );
301 const needMergeProps = hasDynamicVBind || hasCustomDir;
302 if (needMergeProps) {
303 const { props, directives } = compilerDom.buildProps(
304 node,
305 context,
306 node.props,
307 false,
308 false,
309 true
310 );
311 if (props || directives.length) {
312 const mergedProps = buildSSRProps(props, directives, context);
313 const propsExp = compilerDom.createCallExpression(
314 context.helper(SSR_RENDER_ATTRS),
315 [mergedProps]
316 );
317 if (node.tag === "textarea") {
318 const existingText = node.children[0];
319 if (!existingText || existingText.type !== 5) {
320 const tempId = `_temp${context.temps++}`;
321 propsExp.arguments = [
322 compilerDom.createAssignmentExpression(
323 compilerDom.createSimpleExpression(tempId, false),
324 mergedProps
325 )
326 ];
327 rawChildrenMap.set(
328 node,
329 compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
330 compilerDom.createConditionalExpression(
331 compilerDom.createSimpleExpression(`"value" in ${tempId}`, false),
332 compilerDom.createSimpleExpression(`${tempId}.value`, false),
333 compilerDom.createSimpleExpression(
334 existingText ? existingText.content : ``,
335 true
336 ),
337 false
338 )
339 ])
340 );
341 }
342 } else if (node.tag === "input") {
343 const vModel = findVModel(node);
344 if (vModel) {
345 const tempId = `_temp${context.temps++}`;
346 const tempExp = compilerDom.createSimpleExpression(tempId, false);
347 propsExp.arguments = [
348 compilerDom.createSequenceExpression([
349 compilerDom.createAssignmentExpression(tempExp, mergedProps),
350 compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), [
351 tempExp,
352 compilerDom.createCallExpression(
353 context.helper(SSR_GET_DYNAMIC_MODEL_PROPS),
354 [
355 tempExp,
356 // existing props
357 vModel.exp
358 // model
359 ]
360 )
361 ])
362 ])
363 ];
364 }
365 } else if (directives.length && !node.children.length) {
366 const vText = compilerDom.findDir(node, "text");
367 if (!vText) {
368 const tempId = `_temp${context.temps++}`;
369 propsExp.arguments = [
370 compilerDom.createAssignmentExpression(
371 compilerDom.createSimpleExpression(tempId, false),
372 mergedProps
373 )
374 ];
375 rawChildrenMap.set(
376 node,
377 compilerDom.createConditionalExpression(
378 compilerDom.createSimpleExpression(`"textContent" in ${tempId}`, false),
379 compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
380 compilerDom.createSimpleExpression(`${tempId}.textContent`, false)
381 ]),
382 compilerDom.createSimpleExpression(`${tempId}.innerHTML ?? ''`, false),
383 false
384 )
385 );
386 }
387 }
388 if (needTagForRuntime) {
389 propsExp.arguments.push(`"${node.tag}"`);
390 }
391 openTag.push(propsExp);
392 }
393 }
394 let dynamicClassBinding = void 0;
395 let staticClassBinding = void 0;
396 let dynamicStyleBinding = void 0;
397 for (let i = 0; i < node.props.length; i++) {
398 const prop = node.props[i];
399 if (node.tag === "input" && isTrueFalseValue(prop)) {
400 continue;
401 }
402 if (prop.type === 7) {
403 if (prop.name === "html" && prop.exp) {
404 rawChildrenMap.set(
405 node,
406 compilerDom.createCompoundExpression([`(`, prop.exp, `) ?? ''`])
407 );
408 } else if (prop.name === "text" && prop.exp) {
409 node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
410 } else if (prop.name === "slot") {
411 context.onError(
412 compilerDom.createCompilerError(40, prop.loc)
413 );
414 } else if (isTextareaWithValue(node, prop) && prop.exp) {
415 if (!needMergeProps) {
416 node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
417 }
418 } else if (!needMergeProps && prop.name !== "on") {
419 const directiveTransform = context.directiveTransforms[prop.name];
420 if (directiveTransform) {
421 const { props, ssrTagParts } = directiveTransform(
422 prop,
423 node,
424 context
425 );
426 if (ssrTagParts) {
427 openTag.push(...ssrTagParts);
428 }
429 for (let j = 0; j < props.length; j++) {
430 const { key, value } = props[j];
431 if (compilerDom.isStaticExp(key)) {
432 let attrName = key.content;
433 if (attrName === "key" || attrName === "ref") {
434 continue;
435 }
436 if (attrName === "class") {
437 openTag.push(
438 ` class="`,
439 dynamicClassBinding = compilerDom.createCallExpression(
440 context.helper(SSR_RENDER_CLASS),
441 [value]
442 ),
443 `"`
444 );
445 } else if (attrName === "style") {
446 if (dynamicStyleBinding) {
447 mergeCall(dynamicStyleBinding, value);
448 } else {
449 openTag.push(
450 ` style="`,
451 dynamicStyleBinding = compilerDom.createCallExpression(
452 context.helper(SSR_RENDER_STYLE),
453 [value]
454 ),
455 `"`
456 );
457 }
458 } else {
459 attrName = node.tag.indexOf("-") > 0 ? attrName : shared.propsToAttrMap[attrName] || attrName.toLowerCase();
460 if (shared.isBooleanAttr(attrName)) {
461 openTag.push(
462 compilerDom.createConditionalExpression(
463 compilerDom.createCallExpression(
464 context.helper(SSR_INCLUDE_BOOLEAN_ATTR),
465 [value]
466 ),
467 compilerDom.createSimpleExpression(" " + attrName, true),
468 compilerDom.createSimpleExpression("", true),
469 false
470 )
471 );
472 } else if (shared.isSSRSafeAttrName(attrName)) {
473 openTag.push(
474 compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTR), [
475 key,
476 value
477 ])
478 );
479 } else {
480 context.onError(
481 createSSRCompilerError(
482 65,
483 key.loc
484 )
485 );
486 }
487 }
488 } else {
489 const args = [key, value];
490 if (needTagForRuntime) {
491 args.push(`"${node.tag}"`);
492 }
493 openTag.push(
494 compilerDom.createCallExpression(
495 context.helper(SSR_RENDER_DYNAMIC_ATTR),
496 args
497 )
498 );
499 }
500 }
501 }
502 }
503 } else {
504 const name = prop.name;
505 if (node.tag === "textarea" && name === "value" && prop.value) {
506 rawChildrenMap.set(node, shared.escapeHtml(prop.value.content));
507 } else if (!needMergeProps) {
508 if (name === "key" || name === "ref") {
509 continue;
510 }
511 if (name === "class" && prop.value) {
512 staticClassBinding = JSON.stringify(prop.value.content);
513 }
514 openTag.push(
515 ` ${prop.name}` + (prop.value ? `="${shared.escapeHtml(prop.value.content)}"` : ``)
516 );
517 }
518 }
519 }
520 if (dynamicClassBinding && staticClassBinding) {
521 mergeCall(dynamicClassBinding, staticClassBinding);
522 removeStaticBinding(openTag, "class");
523 }
524 if (context.scopeId) {
525 openTag.push(` ${context.scopeId}`);
526 }
527 node.ssrCodegenNode = compilerDom.createTemplateLiteral(openTag);
528 };
529};
530function buildSSRProps(props, directives, context) {
531 let mergePropsArgs = [];
532 if (props) {
533 if (props.type === 14) {
534 mergePropsArgs = props.arguments;
535 } else {
536 mergePropsArgs.push(props);
537 }
538 }
539 if (directives.length) {
540 for (const dir of directives) {
541 mergePropsArgs.push(
542 compilerDom.createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
543 `_ctx`,
544 ...compilerDom.buildDirectiveArgs(dir, context).elements
545 ])
546 );
547 }
548 }
549 return mergePropsArgs.length > 1 ? compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), mergePropsArgs) : mergePropsArgs[0];
550}
551function isTrueFalseValue(prop) {
552 if (prop.type === 7) {
553 return prop.name === "bind" && prop.arg && compilerDom.isStaticExp(prop.arg) && (prop.arg.content === "true-value" || prop.arg.content === "false-value");
554 } else {
555 return prop.name === "true-value" || prop.name === "false-value";
556 }
557}
558function isTextareaWithValue(node, prop) {
559 return !!(node.tag === "textarea" && prop.name === "bind" && compilerDom.isStaticArgOf(prop.arg, "value"));
560}
561function mergeCall(call, arg) {
562 const existing = call.arguments[0];
563 if (existing.type === 17) {
564 existing.elements.push(arg);
565 } else {
566 call.arguments[0] = compilerDom.createArrayExpression([existing, arg]);
567 }
568}
569function removeStaticBinding(tag, binding) {
570 const regExp = new RegExp(`^ ${binding}=".+"$`);
571 const i = tag.findIndex((e) => typeof e === "string" && regExp.test(e));
572 if (i > -1) {
573 tag.splice(i, 1);
574 }
575}
576function findVModel(node) {
577 return node.props.find(
578 (p) => p.type === 7 && p.name === "model" && p.exp
579 );
580}
581function ssrProcessElement(node, context) {
582 const isVoidTag = context.options.isVoidTag || shared.NO;
583 const elementsToAdd = node.ssrCodegenNode.elements;
584 for (let j = 0; j < elementsToAdd.length; j++) {
585 context.pushStringPart(elementsToAdd[j]);
586 }
587 if (context.withSlotScopeId) {
588 context.pushStringPart(compilerDom.createSimpleExpression(`_scopeId`, false));
589 }
590 context.pushStringPart(`>`);
591 const rawChildren = rawChildrenMap.get(node);
592 if (rawChildren) {
593 context.pushStringPart(rawChildren);
594 } else if (node.children.length) {
595 processChildren(node, context);
596 }
597 if (!isVoidTag(node.tag)) {
598 context.pushStringPart(`</${node.tag}>`);
599 }
600}
601
602const wipMap$2 = /* @__PURE__ */ new WeakMap();
603function ssrTransformTransitionGroup(node, context) {
604 return () => {
605 const tag = compilerDom.findProp(node, "tag");
606 if (tag) {
607 const otherProps = node.props.filter((p) => p !== tag);
608 const { props, directives } = compilerDom.buildProps(
609 node,
610 context,
611 otherProps,
612 true,
613 false,
614 true
615 );
616 let propsExp = null;
617 if (props || directives.length) {
618 propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
619 buildSSRProps(props, directives, context)
620 ]);
621 }
622 wipMap$2.set(node, {
623 tag,
624 propsExp,
625 scopeId: context.scopeId || null
626 });
627 }
628 };
629}
630function ssrProcessTransitionGroup(node, context) {
631 const entry = wipMap$2.get(node);
632 if (entry) {
633 const { tag, propsExp, scopeId } = entry;
634 if (tag.type === 7) {
635 context.pushStringPart(`<`);
636 context.pushStringPart(tag.exp);
637 if (propsExp) {
638 context.pushStringPart(propsExp);
639 }
640 if (scopeId) {
641 context.pushStringPart(` ${scopeId}`);
642 }
643 context.pushStringPart(`>`);
644 processChildren(
645 node,
646 context,
647 false,
648 /**
649 * TransitionGroup has the special runtime behavior of flattening and
650 * concatenating all children into a single fragment (in order for them to
651 * be patched using the same key map) so we need to account for that here
652 * by disabling nested fragment wrappers from being generated.
653 */
654 true,
655 /**
656 * TransitionGroup filters out comment children at runtime and thus
657 * doesn't expect comments to be present during hydration. We need to
658 * account for that by disabling the empty comment that is otherwise
659 * rendered for a falsy v-if that has no v-else specified. (#6715)
660 */
661 true
662 );
663 context.pushStringPart(`</`);
664 context.pushStringPart(tag.exp);
665 context.pushStringPart(`>`);
666 } else {
667 context.pushStringPart(`<${tag.value.content}`);
668 if (propsExp) {
669 context.pushStringPart(propsExp);
670 }
671 if (scopeId) {
672 context.pushStringPart(` ${scopeId}`);
673 }
674 context.pushStringPart(`>`);
675 processChildren(node, context, false, true, true);
676 context.pushStringPart(`</${tag.value.content}>`);
677 }
678 } else {
679 processChildren(node, context, true, true, true);
680 }
681}
682
683const wipMap$1 = /* @__PURE__ */ new WeakMap();
684function ssrTransformTransition(node, context) {
685 return () => {
686 const appear = compilerDom.findProp(node, "appear", false, true);
687 wipMap$1.set(node, !!appear);
688 };
689}
690function ssrProcessTransition(node, context) {
691 node.children = node.children.filter((c) => c.type !== 3);
692 const appear = wipMap$1.get(node);
693 if (appear) {
694 context.pushStringPart(`<template>`);
695 processChildren(node, context, false, true);
696 context.pushStringPart(`</template>`);
697 } else {
698 processChildren(node, context, false, true);
699 }
700}
701
702const wipMap = /* @__PURE__ */ new WeakMap();
703const WIP_SLOT = Symbol();
704const componentTypeMap = /* @__PURE__ */ new WeakMap();
705const ssrTransformComponent = (node, context) => {
706 if (node.type !== 1 || node.tagType !== 1) {
707 return;
708 }
709 const component = compilerDom.resolveComponentType(
710 node,
711 context,
712 true
713 /* ssr */
714 );
715 const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
716 componentTypeMap.set(node, component);
717 if (shared.isSymbol(component)) {
718 if (component === compilerDom.SUSPENSE) {
719 return ssrTransformSuspense(node, context);
720 } else if (component === compilerDom.TRANSITION_GROUP) {
721 return ssrTransformTransitionGroup(node, context);
722 } else if (component === compilerDom.TRANSITION) {
723 return ssrTransformTransition(node);
724 }
725 return;
726 }
727 const vnodeBranches = [];
728 const clonedNode = clone(node);
729 return function ssrPostTransformComponent() {
730 if (clonedNode.children.length) {
731 compilerDom.buildSlots(clonedNode, context, (props, vFor, children) => {
732 vnodeBranches.push(
733 createVNodeSlotBranch(props, vFor, children, context)
734 );
735 return compilerDom.createFunctionExpression(void 0);
736 });
737 }
738 let propsExp = `null`;
739 if (node.props.length) {
740 const { props, directives } = compilerDom.buildProps(
741 node,
742 context,
743 void 0,
744 true,
745 isDynamicComponent
746 );
747 if (props || directives.length) {
748 propsExp = buildSSRProps(props, directives, context);
749 }
750 }
751 const wipEntries = [];
752 wipMap.set(node, wipEntries);
753 const buildSSRSlotFn = (props, _vForExp, children, loc) => {
754 const param0 = props && compilerDom.stringifyExpression(props) || `_`;
755 const fn = compilerDom.createFunctionExpression(
756 [param0, `_push`, `_parent`, `_scopeId`],
757 void 0,
758 // no return, assign body later
759 true,
760 // newline
761 true,
762 // isSlot
763 loc
764 );
765 wipEntries.push({
766 type: WIP_SLOT,
767 fn,
768 children,
769 // also collect the corresponding vnode branch built earlier
770 vnodeBranch: vnodeBranches[wipEntries.length]
771 });
772 return fn;
773 };
774 const slots = node.children.length ? compilerDom.buildSlots(node, context, buildSSRSlotFn).slots : `null`;
775 if (typeof component !== "string") {
776 node.ssrCodegenNode = compilerDom.createCallExpression(
777 context.helper(SSR_RENDER_VNODE),
778 [
779 `_push`,
780 compilerDom.createCallExpression(context.helper(compilerDom.CREATE_VNODE), [
781 component,
782 propsExp,
783 slots
784 ]),
785 `_parent`
786 ]
787 );
788 } else {
789 node.ssrCodegenNode = compilerDom.createCallExpression(
790 context.helper(SSR_RENDER_COMPONENT),
791 [component, propsExp, slots, `_parent`]
792 );
793 }
794 };
795};
796function ssrProcessComponent(node, context, parent) {
797 const component = componentTypeMap.get(node);
798 if (!node.ssrCodegenNode) {
799 if (component === compilerDom.TELEPORT) {
800 return ssrProcessTeleport(node, context);
801 } else if (component === compilerDom.SUSPENSE) {
802 return ssrProcessSuspense(node, context);
803 } else if (component === compilerDom.TRANSITION_GROUP) {
804 return ssrProcessTransitionGroup(node, context);
805 } else {
806 if (parent.type === WIP_SLOT) {
807 context.pushStringPart(``);
808 }
809 if (component === compilerDom.TRANSITION) {
810 return ssrProcessTransition(node, context);
811 }
812 processChildren(node, context);
813 }
814 } else {
815 const wipEntries = wipMap.get(node) || [];
816 for (let i = 0; i < wipEntries.length; i++) {
817 const { fn, vnodeBranch } = wipEntries[i];
818 fn.body = compilerDom.createIfStatement(
819 compilerDom.createSimpleExpression(`_push`, false),
820 processChildrenAsStatement(
821 wipEntries[i],
822 context,
823 false,
824 true
825 ),
826 vnodeBranch
827 );
828 }
829 if (context.withSlotScopeId) {
830 node.ssrCodegenNode.arguments.push(`_scopeId`);
831 }
832 if (typeof component === "string") {
833 context.pushStatement(
834 compilerDom.createCallExpression(`_push`, [node.ssrCodegenNode])
835 );
836 } else {
837 context.pushStatement(node.ssrCodegenNode);
838 }
839 }
840}
841const rawOptionsMap = /* @__PURE__ */ new WeakMap();
842const [baseNodeTransforms, baseDirectiveTransforms] = compilerDom.getBaseTransformPreset(true);
843const vnodeNodeTransforms = [...baseNodeTransforms, ...compilerDom.DOMNodeTransforms];
844const vnodeDirectiveTransforms = {
845 ...baseDirectiveTransforms,
846 ...compilerDom.DOMDirectiveTransforms
847};
848function createVNodeSlotBranch(slotProps, vFor, children, parentContext) {
849 const rawOptions = rawOptionsMap.get(parentContext.root);
850 const subOptions = {
851 ...rawOptions,
852 // overwrite with vnode-based transforms
853 nodeTransforms: [
854 ...vnodeNodeTransforms,
855 ...rawOptions.nodeTransforms || []
856 ],
857 directiveTransforms: {
858 ...vnodeDirectiveTransforms,
859 ...rawOptions.directiveTransforms || {}
860 }
861 };
862 const wrapperProps = [];
863 if (slotProps) {
864 wrapperProps.push({
865 type: 7,
866 name: "slot",
867 exp: slotProps,
868 arg: void 0,
869 modifiers: [],
870 loc: compilerDom.locStub
871 });
872 }
873 if (vFor) {
874 wrapperProps.push(shared.extend({}, vFor));
875 }
876 const wrapperNode = {
877 type: 1,
878 ns: 0,
879 tag: "template",
880 tagType: 3,
881 props: wrapperProps,
882 children,
883 loc: compilerDom.locStub,
884 codegenNode: void 0
885 };
886 subTransform(wrapperNode, subOptions, parentContext);
887 return compilerDom.createReturnStatement(children);
888}
889function subTransform(node, options, parentContext) {
890 const childRoot = compilerDom.createRoot([node]);
891 const childContext = compilerDom.createTransformContext(childRoot, options);
892 childContext.ssr = false;
893 childContext.scopes = { ...parentContext.scopes };
894 childContext.identifiers = { ...parentContext.identifiers };
895 childContext.imports = parentContext.imports;
896 compilerDom.traverseNode(childRoot, childContext);
897 ["helpers", "components", "directives"].forEach((key) => {
898 childContext[key].forEach((value, helperKey) => {
899 if (key === "helpers") {
900 const parentCount = parentContext.helpers.get(helperKey);
901 if (parentCount === void 0) {
902 parentContext.helpers.set(helperKey, value);
903 } else {
904 parentContext.helpers.set(helperKey, value + parentCount);
905 }
906 } else {
907 parentContext[key].add(value);
908 }
909 });
910 });
911}
912function clone(v) {
913 if (shared.isArray(v)) {
914 return v.map(clone);
915 } else if (shared.isPlainObject(v)) {
916 const res = {};
917 for (const key in v) {
918 res[key] = clone(v[key]);
919 }
920 return res;
921 } else {
922 return v;
923 }
924}
925
926function ssrCodegenTransform(ast, options) {
927 const context = createSSRTransformContext(ast, options);
928 if (options.ssrCssVars) {
929 const cssContext = compilerDom.createTransformContext(compilerDom.createRoot([]), options);
930 const varsExp = compilerDom.processExpression(
931 compilerDom.createSimpleExpression(options.ssrCssVars, false),
932 cssContext
933 );
934 context.body.push(
935 compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`])
936 );
937 Array.from(cssContext.helpers.keys()).forEach((helper) => {
938 ast.helpers.add(helper);
939 });
940 }
941 const isFragment = ast.children.length > 1 && ast.children.some((c) => !compilerDom.isText(c));
942 processChildren(ast, context, isFragment);
943 ast.codegenNode = compilerDom.createBlockStatement(context.body);
944 ast.ssrHelpers = Array.from(
945 /* @__PURE__ */ new Set([
946 ...Array.from(ast.helpers).filter((h) => h in ssrHelpers),
947 ...context.helpers
948 ])
949 );
950 ast.helpers = new Set(Array.from(ast.helpers).filter((h) => !(h in ssrHelpers)));
951}
952function createSSRTransformContext(root, options, helpers = /* @__PURE__ */ new Set(), withSlotScopeId = false) {
953 const body = [];
954 let currentString = null;
955 return {
956 root,
957 options,
958 body,
959 helpers,
960 withSlotScopeId,
961 onError: options.onError || ((e) => {
962 throw e;
963 }),
964 helper(name) {
965 helpers.add(name);
966 return name;
967 },
968 pushStringPart(part) {
969 if (!currentString) {
970 const currentCall = compilerDom.createCallExpression(`_push`);
971 body.push(currentCall);
972 currentString = compilerDom.createTemplateLiteral([]);
973 currentCall.arguments.push(currentString);
974 }
975 const bufferedElements = currentString.elements;
976 const lastItem = bufferedElements[bufferedElements.length - 1];
977 if (shared.isString(part) && shared.isString(lastItem)) {
978 bufferedElements[bufferedElements.length - 1] += part;
979 } else {
980 bufferedElements.push(part);
981 }
982 },
983 pushStatement(statement) {
984 currentString = null;
985 body.push(statement);
986 }
987 };
988}
989function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
990 return createSSRTransformContext(
991 parent.root,
992 parent.options,
993 parent.helpers,
994 withSlotScopeId
995 );
996}
997function processChildren(parent, context, asFragment = false, disableNestedFragments = false, disableComment = false) {
998 if (asFragment) {
999 context.pushStringPart(`<!--[-->`);
1000 }
1001 const { children } = parent;
1002 for (let i = 0; i < children.length; i++) {
1003 const child = children[i];
1004 switch (child.type) {
1005 case 1:
1006 switch (child.tagType) {
1007 case 0:
1008 ssrProcessElement(child, context);
1009 break;
1010 case 1:
1011 ssrProcessComponent(child, context, parent);
1012 break;
1013 case 2:
1014 ssrProcessSlotOutlet(child, context);
1015 break;
1016 case 3:
1017 break;
1018 default:
1019 context.onError(
1020 createSSRCompilerError(
1021 67,
1022 child.loc
1023 )
1024 );
1025 const exhaustiveCheck2 = child;
1026 return exhaustiveCheck2;
1027 }
1028 break;
1029 case 2:
1030 context.pushStringPart(shared.escapeHtml(child.content));
1031 break;
1032 case 3:
1033 if (!disableComment) {
1034 context.pushStringPart(`<!--${child.content}-->`);
1035 }
1036 break;
1037 case 5:
1038 context.pushStringPart(
1039 compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
1040 child.content
1041 ])
1042 );
1043 break;
1044 case 9:
1045 ssrProcessIf(child, context, disableNestedFragments, disableComment);
1046 break;
1047 case 11:
1048 ssrProcessFor(child, context, disableNestedFragments);
1049 break;
1050 case 10:
1051 break;
1052 case 12:
1053 case 8:
1054 break;
1055 default:
1056 context.onError(
1057 createSSRCompilerError(
1058 67,
1059 child.loc
1060 )
1061 );
1062 const exhaustiveCheck = child;
1063 return exhaustiveCheck;
1064 }
1065 }
1066 if (asFragment) {
1067 context.pushStringPart(`<!--]-->`);
1068 }
1069}
1070function processChildrenAsStatement(parent, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
1071 const childContext = createChildContext(parentContext, withSlotScopeId);
1072 processChildren(parent, childContext, asFragment);
1073 return compilerDom.createBlockStatement(childContext.body);
1074}
1075
1076const ssrTransformModel = (dir, node, context) => {
1077 const model = dir.exp;
1078 function checkDuplicatedValue() {
1079 const value = compilerDom.findProp(node, "value");
1080 if (value) {
1081 context.onError(
1082 compilerDom.createDOMCompilerError(
1083 60,
1084 value.loc
1085 )
1086 );
1087 }
1088 }
1089 function processOption(plainNode) {
1090 if (plainNode.tag === "option") {
1091 if (plainNode.props.findIndex((p) => p.name === "selected") === -1) {
1092 const value = findValueBinding(plainNode);
1093 plainNode.ssrCodegenNode.elements.push(
1094 compilerDom.createConditionalExpression(
1095 compilerDom.createCallExpression(context.helper(SSR_INCLUDE_BOOLEAN_ATTR), [
1096 compilerDom.createConditionalExpression(
1097 compilerDom.createCallExpression(`Array.isArray`, [model]),
1098 compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1099 model,
1100 value
1101 ]),
1102 compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1103 model,
1104 value
1105 ])
1106 )
1107 ]),
1108 compilerDom.createSimpleExpression(" selected", true),
1109 compilerDom.createSimpleExpression("", true),
1110 false
1111 )
1112 );
1113 }
1114 } else if (plainNode.tag === "optgroup") {
1115 plainNode.children.forEach(
1116 (option) => processOption(option)
1117 );
1118 }
1119 }
1120 if (node.tagType === 0) {
1121 const res = { props: [] };
1122 const defaultProps = [
1123 // default value binding for text type inputs
1124 compilerDom.createObjectProperty(`value`, model)
1125 ];
1126 if (node.tag === "input") {
1127 const type = compilerDom.findProp(node, "type");
1128 if (type) {
1129 const value = findValueBinding(node);
1130 if (type.type === 7) {
1131 res.ssrTagParts = [
1132 compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
1133 type.exp,
1134 model,
1135 value
1136 ])
1137 ];
1138 } else if (type.value) {
1139 switch (type.value.content) {
1140 case "radio":
1141 res.props = [
1142 compilerDom.createObjectProperty(
1143 `checked`,
1144 compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1145 model,
1146 value
1147 ])
1148 )
1149 ];
1150 break;
1151 case "checkbox":
1152 const trueValueBinding = compilerDom.findProp(node, "true-value");
1153 if (trueValueBinding) {
1154 const trueValue = trueValueBinding.type === 6 ? JSON.stringify(trueValueBinding.value.content) : trueValueBinding.exp;
1155 res.props = [
1156 compilerDom.createObjectProperty(
1157 `checked`,
1158 compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1159 model,
1160 trueValue
1161 ])
1162 )
1163 ];
1164 } else {
1165 res.props = [
1166 compilerDom.createObjectProperty(
1167 `checked`,
1168 compilerDom.createConditionalExpression(
1169 compilerDom.createCallExpression(`Array.isArray`, [model]),
1170 compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1171 model,
1172 value
1173 ]),
1174 model
1175 )
1176 )
1177 ];
1178 }
1179 break;
1180 case "file":
1181 context.onError(
1182 compilerDom.createDOMCompilerError(
1183 59,
1184 dir.loc
1185 )
1186 );
1187 break;
1188 default:
1189 checkDuplicatedValue();
1190 res.props = defaultProps;
1191 break;
1192 }
1193 }
1194 } else if (compilerDom.hasDynamicKeyVBind(node)) ; else {
1195 checkDuplicatedValue();
1196 res.props = defaultProps;
1197 }
1198 } else if (node.tag === "textarea") {
1199 checkDuplicatedValue();
1200 node.children = [compilerDom.createInterpolation(model, model.loc)];
1201 } else if (node.tag === "select") {
1202 const processChildren = (children) => {
1203 children.forEach((child) => {
1204 if (child.type === 1) {
1205 processOption(child);
1206 } else if (child.type === 11) {
1207 processChildren(child.children);
1208 } else if (child.type === 9) {
1209 child.branches.forEach((b) => processChildren(b.children));
1210 }
1211 });
1212 };
1213 processChildren(node.children);
1214 } else {
1215 context.onError(
1216 compilerDom.createDOMCompilerError(
1217 57,
1218 dir.loc
1219 )
1220 );
1221 }
1222 return res;
1223 } else {
1224 return compilerDom.transformModel(dir, node, context);
1225 }
1226};
1227function findValueBinding(node) {
1228 const valueBinding = compilerDom.findProp(node, "value");
1229 return valueBinding ? valueBinding.type === 7 ? valueBinding.exp : compilerDom.createSimpleExpression(valueBinding.value.content, true) : compilerDom.createSimpleExpression(`null`, false);
1230}
1231
1232const ssrTransformShow = (dir, node, context) => {
1233 if (!dir.exp) {
1234 context.onError(
1235 compilerDom.createDOMCompilerError(61)
1236 );
1237 }
1238 return {
1239 props: [
1240 compilerDom.createObjectProperty(
1241 `style`,
1242 compilerDom.createConditionalExpression(
1243 dir.exp,
1244 compilerDom.createSimpleExpression(`null`, false),
1245 compilerDom.createObjectExpression([
1246 compilerDom.createObjectProperty(
1247 `display`,
1248 compilerDom.createSimpleExpression(`none`, true)
1249 )
1250 ]),
1251 false
1252 )
1253 )
1254 ]
1255 };
1256};
1257
1258const filterChild = (node) => node.children.filter((n) => n.type !== 3);
1259const hasSingleChild = (node) => filterChild(node).length === 1;
1260const ssrInjectFallthroughAttrs = (node, context) => {
1261 if (node.type === 0) {
1262 context.identifiers._attrs = 1;
1263 }
1264 if (node.type === 1 && node.tagType === 1 && (node.tag === "transition" || node.tag === "Transition" || node.tag === "KeepAlive" || node.tag === "keep-alive")) {
1265 const rootChildren = filterChild(context.root);
1266 if (rootChildren.length === 1 && rootChildren[0] === node) {
1267 if (hasSingleChild(node)) {
1268 injectFallthroughAttrs(node.children[0]);
1269 }
1270 return;
1271 }
1272 }
1273 const parent = context.parent;
1274 if (!parent || parent.type !== 0) {
1275 return;
1276 }
1277 if (node.type === 10 && hasSingleChild(node)) {
1278 let hasEncounteredIf = false;
1279 for (const c of filterChild(parent)) {
1280 if (c.type === 9 || c.type === 1 && compilerDom.findDir(c, "if")) {
1281 if (hasEncounteredIf) return;
1282 hasEncounteredIf = true;
1283 } else if (
1284 // node before v-if
1285 !hasEncounteredIf || // non else nodes
1286 !(c.type === 1 && compilerDom.findDir(c, /else/, true))
1287 ) {
1288 return;
1289 }
1290 }
1291 injectFallthroughAttrs(node.children[0]);
1292 } else if (hasSingleChild(parent)) {
1293 injectFallthroughAttrs(node);
1294 }
1295};
1296function injectFallthroughAttrs(node) {
1297 if (node.type === 1 && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1298 node.props.push({
1299 type: 7,
1300 name: "bind",
1301 arg: void 0,
1302 exp: compilerDom.createSimpleExpression(`_attrs`, false),
1303 modifiers: [],
1304 loc: compilerDom.locStub
1305 });
1306 }
1307}
1308
1309const ssrInjectCssVars = (node, context) => {
1310 if (!context.ssrCssVars) {
1311 return;
1312 }
1313 if (node.type === 0) {
1314 context.identifiers._cssVars = 1;
1315 }
1316 const parent = context.parent;
1317 if (!parent || parent.type !== 0) {
1318 return;
1319 }
1320 if (node.type === 10) {
1321 for (const child of node.children) {
1322 injectCssVars(child);
1323 }
1324 } else {
1325 injectCssVars(node);
1326 }
1327};
1328function injectCssVars(node) {
1329 if (node.type === 1 && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1330 if (node.tag === "suspense" || node.tag === "Suspense") {
1331 for (const child of node.children) {
1332 if (child.type === 1 && child.tagType === 3) {
1333 child.children.forEach(injectCssVars);
1334 } else {
1335 injectCssVars(child);
1336 }
1337 }
1338 } else {
1339 node.props.push({
1340 type: 7,
1341 name: "bind",
1342 arg: void 0,
1343 exp: compilerDom.createSimpleExpression(`_cssVars`, false),
1344 modifiers: [],
1345 loc: compilerDom.locStub
1346 });
1347 }
1348 }
1349}
1350
1351function compile(source, options = {}) {
1352 options = {
1353 ...options,
1354 ...compilerDom.parserOptions,
1355 ssr: true,
1356 inSSR: true,
1357 scopeId: options.mode === "function" ? null : options.scopeId,
1358 // always prefix since compiler-ssr doesn't have size concern
1359 prefixIdentifiers: true,
1360 // disable optimizations that are unnecessary for ssr
1361 cacheHandlers: false,
1362 hoistStatic: false
1363 };
1364 const ast = typeof source === "string" ? compilerDom.baseParse(source, options) : source;
1365 rawOptionsMap.set(ast, options);
1366 compilerDom.transform(ast, {
1367 ...options,
1368 hoistStatic: false,
1369 nodeTransforms: [
1370 ssrTransformIf,
1371 ssrTransformFor,
1372 compilerDom.trackVForSlotScopes,
1373 compilerDom.transformExpression,
1374 ssrTransformSlotOutlet,
1375 ssrInjectFallthroughAttrs,
1376 ssrInjectCssVars,
1377 ssrTransformElement,
1378 ssrTransformComponent,
1379 compilerDom.trackSlotScopes,
1380 compilerDom.transformStyle,
1381 ...options.nodeTransforms || []
1382 // user transforms
1383 ],
1384 directiveTransforms: {
1385 // reusing core v-bind
1386 bind: compilerDom.transformBind,
1387 on: compilerDom.transformOn,
1388 // model and show have dedicated SSR handling
1389 model: ssrTransformModel,
1390 show: ssrTransformShow,
1391 // the following are ignored during SSR
1392 // on: noopDirectiveTransform,
1393 cloak: compilerDom.noopDirectiveTransform,
1394 once: compilerDom.noopDirectiveTransform,
1395 memo: compilerDom.noopDirectiveTransform,
1396 ...options.directiveTransforms || {}
1397 // user transforms
1398 }
1399 });
1400 ssrCodegenTransform(ast, options);
1401 return compilerDom.generate(ast, options);
1402}
1403
1404exports.compile = compile;
Note: See TracBrowser for help on using the repository browser.