diff --git a/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts b/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts index 0f8e0af6e6b2..a1a7fb3efd9c 100644 --- a/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts +++ b/src/cdk/overlay/scroll/close-scroll-strategy.spec.ts @@ -1,14 +1,14 @@ import {inject, TestBed, fakeAsync} from '@angular/core/testing'; -import {Component, NgZone} from '@angular/core'; +import {Component, ElementRef, NgZone} from '@angular/core'; import {Subject} from 'rxjs'; import {ComponentPortal, PortalModule} from '@angular/cdk/portal'; -import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling'; +import {CdkScrollable, ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling'; import {Overlay, OverlayConfig, OverlayRef, OverlayModule, OverlayContainer} from '../index'; describe('CloseScrollStrategy', () => { let overlayRef: OverlayRef; let componentPortal: ComponentPortal; - let scrolledSubject = new Subject(); + let scrolledSubject = new Subject(); let scrollPosition: number; beforeEach(fakeAsync(() => { @@ -55,6 +55,16 @@ describe('CloseScrollStrategy', () => { expect(overlayRef.detach).toHaveBeenCalled(); }); + it('should not detach if the scrollable is inside the overlay', () => { + overlayRef.attach(componentPortal); + spyOn(overlayRef, 'detach'); + + scrolledSubject.next({ + getElementRef: () => new ElementRef(overlayRef.overlayElement), + } as CdkScrollable); + expect(overlayRef.detach).not.toHaveBeenCalled(); + }); + it('should not attempt to detach the overlay after it has been detached', () => { overlayRef.attach(componentPortal); overlayRef.detach(); diff --git a/src/cdk/overlay/scroll/close-scroll-strategy.ts b/src/cdk/overlay/scroll/close-scroll-strategy.ts index e0ba4ac251e6..03009268c847 100644 --- a/src/cdk/overlay/scroll/close-scroll-strategy.ts +++ b/src/cdk/overlay/scroll/close-scroll-strategy.ts @@ -10,6 +10,7 @@ import {ScrollStrategy, getMatScrollStrategyAlreadyAttachedError} from './scroll import {OverlayReference} from '../overlay-reference'; import {Subscription} from 'rxjs'; import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling'; +import {filter} from 'rxjs/operators'; /** * Config options for the CloseScrollStrategy. @@ -49,7 +50,14 @@ export class CloseScrollStrategy implements ScrollStrategy { return; } - const stream = this._scrollDispatcher.scrolled(0); + const stream = this._scrollDispatcher.scrolled(0).pipe( + filter(scrollable => { + return ( + !scrollable || + !this._overlayRef.overlayElement.contains(scrollable.getElementRef().nativeElement) + ); + }), + ); if (this._config && this._config.threshold && this._config.threshold > 1) { this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top;