@@ -3,7 +3,12 @@ import {
3
3
type VaporComponent ,
4
4
createComponent as originalCreateComponent ,
5
5
} from '../../src/component'
6
- import { VaporTeleport , template } from '@vue/runtime-vapor'
6
+ import {
7
+ VaporTeleport ,
8
+ createTemplateRefSetter ,
9
+ setInsertionState ,
10
+ template ,
11
+ } from '@vue/runtime-vapor'
7
12
8
13
import { makeRender } from '../_utils'
9
14
import { nextTick , onBeforeUnmount , onUnmounted , ref , shallowRef } from 'vue'
@@ -192,50 +197,219 @@ function runSharedTests(deferMode: boolean): void {
192
197
expect ( target . innerHTML ) . toBe ( '' )
193
198
} )
194
199
195
- test . todo (
196
- 'descendent component should be unmounted when teleport is disabled and unmounted' ,
197
- async ( ) => {
198
- const root = document . createElement ( 'div' )
199
- const beforeUnmount = vi . fn ( )
200
- const unmounted = vi . fn ( )
201
- const { component : Comp } = define ( {
202
- setup ( ) {
203
- onBeforeUnmount ( beforeUnmount )
204
- onUnmounted ( unmounted )
205
- return [ template ( '<p>' ) ( ) , template ( '<p>' ) ( ) ]
206
- } ,
207
- } )
200
+ test ( 'descendent component should be unmounted when teleport is disabled and unmounted' , async ( ) => {
201
+ const root = document . createElement ( 'div' )
202
+ const beforeUnmount = vi . fn ( )
203
+ const unmounted = vi . fn ( )
204
+ const { component : Comp } = define ( {
205
+ setup ( ) {
206
+ onBeforeUnmount ( beforeUnmount )
207
+ onUnmounted ( unmounted )
208
+ return [ template ( '<p>' ) ( ) , template ( '<p>' ) ( ) ]
209
+ } ,
210
+ } )
208
211
209
- const { app } = define ( {
210
- setup ( ) {
211
- const n0 = createComponent (
212
- VaporTeleport ,
213
- {
214
- to : ( ) => null ,
215
- disabled : ( ) => true ,
216
- } ,
217
- {
218
- default : ( ) => createComponent ( Comp ) ,
219
- } ,
220
- )
221
- return [ n0 ]
222
- } ,
223
- } ) . create ( )
224
- app . mount ( root )
212
+ const { app } = define ( {
213
+ setup ( ) {
214
+ const n0 = createComponent (
215
+ VaporTeleport ,
216
+ {
217
+ to : ( ) => null ,
218
+ disabled : ( ) => true ,
219
+ } ,
220
+ {
221
+ default : ( ) => createComponent ( Comp ) ,
222
+ } ,
223
+ )
224
+ return [ n0 ]
225
+ } ,
226
+ } ) . create ( )
227
+ app . mount ( root )
225
228
226
- expect ( beforeUnmount ) . toHaveBeenCalledTimes ( 0 )
227
- expect ( unmounted ) . toHaveBeenCalledTimes ( 0 )
229
+ expect ( beforeUnmount ) . toHaveBeenCalledTimes ( 0 )
230
+ expect ( unmounted ) . toHaveBeenCalledTimes ( 0 )
228
231
229
- app . unmount ( )
230
- expect ( beforeUnmount ) . toHaveBeenCalledTimes ( 1 )
231
- expect ( unmounted ) . toHaveBeenCalledTimes ( 1 )
232
- } ,
233
- )
232
+ app . unmount ( )
233
+ await nextTick ( )
234
+ expect ( beforeUnmount ) . toHaveBeenCalledTimes ( 1 )
235
+ expect ( unmounted ) . toHaveBeenCalledTimes ( 1 )
236
+ } )
237
+
238
+ test ( 'multiple teleport with same target' , async ( ) => {
239
+ const target = document . createElement ( 'div' )
240
+ const root = document . createElement ( 'div' )
241
+
242
+ const child1 = shallowRef ( template ( '<div>one</div>' ) ( ) )
243
+ const child2 = shallowRef ( template ( 'two' ) ( ) )
244
+
245
+ const { mount } = define ( {
246
+ setup ( ) {
247
+ const n0 = template ( '<div></div>' ) ( )
248
+ setInsertionState ( n0 as any )
249
+ createComponent (
250
+ VaporTeleport ,
251
+ {
252
+ to : ( ) => target ,
253
+ } ,
254
+ {
255
+ default : ( ) => child1 . value ,
256
+ } ,
257
+ )
258
+ createComponent (
259
+ VaporTeleport ,
260
+ {
261
+ to : ( ) => target ,
262
+ } ,
263
+ {
264
+ default : ( ) => child2 . value ,
265
+ } ,
266
+ )
267
+ return [ n0 ]
268
+ } ,
269
+ } ) . create ( )
270
+ mount ( root )
271
+ expect ( root . innerHTML ) . toBe ( '<div><!--teleport--><!--teleport--></div>' )
272
+ expect ( target . innerHTML ) . toBe ( '<div>one</div>two' )
273
+
274
+ // update existing content
275
+ child1 . value = [
276
+ template ( '<div>one</div>' ) ( ) ,
277
+ template ( '<div>two</div>' ) ( ) ,
278
+ ] as any
279
+ child2 . value = [ template ( 'three' ) ( ) ] as any
280
+ await nextTick ( )
281
+ expect ( target . innerHTML ) . toBe ( '<div>one</div><div>two</div>three' )
282
+
283
+ // toggling
284
+ child1 . value = [ ] as any
285
+ await nextTick ( )
286
+ expect ( root . innerHTML ) . toBe ( '<div><!--teleport--><!--teleport--></div>' )
287
+ expect ( target . innerHTML ) . toBe ( 'three' )
288
+
289
+ // toggle back
290
+ child1 . value = [
291
+ template ( '<div>one</div>' ) ( ) ,
292
+ template ( '<div>two</div>' ) ( ) ,
293
+ ] as any
294
+ child2 . value = [ template ( 'three' ) ( ) ] as any
295
+ await nextTick ( )
296
+ expect ( root . innerHTML ) . toBe ( '<div><!--teleport--><!--teleport--></div>' )
297
+ // should append
298
+ expect ( target . innerHTML ) . toBe ( '<div>one</div><div>two</div>three' )
299
+
300
+ // toggle the other teleport
301
+ child2 . value = [ ] as any
302
+ await nextTick ( )
303
+ expect ( root . innerHTML ) . toBe ( '<div><!--teleport--><!--teleport--></div>' )
304
+ expect ( target . innerHTML ) . toBe ( '<div>one</div><div>two</div>' )
305
+ } )
306
+
307
+ test ( 'should work when using template ref as target' , async ( ) => {
308
+ const root = document . createElement ( 'div' )
309
+ const target = ref < HTMLElement | null > ( null )
310
+ const disabled = ref ( true )
311
+
312
+ const { mount } = define ( {
313
+ setup ( ) {
314
+ const setTemplateRef = createTemplateRefSetter ( )
315
+ const n0 = template ( '<div></div>' ) ( ) as any
316
+ setTemplateRef ( n0 , target )
317
+
318
+ const n1 = createComponent (
319
+ VaporTeleport ,
320
+ {
321
+ to : ( ) => target . value ,
322
+ disabled : ( ) => disabled . value ,
323
+ } ,
324
+ {
325
+ default : ( ) => template ( '<div>teleported</div>' ) ( ) ,
326
+ } ,
327
+ )
328
+ return [ n0 , n1 ]
329
+ } ,
330
+ } ) . create ( )
331
+ mount ( root )
332
+
333
+ expect ( root . innerHTML ) . toBe (
334
+ '<div></div><div>teleported</div><!--teleport-->' ,
335
+ )
336
+ disabled . value = false
337
+ await nextTick ( )
338
+ expect ( root . innerHTML ) . toBe (
339
+ '<div><div>teleported</div></div><!--teleport-->' ,
340
+ )
341
+ } )
342
+
343
+ test ( 'disabled' , async ( ) => {
344
+ const target = document . createElement ( 'div' )
345
+ const root = document . createElement ( 'div' )
346
+
347
+ const disabled = ref ( false )
348
+ const { mount } = define ( {
349
+ setup ( ) {
350
+ const n0 = createComponent (
351
+ VaporTeleport ,
352
+ {
353
+ to : ( ) => target ,
354
+ disabled : ( ) => disabled . value ,
355
+ } ,
356
+ {
357
+ default : ( ) => template ( '<div>teleported</div>' ) ( ) ,
358
+ } ,
359
+ )
360
+ const n1 = template ( '<div>root</div>' ) ( )
361
+ return [ n0 , n1 ]
362
+ } ,
363
+ } ) . create ( )
364
+ mount ( root )
365
+
366
+ expect ( root . innerHTML ) . toBe ( '<!--teleport--><div>root</div>' )
367
+ expect ( target . innerHTML ) . toBe ( '<div>teleported</div>' )
368
+
369
+ disabled . value = true
370
+ await nextTick ( )
371
+ expect ( root . innerHTML ) . toBe (
372
+ '<!--teleport start--><div>teleported</div><!--teleport end--><!--teleport--><div>root</div>' ,
373
+ )
374
+ expect ( target . innerHTML ) . toBe ( '' )
375
+
376
+ // toggle back
377
+ disabled . value = false
378
+ await nextTick ( )
379
+ expect ( root . innerHTML ) . toBe (
380
+ '<!--teleport start--><!--teleport end--><!--teleport--><div>root</div>' ,
381
+ )
382
+ expect ( target . innerHTML ) . toBe ( '<div>teleported</div>' )
383
+ } )
384
+
385
+ test . todo ( 'moving teleport while enabled' , async ( ) => {
386
+ const target = document . createElement ( 'div' )
387
+ const root = document . createElement ( 'div' )
388
+
389
+ const child1 = createComponent (
390
+ VaporTeleport ,
391
+ { to : ( ) => target } ,
392
+ { default : ( ) => template ( '<div>teleported</div>' ) ( ) } ,
393
+ )
394
+ const child2 = template ( '<div>root</div>' ) ( )
395
+
396
+ const children = shallowRef ( [ child1 , child2 ] )
397
+ const { mount } = define ( {
398
+ setup ( ) {
399
+ return children . value
400
+ } ,
401
+ } ) . create ( )
402
+ mount ( root )
403
+
404
+ expect ( root . innerHTML ) . toBe ( '<!--teleport--><div>root</div>' )
405
+ expect ( target . innerHTML ) . toBe ( '<div>teleported</div>' )
406
+
407
+ children . value = [ child2 , child1 ]
408
+ await nextTick ( )
409
+ expect ( root . innerHTML ) . toBe ( '<div>root</div><!--teleport-->' )
410
+ expect ( target . innerHTML ) . toBe ( '<div>teleported</div>' )
411
+ } )
234
412
235
- test . todo ( 'multiple teleport with same target' , async ( ) => { } )
236
- test . todo ( 'should work when using template ref as target' , async ( ) => { } )
237
- test . todo ( 'disabled' , async ( ) => { } )
238
- test . todo ( 'moving teleport while enabled' , async ( ) => { } )
239
413
test . todo ( 'moving teleport while disabled' , async ( ) => { } )
240
414
test . todo ( 'should work with block tree' , async ( ) => { } )
241
415
test . todo (
0 commit comments