diff --git a/src/transition/test/transition.spec.js b/src/transition/test/transition.spec.js index 34f744b037..9dfff8797d 100644 --- a/src/transition/test/transition.spec.js +++ b/src/transition/test/transition.spec.js @@ -54,6 +54,23 @@ describe('$transition', function() { expect(triggerFunction).toHaveBeenCalledWith(element); }); + // transitionend emulation + describe('emulateTransitionEnd', function() { + it('should emit transition end-event after the specified duration', function() { + var element = angular.element('
'); + var transitionEndHandler = jasmine.createSpy('transitionEndHandler'); + + // There is no transition property, so transitionend could not be fired + // on its own. + var promise = $transition(element, {height: '100px'}); + promise.then(transitionEndHandler); + promise.emulateTransitionEnd(1); + + $timeout.flush(); + expect(transitionEndHandler).toHaveBeenCalledWith(element); + }); + }); + // Versions of Internet Explorer before version 10 do not have CSS transitions if ( !ie || ie > 9 ) { describe('transitionEnd event', function() { diff --git a/src/transition/transition.js b/src/transition/transition.js index c23d3f76f7..4636ee1832 100644 --- a/src/transition/transition.js +++ b/src/transition/transition.js @@ -52,6 +52,31 @@ angular.module('ui.bootstrap.transition', []) deferred.reject('Transition cancelled'); }; + // Emulate transitionend event, useful when support is assumed to be + // available, but may not actually be used due to a transition property + // not being used in CSS (for example, in versions of firefox prior to 16, + // only -moz-transition is supported -- and is not used in Bootstrap3's CSS + // -- As such, no transitionend event would be fired due to no transition + // ever taking place. This method allows a fallback for such browsers.) + deferred.promise.emulateTransitionEnd = function(duration) { + var called = false; + deferred.promise.then( + function() { called = true; }, + function() { called = true; } + ); + + var callback = function() { + if ( !called ) { + // If we got here, we probably aren't going to get a real + // transitionend event. Emit a dummy to the handler. + element.triggerHandler(endEventName); + } + }; + + $timeout(callback, duration); + return deferred.promise; + }; + return deferred.promise; };