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

Commit

Permalink
fix(modal): focus on body if element disappears
Browse files Browse the repository at this point in the history
- Change to focus on `document.body` instead if element is not present

Closes #3653
Fixes #3639
  • Loading branch information
tompi authored and wesleycho committed Jun 11, 2015
1 parent 0d96221 commit 988336c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
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

0 comments on commit 988336c

Please sign in to comment.