Skip to content

Commit

Permalink
fix(modal): support close animation
Browse files Browse the repository at this point in the history
Tests now have to wait for animation before checking for open modals.
Tests should actually check for the 'in' class.

Setting up both the transition end handler and a timeout ensures that
the modal is always closed even if there was an issue with the
transition. This was the implementation used by Twitter Bootstrap modal
JS code.

Note that unbinding the transition end event within the event
handler isn't necessary, and, worse is currently buggy in jqLite (see
angular/angular.js#5109 ).

Note that the scope is already destroyed when the dom is removed so the
$destroy call isn't needed.

Closes angular-ui#1341
  • Loading branch information
chrisirhc committed Dec 24, 2013
1 parent 0b39994 commit 1a11471
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/modal/modal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
angular.module('ui.bootstrap.modal', [])
angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])

/**
* A helper, internal data structure that acts as a map but also allows getting / removing
Expand Down Expand Up @@ -87,7 +87,8 @@ angular.module('ui.bootstrap.modal', [])
return {
restrict: 'EA',
scope: {
index: '@'
index: '@',
animate: '='
},
replace: true,
transclude: true,
Expand All @@ -106,8 +107,8 @@ angular.module('ui.bootstrap.modal', [])
};
}])

.factory('$modalStack', ['$document', '$compile', '$rootScope', '$$stackedMap',
function ($document, $compile, $rootScope, $$stackedMap) {
.factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {

var OPENED_MODAL_CLASS = 'modal-open';

Expand Down Expand Up @@ -140,17 +141,34 @@ angular.module('ui.bootstrap.modal', [])
openedWindows.remove(modalInstance);

//remove window DOM element
modalWindow.modalDomEl.remove();
removeAfterAnimating(modalWindow.modalDomEl, modalWindow.modalScope);
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);

//remove backdrop if no longer needed
if (backdropDomEl && backdropIndex() == -1) {
backdropDomEl.remove();
removeAfterAnimating(backdropDomEl, backdropScope);
backdropDomEl = undefined;
}
}

function removeAfterAnimating(domEl, scope) {
// Closing animation
scope.animate = false;

//destroy scope
modalWindow.modalScope.$destroy();
var transitionEndEventName = $transition.transitionEndEventName;
if (transitionEndEventName) {
// transition out
var timeout = $timeout(function () {
domEl.remove();
}, 500);

domEl.bind(transitionEndEventName, function () {
$timeout.cancel(timeout);
domEl.remove();
});
} else {
domEl.remove();
}
}

$document.bind('keydown', function (evt) {
Expand Down Expand Up @@ -186,6 +204,7 @@ angular.module('ui.bootstrap.modal', [])
var angularDomEl = angular.element('<div modal-window></div>');
angularDomEl.attr('window-class', modal.windowClass);
angularDomEl.attr('index', openedWindows.length() - 1);
angularDomEl.attr('animate', 'animate');
angularDomEl.html(modal.content);

var modalDomEl = $compile(angularDomEl)(modal.scope);
Expand Down
3 changes: 3 additions & 0 deletions src/modal/test/modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ describe('$modal', function () {

function dismiss(modal, reason) {
modal.dismiss(reason);
$timeout.flush();
$rootScope.$digest();
}

Expand Down Expand Up @@ -144,6 +145,7 @@ describe('$modal', function () {
expect($document).toHaveModalsOpen(1);

triggerKeyDown($document, 27);
$timeout.flush();
$rootScope.$digest();

expect($document).toHaveModalsOpen(0);
Expand All @@ -155,6 +157,7 @@ describe('$modal', function () {
expect($document).toHaveModalsOpen(1);

$document.find('body > div.modal-backdrop').click();
$timeout.flush();
$rootScope.$digest();

expect($document).toHaveModalsOpen(0);
Expand Down

0 comments on commit 1a11471

Please sign in to comment.