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

fix(ngAria.ngClick): restrict preventDefault on space / enter to non-… #16680

Merged
merged 3 commits into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/ngAria/aria.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
// Prevent the default browser behavior (e.g. scrolling when pressing spacebar) ...
if (nodeBlackList.indexOf(event.target.nodeName) === -1) {
// ... but only when the event is triggered by a non-interactive element
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would actually flip the last two comments around:

// If the event is triggered on a non-interactive element...
if (...) {
  // ...prevent the default browser behavior...
  ...

// See https://github.com/angular/angular.js/issues/16664
event.preventDefault();
}
scope.$apply(callback);
}

Expand Down
33 changes: 33 additions & 0 deletions test/ngAria/ariaSpec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

/* globals nodeBlackList false */

describe('$aria', function() {
var scope, $compile, element;

Expand Down Expand Up @@ -952,6 +954,37 @@ 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) {
var html = '<' + type + '>';

if (type === 'INPUT' || 'TYPE' === 'A') return html;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'TYPE' === 'A' part seems fishy 😛

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙀


return html + '</' + type + '>';
}

compileElement(
'<section>' +
'<div ng-click="onClick($event)">' + createHTML(elementType) + '</div>' +
'</section>');

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(
Expand Down