Skip to content

Commit accab20

Browse files
crisbetojelbourn
authored andcommitted
fix(dialog): backdrop not being removed if it doesn't have transitions (#1716)
* fix(dialog): backdrop not being removed if it doesn't have transitions Fixes the dialog's backdrop not being removed if it's transition have been disabled. Fixes #1607.
1 parent d3a50b3 commit accab20

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

src/lib/core/overlay/overlay-ref.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ export class OverlayRef implements PortalHost {
9292

9393
// Add class to fade-in the backdrop after one frame.
9494
requestAnimationFrame(() => {
95-
this._backdropElement.classList.add('md-overlay-backdrop-showing');
95+
if (this._backdropElement) {
96+
this._backdropElement.classList.add('md-overlay-backdrop-showing');
97+
}
9698
});
9799
}
98100

@@ -101,18 +103,28 @@ export class OverlayRef implements PortalHost {
101103
let backdropToDetach = this._backdropElement;
102104

103105
if (backdropToDetach) {
104-
backdropToDetach.classList.remove('md-overlay-backdrop-showing');
105-
backdropToDetach.classList.remove(this._state.backdropClass);
106-
backdropToDetach.addEventListener('transitionend', () => {
107-
backdropToDetach.parentNode.removeChild(backdropToDetach);
106+
let finishDetach = () => {
107+
// It may not be attached to anything in certain cases (e.g. unit tests).
108+
if (backdropToDetach && backdropToDetach.parentNode) {
109+
backdropToDetach.parentNode.removeChild(backdropToDetach);
110+
}
108111

109112
// It is possible that a new portal has been attached to this overlay since we started
110113
// removing the backdrop. If that is the case, only clear the backdrop reference if it
111114
// is still the same instance that we started to remove.
112115
if (this._backdropElement == backdropToDetach) {
113116
this._backdropElement = null;
114117
}
115-
});
118+
};
119+
120+
backdropToDetach.classList.remove('md-overlay-backdrop-showing');
121+
backdropToDetach.classList.remove(this._state.backdropClass);
122+
backdropToDetach.addEventListener('transitionend', finishDetach);
123+
124+
// If the backdrop doesn't have a transition, the `transitionend` event won't fire.
125+
// In this case we make it unclickable and we try to remove it after a delay.
126+
backdropToDetach.style.pointerEvents = 'none';
127+
setTimeout(finishDetach, 500);
116128
}
117129
}
118130
}

src/lib/core/overlay/overlay.spec.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ describe('Overlay', () => {
172172
overlayRef.attach(componentPortal);
173173

174174
viewContainerFixture.detectChanges();
175-
let backdrop = <HTMLElement> overlayContainerElement.querySelector('.md-overlay-backdrop');
175+
let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
176176
expect(backdrop).toBeTruthy();
177177
expect(backdrop.classList).not.toContain('md-overlay-backdrop-showing');
178178

@@ -188,7 +188,7 @@ describe('Overlay', () => {
188188
overlayRef.attach(componentPortal);
189189
viewContainerFixture.detectChanges();
190190

191-
let backdrop = <HTMLElement> overlayContainerElement.querySelector('.md-overlay-backdrop');
191+
let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
192192
expect(backdrop.classList).toContain('md-overlay-dark-backdrop');
193193
});
194194

@@ -199,10 +199,24 @@ describe('Overlay', () => {
199199
overlayRef.attach(componentPortal);
200200
viewContainerFixture.detectChanges();
201201

202-
let backdrop = <HTMLElement> overlayContainerElement.querySelector('.md-overlay-backdrop');
202+
let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
203203
expect(backdrop.classList).toContain('md-overlay-transparent-backdrop');
204204
});
205205

206+
it('should disable the pointer events of a backdrop that is being removed', () => {
207+
let overlayRef = overlay.create(config);
208+
overlayRef.attach(componentPortal);
209+
210+
viewContainerFixture.detectChanges();
211+
let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
212+
213+
expect(backdrop.style.pointerEvents).toBeFalsy();
214+
215+
overlayRef.detach();
216+
217+
expect(backdrop.style.pointerEvents).toBe('none');
218+
});
219+
206220
});
207221
});
208222

src/lib/dialog/dialog.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
flushMicrotasks,
66
ComponentFixture,
77
TestBed,
8+
tick,
89
} from '@angular/core/testing';
910
import {By} from '@angular/platform-browser';
1011
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
@@ -207,6 +208,7 @@ describe('MdDialog', () => {
207208
.not.toBe('dialog-trigger', 'Expected the focus to change when dialog was opened.');
208209

209210
dialogRef.close();
211+
tick(500);
210212
viewContainerFixture.detectChanges();
211213
flushMicrotasks();
212214

0 commit comments

Comments
 (0)