mirror of https://github.com/vuejs/core.git
refactor: teleport
This commit is contained in:
parent
1ee1777232
commit
4fc0247d0d
|
@ -2,6 +2,7 @@ import {
|
||||||
type LooseRawProps,
|
type LooseRawProps,
|
||||||
type VaporComponent,
|
type VaporComponent,
|
||||||
createComponent as createComp,
|
createComponent as createComp,
|
||||||
|
createComponent,
|
||||||
} from '../../src/component'
|
} from '../../src/component'
|
||||||
import {
|
import {
|
||||||
type VaporDirective,
|
type VaporDirective,
|
||||||
|
@ -9,15 +10,18 @@ import {
|
||||||
child,
|
child,
|
||||||
createIf,
|
createIf,
|
||||||
createTemplateRefSetter,
|
createTemplateRefSetter,
|
||||||
|
createVaporApp,
|
||||||
defineVaporComponent,
|
defineVaporComponent,
|
||||||
renderEffect,
|
renderEffect,
|
||||||
setInsertionState,
|
setInsertionState,
|
||||||
setText,
|
setText,
|
||||||
template,
|
template,
|
||||||
|
vaporInteropPlugin,
|
||||||
withVaporDirectives,
|
withVaporDirectives,
|
||||||
} from '@vue/runtime-vapor'
|
} from '@vue/runtime-vapor'
|
||||||
import { makeRender } from '../_utils'
|
import { makeRender } from '../_utils'
|
||||||
import {
|
import {
|
||||||
|
h,
|
||||||
nextTick,
|
nextTick,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
onMounted,
|
onMounted,
|
||||||
|
@ -63,7 +67,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<!--teleport--><div id="target"><div>teleported</div></div>',
|
'<!--teleport start--><!--teleport end--><div id="target"><div>teleported</div></div>',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -116,7 +120,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
show.value = true
|
show.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
`<!--teleport--><div>Footer</div><div id="targetId"><div>bar</div></div><!--if-->`,
|
`<!--teleport start--><!--teleport end--><div>Footer</div><div id="targetId"><div>bar</div></div><!--if-->`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -155,7 +159,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
createRecord(parentId, Parent as any)
|
createRecord(parentId, Parent as any)
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
|
|
||||||
// rerender child
|
// rerender child
|
||||||
|
@ -163,7 +169,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
return template('<div>teleported 2</div>')()
|
return template('<div>teleported 2</div>')()
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
||||||
|
|
||||||
// rerender parent
|
// rerender parent
|
||||||
|
@ -181,7 +189,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
return [n0, n1]
|
return [n0, n1]
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root 2</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root 2</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -219,7 +229,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div><div>teleported</div><!--teleport--><div>root</div></div>',
|
'<div><!--teleport start--><div>teleported</div><!--teleport end--><div>root</div></div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -241,14 +251,16 @@ describe('renderer: VaporTeleport', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div><div>teleported</div><!--teleport--><div>root 2</div></div>',
|
'<div><!--teleport start--><div>teleported</div><!--teleport end--><div>root 2</div></div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
// toggle disabled
|
// toggle disabled
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<div><!--teleport--><div>root 2</div></div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<div><!--teleport start--><!--teleport end--><div>root 2</div></div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -300,7 +312,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
createRecord(parentId, Parent as any)
|
createRecord(parentId, Parent as any)
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
|
|
||||||
// reload child by changing msg
|
// reload child by changing msg
|
||||||
|
@ -318,7 +332,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
return [n0]
|
return [n0]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
||||||
|
|
||||||
// reload parent by changing msg
|
// reload parent by changing msg
|
||||||
|
@ -348,7 +364,9 @@ describe('renderer: VaporTeleport', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root 2</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root 2</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
expect(target.innerHTML).toBe('<div>teleported 2</div>')
|
||||||
|
|
||||||
// reload parent again by changing disabled
|
// reload parent again by changing disabled
|
||||||
|
@ -379,7 +397,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported 2</div><!--teleport--><div>root 2</div>',
|
'<!--teleport start--><div>teleported 2</div><!--teleport end--><div>root 2</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
})
|
})
|
||||||
|
@ -434,7 +452,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported</div><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported</div><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -454,7 +472,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported 2</div><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported 2</div><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -474,14 +492,16 @@ describe('renderer: VaporTeleport', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported 3</div><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported 3</div><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
// toggle disabled
|
// toggle disabled
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 3</div>')
|
expect(target.innerHTML).toBe('<div>teleported 3</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -537,7 +557,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported</div><span>child</span><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported</div><span>child</span><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -557,7 +577,7 @@ describe('renderer: VaporTeleport', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported 2</div><span>child</span><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported 2</div><span>child</span><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -577,17 +597,68 @@ describe('renderer: VaporTeleport', () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div>teleported 3</div><span>child</span><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported 3</div><span>child</span><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
// toggle disabled
|
// toggle disabled
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported 3</div><span>child</span>')
|
expect(target.innerHTML).toBe('<div>teleported 3</div><span>child</span>')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('VDOM interop', () => {
|
||||||
|
test('render vdom component', async () => {
|
||||||
|
const target = document.createElement('div')
|
||||||
|
const root = document.createElement('div')
|
||||||
|
|
||||||
|
const VDOMComp = {
|
||||||
|
setup() {
|
||||||
|
return () => h('h1', null, 'vdom comp')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const disabled = ref(true)
|
||||||
|
const App = defineVaporComponent({
|
||||||
|
setup() {
|
||||||
|
const n1 = createComponent(
|
||||||
|
VaporTeleport,
|
||||||
|
{
|
||||||
|
to: () => target,
|
||||||
|
defer: () => '',
|
||||||
|
disabled: () => disabled.value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => {
|
||||||
|
const n0 = createComponent(VDOMComp)
|
||||||
|
return n0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
return n1
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const app = createVaporApp(App)
|
||||||
|
app.use(vaporInteropPlugin)
|
||||||
|
app.mount(root)
|
||||||
|
|
||||||
|
expect(target.innerHTML).toBe('')
|
||||||
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><h1>vdom comp</h1><!--teleport end-->',
|
||||||
|
)
|
||||||
|
|
||||||
|
disabled.value = false
|
||||||
|
await nextTick()
|
||||||
|
expect(root.innerHTML).toBe('<!--teleport start--><!--teleport end-->')
|
||||||
|
expect(target.innerHTML).toBe('<h1>vdom comp</h1>')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function runSharedTests(deferMode: boolean): void {
|
function runSharedTests(deferMode: boolean): void {
|
||||||
|
@ -625,7 +696,9 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
}).create()
|
}).create()
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -654,14 +727,18 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
}).create()
|
}).create()
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(targetA.innerHTML).toBe('<div>teleported</div>')
|
expect(targetA.innerHTML).toBe('<div>teleported</div>')
|
||||||
expect(targetB.innerHTML).toBe('')
|
expect(targetB.innerHTML).toBe('')
|
||||||
|
|
||||||
target.value = targetB
|
target.value = targetB
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(targetA.innerHTML).toBe('')
|
expect(targetA.innerHTML).toBe('')
|
||||||
expect(targetB.innerHTML).toBe('<div>teleported</div>')
|
expect(targetB.innerHTML).toBe('<div>teleported</div>')
|
||||||
})
|
})
|
||||||
|
@ -834,7 +911,9 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
},
|
},
|
||||||
}).create()
|
}).create()
|
||||||
mount(root)
|
mount(root)
|
||||||
expect(root.innerHTML).toBe('<div><!--teleport--><!--teleport--></div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<div><!--teleport start--><!--teleport end--><!--teleport start--><!--teleport end--></div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>one</div>two')
|
expect(target.innerHTML).toBe('<div>one</div>two')
|
||||||
|
|
||||||
// update existing content
|
// update existing content
|
||||||
|
@ -849,7 +928,9 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
// toggling
|
// toggling
|
||||||
child1.value = [] as any
|
child1.value = [] as any
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<div><!--teleport--><!--teleport--></div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<div><!--teleport start--><!--teleport end--><!--teleport start--><!--teleport end--></div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('three')
|
expect(target.innerHTML).toBe('three')
|
||||||
|
|
||||||
// toggle back
|
// toggle back
|
||||||
|
@ -859,14 +940,18 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
] as any
|
] as any
|
||||||
child2.value = [template('three')()] as any
|
child2.value = [template('three')()] as any
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<div><!--teleport--><!--teleport--></div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<div><!--teleport start--><!--teleport end--><!--teleport start--><!--teleport end--></div>',
|
||||||
|
)
|
||||||
// should append
|
// should append
|
||||||
expect(target.innerHTML).toBe('<div>one</div><div>two</div>three')
|
expect(target.innerHTML).toBe('<div>one</div><div>two</div>three')
|
||||||
|
|
||||||
// toggle the other teleport
|
// toggle the other teleport
|
||||||
child2.value = [] as any
|
child2.value = [] as any
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<div><!--teleport--><!--teleport--></div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<div><!--teleport start--><!--teleport end--><!--teleport start--><!--teleport end--></div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>one</div><div>two</div>')
|
expect(target.innerHTML).toBe('<div>one</div><div>two</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -897,12 +982,12 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div></div><div>teleported</div><!--teleport-->',
|
'<div></div><!--teleport start--><div>teleported</div><!--teleport end-->',
|
||||||
)
|
)
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<div><div>teleported</div></div><!--teleport-->',
|
'<div><div>teleported</div></div><!--teleport start--><!--teleport end-->',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -929,13 +1014,15 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
}).create()
|
}).create()
|
||||||
mount(root)
|
mount(root)
|
||||||
|
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
|
|
||||||
disabled.value = true
|
disabled.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<!--teleport start--><div>teleported</div><!--teleport end--><!--teleport--><div>root</div>',
|
'<!--teleport start--><div>teleported</div><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('')
|
expect(target.innerHTML).toBe('')
|
||||||
|
|
||||||
|
@ -943,7 +1030,7 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<!--teleport start--><!--teleport end--><!--teleport--><div>root</div>',
|
'<!--teleport start--><!--teleport end--><div>root</div>',
|
||||||
)
|
)
|
||||||
expect(target.innerHTML).toBe('<div>teleported</div>')
|
expect(target.innerHTML).toBe('<div>teleported</div>')
|
||||||
})
|
})
|
||||||
|
@ -984,14 +1071,14 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
}).create()
|
}).create()
|
||||||
|
|
||||||
mount(root)
|
mount(root)
|
||||||
expect(root.innerHTML).toBe('<!--teleport-->')
|
expect(root.innerHTML).toBe('<!--teleport start--><!--teleport end-->')
|
||||||
expect(target.innerHTML).toBe('<div>foo</div><!--if-->')
|
expect(target.innerHTML).toBe('<div>foo</div><!--if-->')
|
||||||
expect(spy).toHaveBeenCalledTimes(1)
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
expect(teardown).not.toHaveBeenCalled()
|
expect(teardown).not.toHaveBeenCalled()
|
||||||
|
|
||||||
toggle.value = false
|
toggle.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<!--teleport-->')
|
expect(root.innerHTML).toBe('<!--teleport start--><!--teleport end-->')
|
||||||
expect(target.innerHTML).toBe('<!--if-->')
|
expect(target.innerHTML).toBe('<!--if-->')
|
||||||
expect(spy).toHaveBeenCalledTimes(1)
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
expect(teardown).toHaveBeenCalledTimes(1)
|
expect(teardown).toHaveBeenCalledTimes(1)
|
||||||
|
@ -1078,7 +1165,9 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
|
|
||||||
show.value = true
|
show.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe('<!--teleport--><!--if--><div>teleported</div>')
|
expect(root.innerHTML).toBe(
|
||||||
|
'<!--teleport start--><!--teleport end--><!--if--><div>teleported</div>',
|
||||||
|
)
|
||||||
|
|
||||||
show.value = false
|
show.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
@ -1125,7 +1214,7 @@ function runSharedTests(deferMode: boolean): void {
|
||||||
parentShow.value = true
|
parentShow.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(root.innerHTML).toBe(
|
expect(root.innerHTML).toBe(
|
||||||
'<!--teleport--><!--if--><!--if--><div>foo</div>',
|
'<!--teleport start--><!--teleport end--><!--if--><!--if--><div>foo</div>',
|
||||||
)
|
)
|
||||||
|
|
||||||
parentShow.value = false
|
parentShow.value = false
|
||||||
|
|
|
@ -110,12 +110,7 @@ export function insert(
|
||||||
if (block.insert) {
|
if (block.insert) {
|
||||||
block.insert(parent, anchor, (block as TransitionBlock).$transition)
|
block.insert(parent, anchor, (block as TransitionBlock).$transition)
|
||||||
} else {
|
} else {
|
||||||
insert(
|
insert(block.nodes, parent, anchor, parentSuspense)
|
||||||
block.nodes,
|
|
||||||
block.target || parent,
|
|
||||||
block.targetAnchor || anchor,
|
|
||||||
parentSuspense,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,12 @@ export const VaporTeleportImpl = {
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateEffect = renderEffect(() => {
|
const updateEffect = renderEffect(() => {
|
||||||
frag.update(
|
// access the props to trigger tracking
|
||||||
// access the props to trigger tracking
|
frag.props = extend(
|
||||||
extend(
|
{},
|
||||||
{},
|
new Proxy(props, rawPropsProxyHandlers) as any as TeleportProps,
|
||||||
new Proxy(props, rawPropsProxyHandlers) as any as TeleportProps,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
frag.update()
|
||||||
})
|
})
|
||||||
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
|
@ -82,7 +81,10 @@ export const VaporTeleportImpl = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TeleportFragment extends VaporFragment {
|
export class TeleportFragment extends VaporFragment {
|
||||||
|
target?: ParentNode | null
|
||||||
|
targetAnchor?: Node | null
|
||||||
anchor: Node
|
anchor: Node
|
||||||
|
props?: TeleportProps
|
||||||
|
|
||||||
private targetStart?: Node
|
private targetStart?: Node
|
||||||
private mainAnchor?: Node
|
private mainAnchor?: Node
|
||||||
|
@ -92,7 +94,7 @@ export class TeleportFragment extends VaporFragment {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super([])
|
super([])
|
||||||
this.anchor = __DEV__ ? createComment('teleport') : createTextNode()
|
this.anchor = createTextNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentParent(): ParentNode {
|
get currentParent(): ParentNode {
|
||||||
|
@ -104,7 +106,7 @@ export class TeleportFragment extends VaporFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
get parent(): ParentNode | null {
|
get parent(): ParentNode | null {
|
||||||
return this.anchor.parentNode
|
return this.anchor && this.anchor.parentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChildren(children: Block): void {
|
updateChildren(children: Block): void {
|
||||||
|
@ -120,7 +122,10 @@ export class TeleportFragment extends VaporFragment {
|
||||||
insert((this.nodes = children), this.currentParent, this.currentAnchor)
|
insert((this.nodes = children), this.currentParent, this.currentAnchor)
|
||||||
}
|
}
|
||||||
|
|
||||||
update(props: TeleportProps): void {
|
update(): void {
|
||||||
|
// not mounted yet
|
||||||
|
if (!this.parent) return
|
||||||
|
|
||||||
const mount = (parent: ParentNode, anchor: Node | null) => {
|
const mount = (parent: ParentNode, anchor: Node | null) => {
|
||||||
insert(
|
insert(
|
||||||
this.nodes,
|
this.nodes,
|
||||||
|
@ -130,7 +135,10 @@ export class TeleportFragment extends VaporFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mountToTarget = () => {
|
const mountToTarget = () => {
|
||||||
const target = (this.target = resolveTeleportTarget(props, querySelector))
|
const target = (this.target = resolveTeleportTarget(
|
||||||
|
this.props!,
|
||||||
|
querySelector,
|
||||||
|
))
|
||||||
if (target) {
|
if (target) {
|
||||||
if (
|
if (
|
||||||
// initial mount into target
|
// initial mount into target
|
||||||
|
@ -153,29 +161,12 @@ export class TeleportFragment extends VaporFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mount into main container
|
// mount into main container
|
||||||
if (isTeleportDisabled(props)) {
|
if (isTeleportDisabled(this.props!)) {
|
||||||
if (this.parent) {
|
mount(this.parent, this.mainAnchor!)
|
||||||
if (!this.mainAnchor) {
|
|
||||||
this.mainAnchor = __DEV__
|
|
||||||
? createComment('teleport end')
|
|
||||||
: createTextNode()
|
|
||||||
}
|
|
||||||
if (!this.placeholder) {
|
|
||||||
this.placeholder = __DEV__
|
|
||||||
? createComment('teleport start')
|
|
||||||
: createTextNode()
|
|
||||||
}
|
|
||||||
if (!this.mainAnchor.isConnected) {
|
|
||||||
insert(this.placeholder, this.parent, this.anchor)
|
|
||||||
insert(this.mainAnchor, this.parent, this.anchor)
|
|
||||||
}
|
|
||||||
|
|
||||||
mount(this.parent, this.mainAnchor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// mount into target container
|
// mount into target container
|
||||||
else {
|
else {
|
||||||
if (isTeleportDeferred(props)) {
|
if (isTeleportDeferred(this.props!)) {
|
||||||
queuePostFlushCb(mountToTarget)
|
queuePostFlushCb(mountToTarget)
|
||||||
} else {
|
} else {
|
||||||
mountToTarget()
|
mountToTarget()
|
||||||
|
@ -183,6 +174,17 @@ export class TeleportFragment extends VaporFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
insert = (container: ParentNode, anchor: Node | null): void => {
|
||||||
|
// insert anchors in the main view
|
||||||
|
this.placeholder = __DEV__
|
||||||
|
? createComment('teleport start')
|
||||||
|
: createTextNode()
|
||||||
|
this.mainAnchor = __DEV__ ? createComment('teleport end') : createTextNode()
|
||||||
|
insert(this.placeholder, container, anchor)
|
||||||
|
insert(this.mainAnchor, container, anchor)
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
|
||||||
remove = (parent: ParentNode | undefined = this.parent!): void => {
|
remove = (parent: ParentNode | undefined = this.parent!): void => {
|
||||||
// remove nodes
|
// remove nodes
|
||||||
if (this.nodes) {
|
if (this.nodes) {
|
||||||
|
|
|
@ -41,8 +41,6 @@ export class VaporFragment<T extends Block = Block>
|
||||||
remove?: (parent?: ParentNode, transitionHooks?: TransitionHooks) => void
|
remove?: (parent?: ParentNode, transitionHooks?: TransitionHooks) => void
|
||||||
fallback?: BlockFn
|
fallback?: BlockFn
|
||||||
|
|
||||||
target?: ParentNode | null
|
|
||||||
targetAnchor?: Node | null
|
|
||||||
getNodes?: () => Block
|
getNodes?: () => Block
|
||||||
setRef?: (comp: VaporComponentInstance) => void
|
setRef?: (comp: VaporComponentInstance) => void
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue