From: daiwei Date: Wed, 13 Aug 2025 03:07:17 +0000 (+0800) Subject: refactor: warp if/else-if/else node with a template node X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d195b552550f4d0ff1d516280785af1cdc0e4151;p=thirdparty%2Fvuejs%2Fcore.git refactor: warp if/else-if/else node with a template node --- diff --git a/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts b/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts index 745bf65f42..9b25d11231 100644 --- a/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVaporAnchors.spec.ts @@ -176,16 +176,19 @@ describe('insertion anchors', () => { _createVNode("div", null, [ _createCommentVNode("[p"), (_ctx.foo) - ? (_openBlock(), _createBlock("span", { key: 0 }, [ + ? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [ + _createVNode("span"), _createCommentVNode("if") - ])) + ], 64 /* STABLE_FRAGMENT */)) : (_ctx.bar) - ? (_openBlock(), _createBlock("span", { key: 1 }, [ + ? (_openBlock(), _createBlock(_Fragment, { key: 1 }, [ + _createVNode("span"), _createCommentVNode("if-->\`" + `) + }) + + test('if + v-html/v-text', () => { + expect( + getCompiledString( + ` + + + 4 + `, + { + vapor: true, + }, + ), + ).toMatchInlineSnapshot(` + "\`\`) + _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.tag), null, { + default: _withCtx((_, _push, _parent, _scopeId) => { + if (_push) { + if (_ctx.count === 1) { + _push(\`\${ + (_ctx.html) ?? '' + }\`) + _push(\`\`) + } else if (_ctx.count === 2) { + _push(\`\${ + _ssrInterpolate(_ctx.txt) + }\`) + _push(\`\`) + } else { + _push(\`4\`) + _push(\`\`) + } + } else { + return [ + (_ctx.count === 1) + ? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [ + _createVNode("span", { innerHTML: _ctx.html }, null, 8 /* PROPS */, ["innerHTML"]), + _createCommentVNode("if") + ], 64 /* STABLE_FRAGMENT */)) + : (_ctx.count === 2) + ? (_openBlock(), _createBlock(_Fragment, { key: 1 }, [ + _createVNode("span", { + textContent: _toDisplayString(_ctx.txt) + }, null, 8 /* PROPS */, ["textContent"]), + _createCommentVNode("if-->`.repeat(repeatCount).slice(4, -3), - ), - ) - } - - node.children = injectVaporAnchors(node.children, node) - } - - // inject anchor after branch nodes - if (insertionAnchor) { - newChildren.push(createAnchor(`${insertionAnchor}]`)) - } - + injectIfAnchors( + insertionAnchor, + newChildren, + i, + lastBranchIndex, + children, + ) i = lastBranchIndex continue } @@ -505,6 +478,71 @@ function injectVaporAnchors( return newChildren } +function injectIfAnchors( + insertionAnchor: string | undefined, + newChildren: TemplateChildNode[], + i: number, + lastBranchIndex: number, + children: TemplateChildNode[], +) { + // inject anchor before if node + if (insertionAnchor) { + newChildren.push(createAnchor(`[${insertionAnchor}`)) + } + + for (let j = i; j <= lastBranchIndex; j++) { + const node = children[j] as PlainElementNode + const blockAnchorLabel = getBlockAnchorLabel(node) + let isElse = false + + const conditionalProps: typeof node.props = [] + const restProps: typeof node.props = [] + + for (const prop of node.props) { + if ( + prop.name === 'if' || + prop.name === 'else-if' || + prop.name === 'else' + ) { + conditionalProps.push(prop) + if (prop.name === 'else') isElse = true + } else { + restProps.push(prop) + } + } + node.props = restProps + + // wrap the node with a template node + const wrapperNode: TemplateNode = { + type: NodeTypes.ELEMENT, + ns: Namespaces.HTML, + tag: 'template', + tagType: ElementTypes.TEMPLATE, + props: conditionalProps, + children: [node], + loc: node.loc, + codegenNode: undefined, + } + newChildren.push(wrapperNode) + + // inject block anchor + if (blockAnchorLabel) { + const repeatCount = j - i - (isElse ? 1 : 0) + 1 + wrapperNode.children.push( + createAnchor( + ``.repeat(repeatCount).slice(4, -3), + ), + ) + } + node.children = injectVaporAnchors(node.children, node) + } + + // inject anchor after branch nodes + if (insertionAnchor) { + newChildren.push(createAnchor(`${insertionAnchor}]`)) + } +} + function createAnchor(content: string): CommentNode { return { type: NodeTypes.COMMENT,