@@ -107,6 +107,33 @@ describe('Portals', () => {
107107 . toBe ( false , 'Expected content to be removed from outlet on detach.' ) ;
108108 } ) ;
109109
110+ it ( 'should throw when trying to load an element without a parent into a DOM portal' , ( ) => {
111+ const testAppComponent = fixture . componentInstance ;
112+ const element = document . createElement ( 'div' ) ;
113+ const domPortal = new DomPortal ( element ) ;
114+
115+ expect ( ( ) => {
116+ testAppComponent . selectedPortal = domPortal ;
117+ fixture . detectChanges ( ) ;
118+ } ) . toThrowError ( 'DOM portal content must be attached to a parent node.' ) ;
119+ } ) ;
120+
121+ it ( 'should not throw when restoring if the outlet element was cleared' , ( ) => {
122+ const testAppComponent = fixture . componentInstance ;
123+ const parent = fixture . nativeElement . querySelector ( '.dom-portal-parent' ) ;
124+ const domPortal = new DomPortal ( testAppComponent . domPortalContent ) ;
125+
126+ testAppComponent . selectedPortal = domPortal ;
127+ fixture . detectChanges ( ) ;
128+
129+ parent . innerHTML = '' ;
130+
131+ expect ( ( ) => {
132+ testAppComponent . selectedPortal = undefined ;
133+ fixture . detectChanges ( ) ;
134+ } ) . not . toThrow ( ) ;
135+ } ) ;
136+
110137 it ( 'should project template context bindings in the portal' , ( ) => {
111138 let testAppComponent = fixture . componentInstance ;
112139 let hostContainer = fixture . nativeElement . querySelector ( '.portal-container' ) ;
@@ -558,6 +585,29 @@ describe('Portals', () => {
558585 expect ( someDomElement . textContent ! . trim ( ) ) . toBe ( '' ) ;
559586 } ) ;
560587
588+ it ( 'should throw when trying to load an element without a parent into a DOM portal' , ( ) => {
589+ const fixture = TestBed . createComponent ( PortalTestApp ) ;
590+ fixture . detectChanges ( ) ;
591+ const element = document . createElement ( 'div' ) ;
592+ const portal = new DomPortal ( element ) ;
593+
594+ expect ( ( ) => {
595+ portal . attach ( host ) ;
596+ fixture . detectChanges ( ) ;
597+ } ) . toThrowError ( 'DOM portal content must be attached to a parent node.' ) ;
598+ } ) ;
599+
600+ it ( 'should not throw when restoring if the outlet element was cleared' , ( ) => {
601+ const fixture = TestBed . createComponent ( PortalTestApp ) ;
602+ fixture . detectChanges ( ) ;
603+ const portal = new DomPortal ( fixture . componentInstance . domPortalContent ) ;
604+
605+ portal . attach ( host ) ;
606+ host . outletElement . innerHTML = '' ;
607+
608+ expect ( ( ) => host . detach ( ) ) . not . toThrow ( ) ;
609+ } ) ;
610+
561611 } ) ;
562612} ) ;
563613
@@ -618,8 +668,10 @@ class ArbitraryViewContainerRefComponent {
618668
619669 <ng-template #templateRef let-data> {{fruit}} - {{ data?.status }}!</ng-template>
620670
621- <div #domPortalContent>
622- <p class="dom-portal-inner-content">Hello there</p>
671+ <div class="dom-portal-parent">
672+ <div #domPortalContent>
673+ <p class="dom-portal-inner-content">Hello there</p>
674+ </div>
623675 </div>
624676 ` ,
625677} )
0 commit comments