From: daiwei Date: Tue, 15 Apr 2025 07:24:21 +0000 (+0800) Subject: fix(vapor): update insertion handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fedison%2Ffix%2Finsertion;p=thirdparty%2Fvuejs%2Fcore.git fix(vapor): update insertion handling --- diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index e56676d870..195e0b4a2b 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -26,7 +26,7 @@ export function render(_ctx) { `; exports[`compile > custom directive > component 1`] = ` -"import { resolveComponent as _resolveComponent, resolveDirective as _resolveDirective, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, withVaporDirectives as _withVaporDirectives, createIf as _createIf, template as _template } from 'vue'; +"import { resolveComponent as _resolveComponent, resolveDirective as _resolveDirective, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, withVaporDirectives as _withVaporDirectives, insert as _insert, createIf as _createIf, template as _template } from 'vue'; const t0 = _template("
") export function render(_ctx) { @@ -41,6 +41,7 @@ export function render(_ctx) { _setInsertionState(n3) const n2 = _createComponentWithFallback(_component_Bar) _withVaporDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]]) + _insert(n2, n3) return n3 }) return n0 @@ -149,7 +150,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { `; exports[`compile > directives > v-pre > should not affect siblings after it 1`] = ` -"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, child as _child, toDisplayString as _toDisplayString, setText as _setText, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; +"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, child as _child, prepend as _prepend, toDisplayString as _toDisplayString, setText as _setText, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
{{ bar }}
") const t1 = _template("
") @@ -160,6 +161,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { _setInsertionState(n3, 0) const n1 = _createComponentWithFallback(_component_Comp) const n2 = _child(n3) + _prepend(n3, n1) _renderEffect(() => { _setText(n2, _toDisplayString(_ctx.bar)) _setProp(n3, "id", _ctx.foo) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 5ae8a94f5b..a2bdabf61a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: children transform > anchor insertion in middle 1`] = ` -"import { child as _child, next as _next, setInsertionState as _setInsertionState, createIf as _createIf, template as _template } from 'vue'; +"import { child as _child, next as _next, setInsertionState as _setInsertionState, createIf as _createIf, insert as _insert, template as _template } from 'vue'; const t0 = _template("
") const t1 = _template("
", true) @@ -13,6 +13,7 @@ export function render(_ctx) { const n2 = t0() return n2 }, null, true) + _insert(n0, n4, n3) return n4 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index cb14f56afd..76035d5238 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -65,7 +65,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > nested v-for 1`] = ` -"import { setInsertionState as _setInsertionState, child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue'; +"import { setInsertionState as _setInsertionState, child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue'; const t0 = _template(" ") const t1 = _template("
", true) @@ -79,6 +79,7 @@ export function render(_ctx) { _renderEffect(() => _setText(x4, _toDisplayString(_for_item1.value+_for_item0.value))) return n4 }, null, 1) + _insert(n2, n5) return n5 }) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap index ab3ade45b6..f182d03167 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap @@ -36,7 +36,7 @@ export function render(_ctx) { `; exports[`compiler: v-once > on component 1`] = ` -"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue'; +"import { resolveComponent as _resolveComponent, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, insert as _insert, template as _template } from 'vue'; const t0 = _template("
", true) export function render(_ctx) { @@ -44,6 +44,7 @@ export function render(_ctx) { const n1 = t0() _setInsertionState(n1) const n0 = _createComponentWithFallback(_component_Comp, { id: () => (_ctx.foo) }, null, null, true) + _insert(n0, n1) return n1 }" `; diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 4247bc6fec..a3bf5cc219 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -44,7 +44,7 @@ export function genOperationWithInsertionState( ): CodeFragment[] { const [frag, push] = buildCodeFragment() if (isBlockOperation(oper) && oper.parent) { - push(...genInsertionstate(oper, context)) + push(...genInsertionState(oper, context)) } push(...genOperation(oper, context)) return frag @@ -152,7 +152,7 @@ export function genEffect( return frag } -function genInsertionstate( +function genInsertionState( operation: InsertionStateTypes, context: CodegenContext, ): CodeFragment[] { diff --git a/packages/compiler-vapor/src/transforms/transformChildren.ts b/packages/compiler-vapor/src/transforms/transformChildren.ts index 790cd9d6fb..7713bf7c31 100644 --- a/packages/compiler-vapor/src/transforms/transformChildren.ts +++ b/packages/compiler-vapor/src/transforms/transformChildren.ts @@ -74,8 +74,19 @@ function processDynamicChildren(context: TransformContext) { prevDynamics[0].flags -= DynamicFlag.NON_TEMPLATE const anchor = (prevDynamics[0].anchor = context.increaseId()) registerInsertion(prevDynamics, context, anchor) + context.registerOperation({ + type: IRNodeTypes.INSERT_NODE, + elements: prevDynamics.map(child => child.id!), + parent: context.reference(), + anchor, + }) } else { registerInsertion(prevDynamics, context, -1 /* prepend */) + context.registerOperation({ + type: IRNodeTypes.PREPEND_NODE, + elements: prevDynamics.map(child => child.id!), + parent: context.reference(), + }) } prevDynamics = [] } @@ -85,6 +96,11 @@ function processDynamicChildren(context: TransformContext) { if (prevDynamics.length) { registerInsertion(prevDynamics, context) + context.registerOperation({ + type: IRNodeTypes.INSERT_NODE, + elements: prevDynamics.map(child => child.id!), + parent: context.reference(), + }) } } @@ -94,15 +110,7 @@ function registerInsertion( anchor?: number, ) { for (const child of dynamics) { - if (child.template != null) { - // template node due to invalid nesting - generate actual insertion - context.registerOperation({ - type: IRNodeTypes.INSERT_NODE, - elements: dynamics.map(child => child.id!), - parent: context.reference(), - anchor, - }) - } else if (child.operation && isBlockOperation(child.operation)) { + if (child.operation && isBlockOperation(child.operation)) { // block types child.operation.parent = context.reference() child.operation.anchor = anchor diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index 0cd8317532..be389a9865 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -23,7 +23,6 @@ import type { DynamicSlot } from './componentSlots' import { renderEffect } from './renderEffect' import { VaporVForFlags } from '../../shared/src/vaporFlags' import { isHydrating, locateHydrationNode } from './dom/hydration' -import { insertionAnchor, insertionParent } from './insertionState' class ForBlock extends VaporFragment { scope: EffectScope | undefined @@ -68,8 +67,6 @@ export const createFor = ( getKey?: (item: any, key: any, index?: number) => any, flags = 0, ): VaporFragment => { - const _insertionParent = insertionParent - const _insertionAnchor = insertionAnchor if (isHydrating) { locateHydrationNode() } @@ -364,10 +361,6 @@ export const createFor = ( renderEffect(renderList) } - if (!isHydrating && _insertionParent) { - insert(frag, _insertionParent, _insertionAnchor) - } - return frag } diff --git a/packages/runtime-vapor/src/apiCreateIf.ts b/packages/runtime-vapor/src/apiCreateIf.ts index 71bfa32d5d..7067ed704f 100644 --- a/packages/runtime-vapor/src/apiCreateIf.ts +++ b/packages/runtime-vapor/src/apiCreateIf.ts @@ -1,6 +1,5 @@ -import { type Block, type BlockFn, DynamicFragment, insert } from './block' +import { type Block, type BlockFn, DynamicFragment } from './block' import { isHydrating, locateHydrationNode } from './dom/hydration' -import { insertionAnchor, insertionParent } from './insertionState' import { renderEffect } from './renderEffect' export function createIf( @@ -9,8 +8,6 @@ export function createIf( b2?: BlockFn, once?: boolean, ): Block { - const _insertionParent = insertionParent - const _insertionAnchor = insertionAnchor if (isHydrating) { locateHydrationNode() } @@ -23,9 +20,5 @@ export function createIf( renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2)) } - if (!isHydrating && _insertionParent) { - insert(frag, _insertionParent, _insertionAnchor) - } - return frag } diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 548babebf8..710dfe431e 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -59,7 +59,6 @@ import { } from './componentSlots' import { hmrReload, hmrRerender } from './hmr' import { isHydrating, locateHydrationNode } from './dom/hydration' -import { insertionAnchor, insertionParent } from './insertionState' export { currentInstance } from '@vue/runtime-dom' @@ -138,23 +137,13 @@ export function createComponent( currentInstance.appContext) || emptyContext, ): VaporComponentInstance { - const _insertionParent = insertionParent - const _insertionAnchor = insertionAnchor if (isHydrating) { locateHydrationNode() } // vdom interop enabled and component is not an explicit vapor component if (appContext.vapor && !component.__vapor) { - const frag = appContext.vapor.vdomMount( - component as any, - rawProps, - rawSlots, - ) - if (!isHydrating && _insertionParent) { - insert(frag, _insertionParent, _insertionAnchor) - } - return frag + return appContext.vapor.vdomMount(component as any, rawProps, rawSlots) } if ( @@ -269,10 +258,6 @@ export function createComponent( onScopeDispose(() => unmountComponent(instance), true) - if (!isHydrating && _insertionParent) { - insert(instance.block, _insertionParent, _insertionAnchor) - } - return instance } diff --git a/packages/runtime-vapor/src/componentSlots.ts b/packages/runtime-vapor/src/componentSlots.ts index 74296e0946..b18259a5a7 100644 --- a/packages/runtime-vapor/src/componentSlots.ts +++ b/packages/runtime-vapor/src/componentSlots.ts @@ -1,10 +1,9 @@ import { EMPTY_OBJ, NO, hasOwn, isArray, isFunction } from '@vue/shared' -import { type Block, type BlockFn, DynamicFragment, insert } from './block' +import { type Block, type BlockFn, DynamicFragment } from './block' import { rawPropsProxyHandlers } from './componentProps' import { currentInstance, isRef } from '@vue/runtime-dom' import type { LooseRawProps, VaporComponentInstance } from './component' import { renderEffect } from './renderEffect' -import { insertionAnchor, insertionParent } from './insertionState' import { isHydrating, locateHydrationNode } from './dom/hydration' export type RawSlots = Record & { @@ -92,8 +91,6 @@ export function createSlot( rawProps?: LooseRawProps | null, fallback?: VaporSlot, ): Block { - const _insertionParent = insertionParent - const _insertionAnchor = insertionAnchor if (isHydrating) { locateHydrationNode() } @@ -145,9 +142,5 @@ export function createSlot( } } - if (!isHydrating && _insertionParent) { - insert(fragment, _insertionParent, _insertionAnchor) - } - return fragment }