|
1 | 1 | import {computeAccessibleName} from 'dom-accessibility-api' |
2 | | -import {roles as allRoles} from 'aria-query' |
| 2 | +import {roles as allRoles, roleElements} from 'aria-query' |
3 | 3 | import { |
4 | 4 | computeAriaSelected, |
5 | 5 | computeAriaChecked, |
@@ -99,7 +99,12 @@ function queryAllByRole( |
99 | 99 | return subtreeIsInaccessibleCache.get(element) |
100 | 100 | } |
101 | 101 |
|
102 | | - return Array.from(container.querySelectorAll('*')) |
| 102 | + return Array.from( |
| 103 | + container.querySelectorAll( |
| 104 | + // Only query elements that can be matched by the following filters |
| 105 | + makeRoleSelector(role, exact, normalizer ? matchNormalizer : undefined), |
| 106 | + ), |
| 107 | + ) |
103 | 108 | .filter(node => { |
104 | 109 | const isRoleSpecifiedExplicitly = node.hasAttribute('role') |
105 | 110 |
|
@@ -173,6 +178,22 @@ function queryAllByRole( |
173 | 178 | }) |
174 | 179 | } |
175 | 180 |
|
| 181 | +function makeRoleSelector(role, exact, customNormalizer) { |
| 182 | + if (typeof role !== 'string') { |
| 183 | + // For non-string role parameters we can not determine the implicitRoleSelectors. |
| 184 | + return '*' |
| 185 | + } |
| 186 | + |
| 187 | + const explicitRoleSelector = |
| 188 | + exact && !customNormalizer ? `*[role~="${role}"]` : '*[role]' |
| 189 | + |
| 190 | + const roleRelations = roleElements.get(role) |
| 191 | + const implicitRoleSelectors = |
| 192 | + roleRelations && new Set(Array.from(roleRelations).map(({name}) => name)) |
| 193 | + |
| 194 | + return [explicitRoleSelector, ...(implicitRoleSelectors ?? [])].join(',') |
| 195 | +} |
| 196 | + |
176 | 197 | const getMultipleError = (c, role, {name} = {}) => { |
177 | 198 | let nameHint = '' |
178 | 199 | if (name === undefined) { |
|
0 commit comments