@@ -25,6 +25,13 @@ export class MdDuplicatedSidenavError extends MdError {
2525 }
2626}
2727
28+
29+ /** Sidenav toggle promise result. */
30+ export class MdSidenavToggleResult {
31+ constructor ( public type : 'open' | 'close' , public animationFinished : boolean ) { }
32+ }
33+
34+
2835/**
2936 * <md-sidenav> component.
3037 *
@@ -106,6 +113,15 @@ export class MdSidenav implements AfterContentInit {
106113 /** Event emitted when the sidenav alignment changes. */
107114 @Output ( 'align-changed' ) onAlignChanged = new EventEmitter < void > ( ) ;
108115
116+ /** The current toggle animation promise. `null` if no animation is in progress. */
117+ private _toggleAnimationPromise : Promise < MdSidenavToggleResult > = null ;
118+
119+ /**
120+ * The current toggle animation promise resolution function.
121+ * `null` if no animation is in progress.
122+ */
123+ private _resolveToggleAnimationPromise : ( animationFinished : boolean ) => void = null ;
124+
109125 /**
110126 * @param _elementRef The DOM element reference. Used for transition and width calculation.
111127 * If not available we do not hook on transitions.
@@ -115,9 +131,9 @@ export class MdSidenav implements AfterContentInit {
115131 ngAfterContentInit ( ) {
116132 // This can happen when the sidenav is set to opened in the template and the transition
117133 // isn't ended.
118- if ( this . _openPromise ) {
119- this . _openPromiseResolve ( ) ;
120- this . _openPromise = null ;
134+ if ( this . _toggleAnimationPromise ) {
135+ this . _resolveToggleAnimationPromise ( true ) ;
136+ this . _toggleAnimationPromise = this . _resolveToggleAnimationPromise = null ;
121137 }
122138 }
123139
@@ -134,15 +150,15 @@ export class MdSidenav implements AfterContentInit {
134150
135151 /** Open this sidenav, and return a Promise that will resolve when it's fully opened (or get
136152 * rejected if it didn't). */
137- open ( ) : Promise < void > {
153+ open ( ) : Promise < MdSidenavToggleResult > {
138154 return this . toggle ( true ) ;
139155 }
140156
141157 /**
142158 * Close this sidenav, and return a Promise that will resolve when it's fully closed (or get
143159 * rejected if it didn't).
144160 */
145- close ( ) : Promise < void > {
161+ close ( ) : Promise < MdSidenavToggleResult > {
146162 return this . toggle ( false ) ;
147163 }
148164
@@ -151,47 +167,35 @@ export class MdSidenav implements AfterContentInit {
151167 * close() when it's closed.
152168 * @param isOpen
153169 */
154- toggle ( isOpen : boolean = ! this . opened ) : Promise < void > {
155- if ( ! this . valid ) { return Promise . resolve ( null ) ; }
170+ toggle ( isOpen : boolean = ! this . opened ) : Promise < MdSidenavToggleResult > {
171+ if ( ! this . valid ) {
172+ return Promise . resolve ( new MdSidenavToggleResult ( isOpen ? 'open' : 'close' , true ) ) ;
173+ }
156174
157175 // Shortcut it if we're already opened.
158176 if ( isOpen === this . opened ) {
159- if ( ! this . _transition ) {
160- return Promise . resolve ( null ) ;
161- } else {
162- return isOpen ? this . _openPromise : this . _closePromise ;
163- }
177+ return this . _toggleAnimationPromise ||
178+ Promise . resolve ( new MdSidenavToggleResult ( isOpen ? 'open' : 'close' , true ) ) ;
164179 }
165180
166181 this . _opened = isOpen ;
167- this . _transition = true ;
168182
169183 if ( isOpen ) {
170184 this . onOpenStart . emit ( ) ;
171185 } else {
172186 this . onCloseStart . emit ( ) ;
173187 }
174188
175- if ( isOpen ) {
176- if ( this . _openPromise == null ) {
177- this . _openPromise = new Promise < void > ( ( resolve , reject ) => {
178- this . _openPromiseResolve = resolve ;
179- this . _openPromiseReject = reject ;
180- } ) ;
181- }
182- return this . _openPromise ;
183- } else {
184- if ( this . _closePromise == null ) {
185- this . _closePromise = new Promise < void > ( ( resolve , reject ) => {
186- this . _closePromiseResolve = resolve ;
187- this . _closePromiseReject = reject ;
188- } ) ;
189- }
190- return this . _closePromise ;
189+ if ( this . _toggleAnimationPromise ) {
190+ this . _resolveToggleAnimationPromise ( false ) ;
191191 }
192+ this . _toggleAnimationPromise = new Promise < MdSidenavToggleResult > ( resolve => {
193+ this . _resolveToggleAnimationPromise = animationFinished =>
194+ resolve ( new MdSidenavToggleResult ( isOpen ? 'open' : 'close' , animationFinished ) ) ;
195+ } ) ;
196+ return this . _toggleAnimationPromise ;
192197 }
193198
194-
195199 /**
196200 * When transition has finished, set the internal state for classes and emit the proper event.
197201 * The event passed is actually of type TransitionEvent, but that type is not available in
@@ -201,43 +205,30 @@ export class MdSidenav implements AfterContentInit {
201205 if ( transitionEvent . target == this . _elementRef . nativeElement
202206 // Simpler version to check for prefixes.
203207 && transitionEvent . propertyName . endsWith ( 'transform' ) ) {
204- this . _transition = false ;
205208 if ( this . _opened ) {
206- if ( this . _openPromise != null ) {
207- this . _openPromiseResolve ( ) ;
208- }
209- if ( this . _closePromise != null ) {
210- this . _closePromiseReject ( ) ;
211- }
212-
213209 this . onOpen . emit ( ) ;
214210 } else {
215- if ( this . _closePromise != null ) {
216- this . _closePromiseResolve ( ) ;
217- }
218- if ( this . _openPromise != null ) {
219- this . _openPromiseReject ( ) ;
220- }
221-
222211 this . onClose . emit ( ) ;
223212 }
224213
225- this . _openPromise = null ;
226- this . _closePromise = null ;
214+ if ( this . _toggleAnimationPromise ) {
215+ this . _resolveToggleAnimationPromise ( true ) ;
216+ this . _toggleAnimationPromise = this . _resolveToggleAnimationPromise = null ;
217+ }
227218 }
228219 }
229220
230221 get _isClosing ( ) {
231- return ! this . _opened && this . _transition ;
222+ return ! this . _opened && ! ! this . _toggleAnimationPromise ;
232223 }
233224 get _isOpening ( ) {
234- return this . _opened && this . _transition ;
225+ return this . _opened && ! ! this . _toggleAnimationPromise ;
235226 }
236227 get _isClosed ( ) {
237- return ! this . _opened && ! this . _transition ;
228+ return ! this . _opened && ! this . _toggleAnimationPromise ;
238229 }
239230 get _isOpened ( ) {
240- return this . _opened && ! this . _transition ;
231+ return this . _opened && ! this . _toggleAnimationPromise ;
241232 }
242233 get _isEnd ( ) {
243234 return this . align == 'end' ;
@@ -258,14 +249,6 @@ export class MdSidenav implements AfterContentInit {
258249 }
259250 return 0 ;
260251 }
261-
262- private _transition : boolean = false ;
263- private _openPromise : Promise < void > ;
264- private _openPromiseResolve : ( ) => void ;
265- private _openPromiseReject : ( ) => void ;
266- private _closePromise : Promise < void > ;
267- private _closePromiseResolve : ( ) => void ;
268- private _closePromiseReject : ( ) => void ;
269252}
270253
271254/**
0 commit comments