Skip to content

Commit 019635f

Browse files
committed
wip: add more cases
1 parent 83f03be commit 019635f

File tree

3 files changed

+137
-7
lines changed

3 files changed

+137
-7
lines changed

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

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3175,9 +3175,130 @@ describe('Vapor Mode hydration', () => {
31753175
expect(teleport.targetAnchor).toBe(teleportContainer.childNodes[2])
31763176
})
31773177

3178-
test('nested', async () => {})
3178+
test('nested', async () => {
3179+
const teleportContainer = document.createElement('div')
3180+
teleportContainer.id = 'teleport5'
3181+
teleportContainer.innerHTML = `<!--teleport start anchor--><!--teleport start--><!--teleport end--><!--teleport anchor--><!--teleport start anchor--><div>child</div><!--teleport anchor-->`
3182+
document.body.appendChild(teleportContainer)
3183+
3184+
const { block, container } = await mountWithHydration(
3185+
'<!--teleport start--><!--teleport end-->',
3186+
`<teleport to="#teleport5">
3187+
<teleport to="#teleport5"><div>child</div></teleport>
3188+
</teleport>`,
3189+
)
3190+
3191+
const teleport = block as TeleportFragment
3192+
expect(teleport.anchor).toBe(container.childNodes[1])
3193+
expect(teleport.targetStart).toBe(teleportContainer.childNodes[0])
3194+
expect(teleport.targetAnchor).toBe(teleportContainer.childNodes[3])
3195+
3196+
const childTeleport = teleport.nodes as TeleportFragment
3197+
expect(childTeleport.anchor).toBe(teleportContainer.childNodes[2])
3198+
expect(childTeleport.targetStart).toBe(teleportContainer.childNodes[4])
3199+
expect(childTeleport.targetAnchor).toBe(teleportContainer.childNodes[6])
3200+
expect(childTeleport.nodes).toBe(teleportContainer.childNodes[5])
3201+
})
3202+
3203+
test('unmount (full integration)', async () => {
3204+
const data = ref({
3205+
toggle: ref(true),
3206+
})
3207+
3208+
const comp1Code = `<Teleport to="#target">
3209+
<span>Teleported Comp1</span>
3210+
</Teleport>`
3211+
const Comp1 = compile(
3212+
`<template>${comp1Code}</template>`,
3213+
data,
3214+
undefined,
3215+
{
3216+
vapor: true,
3217+
ssr: false,
3218+
},
3219+
)
3220+
const ssrComp1 = compile(
3221+
`<template>${comp1Code}</template>`,
3222+
data,
3223+
undefined,
3224+
{
3225+
vapor: true,
3226+
ssr: true,
3227+
},
3228+
)
3229+
3230+
const comp2Code = `<div>Comp2</div>`
3231+
const Comp2 = compile(
3232+
`<template>${comp2Code}</template>`,
3233+
data,
3234+
undefined,
3235+
{
3236+
vapor: true,
3237+
ssr: false,
3238+
},
3239+
)
3240+
const ssrComp2 = compile(
3241+
`<template>${comp2Code}</template>`,
3242+
data,
3243+
undefined,
3244+
{
3245+
vapor: true,
3246+
ssr: true,
3247+
},
3248+
)
31793249

3180-
test('unmount (full integration)', async () => {})
3250+
const appCode = `<div>
3251+
<components.Comp1 v-if="data.toggle"/>
3252+
<components.Comp2 v-else/>
3253+
</div>`
3254+
3255+
const ssrApp = compile(
3256+
`<template>${appCode}</template>`,
3257+
data,
3258+
{
3259+
Comp1: ssrComp1,
3260+
Comp2: ssrComp2,
3261+
},
3262+
{
3263+
vapor: true,
3264+
ssr: true,
3265+
},
3266+
)
3267+
3268+
const teleportContainer = document.createElement('div')
3269+
teleportContainer.id = 'target'
3270+
document.body.appendChild(teleportContainer)
3271+
3272+
const ctx = {} as any
3273+
const mainHtml = await VueServerRenderer.renderToString(
3274+
runtimeDom.createSSRApp(ssrApp),
3275+
ctx,
3276+
)
3277+
expect(mainHtml).toBe(
3278+
'<div><!--teleport start--><!--teleport end--></div>',
3279+
)
3280+
teleportContainer.innerHTML = ctx.teleports!['#target']
3281+
3282+
const { container } = await mountWithHydration(mainHtml, appCode, data, {
3283+
Comp1,
3284+
Comp2,
3285+
})
3286+
3287+
expect(container.innerHTML).toBe(
3288+
'<div><!--teleport start--><!--teleport end--><!--if--></div>',
3289+
)
3290+
expect(teleportContainer.innerHTML).toBe(
3291+
`<!--teleport start anchor-->` +
3292+
`<span>Teleported Comp1</span>` +
3293+
`<!--teleport anchor-->`,
3294+
)
3295+
expect(`Hydration children mismatch`).not.toHaveBeenWarned()
3296+
3297+
data.value.toggle = false
3298+
await nextTick()
3299+
expect(container.innerHTML).toBe('<div><div>Comp2</div><!--if--></div>')
3300+
expect(teleportContainer.innerHTML).toBe('')
3301+
})
31813302

31823303
test('unmount (mismatch + full integration)', async () => {})
31833304

packages/runtime-vapor/src/components/Teleport.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ export class TeleportFragment extends VaporFragment {
206206
this.targetAnchor = undefined
207207
}
208208

209+
if (this.anchor) {
210+
remove(this.anchor, this.anchor.parentNode!)
211+
this.anchor = undefined
212+
}
213+
209214
if (this.placeholder) {
210215
remove(this.placeholder!, parent)
211216
this.placeholder = undefined
@@ -224,13 +229,14 @@ export class TeleportFragment extends VaporFragment {
224229
const disabled = isTeleportDisabled(this.resolvedProps!)
225230
const targetNode =
226231
(target as TeleportTargetElement)._lpa || target.firstChild
232+
this.placeholder = currentHydrationNode!
227233
if (disabled) {
228-
this.placeholder = currentHydrationNode!
229234
let nextNode = this.placeholder.nextSibling!
230235
setCurrentHydrationNode(nextNode)
231-
this.anchor = locateTeleportEndAnchor(nextNode)!
236+
this.mountAnchor = this.anchor = locateTeleportEndAnchor(nextNode)!
232237
this.targetStart = targetNode
233238
this.targetAnchor = targetNode && targetNode.nextSibling
239+
this.mountContainer = this.anchor.parentNode
234240
} else {
235241
this.anchor = locateTeleportEndAnchor()!
236242
let targetAnchor = targetNode
@@ -239,15 +245,18 @@ export class TeleportFragment extends VaporFragment {
239245
if ((targetAnchor as Comment).data === 'teleport start anchor') {
240246
this.targetStart = targetAnchor
241247
} else if ((targetAnchor as Comment).data === 'teleport anchor') {
242-
this.targetAnchor = targetAnchor
248+
this.mountAnchor = this.targetAnchor = targetAnchor
243249
;(target as TeleportTargetElement)._lpa =
244250
this.targetAnchor && this.targetAnchor.nextSibling
245251
break
246252
}
247253
}
248254
targetAnchor = targetAnchor.nextSibling
249255
}
250-
setCurrentHydrationNode(targetNode && targetNode.nextSibling)
256+
if (targetNode) {
257+
this.mountContainer = this.targetAnchor!.parentNode
258+
setCurrentHydrationNode(targetNode.nextSibling)
259+
}
251260
}
252261

253262
this.initChildren()

packages/runtime-vapor/src/fragment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ export function findLastChild(node: Block): Node | undefined | null {
238238
} else if (isVaporComponent(node)) {
239239
return findLastChild(node.block!)
240240
} else {
241-
if (node instanceof DynamicFragment && node.anchor) return node.anchor
241+
if (node.anchor) return node.anchor
242242
return findLastChild(node.nodes!)
243243
}
244244
}

0 commit comments

Comments
 (0)