Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(ngAria): add button role to ngClick
Browse files Browse the repository at this point in the history
Closes #9254
Closes #10318
  • Loading branch information
Marcy Sutton authored and petebacondarwin committed Mar 2, 2015
1 parent 0f50b01 commit bb36507
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
10 changes: 6 additions & 4 deletions docs/content/guide/accessibility.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,13 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` if it isn't there
already.

For `ng-click`, keypress will also be bound to `div` and `li` elements. You can turn this
functionality on or off with the `bindKeypress` configuration option.
To fix widespread accessibility problems with `ng-click` on div elements, ngAria will dynamically
bind keypress by default as long as the element isn't an anchor, button, input or textarea.
You can turn this functionality on or off with the `bindKeypress` configuration option. ngAria
will also add the `button` role to communicate to users of assistive technologies.

For `ng-dblclick`, you must manually add `ng-keypress` to non-interactive elements such as `div`
or `taco-button` to enable keyboard access.
For `ng-dblclick`, you must still manually add `ng-keypress` and role to non-interactive elements such
as `div` or `taco-button` to enable keyboard access.

<h3>Example</h3>
```html
Expand Down
11 changes: 8 additions & 3 deletions src/ngAria/aria.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
*
* | Directive | Supported Attributes |
* |---------------------------------------------|----------------------------------------------------------------------------------------|
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required |
* | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
* | {@link ng.directive:ngShow ngShow} | aria-hidden |
* | {@link ng.directive:ngHide ngHide} | aria-hidden |
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event |
* | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
* | {@link module:ngMessages ngMessages} | aria-live |
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
*
* Find out more information about each directive by reading the
* {@link guide/accessibility ngAria Developer Guide}.
Expand Down Expand Up @@ -317,17 +317,22 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
return function(scope, elem, attr) {

var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];

function isNodeOneOf(elem, nodeTypeArray) {
if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
return true;
}
}
if (!elem.attr('role') && !isNodeOneOf(elem, nodeBlackList)) {
elem.attr('role', 'button');
}

if ($aria.config('tabindex') && !elem.attr('tabindex')) {
elem.attr('tabindex', 0);
}

if ($aria.config('bindKeypress') && !attr.ngKeypress && isNodeOneOf(elem, ['DIV', 'LI'])) {
if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) {
elem.on('keypress', function(event) {
if (event.keyCode === 32 || event.keyCode === 13) {
scope.$apply(callback);
Expand Down
10 changes: 10 additions & 0 deletions test/ngAria/ariaSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ describe('$aria', function() {
describe('roles for custom inputs', function() {
beforeEach(injectScopeAndCompiler);

it('should add missing role="button" to custom input', function() {
compileElement('<div ng-click="someFunction()"></div>');
expect(element.attr('role')).toBe('button');
});

it('should not add role="button" to anchor', function() {
compileElement('<a ng-click="someFunction()"></a>');
expect(element.attr('role')).not.toBe('button');
});

it('should add missing role="checkbox" to custom input', function() {
compileElement('<div type="checkbox" ng-model="val"></div>');
expect(element.attr('role')).toBe('checkbox');
Expand Down

0 comments on commit bb36507

Please sign in to comment.