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

feat(modal): support requiring from parent directive #4844

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
};
})

.factory('$uibModalStack', ['$animate', '$animateCss', '$timeout', '$document',
.factory('$uibModalStack', ['$animate', '$animateCss', '$document',
'$compile', '$rootScope', '$q', '$$multiMap', '$$stackedMap',
function($animate, $animateCss, $timeout, $document, $compile, $rootScope, $q, $$multiMap, $$stackedMap) {
function($animate, $animateCss, $document, $compile, $rootScope, $q, $$multiMap, $$stackedMap) {
var OPENED_MODAL_CLASS = 'modal-open';

var backdropDomEl, backdropScope;
Expand Down Expand Up @@ -430,14 +430,15 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
angularDomEl.attr('modal-animation', 'true');
}

var modalDomEl = $compile(angularDomEl)(modal.scope);
openedWindows.top().value.modalDomEl = modalDomEl;
openedWindows.top().value.modalOpener = modalOpener;
$animate.enter(modalDomEl, appendToElement)
$animate.enter(angularDomEl, appendToElement)
.then(function() {
$compile(angularDomEl)(modal.scope);
$animate.addClass(appendToElement, modalBodyClass);
});

openedWindows.top().value.modalDomEl = angularDomEl;
openedWindows.top().value.modalOpener = modalOpener;

$modalStack.clearFocusListCache();
};

Expand Down
96 changes: 76 additions & 20 deletions src/modal/test/modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@ describe('$uibModal', function () {
beforeEach(module('ui.bootstrap.modal'));
beforeEach(module('uib/template/modal/backdrop.html'));
beforeEach(module('uib/template/modal/window.html'));
beforeEach(module(function(_$controllerProvider_, _$uibModalProvider_){
beforeEach(module(function(_$controllerProvider_, _$uibModalProvider_, $compileProvider) {
$controllerProvider = _$controllerProvider_;
$uibModalProvider = _$uibModalProvider_;
$compileProvider.directive('parentDirective', function() {
return {
controller: function() {
this.text = 'foo';
}
};
}).directive('childDirective', function() {
return {
require: '^parentDirective',
link: function(scope, elem, attrs, ctrl) {
scope.text = ctrl.text;
}
};
});
}));

beforeEach(inject(function(_$animate_, _$rootScope_, _$document_, _$compile_, _$templateCache_, _$timeout_, _$q_, _$uibModal_, _$uibModalStack_) {
Expand Down Expand Up @@ -144,10 +158,12 @@ describe('$uibModal', function () {
element.trigger(e);
}

function open(modalOptions) {
function open(modalOptions, noFlush) {
var modal = $uibModal.open(modalOptions);
$rootScope.$digest();
$timeout.flush(0);
if (!noFlush) {
$animate.flush();
}
return modal;
}

Expand Down Expand Up @@ -376,9 +392,8 @@ describe('$uibModal', function () {

it('should expose a promise linked to the templateUrl / resolve promises and reject it if needed', function() {
var modal = open({template: '<div>Content</div>', resolve: {
ok: function() {return $q.reject('ko');}
}}
);
ok: function() {return $q.reject('ko');}
}}, true);
expect(modal.opened).toBeRejectedWith('ko');
});

Expand Down Expand Up @@ -633,10 +648,11 @@ describe('$uibModal', function () {
value: function() {
return $timeout(function() { return 'Promise'; }, 100);
}
}));
}), true);
expect($document).toHaveModalsOpen(0);

$timeout.flush();
$animate.flush();
expect($document).toHaveModalOpenWithContent('Promise', 'div');
});

Expand All @@ -647,7 +663,7 @@ describe('$uibModal', function () {
value: function() {
return deferred.promise;
}
}));
}), true);
expect($document).toHaveModalsOpen(0);

deferred.reject('error in test');
Expand Down Expand Up @@ -858,6 +874,8 @@ describe('$uibModal', function () {
expect($document.find('section').children('div.modal').length).toBe(0);
open({template: '<div>Content</div>', appendTo: element});
expect($document.find('section').children('div.modal').length).toBe(1);

element.remove();
});

it('should throw error if appendTo element is not found', function() {
Expand All @@ -874,6 +892,17 @@ describe('$uibModal', function () {
dismiss(modal);
expect($document).toHaveModalsOpen(0);
});

it('should allow requiring parent directive from appendTo target', function() {
var element = $compile('<section parent-directive>Some content</section>')($rootScope);
angular.element(document.body).append(element);

open({template: '<div child-directive>{{text}}</div>', appendTo: element});
$animate.flush();
expect($document.find('[child-directive]').text()).toBe('foo');

element.remove();
});
});

describe('openedClass', function() {
Expand Down Expand Up @@ -1008,7 +1037,7 @@ describe('$uibModal', function () {
expect($document).toHaveModalsOpen(2);
});

it('multiple modals should not interfere with default options', function() {
it('should not interfere with default options', function() {
var modal1 = open({template: '<div>Modal1</div>', backdrop: false});
var modal2 = open({template: '<div>Modal2</div>'});
$rootScope.$digest();
Expand Down Expand Up @@ -1084,7 +1113,7 @@ describe('$uibModal', function () {
} else {
expected += i;
}
ds[x] = {index:i, deferred:$q.defer(), reject:reject};
ds[x] = {index: i, deferred: $q.defer(), reject: reject};

var scope = $rootScope.$new();
scope.index = i;
Expand All @@ -1094,17 +1123,17 @@ describe('$uibModal', function () {
resolve: {
x: function() { return ds[x].deferred.promise; }
}
}).opened.then(function() {
}, true).opened.then(function() {
expect($uibModalStack.getTop().value.modalScope.index).toEqual(i);
actual += i;
});
});

angular.forEach(ds, function(d, i) {
if (d.reject) {
d.deferred.reject('rejected:' + d.index );
d.deferred.reject('rejected:' + d.index);
} else {
d.deferred.resolve('resolved:' + d.index );
d.deferred.resolve('resolved:' + d.index);
}
$rootScope.$digest();
});
Expand Down Expand Up @@ -1138,13 +1167,39 @@ describe('$uibModal', function () {
_permute(0);
}

permute(2, function(a) { test(a); });
permute(2, function(a) { test(a.map(function(x, i) { return {reject:x}; })); });
permute(2, function(a) { test(a.map(function(x, i) { return i === 0 ? {reject:x} : x; })); });
permute(3, function(a) { test(a); });
permute(3, function(a) { test(a.map(function(x, i) { return {reject:x}; })); });
permute(3, function(a) { test(a.map(function(x, i) { return i === 0 ? {reject:x} : x; })); });
permute(3, function(a) { test(a.map(function(x, i) { return i === 1 ? {reject:x} : x; })); });
permute(2, function(a) {
test(a);
});
permute(2, function(a) {
test(a.map(function(x, i) {
return {reject:x};
}));
});
permute(2, function(a) {
test(a.map(function(x, i) {
return i === 0 ? {reject: x} : x;
}));
});
permute(3, function(a) {
test(a);
});
permute(3, function(a) {
test(a.map(function(x, i) {
return {reject: x};
}));
});
permute(3, function(a) {
test(a.map(function(x, i) {
return i === 0 ? {reject: x} : x;
}));
});
permute(3, function(a) {
test(a.map(function(x, i) {
return i === 1 ? {reject: x} : x;
}));
});

$animate.flush();
});

it('should have top class only on top window', function () {
Expand Down Expand Up @@ -1213,6 +1268,7 @@ describe('$uibModal', function () {
var called;

called = false;

close(open({
template: '<div>content</div>',
controller: function($scope) {
Expand Down