Skip to content

Commit edc342d

Browse files
committed
fix(dialog): leaking MdDialogContainer references
Fixes an issue that caused the `MdDialogContainer` references to not be cleaned up, and as a result, any of the `MdDialogRef` and `MdDialogConfig` instances as well. The issue seems to come from the fact that a couple of blocks that look like: ``` this._ngZone.onMicrotaskEmpty.first().subscribe(() => { this._elementFocusedBeforeDialogWasOpened = document.activeElement; this._focusTrap.focusFirstTabbableElement(); }); ``` End up being transpiled to: ``` var _this = this; this._ngZone.onMicrotaskEmpty.first().subscribe(function () { _this._elementFocusedBeforeDialogWasOpened = document.activeElement; _this._focusTrap.focusFirstTabbableElement(); }); ``` This seems to cause the browser to retain the `_this` reference after the dialog has been destroyed. Fixes #2876.
1 parent f8c8e7f commit edc342d

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

src/lib/dialog/dialog-container.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
ViewEncapsulation,
66
NgZone,
77
OnDestroy,
8-
Renderer,
98
} from '@angular/core';
109
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
1110
import {MdDialogConfig} from './dialog-config';
@@ -47,7 +46,7 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
4746
/** Reference to the open dialog. */
4847
dialogRef: MdDialogRef<any>;
4948

50-
constructor(private _ngZone: NgZone, private _renderer: Renderer) {
49+
constructor(private _ngZone: NgZone) {
5150
super();
5251
}
5352

@@ -65,10 +64,8 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6564
// If were to attempt to focus immediately, then the content of the dialog would not yet be
6665
// ready in instances where change detection has to run first. To deal with this, we simply
6766
// wait for the microtask queue to be empty.
68-
this._ngZone.onMicrotaskEmpty.first().subscribe(() => {
69-
this._elementFocusedBeforeDialogWasOpened = document.activeElement;
70-
this._focusTrap.focusFirstTabbableElement();
71-
});
67+
this._elementFocusedBeforeDialogWasOpened = document.activeElement;
68+
this._focusTrap.focusFirstTabbableElementWhenReady();
7269

7370
return attachResult;
7471
}
@@ -93,10 +90,10 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
9390
// the dialog was opened. Wait for the DOM to finish settling before changing the focus so
9491
// that it doesn't end up back on the <body>. Also note that we need the extra check, because
9592
// IE can set the `activeElement` to null in some cases.
96-
if (this._elementFocusedBeforeDialogWasOpened) {
97-
this._ngZone.onMicrotaskEmpty.first().subscribe(() => {
98-
this._renderer.invokeElementMethod(this._elementFocusedBeforeDialogWasOpened, 'focus');
99-
});
93+
let toFocus = this._elementFocusedBeforeDialogWasOpened as HTMLElement;
94+
95+
if (toFocus && 'focus' in toFocus) {
96+
this._ngZone.onMicrotaskEmpty.first().subscribe(() => toFocus.focus());
10097
}
10198
}
10299
}

0 commit comments

Comments
 (0)