@@ -4,14 +4,24 @@ import {
44 createComponent as originalCreateComponent ,
55} from '../../src/component'
66import {
7+ type VaporDirective ,
78 VaporTeleport ,
9+ createIf ,
810 createTemplateRefSetter ,
911 setInsertionState ,
1012 template ,
13+ withVaporDirectives ,
1114} from '@vue/runtime-vapor'
1215
1316import { makeRender } from '../_utils'
14- import { nextTick , onBeforeUnmount , onUnmounted , ref , shallowRef } from 'vue'
17+ import {
18+ nextTick ,
19+ onBeforeUnmount ,
20+ onMounted ,
21+ onUnmounted ,
22+ ref ,
23+ shallowRef ,
24+ } from 'vue'
1525
1626const define = makeRender ( )
1727
@@ -410,17 +420,254 @@ function runSharedTests(deferMode: boolean): void {
410420 expect ( target . innerHTML ) . toBe ( '<div>teleported</div>' )
411421 } )
412422
413- test . todo ( 'moving teleport while disabled' , async ( ) => { } )
414- test . todo ( 'should work with block tree' , async ( ) => { } )
415- test . todo (
416- `the dir hooks of the Teleport's children should be called correctly` ,
417- async ( ) => { } ,
418- )
419- test . todo (
420- `ensure that target changes when disabled are updated correctly when enabled` ,
421- async ( ) => { } ,
422- )
423- test . todo ( 'toggle sibling node inside target node' , async ( ) => { } )
424- test . todo ( 'unmount previous sibling node inside target node' , async ( ) => { } )
425- test . todo ( 'accessing template refs inside teleport' , async ( ) => { } )
423+ test . todo ( 'moving teleport while disabled' , async ( ) => {
424+ const target = document . createElement ( 'div' )
425+ const root = document . createElement ( 'div' )
426+
427+ const child1 = createComponent (
428+ VaporTeleport ,
429+ { to : ( ) => target , disabled : ( ) => true } ,
430+ { default : ( ) => template ( '<div>teleported</div>' ) ( ) } ,
431+ )
432+ const child2 = template ( '<div>root</div>' ) ( )
433+
434+ const children = shallowRef ( [ child1 , child2 ] )
435+ const { mount } = define ( {
436+ setup ( ) {
437+ return children . value
438+ } ,
439+ } ) . create ( )
440+ mount ( root )
441+
442+ expect ( root . innerHTML ) . toBe (
443+ '<div>teleported</div><!--teleport--><div>root</div>' ,
444+ )
445+ expect ( target . innerHTML ) . toBe ( '' )
446+
447+ children . value = [ child2 , child1 ]
448+ await nextTick ( )
449+ expect ( root . innerHTML ) . toBe (
450+ '<div>root</div><div>teleported</div><!--teleport-->' ,
451+ )
452+ expect ( target . innerHTML ) . toBe ( '' )
453+ } )
454+
455+ test ( `the dir hooks of the Teleport's children should be called correctly` , async ( ) => {
456+ const target = document . createElement ( 'div' )
457+ const root = document . createElement ( 'div' )
458+ const toggle = ref ( true )
459+
460+ const spy = vi . fn ( )
461+ const teardown = vi . fn ( )
462+ const dir : VaporDirective = vi . fn ( ( el , source ) => {
463+ spy ( )
464+ return teardown
465+ } )
466+
467+ const { mount } = define ( {
468+ setup ( ) {
469+ return createComponent (
470+ VaporTeleport ,
471+ {
472+ to : ( ) => target ,
473+ } ,
474+ {
475+ default : ( ) => {
476+ return createIf (
477+ ( ) => toggle . value ,
478+ ( ) => {
479+ const n1 = template ( '<div>foo</div>' ) ( ) as any
480+ withVaporDirectives ( n1 , [ [ dir ] ] )
481+ return n1
482+ } ,
483+ )
484+ } ,
485+ } ,
486+ )
487+ } ,
488+ } ) . create ( )
489+
490+ mount ( root )
491+ expect ( root . innerHTML ) . toBe ( '<!--teleport-->' )
492+ expect ( target . innerHTML ) . toBe ( '<div>foo</div><!--if-->' )
493+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
494+ expect ( teardown ) . not . toHaveBeenCalled ( )
495+
496+ toggle . value = false
497+ await nextTick ( )
498+ expect ( root . innerHTML ) . toBe ( '<!--teleport-->' )
499+ expect ( target . innerHTML ) . toBe ( '<!--if-->' )
500+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
501+ expect ( teardown ) . toHaveBeenCalledTimes ( 1 )
502+ } )
503+
504+ test ( `ensure that target changes when disabled are updated correctly when enabled` , async ( ) => {
505+ const root = document . createElement ( 'div' )
506+ const target1 = document . createElement ( 'div' )
507+ const target2 = document . createElement ( 'div' )
508+ const target3 = document . createElement ( 'div' )
509+ const target = ref ( target1 )
510+ const disabled = ref ( true )
511+
512+ const { mount } = define ( {
513+ setup ( ) {
514+ return createComponent (
515+ VaporTeleport ,
516+ {
517+ to : ( ) => target . value ,
518+ disabled : ( ) => disabled . value ,
519+ } ,
520+ {
521+ default : ( ) => template ( '<div>teleported</div>' ) ( ) ,
522+ } ,
523+ )
524+ } ,
525+ } ) . create ( )
526+ mount ( root )
527+
528+ disabled . value = false
529+ await nextTick ( )
530+ expect ( target1 . innerHTML ) . toBe ( '<div>teleported</div>' )
531+ expect ( target2 . innerHTML ) . toBe ( '' )
532+ expect ( target3 . innerHTML ) . toBe ( '' )
533+
534+ disabled . value = true
535+ await nextTick ( )
536+ target . value = target2
537+ await nextTick ( )
538+ expect ( target1 . innerHTML ) . toBe ( '' )
539+ expect ( target2 . innerHTML ) . toBe ( '' )
540+ expect ( target3 . innerHTML ) . toBe ( '' )
541+
542+ target . value = target3
543+ await nextTick ( )
544+ expect ( target1 . innerHTML ) . toBe ( '' )
545+ expect ( target2 . innerHTML ) . toBe ( '' )
546+ expect ( target3 . innerHTML ) . toBe ( '' )
547+
548+ disabled . value = false
549+ await nextTick ( )
550+ expect ( target1 . innerHTML ) . toBe ( '' )
551+ expect ( target2 . innerHTML ) . toBe ( '' )
552+ expect ( target3 . innerHTML ) . toBe ( '<div>teleported</div>' )
553+ } )
554+
555+ test ( 'toggle sibling node inside target node' , async ( ) => {
556+ const root = document . createElement ( 'div' )
557+ const show = ref ( false )
558+ const { mount } = define ( {
559+ setup ( ) {
560+ return createIf (
561+ ( ) => show . value ,
562+ ( ) => {
563+ return createComponent (
564+ VaporTeleport ,
565+ {
566+ to : ( ) => root ,
567+ } ,
568+ {
569+ default : ( ) => template ( '<div>teleported</div>' ) ( ) ,
570+ } ,
571+ )
572+ } ,
573+ ( ) => {
574+ return template ( '<div>foo</div>' ) ( )
575+ } ,
576+ )
577+ } ,
578+ } ) . create ( )
579+
580+ mount ( root )
581+ expect ( root . innerHTML ) . toBe ( '<div>foo</div><!--if-->' )
582+
583+ show . value = true
584+ await nextTick ( )
585+ expect ( root . innerHTML ) . toBe ( '<!--teleport--><!--if--><div>teleported</div>' )
586+
587+ show . value = false
588+ await nextTick ( )
589+ expect ( root . innerHTML ) . toBe ( '<div>foo</div><!--if-->' )
590+ } )
591+
592+ test ( 'unmount previous sibling node inside target node' , async ( ) => {
593+ const root = document . createElement ( 'div' )
594+ const parentShow = ref ( false )
595+ const childShow = ref ( true )
596+
597+ const { component : Comp } = define ( {
598+ setup ( ) {
599+ return createComponent (
600+ VaporTeleport ,
601+ { to : ( ) => root } ,
602+ {
603+ default : ( ) => {
604+ return template ( '<div>foo</div>' ) ( )
605+ } ,
606+ } ,
607+ )
608+ } ,
609+ } )
610+
611+ const { mount } = define ( {
612+ setup ( ) {
613+ return createIf (
614+ ( ) => parentShow . value ,
615+ ( ) =>
616+ createIf (
617+ ( ) => childShow . value ,
618+ ( ) => createComponent ( Comp ) ,
619+ ( ) => template ( 'bar' ) ( ) ,
620+ ) ,
621+ ( ) => template ( 'foo' ) ( ) ,
622+ )
623+ } ,
624+ } ) . create ( )
625+
626+ mount ( root )
627+ expect ( root . innerHTML ) . toBe ( 'foo<!--if-->' )
628+
629+ parentShow . value = true
630+ await nextTick ( )
631+ expect ( root . innerHTML ) . toBe (
632+ '<!--teleport--><!--if--><!--if--><div>foo</div>' ,
633+ )
634+
635+ parentShow . value = false
636+ await nextTick ( )
637+ expect ( root . innerHTML ) . toBe ( 'foo<!--if-->' )
638+ } )
639+
640+ test ( 'accessing template refs inside teleport' , async ( ) => {
641+ const target = document . createElement ( 'div' )
642+ const tRef = ref ( )
643+ let tRefInMounted
644+
645+ const { mount } = define ( {
646+ setup ( ) {
647+ onMounted ( ( ) => {
648+ tRefInMounted = tRef . value
649+ } )
650+ const n1 = createComponent (
651+ VaporTeleport ,
652+ {
653+ to : ( ) => target ,
654+ } ,
655+ {
656+ default : ( ) => {
657+ const setTemplateRef = createTemplateRefSetter ( )
658+ const n0 = template ( '<div>teleported</div>' ) ( ) as any
659+ setTemplateRef ( n0 , tRef )
660+ return n0
661+ } ,
662+ } ,
663+ )
664+ return n1
665+ } ,
666+ } ) . create ( )
667+ mount ( target )
668+
669+ const child = target . children [ 0 ]
670+ expect ( child . outerHTML ) . toBe ( `<div>teleported</div>` )
671+ expect ( tRefInMounted ) . toBe ( child )
672+ } )
426673}
0 commit comments