]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(vapor): update insertion handling edison/fix/insertion 13203/head
authordaiwei <daiwei521@126.com>
Tue, 15 Apr 2025 07:24:21 +0000 (15:24 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 15 Apr 2025 07:24:21 +0000 (15:24 +0800)
packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
packages/compiler-vapor/src/generators/operation.ts
packages/compiler-vapor/src/transforms/transformChildren.ts
packages/runtime-vapor/src/apiCreateFor.ts
packages/runtime-vapor/src/apiCreateIf.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/componentSlots.ts

index e56676d87068a758a3992eb347b6582b5c549ff3..195e0b4a2bb81af21bea248361c8203b370dc947 100644 (file)
@@ -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("<div></div>")
 
 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("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
 const t1 = _template("<div> </div>")
 
@@ -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)
index 5ae8a94f5b1270948377e0f9d0969a96a0e27cc8..a2bdabf61a67693945f08345cea27d0421900b5f 100644 (file)
@@ -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("<div></div>")
 const t1 = _template("<div><div></div><!><div></div></div>", true)
 
@@ -13,6 +13,7 @@ export function render(_ctx) {
     const n2 = t0()
     return n2
   }, null, true)
+  _insert(n0, n4, n3)
   return n4
 }"
 `;
index cb14f56afdbfd800e900c7388716ef2691b171be..76035d52388c67f8ee360c1fe0975126a4b19987 100644 (file)
@@ -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("<span> </span>")
 const t1 = _template("<div></div>", 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
index ab3ade45b602fb013a66fa37922b53f2b2ee92bc..f182d031674dd4fc0ba0ca3273b16199922db231 100644 (file)
@@ -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("<div></div>", 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
 }"
 `;
index 4247bc6fecac29a230ac87e21e4d59ab8aa1543b..a3bf5cc21937a7ee271712c36071228cf906ae4d 100644 (file)
@@ -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[] {
index 790cd9d6fb19038110a5d91ca54f4d62cc7c87a6..7713bf7c31624bee4214e645d85de41794ccb786 100644 (file)
@@ -74,8 +74,19 @@ function processDynamicChildren(context: TransformContext<ElementNode>) {
           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<ElementNode>) {
 
   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
index 0cd8317532f4fb93790775321bf2015fbe2f09da..be389a9865a6ee0f177ec0a8c85c57ebf81b91ba 100644 (file)
@@ -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
 }
 
index 71bfa32d5d3fdbe07213ff6af3125da2c5f8dd25..7067ed704f6f60826d80db4540a93918594f6000 100644 (file)
@@ -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
 }
index 548babebf8beef2115e31356d50a989e2e1a0112..710dfe431e10b74662a4bc3fa52f14e4e1e31d30 100644 (file)
@@ -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
 }
 
index 74296e09466359d9fddc37305b032b4e99741010..b18259a5a71b70c8f0cae89a41e7a5acbfd264af 100644 (file)
@@ -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<string, VaporSlot> & {
@@ -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
 }