|
1 | 1 | // Logic inspired by html-validate (MIT), Copyright 2017 David Sveningsson. |
2 | 2 | // Role resolution delegates to `aria-query` — the authoritative WAI-ARIA |
3 | | -// data package (already a dependency of this plugin). `roles.get(r) |
4 | | -// .prohibitedProps` drives the flag/allow decision. |
| 3 | +// data package (already a dependency of this plugin). The |
| 4 | +// `roles.get(r).prohibitedProps` list drives the flag/allow decision. |
5 | 5 |
|
6 | 6 | const { roles, elementRoles } = require('aria-query'); |
7 | 7 |
|
@@ -79,12 +79,22 @@ function getImplicitRole(node) { |
79 | 79 | } |
80 | 80 |
|
81 | 81 | function getRole(node) { |
82 | | - const explicit = getStaticAttrString(node, 'role'); |
83 | | - if (explicit) { |
| 82 | + const roleAttr = findAttr(node, 'role'); |
| 83 | + if (roleAttr) { |
| 84 | + // Present but dynamic (mustache / concat) — the runtime role is unknown, |
| 85 | + // and if it differs from the element's implicit role we'd false-positive |
| 86 | + // against the implicit. Skip rather than guess. |
| 87 | + const explicit = getStaticAttrString(node, 'role'); |
| 88 | + if (explicit === null) { |
| 89 | + return null; |
| 90 | + } |
84 | 91 | const first = explicit.trim().split(/\s+/)[0]?.toLowerCase(); |
85 | 92 | if (first && roles.has(first)) { |
86 | 93 | return first; |
87 | 94 | } |
| 95 | + // `role` present with an unknown token (e.g. `role="bogus"`) — per ARIA |
| 96 | + // the invalid value is ignored and the implicit role applies. Fall |
| 97 | + // through to the implicit-role lookup. |
88 | 98 | } |
89 | 99 | return getImplicitRole(node); |
90 | 100 | } |
|
0 commit comments