diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 400d951e2bc0..27755ae64e44 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -32,7 +32,7 @@ * | {@link ng.directive:ngHide ngHide} | aria-hidden | * | {@link ng.directive:ngDblclick ngDblclick} | tabindex | * | {@link module:ngMessages ngMessages} | aria-live | - * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role | + * | {@link ng.directive:ngClick ngClick} | tabindex, keydown event, keyup event, keypress event, button role | * * Find out more information about each directive by reading the * {@link guide/accessibility ngAria Developer Guide}. @@ -96,7 +96,7 @@ function $AriaProvider() { ariaInvalid: true, ariaValue: true, tabindex: true, - bindKeypress: true, + bindKeyEvents: true, bindRoleForClick: true }; @@ -113,7 +113,7 @@ function $AriaProvider() { * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags * - **tabindex** – `{boolean}` – Enables/disables tabindex tags - * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `div` and + * - **bindKeyEvents** – `{boolean}` – Enables/disables keyboard event binding on `div` and * `li` elements with ng-click * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div` * using ng-click, making them more accessible to users of assistive technologies @@ -364,8 +364,8 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { elem.attr('tabindex', 0); } - if ($aria.config('bindKeypress') && !attr.ngKeypress) { - elem.on('keypress', function(event) { + if ($aria.config('bindKeyEvents') && !attr.ngKeypress && !attr.ngKeydown && !attr.ngKeyup) { + elem.on('keydown', function(event) { var keyCode = event.which || event.keyCode; if (keyCode === 32 || keyCode === 13) { scope.$apply(callback); diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index 37c4f17bf1d8..cee944137798 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -608,8 +608,8 @@ describe('$aria', function() { var divElement = elements.find('div'); var liElement = elements.find('li'); - divElement.triggerHandler({type: 'keypress', keyCode: 32}); - liElement.triggerHandler({type: 'keypress', keyCode: 32}); + divElement.triggerHandler({type: 'keydown', keyCode: 32}); + liElement.triggerHandler({type: 'keydown', keyCode: 32}); expect(clickFn).toHaveBeenCalledWith('div'); expect(clickFn).toHaveBeenCalledWith('li'); @@ -630,14 +630,42 @@ describe('$aria', function() { var divElement = elements.find('div'); var liElement = elements.find('li'); - divElement.triggerHandler({type: 'keypress', which: 32}); - liElement.triggerHandler({type: 'keypress', which: 32}); + divElement.triggerHandler({type: 'keydown', which: 32}); + liElement.triggerHandler({type: 'keydown', which: 32}); expect(clickFn).toHaveBeenCalledWith('div'); expect(clickFn).toHaveBeenCalledWith('li'); }); - it('should not override existing ng-keypress', function() { + it('should not bind to key events if there is existing ng-keydown', function() { + scope.someOtherAction = function() {}; + var keydownFn = spyOn(scope, 'someOtherAction'); + + scope.someAction = function() {}; + clickFn = spyOn(scope, 'someAction'); + compileElement('
'); + + element.triggerHandler({type: 'keydown', keyCode: 32}); + + expect(clickFn).not.toHaveBeenCalled(); + expect(keydownFn).toHaveBeenCalled(); + }); + + it('should not bind to key events if there is existing ng-keyup', function() { + scope.someOtherAction = function() {}; + var keyupFn = spyOn(scope, 'someOtherAction'); + + scope.someAction = function() {}; + clickFn = spyOn(scope, 'someAction'); + compileElement('
'); + + element.triggerHandler({type: 'keyup', keyCode: 32}); + + expect(clickFn).not.toHaveBeenCalled(); + expect(keyupFn).toHaveBeenCalled(); + }); + + it('should not bind to key events if there is existing ng-keypress', function() { scope.someOtherAction = function() {}; var keypressFn = spyOn(scope, 'someOtherAction'); @@ -651,11 +679,11 @@ describe('$aria', function() { expect(keypressFn).toHaveBeenCalled(); }); - it('should update bindings when keypress handled', function() { + it('should update bindings when keydown handled', function() { compileElement('
{{text}}
'); expect(element.text()).toBe(''); spyOn(scope.$root, '$digest').andCallThrough(); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); + element.triggerHandler({ type: 'keydown', keyCode: 13 }); expect(element.text()).toBe('clicked!'); expect(scope.$root.$digest).toHaveBeenCalledOnce(); }); @@ -664,14 +692,14 @@ describe('$aria', function() { compileElement('
{{event.type}}' + '{{event.keyCode}}
'); expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); - expect(element.text()).toBe('keypress13'); + element.triggerHandler({ type: 'keydown', keyCode: 13 }); + expect(element.text()).toBe('keydown13'); }); - it('should not bind keypress to elements not in the default config', function() { + it('should not bind keydown to elements not in the default config', function() { compileElement(''); expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); + element.triggerHandler({ type: 'keydown', keyCode: 13 }); expect(element.text()).toBe(''); }); }); @@ -688,9 +716,9 @@ describe('$aria', function() { }); }); - describe('actions when bindKeypress is set to false', function() { + describe('actions when bindKeyEvents is set to false', function() { beforeEach(configAriaProvider({ - bindKeypress: false + bindKeyEvents: false })); beforeEach(injectScopeAndCompiler); @@ -700,7 +728,9 @@ describe('$aria', function() { element = $compile('
')(scope); + element.triggerHandler({type: 'keydown', keyCode: 32}); element.triggerHandler({type: 'keypress', keyCode: 32}); + element.triggerHandler({type: 'keyup', keyCode: 32}); expect(clickFn).not.toHaveBeenCalled(); });