@@ -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,55 @@ 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 ( attr . mdIsLockedOpen ) return ;
276
+
277
+ if ( isHidden ( element , true ) && scope . isOpen ) {
278
+ scope . isOpen = false ;
279
+ } else if ( ! isHidden ( element , true ) && ! scope . isOpen ) {
280
+ scope . isOpen = true ;
281
+ }
282
+
283
+ // If the revalidated isOpen Value got changed,
284
+ // we should apply it to the view without running the updateOpen watcher
285
+ if ( lastValue != scope . isOpen ) {
286
+ skipSidenav = true ;
287
+ if ( ! scope . $$phase ) scope . $apply ( ) ;
288
+ skipSidenav = false ;
289
+ }
290
+ }
291
+
292
+ // Check if the element is hidden by any hide attribute (using computed style)
293
+ function isHidden ( element , compute ) {
294
+ if ( element [ 0 ] . offsetParent == null ) return true ;
295
+ if ( ! compute ) return false ;
296
+ return window . getComputedStyle ( element [ 0 ] ) . display === 'none' ;
297
+ }
298
+
263
299
/**
264
300
* Toggle the DOM classes to indicate `locked`
265
301
* @param isLocked
@@ -278,26 +314,43 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
278
314
* Toggle the SideNav view and attach/detach listeners
279
315
* @param isOpen
280
316
*/
281
- function updateIsOpen ( isOpen ) {
317
+ function updateIsOpen ( isOpen , oldValue ) {
318
+ if ( skipNextUpdate ) {
319
+ skipNextUpdate = false ;
320
+ return ;
321
+ }
322
+
282
323
// Support deprecated md-sidenav-focus attribute as fallback
283
324
var focusEl = $mdUtil . findFocusTarget ( element ) || $mdUtil . findFocusTarget ( element , '[md-sidenav-focus]' ) || element ;
284
325
var parent = element . parent ( ) ;
285
326
327
+ // little hack to check show abbility
328
+ if ( ! skipSidenav ) {
329
+ var wasClosed = element . hasClass ( 'md-closed' ) ;
330
+ element . removeClass ( 'md-closed' ) ;
331
+ if ( isHidden ( element , false ) && ! skipSidenav ) {
332
+ element . toggleClass ( 'md-closed' , wasClosed ) ;
333
+ skipNextUpdate = true ;
334
+ scope . isOpen = oldValue ;
335
+ return ;
336
+ }
337
+ element . toggleClass ( 'md-closed' , wasClosed ) ;
338
+ }
339
+
286
340
parent [ isOpen ? 'on' : 'off' ] ( 'keydown' , onKeyDown ) ;
287
341
backdrop [ isOpen ? 'on' : 'off' ] ( 'click' , close ) ;
288
342
289
- if ( isOpen ) {
343
+ if ( isOpen && ! skipSidenav ) {
290
344
// Capture upon opening..
291
345
triggeringElement = $document [ 0 ] . activeElement ;
292
346
}
293
347
294
348
disableParentScroll ( isOpen ) ;
295
349
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 ( ) {
350
+ var actions = [ isOpen ? $animate . enter ( backdrop , parent ) : $animate . leave ( backdrop ) ] ;
351
+ if ( ! skipSidenav ) actions . push ( isOpen ? $animate . removeClass ( element , 'md-closed' ) : $animate . addClass ( element , 'md-closed' ) ) ;
352
+
353
+ return promise = $q . all ( actions ) . then ( function ( ) {
301
354
// Perform focus when animations are ALL done...
302
355
if ( scope . isOpen ) {
303
356
focusEl && focusEl . focus ( ) ;
0 commit comments