Skip to content

Commit 1bdf02e

Browse files
committed
Limit failures in non-interactive interacts to keyboard, mouse and focus event handler types
1 parent b15b7f8 commit 1bdf02e

File tree

4 files changed

+31
-122
lines changed

4 files changed

+31
-122
lines changed

__tests__/src/rules/no-noninteractive-element-interactions-test.js

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const alwaysValid = [
8484
{ code: '<big onClick={() => {}} />;' },
8585
{ code: '<blink onClick={() => {}} />;' },
8686
{ code: '<body onClick={() => {}} />;' },
87+
{ code: '<body onLoad={() => {}} />;' },
8788
{ code: '<canvas onClick={() => {}} />;' },
8889
{ code: '<center onClick={() => {}} />;' },
8990
{ code: '<cite onClick={() => {}} />;' },
@@ -107,12 +108,15 @@ const alwaysValid = [
107108
{ code: '<em onClick={() => {}} />;' },
108109
{ code: '<embed onClick={() => {}} />;' },
109110
{ code: '<font onClick={() => {}} />;' },
111+
{ code: '<font onSubmit={() => {}} />;' },
110112
{ code: '<frameset onClick={() => {}} />;' },
111113
{ code: '<head onClick={() => {}} />;' },
112114
{ code: '<header onClick={() => {}} />;' },
113115
{ code: '<hgroup onClick={() => {}} />;' },
114116
{ code: '<html onClick={() => {}} />;' },
115117
{ code: '<i onClick={() => {}} />;' },
118+
{ code: '<iframe onLoad={() => {}} />;' },
119+
{ code: '<img onLoad={() => {}} />;' },
116120
{ code: '<ins onClick={() => {}} />;' },
117121
{ code: '<kbd onClick={() => {}} />;' },
118122
{ code: '<keygen onClick={() => {}} />;' },
@@ -289,6 +293,13 @@ const neverValid = [
289293
{ code: '<div role="term" onClick={() => {}} />;', errors: [expectedError] },
290294
{ code: '<div role="timer" onClick={() => {}} />;', errors: [expectedError] },
291295
{ code: '<div role="tooltip" onClick={() => {}} />;', errors: [expectedError] },
296+
// Handlers
297+
{ code: '<div role="article" onKeyDown={() => {}} />;', errors: [expectedError] },
298+
{ code: '<div role="article" onKeyPress={() => {}} />;', errors: [expectedError] },
299+
{ code: '<div role="article" onKeyUp={() => {}} />;', errors: [expectedError] },
300+
{ code: '<div role="article" onClick={() => {}} />;', errors: [expectedError] },
301+
{ code: '<div role="article" onMouseDown={() => {}} />;', errors: [expectedError] },
302+
{ code: '<div role="article" onMouseUp={() => {}} />;', errors: [expectedError] },
292303
];
293304

294305
const recommendedOptions =
@@ -365,13 +376,6 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
365376
.map(parserOptionsMapper),
366377
invalid: [
367378
...neverValid,
368-
// All the possible handlers
369-
{ code: '<div role="article" onKeyDown={() => {}} />;', errors: [expectedError] },
370-
{ code: '<div role="article" onKeyPress={() => {}} />;', errors: [expectedError] },
371-
{ code: '<div role="article" onKeyUp={() => {}} />;', errors: [expectedError] },
372-
{ code: '<div role="article" onClick={() => {}} />;', errors: [expectedError] },
373-
{ code: '<div role="article" onMouseDown={() => {}} />;', errors: [expectedError] },
374-
{ code: '<div role="article" onMouseUp={() => {}} />;', errors: [expectedError] },
375379
]
376380
.map(ruleOptionsMapperFactory(recommendedOptions))
377381
.map(parserOptionsMapper),
@@ -384,21 +388,8 @@ ruleTester.run(`${ruleName}:strict`, rule, {
384388
invalid: [
385389
...neverValid,
386390
// All the possible handlers
387-
{ code: '<div role="article" onCopy={() => {}} />;', errors: [expectedError] },
388-
{ code: '<div role="article" onCut={() => {}} />;', errors: [expectedError] },
389-
{ code: '<div role="article" onPaste={() => {}} />;', errors: [expectedError] },
390-
{ code: '<div role="article" onCompositionEnd={() => {}} />;', errors: [expectedError] },
391-
{ code: '<div role="article" onCompositionStart={() => {}} />;', errors: [expectedError] },
392-
{ code: '<div role="article" onCompositionUpdate={() => {}} />;', errors: [expectedError] },
393-
{ code: '<div role="article" onKeyDown={() => {}} />;', errors: [expectedError] },
394-
{ code: '<div role="article" onKeyPress={() => {}} />;', errors: [expectedError] },
395-
{ code: '<div role="article" onKeyUp={() => {}} />;', errors: [expectedError] },
396391
{ code: '<div role="article" onFocus={() => {}} />;', errors: [expectedError] },
397392
{ code: '<div role="article" onBlur={() => {}} />;', errors: [expectedError] },
398-
{ code: '<div role="article" onChange={() => {}} />;', errors: [expectedError] },
399-
{ code: '<div role="article" onInput={() => {}} />;', errors: [expectedError] },
400-
{ code: '<div role="article" onSubmit={() => {}} />;', errors: [expectedError] },
401-
{ code: '<div role="article" onClick={() => {}} />;', errors: [expectedError] },
402393
{ code: '<div role="article" onContextMenu={() => {}} />;', errors: [expectedError] },
403394
{ code: '<div role="article" onDblClick={() => {}} />;', errors: [expectedError] },
404395
{ code: '<div role="article" onDoubleClick={() => {}} />;', errors: [expectedError] },
@@ -410,48 +401,10 @@ ruleTester.run(`${ruleName}:strict`, rule, {
410401
{ code: '<div role="article" onDragOver={() => {}} />;', errors: [expectedError] },
411402
{ code: '<div role="article" onDragStart={() => {}} />;', errors: [expectedError] },
412403
{ code: '<div role="article" onDrop={() => {}} />;', errors: [expectedError] },
413-
{ code: '<div role="article" onMouseDown={() => {}} />;', errors: [expectedError] },
414404
{ code: '<div role="article" onMouseEnter={() => {}} />;', errors: [expectedError] },
415405
{ code: '<div role="article" onMouseLeave={() => {}} />;', errors: [expectedError] },
416406
{ code: '<div role="article" onMouseMove={() => {}} />;', errors: [expectedError] },
417407
{ code: '<div role="article" onMouseOut={() => {}} />;', errors: [expectedError] },
418408
{ code: '<div role="article" onMouseOver={() => {}} />;', errors: [expectedError] },
419-
{ code: '<div role="article" onMouseUp={() => {}} />;', errors: [expectedError] },
420-
{ code: '<div role="article" onSelect={() => {}} />;', errors: [expectedError] },
421-
{ code: '<div role="article" onTouchCancel={() => {}} />;', errors: [expectedError] },
422-
{ code: '<div role="article" onTouchEnd={() => {}} />;', errors: [expectedError] },
423-
{ code: '<div role="article" onTouchMove={() => {}} />;', errors: [expectedError] },
424-
{ code: '<div role="article" onTouchStart={() => {}} />;', errors: [expectedError] },
425-
{ code: '<div role="article" onScroll={() => {}} />;', errors: [expectedError] },
426-
{ code: '<div role="article" onWheel={() => {}} />;', errors: [expectedError] },
427-
{ code: '<div role="article" onAbort={() => {}} />;', errors: [expectedError] },
428-
{ code: '<div role="article" onCanPlay={() => {}} />;', errors: [expectedError] },
429-
{ code: '<div role="article" onCanPlayThrough={() => {}} />;', errors: [expectedError] },
430-
{ code: '<div role="article" onDurationChange={() => {}} />;', errors: [expectedError] },
431-
{ code: '<div role="article" onEmptied={() => {}} />;', errors: [expectedError] },
432-
{ code: '<div role="article" onEncrypted={() => {}} />;', errors: [expectedError] },
433-
{ code: '<div role="article" onEnded={() => {}} />;', errors: [expectedError] },
434-
{ code: '<div role="article" onError={() => {}} />;', errors: [expectedError] },
435-
{ code: '<div role="article" onLoadedData={() => {}} />;', errors: [expectedError] },
436-
{ code: '<div role="article" onLoadedMetadata={() => {}} />;', errors: [expectedError] },
437-
{ code: '<div role="article" onLoadStart={() => {}} />;', errors: [expectedError] },
438-
{ code: '<div role="article" onPause={() => {}} />;', errors: [expectedError] },
439-
{ code: '<div role="article" onPlay={() => {}} />;', errors: [expectedError] },
440-
{ code: '<div role="article" onPlaying={() => {}} />;', errors: [expectedError] },
441-
{ code: '<div role="article" onProgress={() => {}} />;', errors: [expectedError] },
442-
{ code: '<div role="article" onRateChange={() => {}} />;', errors: [expectedError] },
443-
{ code: '<div role="article" onSeeked={() => {}} />;', errors: [expectedError] },
444-
{ code: '<div role="article" onSeeking={() => {}} />;', errors: [expectedError] },
445-
{ code: '<div role="article" onStalled={() => {}} />;', errors: [expectedError] },
446-
{ code: '<div role="article" onSuspend={() => {}} />;', errors: [expectedError] },
447-
{ code: '<div role="article" onTimeUpdate={() => {}} />;', errors: [expectedError] },
448-
{ code: '<div role="article" onVolumeChange={() => {}} />;', errors: [expectedError] },
449-
{ code: '<div role="article" onWaiting={() => {}} />;', errors: [expectedError] },
450-
{ code: '<div role="article" onLoad={() => {}} />;', errors: [expectedError] },
451-
{ code: '<div role="article" onError={() => {}} />;', errors: [expectedError] },
452-
{ code: '<div role="article" onAnimationStart={() => {}} />;', errors: [expectedError] },
453-
{ code: '<div role="article" onAnimationEnd={() => {}} />;', errors: [expectedError] },
454-
{ code: '<div role="article" onAnimationIteration={() => {}} />;', errors: [expectedError] },
455-
{ code: '<div role="article" onTransitionEnd={() => {}} />;', errors: [expectedError] },
456409
].map(parserOptionsMapper),
457410
});

__tests__/src/rules/no-static-element-interactions-test.js

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const alwaysValid = [
7474
{ code: '<a onClick={() => void 0} href="http://x.y.z" tabIndex="0" />' },
7575
{ code: '<audio onClick={() => {}} />;' },
7676
{ code: '<form onClick={() => {}} />;' },
77+
{ code: '<form onSubmit={() => {}} />;' },
7778
/* HTML elements attributed with an interactive role */
7879
{ code: '<div role="button" onClick={() => {}} />;' },
7980
{ code: '<div role="checkbox" onClick={() => {}} />;' },
@@ -289,6 +290,13 @@ const neverValid = [
289290
{ code: '<var onClick={() => {}} />;', errors: [expectedError] },
290291
{ code: '<wbr onClick={() => {}} />;', errors: [expectedError] },
291292
{ code: '<xmp onClick={() => {}} />;', errors: [expectedError] },
293+
// Handlers
294+
{ code: '<div onKeyDown={() => {}} />;', errors: [expectedError] },
295+
{ code: '<div onKeyPress={() => {}} />;', errors: [expectedError] },
296+
{ code: '<div onKeyUp={() => {}} />;', errors: [expectedError] },
297+
{ code: '<div onClick={() => {}} />;', errors: [expectedError] },
298+
{ code: '<div onMouseDown={() => {}} />;', errors: [expectedError] },
299+
{ code: '<div onMouseUp={() => {}} />;', errors: [expectedError] },
292300
];
293301

294302
const recommendedOptions =
@@ -365,13 +373,6 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
365373
.map(parserOptionsMapper),
366374
invalid: [
367375
...neverValid,
368-
// All the possible handlers
369-
{ code: '<div onKeyDown={() => {}} />;', errors: [expectedError] },
370-
{ code: '<div onKeyPress={() => {}} />;', errors: [expectedError] },
371-
{ code: '<div onKeyUp={() => {}} />;', errors: [expectedError] },
372-
{ code: '<div onClick={() => {}} />;', errors: [expectedError] },
373-
{ code: '<div onMouseDown={() => {}} />;', errors: [expectedError] },
374-
{ code: '<div onMouseUp={() => {}} />;', errors: [expectedError] },
375376
]
376377
.map(ruleOptionsMapperFactory(recommendedOptions))
377378
.map(parserOptionsMapper),
@@ -384,21 +385,6 @@ ruleTester.run(`${ruleName}:strict`, rule, {
384385
invalid: [
385386
...neverValid,
386387
// All the possible handlers
387-
{ code: '<div onCopy={() => {}} />;', errors: [expectedError] },
388-
{ code: '<div onCut={() => {}} />;', errors: [expectedError] },
389-
{ code: '<div onPaste={() => {}} />;', errors: [expectedError] },
390-
{ code: '<div onCompositionEnd={() => {}} />;', errors: [expectedError] },
391-
{ code: '<div onCompositionStart={() => {}} />;', errors: [expectedError] },
392-
{ code: '<div onCompositionUpdate={() => {}} />;', errors: [expectedError] },
393-
{ code: '<div onKeyDown={() => {}} />;', errors: [expectedError] },
394-
{ code: '<div onKeyPress={() => {}} />;', errors: [expectedError] },
395-
{ code: '<div onKeyUp={() => {}} />;', errors: [expectedError] },
396-
{ code: '<div onFocus={() => {}} />;', errors: [expectedError] },
397-
{ code: '<div onBlur={() => {}} />;', errors: [expectedError] },
398-
{ code: '<div onChange={() => {}} />;', errors: [expectedError] },
399-
{ code: '<div onInput={() => {}} />;', errors: [expectedError] },
400-
{ code: '<div onSubmit={() => {}} />;', errors: [expectedError] },
401-
{ code: '<div onClick={() => {}} />;', errors: [expectedError] },
402388
{ code: '<div onContextMenu={() => {}} />;', errors: [expectedError] },
403389
{ code: '<div onDblClick={() => {}} />;', errors: [expectedError] },
404390
{ code: '<div onDoubleClick={() => {}} />;', errors: [expectedError] },
@@ -410,48 +396,10 @@ ruleTester.run(`${ruleName}:strict`, rule, {
410396
{ code: '<div onDragOver={() => {}} />;', errors: [expectedError] },
411397
{ code: '<div onDragStart={() => {}} />;', errors: [expectedError] },
412398
{ code: '<div onDrop={() => {}} />;', errors: [expectedError] },
413-
{ code: '<div onMouseDown={() => {}} />;', errors: [expectedError] },
414399
{ code: '<div onMouseEnter={() => {}} />;', errors: [expectedError] },
415400
{ code: '<div onMouseLeave={() => {}} />;', errors: [expectedError] },
416401
{ code: '<div onMouseMove={() => {}} />;', errors: [expectedError] },
417402
{ code: '<div onMouseOut={() => {}} />;', errors: [expectedError] },
418403
{ code: '<div onMouseOver={() => {}} />;', errors: [expectedError] },
419-
{ code: '<div onMouseUp={() => {}} />;', errors: [expectedError] },
420-
{ code: '<div onSelect={() => {}} />;', errors: [expectedError] },
421-
{ code: '<div onTouchCancel={() => {}} />;', errors: [expectedError] },
422-
{ code: '<div onTouchEnd={() => {}} />;', errors: [expectedError] },
423-
{ code: '<div onTouchMove={() => {}} />;', errors: [expectedError] },
424-
{ code: '<div onTouchStart={() => {}} />;', errors: [expectedError] },
425-
{ code: '<div onScroll={() => {}} />;', errors: [expectedError] },
426-
{ code: '<div onWheel={() => {}} />;', errors: [expectedError] },
427-
{ code: '<div onAbort={() => {}} />;', errors: [expectedError] },
428-
{ code: '<div onCanPlay={() => {}} />;', errors: [expectedError] },
429-
{ code: '<div onCanPlayThrough={() => {}} />;', errors: [expectedError] },
430-
{ code: '<div onDurationChange={() => {}} />;', errors: [expectedError] },
431-
{ code: '<div onEmptied={() => {}} />;', errors: [expectedError] },
432-
{ code: '<div onEncrypted={() => {}} />;', errors: [expectedError] },
433-
{ code: '<div onEnded={() => {}} />;', errors: [expectedError] },
434-
{ code: '<div onError={() => {}} />;', errors: [expectedError] },
435-
{ code: '<div onLoadedData={() => {}} />;', errors: [expectedError] },
436-
{ code: '<div onLoadedMetadata={() => {}} />;', errors: [expectedError] },
437-
{ code: '<div onLoadStart={() => {}} />;', errors: [expectedError] },
438-
{ code: '<div onPause={() => {}} />;', errors: [expectedError] },
439-
{ code: '<div onPlay={() => {}} />;', errors: [expectedError] },
440-
{ code: '<div onPlaying={() => {}} />;', errors: [expectedError] },
441-
{ code: '<div onProgress={() => {}} />;', errors: [expectedError] },
442-
{ code: '<div onRateChange={() => {}} />;', errors: [expectedError] },
443-
{ code: '<div onSeeked={() => {}} />;', errors: [expectedError] },
444-
{ code: '<div onSeeking={() => {}} />;', errors: [expectedError] },
445-
{ code: '<div onStalled={() => {}} />;', errors: [expectedError] },
446-
{ code: '<div onSuspend={() => {}} />;', errors: [expectedError] },
447-
{ code: '<div onTimeUpdate={() => {}} />;', errors: [expectedError] },
448-
{ code: '<div onVolumeChange={() => {}} />;', errors: [expectedError] },
449-
{ code: '<div onWaiting={() => {}} />;', errors: [expectedError] },
450-
{ code: '<div onLoad={() => {}} />;', errors: [expectedError] },
451-
{ code: '<div onError={() => {}} />;', errors: [expectedError] },
452-
{ code: '<div onAnimationStart={() => {}} />;', errors: [expectedError] },
453-
{ code: '<div onAnimationEnd={() => {}} />;', errors: [expectedError] },
454-
{ code: '<div onAnimationIteration={() => {}} />;', errors: [expectedError] },
455-
{ code: '<div onTransitionEnd={() => {}} />;', errors: [expectedError] },
456404
].map(parserOptionsMapper),
457405
});

src/rules/no-noninteractive-element-interactions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from 'aria-query';
1313
import {
1414
elementType,
15-
eventHandlers,
15+
eventHandlersByType,
1616
getPropValue,
1717
getProp,
1818
hasProp,
@@ -33,7 +33,11 @@ const errorMessage =
3333
'Non-interactive elements should not be assigned mouse or keyboard event listeners.';
3434

3535
const domElements = [...dom.keys()];
36-
const defaultInteractiveProps = eventHandlers;
36+
const defaultInteractiveProps = [
37+
...eventHandlersByType.focus,
38+
...eventHandlersByType.keyboard,
39+
...eventHandlersByType.mouse,
40+
];
3741
const schema = generateObjSchema({
3842
handlers: arraySchema,
3943
});

src/rules/no-static-element-interactions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from 'aria-query';
1414
import {
1515
elementType,
16-
eventHandlers,
16+
eventHandlersByType,
1717
getPropValue,
1818
getProp,
1919
hasProp,
@@ -34,7 +34,11 @@ const errorMessage =
3434
'Static HTML elements with event handlers require a role.';
3535

3636
const domElements = [...dom.keys()];
37-
const defaultInteractiveProps = eventHandlers;
37+
const defaultInteractiveProps = [
38+
...eventHandlersByType.focus,
39+
...eventHandlersByType.keyboard,
40+
...eventHandlersByType.mouse,
41+
];
3842
const schema = generateObjSchema({
3943
handlers: arraySchema,
4044
});

0 commit comments

Comments
 (0)