diff --git a/src/framework/theme/components/window/window.service.spec.ts b/src/framework/theme/components/window/window.service.spec.ts index c85bd61bbc..654bd258b9 100644 --- a/src/framework/theme/components/window/window.service.spec.ts +++ b/src/framework/theme/components/window/window.service.spec.ts @@ -1,12 +1,14 @@ -import { Component, ElementRef, NgModule, ViewChild, TemplateRef } from '@angular/core'; -import { TestBed } from '@angular/core/testing'; -import { NB_DOCUMENT } from '../../theme.options'; -import { NbThemeModule } from '../../theme.module'; -import { NbOverlayContainerAdapter } from '../cdk/adapter/overlay-container-adapter'; -import { NbViewportRulerAdapter } from '../cdk/adapter/viewport-ruler-adapter'; -import { NbWindowModule } from './window.module'; -import { NbWindowService } from './window.service'; import createSpy = jasmine.createSpy; +import { Component, ElementRef, NgModule, ViewChild, TemplateRef } from '@angular/core'; +import { TestBed, fakeAsync, flush } from '@angular/core/testing'; +import { + NbWindowService, + NbWindowModule, + NbViewportRulerAdapter, + NbOverlayContainerAdapter, + NB_DOCUMENT, + NbThemeModule, +} from '@nebular/theme'; const WINDOW_CONTENT = 'window content'; @Component({ @@ -38,7 +40,7 @@ class NbTestWindowWithTemplateComponent { @Component({ selector: 'nb-test-window-with-component', - template: `

window content {{ componentInput }}

`, + template: `

window content {{ componentInput }}

`, }) export class TestWindowComponent {} @@ -259,4 +261,32 @@ describe('window-service', () => { const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef); expect(windowElement.nativeElement.innerText).toEqual('window content hello world'); }); + + it('should create new window container when overlay container changed', fakeAsync(() => { + const fixture = TestBed.createComponent(NbTestWindowWithTemplateComponent); + fixture.detectChanges(); + + // Show window to force windows container creation + const windowRef = fixture.componentInstance.openWindow(); + fixture.detectChanges(); + flush(); + + windowRef.close(); + fixture.detectChanges(); + flush(); + + // Change overlay container + overlayContainerService.ngOnDestroy(); + overlayContainerService.clearContainer(); + overlayContainer = document.createElement('div'); + overlayContainerService.setContainer(overlayContainer); + document.body.appendChild(overlayContainer); + + windowService.open(TestWindowComponent); + fixture.detectChanges(); + flush(); + + const windowContent = document.getElementById('window-content'); + expect(document.body.contains(windowContent)).toEqual(true); + })); }); diff --git a/src/framework/theme/components/window/window.service.ts b/src/framework/theme/components/window/window.service.ts index fe849d6c95..50a95e0ff2 100644 --- a/src/framework/theme/components/window/window.service.ts +++ b/src/framework/theme/components/window/window.service.ts @@ -26,6 +26,7 @@ import { import { NbWindowRef } from './window-ref'; import { NbWindowsContainerComponent } from './windows-container.component'; import { NbWindowComponent } from './window.component'; +import { NB_DOCUMENT } from '../../theme.options'; /** * The `NbWindowService` can be used to open windows. @@ -38,7 +39,7 @@ import { NbWindowComponent } from './window.component'; * ```ts * @NgModule({ * imports: [ - * // ... + * // ... * NbWindowModule.forRoot(config), * ], * }) @@ -49,7 +50,7 @@ import { NbWindowComponent } from './window.component'; * ```ts * @NgModule({ * imports: [ - * // ... + * // ... * NbWindowModule.forChild(config), * ], * }) @@ -101,6 +102,7 @@ import { NbWindowComponent } from './window.component'; @Injectable() export class NbWindowService { + protected document: Document; protected overlayRef: NbOverlayRef; protected windowsContainerViewRef: ViewContainerRef; protected openWindows: NbWindowRef[] = []; @@ -112,7 +114,9 @@ export class NbWindowService { protected blockScrollStrategy: NbBlockScrollStrategyAdapter, @Inject(NB_WINDOW_CONFIG) protected readonly defaultWindowsConfig: NbWindowConfig, protected cfr: ComponentFactoryResolver, + @Inject(NB_DOCUMENT) document, ) { + this.document = document; } /** @@ -124,7 +128,7 @@ export class NbWindowService { windowContent: TemplateRef | NbComponentType, windowConfig: Partial = {}, ): NbWindowRef { - if (this.windowsContainerViewRef == null) { + if (this.shouldCreateWindowsContainer()) { this.createWindowsContainer(); } @@ -138,7 +142,20 @@ export class NbWindowService { return windowRef; } + protected shouldCreateWindowsContainer(): boolean { + if (this.windowsContainerViewRef) { + const containerEl = this.windowsContainerViewRef.element.nativeElement; + return !this.document.body.contains(containerEl); + } + + return true; + } + protected createWindowsContainer() { + if (this.overlayRef) { + this.overlayRef.dispose(); + } + this.overlayRef = this.overlayService.create({ scrollStrategy: this.overlayService.scrollStrategies.noop(), positionStrategy: this.overlayPositionBuilder.global().bottom().right(),