Skip to content

Commit 8fc6f6d

Browse files
committed
fix(template-no-redundant-role): lowercase role; add <select>→combobox mapping
Two changes. 1. Compare role tokens case-insensitively. ARIA role values are ASCII-case-insensitive (HTML-AAM inherits HTML's attribute-comparison semantics). Before: <body role="DOCUMENT"> was not flagged because "DOCUMENT" didn't match "document" in ROLE_TO_ELEMENTS. 2. Add 'combobox' → ['select'] mapping. <select> without `multiple` or `size > 1` has an implicit role of "combobox" per HTML-AAM §4.1. Before: <select role="combobox"> was silently accepted as a redundant role. Two new invalid tests cover the fixes.
1 parent 24882a3 commit 8fc6f6d

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

lib/rules/template-no-redundant-role.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const ROLE_TO_ELEMENTS = {
4545
button: ['button'],
4646
cell: ['td'],
4747
checkbox: ['input'],
48+
// <select> is a combobox by default (per HTML-AAM §4.1 — unless `multiple` or
49+
// a `size > 1` is set, in which case it's a listbox; both mappings are listed).
50+
combobox: ['select'],
4851
columnheader: ['th'],
4952
complementary: ['aside'],
5053
contentinfo: ['footer'],
@@ -125,7 +128,8 @@ module.exports = {
125128

126129
let roleValue;
127130
if (roleAttr.value && roleAttr.value.type === 'GlimmerTextNode') {
128-
roleValue = roleAttr.value.chars || '';
131+
// ARIA role tokens are compared ASCII-case-insensitively.
132+
roleValue = (roleAttr.value.chars || '').toLowerCase();
129133
} else {
130134
// Skip dynamic role values
131135
return;

tests/lib/rules/template-no-redundant-role.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,18 @@ hbsRuleTester.run('template-no-redundant-role', rule, {
243243
'<select name="color" id="color" multiple><option value="default-color">black</option></select>',
244244
errors: [{ message: 'Use of redundant or invalid role: listbox on <select> detected.' }],
245245
},
246+
{
247+
// <select> without `multiple` or `size` defaults to role "combobox".
248+
code: '<select role="combobox"></select>',
249+
output: '<select></select>',
250+
errors: [{ message: 'Use of redundant or invalid role: combobox on <select> detected.' }],
251+
},
252+
{
253+
// Case-insensitive matching — ARIA role tokens compare as ASCII-case-insensitive.
254+
code: '<body role="DOCUMENT"></body>',
255+
output: '<body></body>',
256+
errors: [{ message: 'Use of redundant or invalid role: document on <body> detected.' }],
257+
},
246258
{
247259
code: '<main role="main"></main>',
248260
output: '<main></main>',

0 commit comments

Comments
 (0)