compiler-ssr.cjs.js 43 KB

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