@@ -208,7 +208,7 @@ function SidenavFocusDirective() {
208
208
* - `<md-sidenav md-is-locked-open="$mdMedia('min-width: 1000px')"></md-sidenav>`
209
209
* - `<md-sidenav md-is-locked-open="$mdMedia('sm')"></md-sidenav>` (locks open on small screens)
210
210
*/
211
- function SidenavDirective ( $mdMedia , $mdUtil , $mdConstant , $mdTheming , $animate , $compile , $parse , $log , $q , $document ) {
211
+ function SidenavDirective ( $mdMedia , $mdUtil , $mdConstant , $mdTheming , $animate , $compile , $parse , $log , $q , $document , $$rAF ) {
212
212
return {
213
213
restrict : 'E' ,
214
214
scope : {
@@ -229,6 +229,9 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
229
229
var lastParentOverFlow ;
230
230
var triggeringElement = null ;
231
231
var promise = $q . when ( true ) ;
232
+ var skipSidenav = false ;
233
+ var skipNextUpdate = false ;
234
+ var $window = angular . element ( window ) ;
232
235
233
236
var isLockedOpenParsed = $parse ( attr . mdIsLockedOpen ) ;
234
237
var isLocked = function ( ) {
@@ -244,22 +247,49 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
244
247
245
248
$mdTheming . inherit ( backdrop , element ) ;
246
249
250
+ var throttleResize = $$rAF . throttle ( revalidateVisibility ) ;
251
+ $window . on ( 'resize' , throttleResize ) ;
252
+ revalidateVisibility ( ) ;
253
+
247
254
element . on ( '$destroy' , function ( ) {
248
255
backdrop . remove ( ) ;
249
256
sidenavCtrl . destroy ( ) ;
257
+ $window . off ( 'resize' , throttleResize ) ;
250
258
} ) ;
251
259
252
260
scope . $on ( '$destroy' , function ( ) {
261
+ $window . off ( 'resize' , throttleResize ) ;
253
262
backdrop . remove ( )
254
263
} ) ;
255
264
256
265
scope . $watch ( isLocked , updateIsLocked ) ;
257
266
scope . $watch ( 'isOpen' , updateIsOpen ) ;
258
267
259
268
269
+
260
270
// Publish special accessor for the Controller instance
261
271
sidenavCtrl . $toggleOpen = toggleOpen ;
262
272
273
+ function revalidateVisibility ( ) {
274
+ var lastValue = scope . isOpen ;
275
+ if ( isHidden ( element , true , true ) && scope . isOpen == true ) scope . isOpen = false ;
276
+ else if ( ! isHidden ( element , true , true ) && scope . isOpen == false ) scope . isOpen = true ;
277
+
278
+ if ( lastValue != scope . isOpen ) {
279
+ skipSidenav = true ;
280
+ if ( ! scope . $$phase ) scope . $apply ( ) ;
281
+ skipSidenav = false ;
282
+ }
283
+ }
284
+
285
+ function isHidden ( element , compute , both ) {
286
+ if ( ! compute || both ) {
287
+ if ( element [ 0 ] . offsetParent == null ) return true ;
288
+ if ( ! both ) return false ;
289
+ }
290
+ return window . getComputedStyle ( element [ 0 ] ) . display === 'none' ;
291
+ }
292
+
263
293
/**
264
294
* Toggle the DOM classes to indicate `locked`
265
295
* @param isLocked
@@ -278,26 +308,43 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
278
308
* Toggle the SideNav view and attach/detach listeners
279
309
* @param isOpen
280
310
*/
281
- function updateIsOpen ( isOpen ) {
311
+ function updateIsOpen ( isOpen , oldValue ) {
312
+ if ( skipNextUpdate ) {
313
+ skipNextUpdate = false ;
314
+ return ;
315
+ }
316
+
282
317
// Support deprecated md-sidenav-focus attribute as fallback
283
318
var focusEl = $mdUtil . findFocusTarget ( element ) || $mdUtil . findFocusTarget ( element , '[md-sidenav-focus]' ) || element ;
284
319
var parent = element . parent ( ) ;
285
320
321
+ // little hack to check show abbility
322
+ if ( ! skipSidenav ) {
323
+ var wasClosed = element . hasClass ( 'md-closed' ) ;
324
+ element . removeClass ( 'md-closed' ) ;
325
+ if ( isHidden ( element , true ) && ! skipSidenav ) {
326
+ element . toggleClass ( 'md-closed' , wasClosed ) ;
327
+ skipNextUpdate = true ;
328
+ scope . isOpen = oldValue ;
329
+ return ;
330
+ }
331
+ element . toggleClass ( 'md-closed' , wasClosed ) ;
332
+ }
333
+
286
334
parent [ isOpen ? 'on' : 'off' ] ( 'keydown' , onKeyDown ) ;
287
335
backdrop [ isOpen ? 'on' : 'off' ] ( 'click' , close ) ;
288
336
289
- if ( isOpen ) {
337
+ if ( isOpen && ! skipSidenav ) {
290
338
// Capture upon opening..
291
339
triggeringElement = $document [ 0 ] . activeElement ;
292
340
}
293
341
294
342
disableParentScroll ( isOpen ) ;
295
343
296
- return promise = $q . all ( [
297
- isOpen ? $animate . enter ( backdrop , parent ) : $animate . leave ( backdrop ) ,
298
- $animate [ isOpen ? 'removeClass' : 'addClass' ] ( element , 'md-closed' )
299
- ] )
300
- . then ( function ( ) {
344
+ var actions = [ isOpen ? $animate . enter ( backdrop , parent ) : $animate . leave ( backdrop ) ] ;
345
+ if ( ! skipSidenav ) actions . push ( $animate [ isOpen ? 'removeClass' : 'addClass' ] ( element , 'md-closed' ) ) ;
346
+
347
+ return promise = $q . all ( actions ) . then ( function ( ) {
301
348
// Perform focus when animations are ALL done...
302
349
if ( scope . isOpen ) {
303
350
focusEl && focusEl . focus ( ) ;
0 commit comments