Skip to content

Commit b703416

Browse files
committed
test: add tests
1 parent bb4ae25 commit b703416

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed

packages/runtime-vapor/__tests__/componentSlots.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
insert,
1111
prepend,
1212
renderEffect,
13+
setInsertionState,
1314
template,
1415
} from '../src'
1516
import { currentInstance, nextTick, ref } from '@vue/runtime-dom'
@@ -502,5 +503,35 @@ describe('component: slots', () => {
502503
await nextTick()
503504
expect(host.innerHTML).toBe('<div><h1></h1><!--slot--></div>')
504505
})
506+
507+
test('consecutive slots with insertion state', async () => {
508+
const { component: Child } = define({
509+
setup() {
510+
const n2 = template('<div><div>baz</div></div>', true)() as any
511+
setInsertionState(n2, 0)
512+
createSlot('default', null)
513+
setInsertionState(n2, 0)
514+
createSlot('foo', null)
515+
return n2
516+
},
517+
})
518+
519+
const { html } = define({
520+
setup() {
521+
return createComponent(Child, null, {
522+
default: () => template('default')(),
523+
foo: () => template('foo')(),
524+
})
525+
},
526+
}).render()
527+
528+
expect(html()).toBe(
529+
`<div>` +
530+
`default<!--slot-->` +
531+
`foo<!--slot-->` +
532+
`<div>baz</div>` +
533+
`</div>`,
534+
)
535+
})
505536
})
506537
})

packages/runtime-vapor/src/block.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ export function isValidBlock(block: Block): boolean {
105105

106106
export function insert(
107107
block: Block,
108-
parent: ParentNode,
108+
parent: ParentNode & { $anchor?: Node | null },
109109
anchor: Node | null | 0 = null, // 0 means prepend
110110
): void {
111-
anchor = anchor === 0 ? parent.firstChild : anchor
111+
anchor = anchor === 0 ? parent.$anchor || parent.firstChild : anchor
112112
if (block instanceof Node) {
113113
if (!isHydrating) {
114114
parent.insertBefore(block, anchor)

packages/runtime-vapor/src/dom/prop.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export function optimizePropertyLookup(): void {
269269
if (isOptimized) return
270270
isOptimized = true
271271
const proto = Element.prototype as any
272-
proto.$evtclick = undefined
272+
proto.$anchor = proto.$evtclick = undefined
273273
proto.$root = false
274274
proto.$html =
275275
proto.$txt =

packages/runtime-vapor/src/insertionState.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@ export let insertionAnchor: Node | 0 | undefined
66
* (component, slot outlet, if, for) is created. The state is used for actual
77
* insertion on client-side render, and used for node adoption during hydration.
88
*/
9-
export function setInsertionState(parent: ParentNode, anchor?: Node | 0): void {
9+
export function setInsertionState(
10+
parent: ParentNode & { $anchor?: Node | null },
11+
anchor?: Node | 0,
12+
): void {
13+
// When setInsertionState(n3, 0) is called consecutively, the first prepend operation
14+
// uses parent.firstChild as the anchor. However, after insertion, parent.firstChild
15+
// changes and cannot serve as the anchor for subsequent prepends. Therefore, we cache
16+
// the original parent.firstChild on the first call for subsequent prepend operations.
17+
if (anchor === 0 && !parent.$anchor) {
18+
parent.$anchor = parent.firstChild
19+
}
20+
1021
insertionParent = parent
1122
insertionAnchor = anchor
1223
}

0 commit comments

Comments
 (0)