diff --git a/src/collapse/collapse.js b/src/collapse/collapse.js index ece61727c4..8ce9955cf4 100644 --- a/src/collapse/collapse.js +++ b/src/collapse/collapse.js @@ -8,39 +8,43 @@ angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition']) var initialAnimSkip = true; var currentTransition; - function resetCurrentTransition() { - currentTransition = undefined; - } - function doTransition(change) { + var newTransition = $transition(element, change); if (currentTransition) { currentTransition.cancel(); } - (currentTransition = $transition(element, change)).then(resetCurrentTransition, resetCurrentTransition); - return currentTransition; + currentTransition = newTransition; + newTransition.then(newTransitionDone, newTransitionDone); + return newTransition; + + function newTransitionDone() { + // Make sure it's this transition, otherwise, leave it alone. + if (currentTransition === newTransition) { + currentTransition = undefined; + } + } } function expand() { if (initialAnimSkip) { initialAnimSkip = false; - element.removeClass('collapsing'); - element.addClass('collapse in'); - element.css({height: 'auto'}); + expandDone(); } else { element.removeClass('collapse').addClass('collapsing'); - doTransition({ height: element[0].scrollHeight + 'px' }).then(function () { - element.removeClass('collapsing'); - element.addClass('collapse in'); - element.css({height: 'auto'}); - }); + doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone); } } + function expandDone() { + element.removeClass('collapsing'); + element.addClass('collapse in'); + element.css({height: 'auto'}); + } + function collapse() { if (initialAnimSkip) { initialAnimSkip = false; - element.removeClass('collapsing'); - element.addClass('collapse'); + collapseDone(); element.css({height: 0}); } else { // CSS transitions don't work with height: auto, so we have to manually change the height to a specific value @@ -50,13 +54,15 @@ angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition']) element.removeClass('collapse in').addClass('collapsing'); - doTransition({ height: 0 }).then(function () { - element.removeClass('collapsing'); - element.addClass('collapse'); - }); + doTransition({ height: 0 }).then(collapseDone); } } + function collapseDone() { + element.removeClass('collapsing'); + element.addClass('collapse'); + } + scope.$watch(attrs.collapse, function (shouldCollapse) { if (shouldCollapse) { collapse(); diff --git a/src/collapse/test/collapse.spec.js b/src/collapse/test/collapse.spec.js index d3784ad4c6..f2069b1135 100644 --- a/src/collapse/test/collapse.spec.js +++ b/src/collapse/test/collapse.spec.js @@ -55,6 +55,23 @@ describe('collapse directive', function () { expect(element.height()).not.toBe(0); }); + it('should expand if isCollapsed = true with animation on subsequent uses', function() { + scope.isCollapsed = false; + scope.$digest(); + scope.isCollapsed = true; + scope.$digest(); + scope.isCollapsed = false; + scope.$digest(); + scope.isCollapsed = true; + scope.$digest(); + $timeout.flush(); + expect(element.height()).toBe(0); + if ($transition.transitionEndEventName) { + element.triggerHandler($transition.transitionEndEventName); + expect(element.height()).toBe(0); + } + }); + describe('dynamic content', function() { beforeEach(function() { element = angular.element('

Initial content

Additional content
');