Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
fix(modal): backdrop should cover previously opened modals
Browse files Browse the repository at this point in the history
Closes #922
Closes #931
  • Loading branch information
pkozlowski-opensource committed Sep 7, 2013
1 parent 015625d commit 7fce2fe
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 31 deletions.
77 changes: 48 additions & 29 deletions src/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ angular.module('ui.bootstrap.modal', [])
}
}
},
keys: function() {
var keys = [];
for (var i = 0; i < stack.length; i++) {
keys.push(stack[i].key);
}
return keys;
},
top: function () {
return stack[stack.length - 1];
},
Expand Down Expand Up @@ -53,7 +60,6 @@ angular.module('ui.bootstrap.modal', [])
.directive('modalBackdrop', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
return {
restrict: 'EA',
scope: {},
replace: true,
templateUrl: 'template/modal/backdrop.html',
link: function (scope, element, attrs) {
Expand All @@ -65,11 +71,10 @@ angular.module('ui.bootstrap.modal', [])

scope.close = function (evt) {
var modal = $modalStack.getTop();
//TODO: this logic is duplicated with the place where modal gets opened
if (modal && modal.window.backdrop && modal.window.backdrop != 'static') {
if (modal && modal.value.backdrop && modal.value.backdrop != 'static') {
evt.preventDefault();
evt.stopPropagation();
$modalStack.dismiss(modal.instance, 'backdrop click');
$modalStack.dismiss(modal.key, 'backdrop click');
}
};
}
Expand All @@ -79,7 +84,9 @@ angular.module('ui.bootstrap.modal', [])
.directive('modalWindow', ['$timeout', function ($timeout) {
return {
restrict: 'EA',
scope: {},
scope: {
index: '@'
},
replace: true,
transclude: true,
templateUrl: 'template/modal/window.html',
Expand All @@ -97,23 +104,41 @@ angular.module('ui.bootstrap.modal', [])
.factory('$modalStack', ['$document', '$compile', '$rootScope', '$$stackedMap',
function ($document, $compile, $rootScope, $$stackedMap) {

var backdropjqLiteEl, backdropDomEl;
var backdropScope = $rootScope.$new(true);
var body = $document.find('body').eq(0);
var openedWindows = $$stackedMap.createNew();
var $modalStack = {};

function backdropIndex() {
var topBackdropIndex = -1;
var opened = openedWindows.keys();
for (var i = 0; i < opened.length; i++) {
if (openedWindows.get(opened[i]).value.backdrop) {
topBackdropIndex = i;
}
}
return topBackdropIndex;
}

$rootScope.$watch(backdropIndex, function(newBackdropIndex){
backdropScope.index = newBackdropIndex;
});

function removeModalWindow(modalInstance) {

var modalWindow = openedWindows.get(modalInstance).value;

//clean up the stack
openedWindows.remove(modalInstance);

//remove DOM element
//remove window DOM element
modalWindow.modalDomEl.remove();

//remove backdrop
if (modalWindow.backdropDomEl) {
modalWindow.backdropDomEl.remove();
//remove backdrop if no longer needed
if (backdropIndex() == -1) {
backdropDomEl.remove();
backdropDomEl = undefined;
}

//destroy scope
Expand All @@ -135,27 +160,27 @@ angular.module('ui.bootstrap.modal', [])

$modalStack.open = function (modalInstance, modal) {

var backdropDomEl;
if (modal.backdrop) {
backdropDomEl = $compile(angular.element('<div modal-backdrop></div>'))($rootScope);
body.append(backdropDomEl);
}
openedWindows.add(modalInstance, {
deferred: modal.deferred,
modalScope: modal.scope,
backdrop: modal.backdrop,
keyboard: modal.keyboard
});

var angularDomEl = angular.element('<div modal-window></div>');
angularDomEl.attr('window-class', modal.windowClass);
angularDomEl.attr('index', openedWindows.length() - 1);
angularDomEl.html(modal.content);

var modalDomEl = $compile(angularDomEl)(modal.scope);
openedWindows.top().value.modalDomEl = modalDomEl;
body.append(modalDomEl);

openedWindows.add(modalInstance, {
deferred: modal.deferred,
modalScope: modal.scope,
modalDomEl: modalDomEl,
backdrop: modal.backdrop,
backdropDomEl: backdropDomEl,
keyboard: modal.keyboard
});
if (backdropIndex() >= 0 && !backdropDomEl) {
backdropjqLiteEl = angular.element('<div modal-backdrop></div>');
backdropDomEl = $compile(backdropjqLiteEl)(backdropScope);
body.append(backdropDomEl);
}
};

$modalStack.close = function (modalInstance, result) {
Expand All @@ -175,13 +200,7 @@ angular.module('ui.bootstrap.modal', [])
};

$modalStack.getTop = function () {
var top = openedWindows.top();
if (top) {
return {
instance: top.key,
window: top.value
};
}
return openedWindows.top();
};

return $modalStack;
Expand Down
7 changes: 7 additions & 0 deletions src/modal/test/stackedMap.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ describe('stacked map', function () {
expect(stackedMap.get('foo')).toBeUndefined();
});

it('should support listing keys', function () {
stackedMap.add('foo', 'foo_value');
stackedMap.add('bar', 'bar_value');

expect(stackedMap.keys()).toEqual(['foo', 'bar']);
});

it('should get topmost element', function () {

stackedMap.add('foo', 'foo_value');
Expand Down
2 changes: 1 addition & 1 deletion template/modal/backdrop.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="modal-backdrop fade" ng-class="{in: animate}" ng-click="close($event)"></div>
<div class="modal-backdrop fade" ng-class="{in: animate}" ng-style="{'z-index': 1040 + index*10}" ng-click="close($event)"></div>
2 changes: 1 addition & 1 deletion template/modal/window.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="modal fade {{ windowClass }}" ng-class="{in: animate}" ng-transclude></div>
<div class="modal fade {{ windowClass }}" ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10}" ng-transclude></div>

0 comments on commit 7fce2fe

Please sign in to comment.