From 77d329107e9fd74aa185dccc869280063e66957c Mon Sep 17 00:00:00 2001 From: Philipp Fritsche Date: Mon, 4 Oct 2021 08:05:44 +0000 Subject: [PATCH 1/2] perf(byRole): check only elements that could be a match --- src/queries/role.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/queries/role.js b/src/queries/role.js index 8f08ae67..2457b6c0 100644 --- a/src/queries/role.js +++ b/src/queries/role.js @@ -1,5 +1,5 @@ import {computeAccessibleName} from 'dom-accessibility-api' -import {roles as allRoles} from 'aria-query' +import {roles as allRoles, roleElements} from 'aria-query' import { computeAriaSelected, computeAriaChecked, @@ -99,7 +99,12 @@ function queryAllByRole( return subtreeIsInaccessibleCache.get(element) } - return Array.from(container.querySelectorAll('*')) + return Array.from( + container.querySelectorAll( + // Only query elements that can be matched by the following filters + makeRoleSelector(role, exact, normalizer ? matchNormalizer : undefined), + ), + ) .filter(node => { const isRoleSpecifiedExplicitly = node.hasAttribute('role') @@ -173,6 +178,22 @@ function queryAllByRole( }) } +function makeRoleSelector(role, exact, customNormalizer) { + if (typeof role !== 'string') { + // For non-string role parameters we can not determine the implicitRoleSelectors. + return '*' + } + + const explicitRoleSelector = + exact && !customNormalizer ? `*[role~="${role}"]` : '*[role]' + + const roleRelations = roleElements.get(role) + const implicitRoleSelectors = + roleRelations && new Set(Array.from(roleRelations).map(({name}) => name)) + + return [explicitRoleSelector, ...(implicitRoleSelectors ?? [])].join(',') +} + const getMultipleError = (c, role, {name} = {}) => { let nameHint = '' if (name === undefined) { From a592dbaad8f82cd42da7bc0765082a713db1e0d1 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 13 Oct 2021 10:00:58 +0200 Subject: [PATCH 2/2] poke CodeSandbox