diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js
index 904d9a0e5959..73e9e0733f9f 100644
--- a/src/ngAria/aria.js
+++ b/src/ngAria/aria.js
@@ -387,7 +387,10 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
if ($aria.config('bindKeydown') && !attr.ngKeydown && !attr.ngKeypress && !attr.ngKeyup) {
elem.on('keydown', function(event) {
var keyCode = event.which || event.keyCode;
- if (keyCode === 32 || keyCode === 13) {
+
+ if (keyCode === 13 || keyCode === 32) {
+ // Prevent the default browser behavior (e.g. scrolling when pressing spacebar).
+ event.preventDefault();
scope.$apply(callback);
}
diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js
index 1970b01438b0..11130b17430e 100644
--- a/test/ngAria/ariaSpec.js
+++ b/test/ngAria/ariaSpec.js
@@ -922,116 +922,101 @@ describe('$aria', function() {
});
describe('accessible actions', function() {
- beforeEach(injectScopeAndCompiler);
-
- var clickFn;
-
- it('should trigger a click from the keyboard', function() {
- scope.someAction = function() {};
+ var clickEvents;
- var elements = $compile('')(scope);
-
- scope.$digest();
+ beforeEach(injectScopeAndCompiler);
+ beforeEach(function() {
+ clickEvents = [];
+ scope.onClick = jasmine.createSpy('onClick').and.callFake(function(evt) {
+ var nodeName = evt ? evt.target.nodeName.toLowerCase() : '';
+ var prevented = !!(evt && evt.isDefaultPrevented());
+ clickEvents.push(nodeName + '(' + prevented + ')');
+ });
+ });
- clickFn = spyOn(scope, 'someAction');
+ it('should trigger a click from the keyboard (and prevent default action)', function() {
+ compileElement(
+ '');
- var divElement = elements.find('div');
- var liElement = elements.find('li');
+ var divElement = element.find('div');
+ var liElement = element.find('li');
+ divElement.triggerHandler({type: 'keydown', keyCode: 13});
+ liElement.triggerHandler({type: 'keydown', keyCode: 13});
divElement.triggerHandler({type: 'keydown', keyCode: 32});
liElement.triggerHandler({type: 'keydown', keyCode: 32});
- expect(clickFn).toHaveBeenCalledWith('div');
- expect(clickFn).toHaveBeenCalledWith('li');
+ expect(clickEvents).toEqual(['div(true)', 'li(true)', 'div(true)', 'li(true)']);
});
- it('should trigger a click in browsers that provide event.which instead of event.keyCode', function() {
- scope.someAction = function() {};
+ it('should trigger a click in browsers that provide `event.which` instead of `event.keyCode`',
+ function() {
+ compileElement(
+ '');
+
+ var divElement = element.find('div');
+ var liElement = element.find('li');
- var elements = $compile('')(scope);
+ divElement.triggerHandler({type: 'keydown', which: 13});
+ liElement.triggerHandler({type: 'keydown', which: 13});
+ divElement.triggerHandler({type: 'keydown', which: 32});
+ liElement.triggerHandler({type: 'keydown', which: 32});
- scope.$digest();
+ expect(clickEvents).toEqual(['div(true)', 'li(true)', 'div(true)', 'li(true)']);
+ }
+ );
- clickFn = spyOn(scope, 'someAction');
+ they('should not bind to key events if there is existing `ng-$prop`',
+ ['keydown', 'keypress', 'keyup'], function(eventName) {
+ scope.onKeyEvent = jasmine.createSpy('onKeyEvent');
+ compileElement('
');
- var divElement = elements.find('div');
- var liElement = elements.find('li');
+ element.triggerHandler({type: eventName, keyCode: 13});
+ element.triggerHandler({type: eventName, keyCode: 32});
- divElement.triggerHandler({type: 'keydown', which: 32});
- liElement.triggerHandler({type: 'keydown', which: 32});
+ expect(scope.onClick).not.toHaveBeenCalled();
+ expect(scope.onKeyEvent).toHaveBeenCalledTimes(2);
+ }
+ );
- expect(clickFn).toHaveBeenCalledWith('div');
- expect(clickFn).toHaveBeenCalledWith('li');
- });
+ it('should update bindings when keydown is handled', function() {
+ scope.count = 0;
+ compileElement('Count: {{ count }}
');
- it('should not bind to key events if there is existing ng-keydown', function() {
- scope.onClick = jasmine.createSpy('onClick');
- scope.onKeydown = jasmine.createSpy('onKeydown');
+ expect(element.text()).toBe('Count: 0');
- var tmpl = '';
- compileElement(tmpl);
+ element.triggerHandler({type: 'keydown', keyCode: 13});
+ expect(element.text()).toBe('Count: 1');
element.triggerHandler({type: 'keydown', keyCode: 32});
-
- expect(scope.onKeydown).toHaveBeenCalled();
- expect(scope.onClick).not.toHaveBeenCalled();
+ expect(element.text()).toBe('Count: 2');
});
- it('should not bind to key events if there is existing ng-keypress', function() {
- scope.onClick = jasmine.createSpy('onClick');
- scope.onKeypress = jasmine.createSpy('onKeypress');
-
- var tmpl = '';
- compileElement(tmpl);
+ it('should pass `$event` to `ng-click` handler as local', function() {
+ compileElement('{{ event.type }}{{ event.keyCode }}
');
+ expect(element.text()).toBe('');
- element.triggerHandler({type: 'keypress', keyCode: 32});
+ element.triggerHandler({type: 'keydown', keyCode: 13});
+ expect(element.text()).toBe('keydown13');
- expect(scope.onKeypress).toHaveBeenCalled();
- expect(scope.onClick).not.toHaveBeenCalled();
+ element.triggerHandler({type: 'keydown', keyCode: 32});
+ expect(element.text()).toBe('keydown32');
});
- it('should not bind to key events if there is existing ng-keyup', function() {
- scope.onClick = jasmine.createSpy('onClick');
- scope.onKeyup = jasmine.createSpy('onKeyup');
-
- var tmpl = '';
- compileElement(tmpl);
+ it('should not bind keydown to natively interactive elements', function() {
+ compileElement('');
- element.triggerHandler({type: 'keyup', keyCode: 32});
+ element.triggerHandler({type: 'keydown', keyCode: 13});
+ element.triggerHandler({type: 'keydown', keyCode: 32});
- expect(scope.onKeyup).toHaveBeenCalled();
expect(scope.onClick).not.toHaveBeenCalled();
});
-
- it('should update bindings when keydown is handled', function() {
- compileElement('{{text}}
');
- expect(element.text()).toBe('');
- spyOn(scope.$root, '$digest').and.callThrough();
- element.triggerHandler({ type: 'keydown', keyCode: 13 });
- expect(element.text()).toBe('clicked!');
- expect(scope.$root.$digest).toHaveBeenCalledOnce();
- });
-
- it('should pass $event to ng-click handler as local', function() {
- compileElement('{{event.type}}' +
- '{{event.keyCode}}
');
- expect(element.text()).toBe('');
- element.triggerHandler({ type: 'keydown', keyCode: 13 });
- expect(element.text()).toBe('keydown13');
- });
-
- it('should not bind keydown to natively interactive elements', function() {
- compileElement('');
- expect(element.text()).toBe('');
- element.triggerHandler({ type: 'keydown', keyCode: 13 });
- expect(element.text()).toBe('');
- });
});
describe('actions when bindRoleForClick is set to false', function() {