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

fix(modal): IE throws exceptions on body.activeElement.focus #3653

Closed
wants to merge 2 commits 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
15 changes: 10 additions & 5 deletions src/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ angular.module('ui.bootstrap.modal', [])
}
});

function removeModalWindow(modalInstance) {
function removeModalWindow(modalInstance, elementToReceiveFocus) {

var body = $document.find('body').eq(0);
var modalWindow = openedWindows.get(modalInstance).value;
Expand All @@ -208,6 +208,13 @@ angular.module('ui.bootstrap.modal', [])
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
checkRemoveBackdrop();
});

//move focus to specified element if available, or else to body
if (elementToReceiveFocus && elementToReceiveFocus.focus) {
elementToReceiveFocus.focus();
} else {
body.focus();
}
}

function checkRemoveBackdrop() {
Expand Down Expand Up @@ -318,8 +325,7 @@ angular.module('ui.bootstrap.modal', [])
var modalWindow = openedWindows.get(modalInstance);
if (modalWindow && broadcastClosing(modalWindow, result, true)) {
modalWindow.value.deferred.resolve(result);
removeModalWindow(modalInstance);
modalWindow.value.modalOpener.focus();
removeModalWindow(modalInstance, modalWindow.value.modalOpener);
return true;
}
return !modalWindow;
Expand All @@ -329,8 +335,7 @@ angular.module('ui.bootstrap.modal', [])
var modalWindow = openedWindows.get(modalInstance);
if (modalWindow && broadcastClosing(modalWindow, reason, false)) {
modalWindow.value.deferred.reject(reason);
removeModalWindow(modalInstance);
modalWindow.value.modalOpener.focus();
removeModalWindow(modalInstance, modalWindow.value.modalOpener);
return true;
}
return !modalWindow;
Expand Down
26 changes: 25 additions & 1 deletion src/modal/test/modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe('$modal', function () {
expect($document).toHaveModalsOpen(0);
});

it('should return to the element which had focus before the dialog is invoked', function () {
it('should return to the element which had focus before the dialog was invoked', function () {
var link = '<a href>Link</a>';
var element = angular.element(link);
angular.element(document.body).append(element);
Expand All @@ -272,6 +272,30 @@ describe('$modal', function () {
element.remove();
});

it('should return to document.body if element which had focus before the dialog was invoked is gone, or is missing focus function', function () {
var link = '<a href>Link</a>';
var element = angular.element(link);
angular.element(document.body).append(element);
element.focus();
expect(document.activeElement.tagName).toBe('A');

var modal = open({template: '<div>Content</div>'});
$timeout.flush();
expect(document.activeElement.tagName).toBe('DIV');
expect($document).toHaveModalsOpen(1);

// Fake undefined focus function, happening in IE in certain
// iframe conditions. See issue 3639
element[0].focus = undefined;
triggerKeyDown($document, 27);
$timeout.flush();
$rootScope.$digest();

expect(document.activeElement.tagName).toBe('BODY');
expect($document).toHaveModalsOpen(0);
element.remove();
});

it('should resolve returned promise on close', function () {
var modal = open({template: '<div>Content</div>'});
close(modal, 'closed ok');
Expand Down