Skip to content

Commit 0470d35

Browse files
committed
fix(dialog): capture previously focused element immediately
Captures the previously-focused element immediately, instead of waiting until the animation is done. This fixes a regression from #3774, because if we wait for the animation to finish, the focus might have shifted, or the element could have been disabled.
1 parent f40296e commit 0470d35

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

src/lib/dialog/dialog-container.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
Renderer,
99
ElementRef,
1010
EventEmitter,
11+
Inject,
12+
Optional,
1113
} from '@angular/core';
1214
import {
1315
animate,
@@ -17,6 +19,7 @@ import {
1719
transition,
1820
AnimationEvent,
1921
} from '@angular/animations';
22+
import {DOCUMENT} from '@angular/platform-browser';
2023
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
2124
import {MdDialogConfig} from './dialog-config';
2225
import {MdDialogContentAlreadyAttachedError} from './dialog-errors';
@@ -77,7 +80,8 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
7780
private _ngZone: NgZone,
7881
private _renderer: Renderer,
7982
private _elementRef: ElementRef,
80-
private _focusTrapFactory: FocusTrapFactory) {
83+
private _focusTrapFactory: FocusTrapFactory,
84+
@Optional() @Inject(DOCUMENT) private _document: Document|Document) {
8185

8286
super();
8387
}
@@ -91,6 +95,7 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
9195
throw new MdDialogContentAlreadyAttachedError();
9296
}
9397

98+
this._savePreviouslyFocusedElement();
9499
return this._portalHost.attachComponentPortal(portal);
95100
}
96101

@@ -103,12 +108,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
103108
throw new MdDialogContentAlreadyAttachedError();
104109
}
105110

111+
this._savePreviouslyFocusedElement();
106112
return this._portalHost.attachTemplatePortal(portal);
107113
}
108114

109115
/**
110116
* Moves the focus inside the focus trap.
111-
* @private
112117
*/
113118
private _trapFocus() {
114119
if (!this._focusTrap) {
@@ -118,10 +123,18 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
118123
// If were to attempt to focus immediately, then the content of the dialog would not yet be
119124
// ready in instances where change detection has to run first. To deal with this, we simply
120125
// wait for the microtask queue to be empty.
121-
this._elementFocusedBeforeDialogWasOpened = document.activeElement as HTMLElement;
122126
this._focusTrap.focusFirstTabbableElementWhenReady();
123127
}
124128

129+
/**
130+
* Saves a reference to the element that was focused before the dialog was opened.
131+
*/
132+
private _savePreviouslyFocusedElement() {
133+
if (this._document) {
134+
this._elementFocusedBeforeDialogWasOpened = this._document.activeElement as HTMLElement;
135+
}
136+
}
137+
125138
/**
126139
* Kicks off the leave animation.
127140
* @docs-private

0 commit comments

Comments
 (0)