From 35ced0444504344def981036883047656c0603d0 Mon Sep 17 00:00:00 2001 From: atrinh Date: Fri, 3 Jun 2016 12:45:07 +1000 Subject: [PATCH] fix(modal): filter out non-tabbable elements - Ensure non-tabbable elements with taxindex of -1 are not tabbed to Closes #5963 Fixes #5955 --- src/modal/modal.js | 8 +++---- src/modal/test/modal.spec.js | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index 356299da8b..23e81007dd 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -261,9 +261,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p var previousTopOpenedModal = null; //Modal focus behavior - var tabableSelector = 'a[href], area[href], input:not([disabled]), ' + - 'button:not([disabled]),select:not([disabled]), textarea:not([disabled]), ' + - 'iframe, object, embed, *[tabindex], *[contenteditable=true]'; + var tabbableSelector = 'a[href], area[href], input:not([disabled]):not([tabindex=\'-1\']), ' + + 'button:not([disabled]):not([tabindex=\'-1\']),select:not([disabled]):not([tabindex=\'-1\']), textarea:not([disabled]):not([tabindex=\'-1\']), ' + + 'iframe, object, embed, *[tabindex]:not([tabindex=\'-1\']), *[contenteditable=true]'; var scrollbarPadding; function isVisible(element) { @@ -599,7 +599,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap', 'ui.bootstrap.p if (modalWindow) { var modalDomE1 = modalWindow.value.modalDomEl; if (modalDomE1 && modalDomE1.length) { - var elements = modalDomE1[0].querySelectorAll(tabableSelector); + var elements = modalDomE1[0].querySelectorAll(tabbableSelector); return elements ? Array.prototype.filter.call(elements, function(element) { return isVisible(element); diff --git a/src/modal/test/modal.spec.js b/src/modal/test/modal.spec.js index 1e43b037d2..dff247e966 100644 --- a/src/modal/test/modal.spec.js +++ b/src/modal/test/modal.spec.js @@ -807,6 +807,52 @@ describe('$uibModal', function() { initialPage.remove(); }); + + it('should change focus to next tabbable element when tab is pressed', function() { + var initialPage = angular.element('Outland link'); + angular.element(document.body).append(initialPage); + initialPage.focus(); + + open({ + template:'a' + + 'bc' + + '', + keyboard: false + }); + $rootScope.$digest(); + expect($document).toHaveModalsOpen(1); + + $('#tab-focus-link3').focus(); + expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link3'); + + triggerKeyDown(angular.element(document.activeElement), 9, false); + expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link1'); + + initialPage.remove(); + }); + + it('should change focus to previous tabbable element when shift+tab is pressed', function() { + var initialPage = angular.element('Outland link'); + angular.element(document.body).append(initialPage); + initialPage.focus(); + + open({ + template:'a' + + 'bc' + + '', + keyboard: false + }); + $rootScope.$digest(); + expect($document).toHaveModalsOpen(1); + + $('#tab-focus-link1').focus(); + expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link1'); + + triggerKeyDown(angular.element(document.activeElement), 9, true); + expect(document.activeElement.getAttribute('id')).toBe('tab-focus-link3'); + + initialPage.remove(); + }); }); describe('default options can be changed in a provider', function() {