From 0ee5a4a89bfb9cde81af69911e3896cda87b7bfb Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Wed, 10 Feb 2016 15:30:43 +0000 Subject: [PATCH 1/8] feat(ngAria[ngClick]): ngAria should make ng-click accessible for anchor, button elements Enhances ngAria to trigger ngClick for 'space' keypresses on anchor and button elements, and for 'enter' keypresses on anchor tags when there is no value for the href attribute. Closes https://github.com/angular/angular.js/issues/11053 --- src/ngAria/aria.js | 22 ++++++++++++++++++++++ test/ngAria/ariaSpec.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 036dd42b47de..93f3ef049309 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -377,6 +377,28 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { }); } } + + if ($aria.config('bindKeypress') && isNodeOneOf(elem, ['A', 'BUTTON'])) { + elem.on('keypress', function(event) { + var keyCode = event.which || event.keyCode; + + if (elem[0].nodeName==='A') { + var hasHref = elem.attr('href') != null && elem.attr('href') != ''; + if ((keyCode === 13 && !hasHref) || keyCode === 32) { + scope.$apply(callback); + } + } + else if (elem[0].nodeName==='BUTTON') { + if (keyCode === 32) { + scope.$apply(callback); + } + } + + function callback() { + fn(scope, { $event: event }); + } + }); + } }; } }; diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index 73b015f710c3..9bbe1dc78ce7 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -755,6 +755,35 @@ describe('$aria', function() { element.triggerHandler({ type: 'keypress', keyCode: 13 }); expect(element.text()).toBe(''); }); + + it('should bind keypress to anchor elements without href defined', function() { + compileElement('{{event.type}}{{event.keyCode}}'); + expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); + expect(element.text()).toBe('keypress13'); + }); + + it('should bind keypress to anchor elements with empty href defined', function() { + compileElement('{{event.type}}{{event.keyCode}}'); + expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); + expect(element.text()).toBe('keypress13'); + }); + + it('should not bind keypress to anchor elements with href defined', function() { + compileElement('{{event.type}}{{event.keyCode}}'); + expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); + expect(element.text()).toBe(''); + }); + + it('should bind space keypress to button elements', function() { + compileElement(''); + expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 32 }); + expect(element.text()).toBe('keypress32'); + }); + }); describe('actions when bindRoleForClick is set to false', function() { From 9a545621909a5928ac26ef2949f405d5ffb5e1dd Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Wed, 10 Feb 2016 16:24:23 +0000 Subject: [PATCH 2/8] feat(ngAria[ngClick]): accessibility for space and enter keypress --- src/ngAria/aria.js | 9 ++++----- test/ngAria/ariaSpec.js | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 93f3ef049309..eb2da73d898f 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -382,18 +382,17 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { elem.on('keypress', function(event) { var keyCode = event.which || event.keyCode; - if (elem[0].nodeName==='A') { - var hasHref = elem.attr('href') != null && elem.attr('href') != ''; + if (elem[0].nodeName === 'A') { + var hasHref = elem.attr('href') != null && elem.attr('href') !== ''; if ((keyCode === 13 && !hasHref) || keyCode === 32) { scope.$apply(callback); } - } - else if (elem[0].nodeName==='BUTTON') { + } else if (elem[0].nodeName === 'BUTTON') { if (keyCode === 32) { scope.$apply(callback); } } - + function callback() { fn(scope, { $event: event }); } diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index 9bbe1dc78ce7..b31c9bcc5d0f 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -776,7 +776,7 @@ describe('$aria', function() { element.triggerHandler({ type: 'keypress', keyCode: 13 }); expect(element.text()).toBe(''); }); - + it('should bind space keypress to button elements', function() { compileElement(''); expect(element.text()).toBe(''); From 9d2148f43a70628b6ae96ed6c2258d9d894f39ce Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Fri, 12 Feb 2016 03:33:18 +0000 Subject: [PATCH 3/8] feat(ngAria[ngClick]): button, anchor should treat keypress as click --- src/ngAria/aria.js | 30 ++++++++++++++---------------- test/ngAria/ariaSpec.js | 27 ++++++++++++--------------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index eb2da73d898f..9bc8e9a7bdf8 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -378,25 +378,23 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { } } - if ($aria.config('bindKeypress') && isNodeOneOf(elem, ['A', 'BUTTON'])) { - elem.on('keypress', function(event) { - var keyCode = event.which || event.keyCode; - - if (elem[0].nodeName === 'A') { - var hasHref = elem.attr('href') != null && elem.attr('href') !== ''; - if ((keyCode === 13 && !hasHref) || keyCode === 32) { - scope.$apply(callback); - } - } else if (elem[0].nodeName === 'BUTTON') { - if (keyCode === 32) { + if (elem[0].nodeName === 'A') { + if ($aria.config('bindRoleForClick') && !attr.href && !attr.xlinkHref && !attr.role) { + elem.attr('role', 'link'); + } + if($aria.config('bindKeypress')) { + elem.on('keypress', function(event) { + var keyCode = event.which || event.keyCode; + var hasHref = (attr.href || attr.xlinkHref); + if (keyCode === 32 && !hasHref && !attr.ngKeypress) { scope.$apply(callback); } - } - function callback() { - fn(scope, { $event: event }); - } - }); + function callback() { + fn(scope, { $event: event }); + } + }); + } } }; } diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index b31c9bcc5d0f..ec796e6b703e 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -756,34 +756,31 @@ describe('$aria', function() { expect(element.text()).toBe(''); }); - it('should bind keypress to anchor elements without href defined', function() { + it('should bind keypress to anchor elements when href is falsy', function() { compileElement('{{event.type}}{{event.keyCode}}'); - expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); - expect(element.text()).toBe('keypress13'); + expect(element.attr('role')).toBe('link'); }); - it('should bind keypress to anchor elements with empty href defined', function() { - compileElement('{{event.type}}{{event.keyCode}}'); + it('should bind keypress to anchor elements when href is falsy', function() { + compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); - expect(element.text()).toBe('keypress13'); + element.triggerHandler({ type: 'keypress', keyCode: 32 }); + expect(element.text()).toBe('keypress32'); }); - it('should not bind keypress to anchor elements with href defined', function() { - compileElement('{{event.type}}{{event.keyCode}}'); + it('should bind keypress to anchor elements when keypress is not falsy', function() { + compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 13 }); + element.triggerHandler({ type: 'keypress', keyCode: 32 }); expect(element.text()).toBe(''); }); - it('should bind space keypress to button elements', function() { - compileElement(''); + it('should not bind keypress to anchor elements when href is not falsy', function() { + compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 32 }); - expect(element.text()).toBe('keypress32'); + expect(element.text()).toBe(''); }); - }); describe('actions when bindRoleForClick is set to false', function() { From d7b0eb2ce649e6cadac724a4a5adb497323f0c8e Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Fri, 12 Feb 2016 12:53:10 +0000 Subject: [PATCH 4/8] feat(ngAria[ngClick]): fix javascript code style issue --- src/ngAria/aria.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 9bc8e9a7bdf8..3a3c32e05e50 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -382,7 +382,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { if ($aria.config('bindRoleForClick') && !attr.href && !attr.xlinkHref && !attr.role) { elem.attr('role', 'link'); } - if($aria.config('bindKeypress')) { + if ($aria.config('bindKeypress')) { elem.on('keypress', function(event) { var keyCode = event.which || event.keyCode; var hasHref = (attr.href || attr.xlinkHref); From 368899fc2e505a8e4b7f769b9e971c029fcbf5b0 Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Sat, 13 Feb 2016 14:33:13 +0000 Subject: [PATCH 5/8] feat(ngAria[ngClick]): bind to enter keypres --- src/ngAria/aria.js | 2 +- test/ngAria/ariaSpec.js | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 3a3c32e05e50..93cbbaf84c0d 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -386,7 +386,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { elem.on('keypress', function(event) { var keyCode = event.which || event.keyCode; var hasHref = (attr.href || attr.xlinkHref); - if (keyCode === 32 && !hasHref && !attr.ngKeypress) { + if ((keyCode === 32 || (keyCode === 13 && !hasHref)) && !attr.ngKeypress) { scope.$apply(callback); } diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index ec796e6b703e..b9fb5351a0a7 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -768,17 +768,26 @@ describe('$aria', function() { expect(element.text()).toBe('keypress32'); }); - it('should bind keypress to anchor elements when keypress is not falsy', function() { + it('should not bind keypress to anchor elements when keypress is not falsy', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 32 }); expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); + expect(element.text()).toBe(''); }); - it('should not bind keypress to anchor elements when href is not falsy', function() { + it('should bind SPACE keypress to anchor elements', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 32 }); + expect(element.text()).toBe('keypress32'); + }); + + it('should not bind ENTER keypress to anchor elements when href is not falsy', function() { + compileElement('{{event.type}}{{event.keyCode}}'); + expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); expect(element.text()).toBe(''); }); }); From 827845b3735e403577ca47b7be47493d60bcd524 Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Sat, 13 Feb 2016 15:05:43 +0000 Subject: [PATCH 6/8] feat(ngAria[ngClick]): aria should trigger click on anchor keypress --- src/ngAria/aria.js | 2 +- test/ngAria/ariaSpec.js | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 93cbbaf84c0d..288fbb114e3c 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -387,7 +387,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { var keyCode = event.which || event.keyCode; var hasHref = (attr.href || attr.xlinkHref); if ((keyCode === 32 || (keyCode === 13 && !hasHref)) && !attr.ngKeypress) { - scope.$apply(callback); + elem[0].click(); } function callback() { diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index b9fb5351a0a7..70d50885c75b 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -765,7 +765,7 @@ describe('$aria', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 32 }); - expect(element.text()).toBe('keypress32'); + expect(element.text()).toContain('click'); }); it('should not bind keypress to anchor elements when keypress is not falsy', function() { @@ -777,13 +777,6 @@ describe('$aria', function() { expect(element.text()).toBe(''); }); - it('should bind SPACE keypress to anchor elements', function() { - compileElement('{{event.type}}{{event.keyCode}}'); - expect(element.text()).toBe(''); - element.triggerHandler({ type: 'keypress', keyCode: 32 }); - expect(element.text()).toBe('keypress32'); - }); - it('should not bind ENTER keypress to anchor elements when href is not falsy', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); From 56d66b549ac56c22a656e76af20ae17d3b2ca5b7 Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Thu, 18 Feb 2016 02:45:10 +0000 Subject: [PATCH 7/8] feat(ngAria[ngClick]): anchor should treat keypress as click --- src/ngAria/aria.js | 6 +++--- test/ngAria/ariaSpec.js | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 288fbb114e3c..6baf556ff6b7 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -385,9 +385,9 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { if ($aria.config('bindKeypress')) { elem.on('keypress', function(event) { var keyCode = event.which || event.keyCode; - var hasHref = (attr.href || attr.xlinkHref); - if ((keyCode === 32 || (keyCode === 13 && !hasHref)) && !attr.ngKeypress) { - elem[0].click(); + var hasHref = attr.href || attr.xlinkHref; + if ((keyCode===13 || keyCode === 32) && !hasHref && !attr.ngKeypress) { + scope.$apply(callback); } function callback() { diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index 70d50885c75b..e547f8bd30cc 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -756,7 +756,7 @@ describe('$aria', function() { expect(element.text()).toBe(''); }); - it('should bind keypress to anchor elements when href is falsy', function() { + it('should apply role to anchor elements without href ', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.attr('role')).toBe('link'); }); @@ -765,7 +765,9 @@ describe('$aria', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 32 }); - expect(element.text()).toContain('click'); + expect(element.text()).toBe('keypress32'); + element.triggerHandler({ type: 'keypress', keyCode: 13 }); + expect(element.text()).toBe('keypress13'); }); it('should not bind keypress to anchor elements when keypress is not falsy', function() { @@ -777,9 +779,11 @@ describe('$aria', function() { expect(element.text()).toBe(''); }); - it('should not bind ENTER keypress to anchor elements when href is not falsy', function() { + it('should not bind keypress to anchor elements when href is not falsy', function() { compileElement('{{event.type}}{{event.keyCode}}'); expect(element.text()).toBe(''); + element.triggerHandler({ type: 'keypress', keyCode: 32 }); + expect(element.text()).toBe(''); element.triggerHandler({ type: 'keypress', keyCode: 13 }); expect(element.text()).toBe(''); }); From 7fd46db9ae71636efae3f0de0d2a32964003bc29 Mon Sep 17 00:00:00 2001 From: Lee Adcock Date: Thu, 18 Feb 2016 03:59:20 +0000 Subject: [PATCH 8/8] fix(ngAria): correct code style issue --- src/ngAria/aria.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 6baf556ff6b7..08a26e73fc7a 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -386,7 +386,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { elem.on('keypress', function(event) { var keyCode = event.which || event.keyCode; var hasHref = attr.href || attr.xlinkHref; - if ((keyCode===13 || keyCode === 32) && !hasHref && !attr.ngKeypress) { + if ((keyCode === 32 || keyCode === 13) && !hasHref && !attr.ngKeypress) { scope.$apply(callback); }