Skip to content

Commit 4925ba8

Browse files
committed
[Fix] handle interactive/noninteractive changes from aria-query
1 parent e517937 commit 4925ba8

8 files changed

+62
-60
lines changed

__mocks__/genInteractives.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ const interactiveElementsMap = {
4545
'input[type="time"]': [{ prop: 'type', value: 'time' }],
4646
'input[type="url"]': [{ prop: 'type', value: 'url' }],
4747
'input[type="week"]': [{ prop: 'type', value: 'week' }],
48-
link: [{ prop: 'href', value: '#' }],
4948
menuitem: [],
5049
option: [],
5150
select: [],
51+
summary: [],
5252
// Whereas ARIA makes a distinction between cell and gridcell, the AXObject
5353
// treats them both as CellRole and since gridcell is interactive, we consider
5454
// cell interactive as well.
55-
// td: [],
55+
td: [],
5656
th: [],
5757
tr: [],
5858
textarea: [],
@@ -61,34 +61,38 @@ const interactiveElementsMap = {
6161

6262
const nonInteractiveElementsMap: {[string]: Array<{[string]: string}>} = {
6363
abbr: [],
64-
aside: [],
64+
address: [],
6565
article: [],
66+
aside: [],
6667
blockquote: [],
67-
body: [],
6868
br: [],
6969
caption: [],
70+
code: [],
7071
dd: [],
72+
del: [],
7173
details: [],
7274
dfn: [],
7375
dialog: [],
7476
dir: [],
7577
dl: [],
7678
dt: [],
79+
em: [],
7780
fieldset: [],
7881
figcaption: [],
7982
figure: [],
8083
footer: [],
8184
form: [],
82-
frame: [],
8385
h1: [],
8486
h2: [],
8587
h3: [],
8688
h4: [],
8789
h5: [],
8890
h6: [],
8991
hr: [],
92+
html: [],
9093
iframe: [],
9194
img: [],
95+
ins: [],
9296
label: [],
9397
legend: [],
9498
li: [],
@@ -107,20 +111,22 @@ const nonInteractiveElementsMap: {[string]: Array<{[string]: string}>} = {
107111
ruby: [],
108112
'section[aria-label]': [{ prop: 'aria-label' }],
109113
'section[aria-labelledby]': [{ prop: 'aria-labelledby' }],
114+
strong: [],
115+
sub: [],
116+
sup: [],
110117
table: [],
111118
tbody: [],
112-
td: [],
113119
tfoot: [],
114120
thead: [],
115121
time: [],
116122
ul: [],
117123
};
118124

119-
const indeterminantInteractiveElementsMap: { [key: string]: Array<any> } = fromEntries(domElements.map((name: string) => [name, []]));
125+
const indeterminantInteractiveElementsMap: { [key: string]: Array<any> } = fromEntries(domElements.map((name) => [name, []]));
120126

121127
Object.keys(interactiveElementsMap)
122128
.concat(Object.keys(nonInteractiveElementsMap))
123-
.forEach((name: string) => delete indeterminantInteractiveElementsMap[name]);
129+
.forEach((name) => delete indeterminantInteractiveElementsMap[name]);
124130

125131
const abstractRoles = roleNames.filter((role) => roles.get(role).abstract);
126132

__tests__/src/rules/control-has-associated-label-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ const alwaysValid = [
157157
{ code: '<section />' },
158158
{ code: '<table />' },
159159
{ code: '<tbody />' },
160-
{ code: '<td />' },
161160
{ code: '<tfoot />' },
162161
{ code: '<thead />' },
163162
{ code: '<time />' },
@@ -263,6 +262,7 @@ const neverValid = [
263262
{ code: '<menuitem />', errors: [expectedError] },
264263
{ code: '<option />', errors: [expectedError] },
265264
{ code: '<th />', errors: [expectedError] },
265+
{ code: '<td />', errors: [expectedError] },
266266
// Interactive Roles
267267
{ code: '<div role="button" />', errors: [expectedError] },
268268
{ code: '<div role="checkbox" />', errors: [expectedError] },

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const alwaysValid = [
6969
{ code: '<a onClick={() => void 0} href="http://x.y.z" />' },
7070
{ code: '<a onClick={() => void 0} href="http://x.y.z" tabIndex="0" />' },
7171
{ code: '<area onClick={() => {}} />;' },
72+
{ code: '<body onClick={() => {}} />;' },
7273
{ code: '<button onClick={() => void 0} className="foo" />' },
7374
{ code: '<menuitem onClick={() => {}} />;' },
7475
{ code: '<option onClick={() => void 0} className="foo" />' },
@@ -77,7 +78,6 @@ const alwaysValid = [
7778
{ code: '<tr onClick={() => {}} />;' },
7879
/* HTML elements with neither an interactive or non-interactive valence (static) */
7980
{ code: '<acronym onClick={() => {}} />;' },
80-
{ code: '<address onClick={() => {}} />;' },
8181
{ code: '<applet onClick={() => {}} />;' },
8282
{ code: '<audio onClick={() => {}} />;' },
8383
{ code: '<b onClick={() => {}} />;' },
@@ -90,13 +90,11 @@ const alwaysValid = [
9090
{ code: '<canvas onClick={() => {}} />;' },
9191
{ code: '<center onClick={() => {}} />;' },
9292
{ code: '<cite onClick={() => {}} />;' },
93-
{ code: '<code onClick={() => {}} />;' },
9493
{ code: '<col onClick={() => {}} />;' },
9594
{ code: '<colgroup onClick={() => {}} />;' },
9695
{ code: '<content onClick={() => {}} />;' },
9796
{ code: '<data onClick={() => {}} />;' },
9897
{ code: '<datalist onClick={() => {}} />;' },
99-
{ code: '<del onClick={() => {}} />;' },
10098
{ code: '<div />;' },
10199
{ code: '<div className="foo" />;' },
102100
{ code: '<div className="foo" {...props} />;' },
@@ -107,7 +105,6 @@ const alwaysValid = [
107105
{ code: '<div onClick={() => void 0} {...props} />;' },
108106
{ code: '<div onClick={null} />;' },
109107
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} />;' },
110-
{ code: '<em onClick={() => {}} />;' },
111108
{ code: '<embed onClick={() => {}} />;' },
112109
{ code: '<font onClick={() => {}} />;' },
113110
{ code: '<font onSubmit={() => {}} />;' },
@@ -121,11 +118,11 @@ const alwaysValid = [
121118
</form>
122119
`,
123120
},
121+
{ code: '<frame onClick={() => {}} />;' },
124122
{ code: '<frameset onClick={() => {}} />;' },
125123
{ code: '<head onClick={() => {}} />;' },
126124
{ code: '<header onClick={() => {}} />;' },
127125
{ code: '<hgroup onClick={() => {}} />;' },
128-
{ code: '<html onClick={() => {}} />;' },
129126
{ code: '<i onClick={() => {}} />;' },
130127
{ code: '<iframe onLoad={() => {}} />;' },
131128
{
@@ -153,7 +150,6 @@ const alwaysValid = [
153150
/>
154151
`,
155152
},
156-
{ code: '<ins onClick={() => {}} />;' },
157153
{ code: '<kbd onClick={() => {}} />;' },
158154
{ code: '<keygen onClick={() => {}} />;' },
159155
{ code: '<link onClick={() => {}} />;' },
@@ -178,14 +174,12 @@ const alwaysValid = [
178174
{ code: '<spacer onClick={() => {}} />;' },
179175
{ code: '<span onClick={() => {}} />;' },
180176
{ code: '<strike onClick={() => {}} />;' },
181-
{ code: '<strong onClick={() => {}} />;' },
182177
{ code: '<style onClick={() => {}} />;' },
183-
{ code: '<sub onClick={() => {}} />;' },
184178
{ code: '<summary onClick={() => {}} />;' },
185-
{ code: '<sup onClick={() => {}} />;' },
186179
{ code: '<th onClick={() => {}} />;' },
187180
{ code: '<title onClick={() => {}} />;' },
188181
{ code: '<track onClick={() => {}} />;' },
182+
{ code: '<td onClick={() => {}} />;' },
189183
{ code: '<tt onClick={() => {}} />;' },
190184
{ code: '<u onClick={() => {}} />;' },
191185
{ code: '<var onClick={() => {}} />;' },
@@ -286,33 +280,37 @@ const alwaysValid = [
286280
const neverValid = [
287281
/* HTML elements with an inherent, non-interactive role */
288282
{ code: '<main onClick={() => void 0} />;', errors: [expectedError] },
283+
{ code: '<address onClick={() => {}} />;', errors: [expectedError] },
289284
{ code: '<article onClick={() => {}} />;', errors: [expectedError] },
290285
{ code: '<aside onClick={() => {}} />;', errors: [expectedError] },
291286
{ code: '<blockquote onClick={() => {}} />;', errors: [expectedError] },
292-
{ code: '<body onClick={() => {}} />;', errors: [expectedError] },
293287
{ code: '<br onClick={() => {}} />;', errors: [expectedError] },
294288
{ code: '<caption onClick={() => {}} />;', errors: [expectedError] },
289+
{ code: '<code onClick={() => {}} />;', errors: [expectedError] },
295290
{ code: '<dd onClick={() => {}} />;', errors: [expectedError] },
291+
{ code: '<del onClick={() => {}} />;', errors: [expectedError] },
296292
{ code: '<details onClick={() => {}} />;', errors: [expectedError] },
297293
{ code: '<dfn onClick={() => {}} />;', errors: [expectedError] },
298294
{ code: '<dl onClick={() => {}} />;', errors: [expectedError] },
299295
{ code: '<dir onClick={() => {}} />;', errors: [expectedError] },
300296
{ code: '<dt onClick={() => {}} />;', errors: [expectedError] },
297+
{ code: '<em onClick={() => {}} />;', errors: [expectedError] },
301298
{ code: '<fieldset onClick={() => {}} />;', errors: [expectedError] },
302299
{ code: '<figcaption onClick={() => {}} />;', errors: [expectedError] },
303300
{ code: '<figure onClick={() => {}} />;', errors: [expectedError] },
304301
{ code: '<footer onClick={() => {}} />;', errors: [expectedError] },
305302
{ code: '<form onClick={() => {}} />;', errors: [expectedError] },
306-
{ code: '<frame onClick={() => {}} />;', errors: [expectedError] },
307303
{ code: '<h1 onClick={() => {}} />;', errors: [expectedError] },
308304
{ code: '<h2 onClick={() => {}} />;', errors: [expectedError] },
309305
{ code: '<h3 onClick={() => {}} />;', errors: [expectedError] },
310306
{ code: '<h4 onClick={() => {}} />;', errors: [expectedError] },
311307
{ code: '<h5 onClick={() => {}} />;', errors: [expectedError] },
312308
{ code: '<h6 onClick={() => {}} />;', errors: [expectedError] },
313309
{ code: '<hr onClick={() => {}} />;', errors: [expectedError] },
310+
{ code: '<html onClick={() => {}} />;', errors: [expectedError] },
314311
{ code: '<iframe onClick={() => {}} />;', errors: [expectedError] },
315312
{ code: '<img onClick={() => {}} />;', errors: [expectedError] },
313+
{ code: '<ins onClick={() => {}} />;', errors: [expectedError] },
316314
{ code: '<label onClick={() => {}} />;', errors: [expectedError] },
317315
{ code: '<legend onClick={() => {}} />;', errors: [expectedError] },
318316
{ code: '<li onClick={() => {}} />;', errors: [expectedError] },
@@ -330,9 +328,11 @@ const neverValid = [
330328
{ code: '<ruby onClick={() => {}} />;', errors: [expectedError] },
331329
{ code: '<section onClick={() => {}} aria-label="Aardvark" />;', errors: [expectedError] },
332330
{ code: '<section onClick={() => {}} aria-labelledby="js_1" />;', errors: [expectedError] },
331+
{ code: '<strong onClick={() => {}} />;', errors: [expectedError] },
332+
{ code: '<sub onClick={() => {}} />;', errors: [expectedError] },
333+
{ code: '<sup onClick={() => {}} />;', errors: [expectedError] },
333334
{ code: '<table onClick={() => {}} />;', errors: [expectedError] },
334335
{ code: '<tbody onClick={() => {}} />;', errors: [expectedError] },
335-
{ code: '<td onClick={() => {}} />;', errors: [expectedError] },
336336
{ code: '<tfoot onClick={() => {}} />;', errors: [expectedError] },
337337
{ code: '<thead onClick={() => {}} />;', errors: [expectedError] },
338338
{ code: '<time onClick={() => {}} />;', errors: [expectedError] },

__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js

+16-16
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ const alwaysValid = [
5050
{ code: '<area role="button" />;' },
5151
{ code: '<area role="menuitem" />;' },
5252
{ code: '<button className="foo" role="button" />' },
53+
{ code: '<body role="button" />;' },
54+
{ code: '<frame role="button" />;' },
55+
{ code: '<td role="button" />;' },
56+
{ code: '<frame role="menuitem" />;' },
57+
{ code: '<td role="menuitem" />;' },
5358
/* All flavors of input */
5459
{ code: '<input role="button" />' },
5560
{ code: '<input type="button" role="button" />' },
@@ -154,7 +159,6 @@ const alwaysValid = [
154159
{ code: '<tr role="listitem" />;' },
155160
/* HTML elements with neither an interactive or non-interactive valence (static) */
156161
{ code: '<acronym role="button" />;' },
157-
{ code: '<address role="button" />;' },
158162
{ code: '<applet role="button" />;' },
159163
{ code: '<audio role="button" />;' },
160164
{ code: '<b role="button" />;' },
@@ -166,13 +170,11 @@ const alwaysValid = [
166170
{ code: '<canvas role="button" />;' },
167171
{ code: '<center role="button" />;' },
168172
{ code: '<cite role="button" />;' },
169-
{ code: '<code role="button" />;' },
170173
{ code: '<col role="button" />;' },
171174
{ code: '<colgroup role="button" />;' },
172175
{ code: '<content role="button" />;' },
173176
{ code: '<data role="button" />;' },
174177
{ code: '<datalist role="button" />;' },
175-
{ code: '<del role="button" />;' },
176178
{ code: '<div role="button" />;' },
177179
{ code: '<div className="foo" role="button" />;' },
178180
{ code: '<div className="foo" {...props} role="button" />;' },
@@ -182,16 +184,13 @@ const alwaysValid = [
182184
{ code: '<div role={undefined} role="button" />;' },
183185
{ code: '<div {...props} role="button" />;' },
184186
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} role="button" />;' },
185-
{ code: '<em role="button" />;' },
186187
{ code: '<embed role="button" />;' },
187188
{ code: '<font role="button" />;' },
188189
{ code: '<frameset role="button" />;' },
189190
{ code: '<head role="button" />;' },
190191
{ code: '<header role="button" />;' },
191192
{ code: '<hgroup role="button" />;' },
192-
{ code: '<html role="button" />;' },
193193
{ code: '<i role="button" />;' },
194-
{ code: '<ins role="button" />;' },
195194
{ code: '<kbd role="button" />;' },
196195
{ code: '<keygen role="button" />;' },
197196
{ code: '<link role="button" />;' },
@@ -214,11 +213,8 @@ const alwaysValid = [
214213
{ code: '<spacer role="button" />;' },
215214
{ code: '<span role="button" />;' },
216215
{ code: '<strike role="button" />;' },
217-
{ code: '<strong role="button" />;' },
218216
{ code: '<style role="button" />;' },
219-
{ code: '<sub role="button" />;' },
220217
{ code: '<summary role="button" />;' },
221-
{ code: '<sup role="button" />;' },
222218
{ code: '<th role="button" />;' },
223219
{ code: '<title role="button" />;' },
224220
{ code: '<track role="button" />;' },
@@ -358,37 +354,41 @@ const alwaysValid = [
358354
const neverValid = [
359355
/* HTML elements with an inherent non-interactive role, assigned an
360356
* interactive role. */
361-
{ code: '<main role="button" />;', errors: [expectedError] },
357+
{ code: '<address role="button" />;', errors: [expectedError] },
362358
{ code: '<article role="button" />;', errors: [expectedError] },
363359
{ code: '<aside role="button" />;', errors: [expectedError] },
364360
{ code: '<blockquote role="button" />;', errors: [expectedError] },
365-
{ code: '<body role="button" />;', errors: [expectedError] },
366361
{ code: '<br role="button" />;', errors: [expectedError] },
367362
{ code: '<caption role="button" />;', errors: [expectedError] },
363+
{ code: '<code role="button" />;', errors: [expectedError] },
368364
{ code: '<dd role="button" />;', errors: [expectedError] },
365+
{ code: '<del role="button" />;', errors: [expectedError] },
369366
{ code: '<details role="button" />;', errors: [expectedError] },
367+
{ code: '<dfn role="button" />;', errors: [expectedError] },
370368
{ code: '<dir role="button" />;', errors: [expectedError] },
371369
{ code: '<dl role="button" />;', errors: [expectedError] },
372-
{ code: '<dfn role="button" />;', errors: [expectedError] },
373370
{ code: '<dt role="button" />;', errors: [expectedError] },
371+
{ code: '<em role="button" />;', errors: [expectedError] },
374372
{ code: '<fieldset role="button" />;', errors: [expectedError] },
375373
{ code: '<figcaption role="button" />;', errors: [expectedError] },
376374
{ code: '<figure role="button" />;', errors: [expectedError] },
377375
{ code: '<footer role="button" />;', errors: [expectedError] },
378376
{ code: '<form role="button" />;', errors: [expectedError] },
379-
{ code: '<frame role="button" />;', errors: [expectedError] },
380377
{ code: '<h1 role="button" />;', errors: [expectedError] },
381378
{ code: '<h2 role="button" />;', errors: [expectedError] },
382379
{ code: '<h3 role="button" />;', errors: [expectedError] },
383380
{ code: '<h4 role="button" />;', errors: [expectedError] },
384381
{ code: '<h5 role="button" />;', errors: [expectedError] },
385382
{ code: '<h6 role="button" />;', errors: [expectedError] },
386383
{ code: '<hr role="button" />;', errors: [expectedError] },
384+
{ code: '<html role="button" />;', errors: [expectedError] },
387385
{ code: '<iframe role="button" />;', errors: [expectedError] },
388386
{ code: '<img role="button" />;', errors: [expectedError] },
387+
{ code: '<ins role="button" />;', errors: [expectedError] },
389388
{ code: '<label role="button" />;', errors: [expectedError] },
390389
{ code: '<legend role="button" />;', errors: [expectedError] },
391390
{ code: '<li role="button" />;', errors: [expectedError] },
391+
{ code: '<main role="button" />;', errors: [expectedError] },
392392
{ code: '<mark role="button" />;', errors: [expectedError] },
393393
{ code: '<marquee role="button" />;', errors: [expectedError] },
394394
{ code: '<menu role="button" />;', errors: [expectedError] },
@@ -400,9 +400,11 @@ const neverValid = [
400400
{ code: '<pre role="button" />;', errors: [expectedError] },
401401
{ code: '<progress role="button" />;', errors: [expectedError] },
402402
{ code: '<ruby role="button" />;', errors: [expectedError] },
403+
{ code: '<strong role="button" />;', errors: [expectedError] },
404+
{ code: '<sub role="button" />;', errors: [expectedError] },
405+
{ code: '<sup role="button" />;', errors: [expectedError] },
403406
{ code: '<table role="button" />;', errors: [expectedError] },
404407
{ code: '<tbody role="button" />;', errors: [expectedError] },
405-
{ code: '<td role="button" />;', errors: [expectedError] },
406408
{ code: '<tfoot role="button" />;', errors: [expectedError] },
407409
{ code: '<thead role="button" />;', errors: [expectedError] },
408410
{ code: '<time role="button" />;', errors: [expectedError] },
@@ -417,7 +419,6 @@ const neverValid = [
417419
{ code: '<fieldset role="menuitem" />;', errors: [expectedError] },
418420
{ code: '<figure role="menuitem" />;', errors: [expectedError] },
419421
{ code: '<form role="menuitem" />;', errors: [expectedError] },
420-
{ code: '<frame role="menuitem" />;', errors: [expectedError] },
421422
{ code: '<h1 role="menuitem" />;', errors: [expectedError] },
422423
{ code: '<h2 role="menuitem" />;', errors: [expectedError] },
423424
{ code: '<h3 role="menuitem" />;', errors: [expectedError] },
@@ -432,7 +433,6 @@ const neverValid = [
432433
{ code: '<section role="button" aria-label="Aardvark" />;', errors: [expectedError] },
433434
{ code: '<table role="menuitem" />;', errors: [expectedError] },
434435
{ code: '<tbody role="menuitem" />;', errors: [expectedError] },
435-
{ code: '<td role="menuitem" />;', errors: [expectedError] },
436436
{ code: '<tfoot role="menuitem" />;', errors: [expectedError] },
437437
{ code: '<thead role="menuitem" />;', errors: [expectedError] },
438438
/* Custom components */

0 commit comments

Comments
 (0)