@@ -25,6 +25,13 @@ export class MdDuplicatedSidenavError extends MdError {
25
25
}
26
26
}
27
27
28
+
29
+ /** Sidenav toggle promise result. */
30
+ export class MdSidenavToggleResult {
31
+ constructor ( public type : 'open' | 'close' , public animationFinished : boolean ) { }
32
+ }
33
+
34
+
28
35
/**
29
36
* <md-sidenav> component.
30
37
*
@@ -106,6 +113,15 @@ export class MdSidenav implements AfterContentInit {
106
113
/** Event emitted when the sidenav alignment changes. */
107
114
@Output ( 'align-changed' ) onAlignChanged = new EventEmitter < void > ( ) ;
108
115
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
+
109
125
/**
110
126
* @param _elementRef The DOM element reference. Used for transition and width calculation.
111
127
* If not available we do not hook on transitions.
@@ -115,9 +131,9 @@ export class MdSidenav implements AfterContentInit {
115
131
ngAfterContentInit ( ) {
116
132
// This can happen when the sidenav is set to opened in the template and the transition
117
133
// 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 ;
121
137
}
122
138
}
123
139
@@ -134,15 +150,15 @@ export class MdSidenav implements AfterContentInit {
134
150
135
151
/** Open this sidenav, and return a Promise that will resolve when it's fully opened (or get
136
152
* rejected if it didn't). */
137
- open ( ) : Promise < void > {
153
+ open ( ) : Promise < MdSidenavToggleResult > {
138
154
return this . toggle ( true ) ;
139
155
}
140
156
141
157
/**
142
158
* Close this sidenav, and return a Promise that will resolve when it's fully closed (or get
143
159
* rejected if it didn't).
144
160
*/
145
- close ( ) : Promise < void > {
161
+ close ( ) : Promise < MdSidenavToggleResult > {
146
162
return this . toggle ( false ) ;
147
163
}
148
164
@@ -151,47 +167,35 @@ export class MdSidenav implements AfterContentInit {
151
167
* close() when it's closed.
152
168
* @param isOpen
153
169
*/
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
+ }
156
174
157
175
// Shortcut it if we're already opened.
158
176
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 ) ) ;
164
179
}
165
180
166
181
this . _opened = isOpen ;
167
- this . _transition = true ;
168
182
169
183
if ( isOpen ) {
170
184
this . onOpenStart . emit ( ) ;
171
185
} else {
172
186
this . onCloseStart . emit ( ) ;
173
187
}
174
188
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 ) ;
191
191
}
192
+ this . _toggleAnimationPromise = new Promise < MdSidenavToggleResult > ( resolve => {
193
+ this . _resolveToggleAnimationPromise = animationFinished =>
194
+ resolve ( new MdSidenavToggleResult ( isOpen ? 'open' : 'close' , animationFinished ) ) ;
195
+ } ) ;
196
+ return this . _toggleAnimationPromise ;
192
197
}
193
198
194
-
195
199
/**
196
200
* When transition has finished, set the internal state for classes and emit the proper event.
197
201
* The event passed is actually of type TransitionEvent, but that type is not available in
@@ -201,43 +205,30 @@ export class MdSidenav implements AfterContentInit {
201
205
if ( transitionEvent . target == this . _elementRef . nativeElement
202
206
// Simpler version to check for prefixes.
203
207
&& transitionEvent . propertyName . endsWith ( 'transform' ) ) {
204
- this . _transition = false ;
205
208
if ( this . _opened ) {
206
- if ( this . _openPromise != null ) {
207
- this . _openPromiseResolve ( ) ;
208
- }
209
- if ( this . _closePromise != null ) {
210
- this . _closePromiseReject ( ) ;
211
- }
212
-
213
209
this . onOpen . emit ( ) ;
214
210
} else {
215
- if ( this . _closePromise != null ) {
216
- this . _closePromiseResolve ( ) ;
217
- }
218
- if ( this . _openPromise != null ) {
219
- this . _openPromiseReject ( ) ;
220
- }
221
-
222
211
this . onClose . emit ( ) ;
223
212
}
224
213
225
- this . _openPromise = null ;
226
- this . _closePromise = null ;
214
+ if ( this . _toggleAnimationPromise ) {
215
+ this . _resolveToggleAnimationPromise ( true ) ;
216
+ this . _toggleAnimationPromise = this . _resolveToggleAnimationPromise = null ;
217
+ }
227
218
}
228
219
}
229
220
230
221
get _isClosing ( ) {
231
- return ! this . _opened && this . _transition ;
222
+ return ! this . _opened && ! ! this . _toggleAnimationPromise ;
232
223
}
233
224
get _isOpening ( ) {
234
- return this . _opened && this . _transition ;
225
+ return this . _opened && ! ! this . _toggleAnimationPromise ;
235
226
}
236
227
get _isClosed ( ) {
237
- return ! this . _opened && ! this . _transition ;
228
+ return ! this . _opened && ! this . _toggleAnimationPromise ;
238
229
}
239
230
get _isOpened ( ) {
240
- return this . _opened && ! this . _transition ;
231
+ return this . _opened && ! this . _toggleAnimationPromise ;
241
232
}
242
233
get _isEnd ( ) {
243
234
return this . align == 'end' ;
@@ -258,14 +249,6 @@ export class MdSidenav implements AfterContentInit {
258
249
}
259
250
return 0 ;
260
251
}
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 ;
269
252
}
270
253
271
254
/**
0 commit comments