Skip to content

Commit 2ab2f4a

Browse files
committed
start adding excludeHidden for *ByText queries
1 parent edffb7c commit 2ab2f4a

File tree

6 files changed

+49
-14
lines changed

6 files changed

+49
-14
lines changed

src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ let config: InternalConfig = {
2424
eventWrapper: cb => cb(),
2525
// default value for the `hidden` option in `ByRole` queries
2626
defaultHidden: false,
27+
// default value for the `hidden` option in `ByText` queries
28+
defaultExcludeHiddenText: false,
2729
// default value for the `ignore` option in `ByText` queries
2830
defaultIgnore: 'script, style',
2931
// showOriginalStackTrace flag to show the full error stack traces for async errors

src/queries/role.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
getImplicitAriaRoles,
1414
prettyRoles,
1515
isInaccessible,
16-
isSubtreeInaccessible,
16+
getCachedIsSubtreeInaccessible,
1717
} from '../role-helpers'
1818
import {wrapAllByQueryWithSuggestion} from '../query-helpers'
1919
import {checkContainerType} from '../helpers'
@@ -94,14 +94,7 @@ function queryAllByRole(
9494
}
9595
}
9696

97-
const subtreeIsInaccessibleCache = new WeakMap()
98-
function cachedIsSubtreeInaccessible(element) {
99-
if (!subtreeIsInaccessibleCache.has(element)) {
100-
subtreeIsInaccessibleCache.set(element, isSubtreeInaccessible(element))
101-
}
102-
103-
return subtreeIsInaccessibleCache.get(element)
104-
}
97+
const cachedIsSubtreeInaccessible = getCachedIsSubtreeInaccessible()
10598

10699
return Array.from(
107100
container.querySelectorAll(

src/queries/text.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
SelectorMatcherOptions,
77
Matcher,
88
} from '../../types'
9+
import {getCachedIsSubtreeInaccessible, isInaccessible} from '../role-helpers'
910
import {
1011
fuzzyMatches,
1112
matches,
@@ -25,6 +26,7 @@ const queryAllByText: AllByText = (
2526
trim,
2627
ignore = getConfig().defaultIgnore,
2728
normalizer,
29+
excludeHidden = getConfig().defaultExcludeHiddenText,
2830
} = {},
2931
) => {
3032
checkContainerType(container)
@@ -34,13 +36,27 @@ const queryAllByText: AllByText = (
3436
if (typeof container.matches === 'function' && container.matches(selector)) {
3537
baseArray = [container]
3638
}
39+
const cachedIsSubtreeInaccessible = getCachedIsSubtreeInaccessible()
40+
3741
return (
3842
[
3943
...baseArray,
4044
...Array.from(container.querySelectorAll<HTMLElement>(selector)),
4145
]
4246
// TODO: `matches` according lib.dom.d.ts can get only `string` but according our code it can handle also boolean :)
43-
.filter(node => !ignore || !node.matches(ignore as string))
47+
.filter(node => {
48+
if (ignore && node.matches(ignore as string)) {
49+
return false
50+
}
51+
52+
if (!excludeHidden) {
53+
return true
54+
}
55+
56+
return isInaccessible(node, {
57+
isSubtreeInaccessible: cachedIsSubtreeInaccessible,
58+
})
59+
})
4460
.filter(node => matcher(getNodeText(node), node, text, matchNormalizer))
4561
)
4662
}

src/role-helpers.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ function isSubtreeInaccessible(element) {
2929
return false
3030
}
3131

32+
/**
33+
* @returns {function (element: Element): boolean}
34+
*/
35+
function getCachedIsSubtreeInaccessible() {
36+
const subtreeIsInaccessibleCache = new WeakMap()
37+
return function cachedIsSubtreeInaccessible(element) {
38+
if (!subtreeIsInaccessibleCache.has(element)) {
39+
subtreeIsInaccessibleCache.set(element, isSubtreeInaccessible(element))
40+
}
41+
42+
return subtreeIsInaccessibleCache.get(element)
43+
}
44+
}
45+
3246
/**
3347
* Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
3448
* which should only be used for elements with a non-presentational role i.e.
@@ -330,6 +344,7 @@ export {
330344
logRoles,
331345
getImplicitAriaRoles,
332346
isSubtreeInaccessible,
347+
getCachedIsSubtreeInaccessible,
333348
prettyRoles,
334349
isInaccessible,
335350
computeAriaSelected,

types/config.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface Config {
1212
asyncUtilTimeout: number
1313
computedStyleSupportsPseudoElements: boolean
1414
defaultHidden: boolean
15+
defaultExcludeHiddenText: boolean
1516
/** default value for the `ignore` option in `ByText` queries */
1617
defaultIgnore: string
1718
showOriginalStackTrace: boolean

types/queries.d.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,37 @@ export type QueryByText<T extends HTMLElement = HTMLElement> = (
4040
options?: SelectorMatcherOptions,
4141
) => T | null
4242

43+
export interface ByTextOptions extends SelectorMatcherOptions {
44+
/**
45+
* If true exclude elements in the query set that are usually excluded from
46+
* the accessibility tree.
47+
*/
48+
excludeHidden?: boolean
49+
}
50+
4351
export type AllByText<T extends HTMLElement = HTMLElement> = (
4452
container: HTMLElement,
4553
id: Matcher,
46-
options?: SelectorMatcherOptions,
54+
options?: ByTextOptions,
4755
) => T[]
4856

4957
export type FindAllByText<T extends HTMLElement = HTMLElement> = (
5058
container: HTMLElement,
5159
id: Matcher,
52-
options?: SelectorMatcherOptions,
60+
options?: ByTextOptions,
5361
waitForElementOptions?: waitForOptions,
5462
) => Promise<T[]>
5563

5664
export type GetByText<T extends HTMLElement = HTMLElement> = (
5765
container: HTMLElement,
5866
id: Matcher,
59-
options?: SelectorMatcherOptions,
67+
options?: ByTextOptions,
6068
) => T
6169

6270
export type FindByText<T extends HTMLElement = HTMLElement> = (
6371
container: HTMLElement,
6472
id: Matcher,
65-
options?: SelectorMatcherOptions,
73+
options?: ByTextOptions,
6674
waitForElementOptions?: waitForOptions,
6775
) => Promise<T>
6876

0 commit comments

Comments
 (0)