diff --git a/src/components/sidenav/sidenav.js b/src/components/sidenav/sidenav.js
index 593a90ff066..0997a84d8db 100644
--- a/src/components/sidenav/sidenav.js
+++ b/src/components/sidenav/sidenav.js
@@ -208,7 +208,7 @@ function SidenavFocusDirective() {
* - ``
* - `` (locks open on small screens)
*/
-function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate, $compile, $parse, $log, $q, $document) {
+function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate, $compile, $parse, $log, $q, $document, $$rAF) {
return {
restrict: 'E',
scope: {
@@ -229,6 +229,9 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
var lastParentOverFlow;
var triggeringElement = null;
var promise = $q.when(true);
+ var skipSidenav = false;
+ var skipNextUpdate = false;
+ var $window = angular.element(window);
var isLockedOpenParsed = $parse(attr.mdIsLockedOpen);
var isLocked = function() {
@@ -244,12 +247,18 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
$mdTheming.inherit(backdrop, element);
+ var throttleResize = $$rAF.throttle(revalidateVisibility);
+ $window.on('resize', throttleResize);
+ revalidateVisibility();
+
element.on('$destroy', function() {
backdrop.remove();
sidenavCtrl.destroy();
+ $window.off('resize', throttleResize);
});
scope.$on('$destroy', function(){
+ $window.off('resize', throttleResize);
backdrop.remove()
});
@@ -257,9 +266,30 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
scope.$watch('isOpen', updateIsOpen);
+
// Publish special accessor for the Controller instance
sidenavCtrl.$toggleOpen = toggleOpen;
+ function revalidateVisibility() {
+ var lastValue = scope.isOpen;
+ if (isHidden(element, true, true) && scope.isOpen == true) scope.isOpen = false;
+ else if (!isHidden(element, true, true) && scope.isOpen == false) scope.isOpen = true;
+
+ if (lastValue != scope.isOpen) {
+ skipSidenav = true;
+ if (!scope.$$phase) scope.$apply();
+ skipSidenav = false;
+ }
+ }
+
+ function isHidden(element, compute, both) {
+ if (!compute || both) {
+ if (element[0].offsetParent == null) return true;
+ if (!both) return false;
+ }
+ return window.getComputedStyle(element[0]).display === 'none';
+ }
+
/**
* Toggle the DOM classes to indicate `locked`
* @param isLocked
@@ -278,26 +308,43 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
* Toggle the SideNav view and attach/detach listeners
* @param isOpen
*/
- function updateIsOpen(isOpen) {
+ function updateIsOpen(isOpen, oldValue) {
+ if (skipNextUpdate) {
+ skipNextUpdate = false;
+ return;
+ }
+
// Support deprecated md-sidenav-focus attribute as fallback
var focusEl = $mdUtil.findFocusTarget(element) || $mdUtil.findFocusTarget(element,'[md-sidenav-focus]') || element;
var parent = element.parent();
+ // little hack to check show abbility
+ if (!skipSidenav) {
+ var wasClosed = element.hasClass('md-closed');
+ element.removeClass('md-closed');
+ if (isHidden(element, true) && !skipSidenav) {
+ element.toggleClass('md-closed', wasClosed);
+ skipNextUpdate = true;
+ scope.isOpen = oldValue;
+ return;
+ }
+ element.toggleClass('md-closed', wasClosed);
+ }
+
parent[isOpen ? 'on' : 'off']('keydown', onKeyDown);
backdrop[isOpen ? 'on' : 'off']('click', close);
- if ( isOpen ) {
+ if ( isOpen && !skipSidenav) {
// Capture upon opening..
triggeringElement = $document[0].activeElement;
}
disableParentScroll(isOpen);
- return promise = $q.all([
- isOpen ? $animate.enter(backdrop, parent) : $animate.leave(backdrop),
- $animate[isOpen ? 'removeClass' : 'addClass'](element, 'md-closed')
- ])
- .then(function() {
+ var actions = [isOpen ? $animate.enter(backdrop, parent) : $animate.leave(backdrop)];
+ if (!skipSidenav) actions.push($animate[isOpen ? 'removeClass' : 'addClass'](element, 'md-closed'));
+
+ return promise = $q.all(actions).then(function() {
// Perform focus when animations are ALL done...
if (scope.isOpen) {
focusEl && focusEl.focus();