diff --git a/.all-contributorsrc b/.all-contributorsrc index 3ba10eb3..679954c9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1452,6 +1452,24 @@ "contributions": [ "code" ] + }, + { + "login": "SantoJambit", + "name": "SantoJambit", + "avatar_url": "https://avatars.githubusercontent.com/u/53570854?v=4", + "profile": "https://github.com/Lusito", + "contributions": [ + "code" + ] + }, + { + "login": "mittalyashu", + "name": "Yashu Mittal", + "avatar_url": "https://avatars.githubusercontent.com/u/29014463?v=4", + "profile": "https://github.com/mittalyashu", + "contributions": [ + "doc" + ] } ], "repoHost": "https://github.com" diff --git a/.npmrc b/.npmrc index d2722898..1df2a6d8 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ -registry=http://registry.npmjs.org/ +registry=https://registry.npmjs.org/ package-lock=false diff --git a/README.md b/README.md index e1f3699d..f8eb543a 100644 --- a/README.md +++ b/README.md @@ -322,6 +322,8 @@ Thanks goes to these people ([emoji key][emojis]):
Jack Laurence

💻 +
SantoJambit

💻 +
Yashu Mittal

📖 diff --git a/src/__tests__/queries.find.js b/src/__tests__/queries.find.js index 6372f957..48d79a8b 100644 --- a/src/__tests__/queries.find.js +++ b/src/__tests__/queries.find.js @@ -31,6 +31,7 @@ test('find asynchronously finds elements', async () => { test alt text +
diff --git a/src/__tests__/text-matchers.js b/src/__tests__/text-matchers.js index 145d84bf..d272f15a 100644 --- a/src/__tests__/text-matchers.js +++ b/src/__tests__/text-matchers.js @@ -34,6 +34,15 @@ cases( query: `Finding Nemo poster`, queryFn: `queryAllByAltText`, }, + 'queryAllByAltText (for amp-img)': { + dom: ` + `, + query: `Finding Nemo poster`, + queryFn: `queryAllByAltText`, + }, queryAllByPlaceholderText: { dom: ``, query: `Dwayne 'The Rock' Johnson`, @@ -93,6 +102,16 @@ cases( query: /^Finding Nemo poster$/, queryFn: `queryAllByAltText`, }, + 'queryAllByAltText (for amp-img)': { + dom: ` + `, + query: /^Finding Nemo poster$/, + queryFn: `queryAllByAltText`, + }, queryAllByPlaceholderText: { dom: ` `, @@ -198,6 +217,15 @@ cases( query: `Finding Nemo poster`, queryFn: `queryAllByAltText`, }, + 'queryAllByAltText (for amp-img)': { + dom: ` + `, + query: `Finding Nemo poster`, + queryFn: `queryAllByAltText`, + }, }, ) @@ -251,6 +279,10 @@ cases( dom: `User ${LRM}name`, queryFn: 'queryAllByAltText', }, + 'queryAllByAltText (for amp-img)': { + dom: ``, + queryFn: 'queryAllByAltText', + }, queryAllByTitle: { dom: `
`, queryFn: 'queryAllByTitle', diff --git a/src/queries/alt-text.ts b/src/queries/alt-text.ts index a7c84031..b3c83a00 100644 --- a/src/queries/alt-text.ts +++ b/src/queries/alt-text.ts @@ -1,20 +1,26 @@ -import {wrapAllByQueryWithSuggestion} from '../query-helpers' +import { + queryAllByAttribute, + wrapAllByQueryWithSuggestion, +} from '../query-helpers' import {checkContainerType} from '../helpers' -import {AllByBoundAttribute, GetErrorFunction} from '../../types' -import {matches, fuzzyMatches, makeNormalizer, buildQueries} from './all-utils' +import { + AllByBoundAttribute, + GetErrorFunction, + MatcherOptions, +} from '../../types' +import {buildQueries} from './all-utils' + +// Valid tags are img, input, area and custom elements +const VALID_TAG_REGEXP = /^(img|input|area|.+-.+)$/i const queryAllByAltText: AllByBoundAttribute = ( container, alt, - {exact = true, collapseWhitespace, trim, normalizer} = {}, + options: MatcherOptions = {}, ) => { checkContainerType(container) - const matcher = exact ? matches : fuzzyMatches - const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer}) - return Array.from( - container.querySelectorAll('img,input,area'), - ).filter(node => - matcher(node.getAttribute('alt'), node, alt, matchNormalizer), + return queryAllByAttribute('alt', container, alt, options).filter(node => + VALID_TAG_REGEXP.test(node.tagName), ) } diff --git a/src/queries/role.js b/src/queries/role.js index 8f08ae67..826edd43 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,28 @@ 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) ?? new Set() + const implicitRoleSelectors = new Set( + Array.from(roleRelations).map(({name}) => name), + ) + + // Current transpilation config sometimes assumes `...` is always applied to arrays. + // `...` is equivalent to `Array.prototype.concat` for arrays. + // If you replace this code with `[explicitRoleSelector, ...implicitRoleSelectors]`, make sure every transpilation target retains the `...` in favor of `Array.prototype.concat`. + return [explicitRoleSelector] + .concat(Array.from(implicitRoleSelectors)) + .join(',') +} + const getMultipleError = (c, role, {name} = {}) => { let nameHint = '' if (name === undefined) { diff --git a/types/queries.d.ts b/types/queries.d.ts index 0917f8e5..1ed64151 100644 --- a/types/queries.d.ts +++ b/types/queries.d.ts @@ -109,7 +109,7 @@ export interface ByRoleOptions extends MatcherOptions { */ queryFallbacks?: boolean /** - * Only considers elements with the specified accessible name. + * Only considers elements with the specified accessible name. */ name?: | RegExp