@@ -3,11 +3,10 @@ import {
33 ComponentRef ,
44 ViewChild ,
55 ViewEncapsulation ,
6- NgZone ,
7- OnDestroy ,
86 Renderer ,
97 ElementRef ,
108 EventEmitter ,
9+ OnDestroy ,
1110} from '@angular/core' ;
1211import {
1312 animate ,
@@ -21,11 +20,6 @@ import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} fr
2120import { MdDialogConfig } from './dialog-config' ;
2221import { MdDialogContentAlreadyAttachedError } from './dialog-errors' ;
2322import { FocusTrapFactory , FocusTrap } from '../core/a11y/focus-trap' ;
24- import 'rxjs/add/operator/first' ;
25-
26-
27- /** Possible states for the dialog container animation. */
28- export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-start' ;
2923
3024
3125/**
@@ -68,13 +62,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6862 dialogConfig : MdDialogConfig ;
6963
7064 /** State of the dialog animation. */
71- _state : MdDialogContainerAnimationState = 'enter' ;
65+ _state : 'void' | 'enter' | 'exit' = 'enter' ;
7266
7367 /** Emits the current animation state whenever it changes. */
74- _onAnimationStateChange = new EventEmitter < MdDialogContainerAnimationState > ( ) ;
68+ _onAnimationStateChange = new EventEmitter < AnimationEvent > ( ) ;
7569
7670 constructor (
77- private _ngZone : NgZone ,
7871 private _renderer : Renderer ,
7972 private _elementRef : ElementRef ,
8073 private _focusTrapFactory : FocusTrapFactory ) {
@@ -108,7 +101,6 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
108101
109102 /**
110103 * Moves the focus inside the focus trap.
111- * @private
112104 */
113105 private _trapFocus ( ) {
114106 if ( ! this . _focusTrap ) {
@@ -123,46 +115,38 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
123115 }
124116
125117 /**
126- * Kicks off the leave animation.
127- * @docs -private
118+ * Restores focus to the element that was focused before the dialog was opened.
128119 */
129- _exit ( ) : void {
130- this . _state = 'exit' ;
131- this . _onAnimationStateChange . emit ( 'exit-start' ) ;
120+ private _restoreFocus ( ) {
121+ // We need the extra check, because IE can set the `activeElement` to null in some cases.
122+ let toFocus = this . _elementFocusedBeforeDialogWasOpened ;
123+
124+ if ( toFocus && 'focus' in toFocus ) {
125+ toFocus . focus ( ) ;
126+ }
127+
128+ if ( this . _focusTrap ) {
129+ this . _focusTrap . destroy ( ) ;
130+ }
132131 }
133132
134133 /**
135134 * Callback, invoked whenever an animation on the host completes.
136135 * @docs -private
137136 */
138137 _onAnimationDone ( event : AnimationEvent ) {
138+ this . _onAnimationStateChange . emit ( event ) ;
139+
139140 if ( event . toState === 'enter' ) {
140141 this . _trapFocus ( ) ;
142+ } else if ( event . toState === 'exit' ) {
143+ this . _restoreFocus ( ) ;
141144 }
142-
143- this . _onAnimationStateChange . emit ( event . toState as MdDialogContainerAnimationState ) ;
144145 }
145146
146147 ngOnDestroy ( ) {
147- // When the dialog is destroyed, return focus to the element that originally had it before
148- // the dialog was opened. Wait for the DOM to finish settling before changing the focus so
149- // that it doesn't end up back on the <body>. Also note that we need the extra check, because
150- // IE can set the `activeElement` to null in some cases.
151- let toFocus = this . _elementFocusedBeforeDialogWasOpened as HTMLElement ;
152-
153- // We shouldn't use `this` inside of the NgZone subscription, because it causes a memory leak.
154- let animationStream = this . _onAnimationStateChange ;
155-
156- this . _ngZone . onMicrotaskEmpty . first ( ) . subscribe ( ( ) => {
157- if ( toFocus && 'focus' in toFocus ) {
158- toFocus . focus ( ) ;
159- }
160-
161- animationStream . complete ( ) ;
162- } ) ;
163-
164- if ( this . _focusTrap ) {
165- this . _focusTrap . destroy ( ) ;
166- }
148+ // This needs to happen in OnDestroy, because the exit->void animation event
149+ // won't fire if the consumer is using the NoopAnimationsModule
150+ this . _onAnimationStateChange . complete ( ) ;
167151 }
168152}
0 commit comments