From 61b33543ff8e7f32464dec98a46bf0a35e9b03a4 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 6 Sep 2018 15:53:33 +0200 Subject: [PATCH] fix(ngAria.ngClick): preventDefault on space/enter only on non-interactive elements Fixes #16664 Closes #16680 --- src/ngAria/aria.js | 8 ++++++-- test/ngAria/ariaSpec.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/ngAria/aria.js b/src/ngAria/aria.js index 73e9e0733f9..cc7e481c558 100644 --- a/src/ngAria/aria.js +++ b/src/ngAria/aria.js @@ -389,8 +389,12 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { var keyCode = event.which || event.keyCode; if (keyCode === 13 || keyCode === 32) { - // Prevent the default browser behavior (e.g. scrolling when pressing spacebar). - event.preventDefault(); + // If the event is triggered on a non-interactive element ... + if (nodeBlackList.indexOf(event.target.nodeName) === -1) { + // ... prevent the default browser behavior (e.g. scrolling when pressing spacebar) + // See https://github.com/angular/angular.js/issues/16664 + event.preventDefault(); + } scope.$apply(callback); } diff --git a/test/ngAria/ariaSpec.js b/test/ngAria/ariaSpec.js index 11130b17430..e36fb9cc277 100644 --- a/test/ngAria/ariaSpec.js +++ b/test/ngAria/ariaSpec.js @@ -1,5 +1,7 @@ 'use strict'; +/* globals nodeBlackList false */ + describe('$aria', function() { var scope, $compile, element; @@ -952,6 +954,33 @@ describe('$aria', function() { expect(clickEvents).toEqual(['div(true)', 'li(true)', 'div(true)', 'li(true)']); }); + they('should not prevent default keyboard action if an interactive $type element' + + 'is nested inside ng-click', nodeBlackList, function(elementType) { + function createHTML(type) { + return '<' + type + '>'; + } + + compileElement( + '
' + + '
' + createHTML(elementType) + '
' + + '
'); + + var divElement = element.find('div'); + var interactiveElement = element.find(elementType); + + // Use browserTrigger because it supports event bubbling + // 13 Enter + browserTrigger(interactiveElement, 'keydown', {cancelable: true, bubbles: true, keyCode: 13}); + expect(clickEvents).toEqual([elementType.toLowerCase() + '(false)']); + + clickEvents = []; + + // 32 Space + browserTrigger(interactiveElement, 'keydown', {cancelable: true, bubbles: true, keyCode: 32}); + expect(clickEvents).toEqual([elementType.toLowerCase() + '(false)']); + } + ); + it('should trigger a click in browsers that provide `event.which` instead of `event.keyCode`', function() { compileElement(