fix(overlay): disable pointer events if overlay is detached (#2747)

Fixes #2739
This commit is contained in:
Paul Gschwendtner
2017-02-02 22:45:50 +01:00
committed by Kara
parent f63eb43cb6
commit 453fa7fb23
4 changed files with 48 additions and 1 deletions
@@ -29,16 +29,25 @@ describe('Overlay directives', () => {
fixture.detectChanges();
});
/** Returns the current open overlay pane element. */
function getPaneElement() {
return overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
}
it(`should attach the overlay based on the open property`, () => {
fixture.componentInstance.isOpen = true;
fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain('Menu content');
expect(getPaneElement().style.pointerEvents)
.toBeFalsy('Expected the overlay pane to enable pointerEvents when attached.');
fixture.componentInstance.isOpen = false;
fixture.detectChanges();
expect(overlayContainerElement.textContent).toBe('');
expect(getPaneElement().style.pointerEvents)
.toBe('none', 'Expected the overlay pane to disable pointerEvents when detached.');
});
it('should destroy the overlay when the directive is destroyed', () => {
@@ -47,6 +56,8 @@ describe('Overlay directives', () => {
fixture.destroy();
expect(overlayContainerElement.textContent.trim()).toBe('');
expect(getPaneElement())
.toBeFalsy('Expected the overlay pane element to be removed when disposed.');
});
it('should use a connected position strategy with a default set of positions', () => {
+16
View File
@@ -35,10 +35,15 @@ export class OverlayRef implements PortalHost {
}
let attachResult = this._portalHost.attach(portal);
// Update the pane element with the given state configuration.
this.updateSize();
this.updateDirection();
this.updatePosition();
// Enable pointer events for the overlay pane element.
this._togglePointerEvents(true);
return attachResult;
}
@@ -48,6 +53,12 @@ export class OverlayRef implements PortalHost {
*/
detach(): Promise<any> {
this._detachBackdrop();
// When the overlay is detached, the pane element should disable pointer events.
// This is necessary because otherwise the pane element will cover the page and disable
// pointer events therefore. Depends on the position strategy and the applied pane boundaries.
this._togglePointerEvents(false);
return this._portalHost.detach();
}
@@ -115,6 +126,11 @@ export class OverlayRef implements PortalHost {
}
}
/** Toggles the pointer events for the overlay pane element. */
private _togglePointerEvents(enablePointer: boolean) {
this._pane.style.pointerEvents = enablePointer ? null : 'none';
}
/** Attaches a backdrop for this overlay. */
private _attachBackdrop() {
this._backdropElement = document.createElement('div');
+17
View File
@@ -62,6 +62,23 @@ describe('Overlay', () => {
expect(overlayContainerElement.textContent).toBe('');
});
it('should disable pointer events of the pane element if detached', () => {
let overlayRef = overlay.create();
let paneElement = overlayRef.overlayElement;
overlayRef.attach(componentPortal);
expect(paneElement.childNodes.length).not.toBe(0);
expect(paneElement.style.pointerEvents)
.toBeFalsy('Expected the overlay pane to enable pointerEvents when attached.');
overlayRef.detach();
expect(paneElement.childNodes.length).toBe(0);
expect(paneElement.style.pointerEvents)
.toBe('none', 'Expected the overlay pane to disable pointerEvents when detached.');
});
it('should open multiple overlays', () => {
let pizzaOverlayRef = overlay.create();
pizzaOverlayRef.attach(componentPortal);
+4 -1
View File
@@ -65,11 +65,14 @@ export class DomPortalHost extends BasePortalHost {
let viewContainer = portal.viewContainerRef;
let viewRef = viewContainer.createEmbeddedView(portal.templateRef);
// The method `createEmbeddedView` will add the view as a child of the viewContainer.
// But for the DomPortalHost the view can be added everywhere in the DOM (e.g Overlay Container)
// To move the view to the specified host element. We just re-append the existing root nodes.
viewRef.rootNodes.forEach(rootNode => this._hostDomElement.appendChild(rootNode));
this.setDisposeFn((() => {
let index = viewContainer.indexOf(viewRef);
if (index != -1) {
if (index !== -1) {
viewContainer.remove(index);
}
}));