-
-
Notifications
You must be signed in to change notification settings - Fork 208
/
get-non-interactive-element-role-schemas.ts
58 lines (52 loc) · 2.03 KB
/
get-non-interactive-element-role-schemas.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import type {
ARIARoleDefinitionKey,
ARIARoleRelationConcept,
} from 'aria-query';
import { elementRoles, roles } from 'aria-query';
let nonInteractiveElementRoleSchemas: ARIARoleRelationConcept[] | null = null;
let nonInteractiveRoles: Set<ARIARoleDefinitionKey> | null = null;
// These functions follow the lazy initialization pattern.
// Since this is a top-level module (it will be included via `require`),
// we do not need to initialize the `nonInteractiveElementRoleSchemas` or
// `nonInteractiveRoles` until the functions are called for the first time,
// so we will not take up the memory.
export function getNonInteractiveElementRoleSchemas(): ARIARoleRelationConcept[] {
if (nonInteractiveElementRoleSchemas === null) {
const elementRoleEntries = [...elementRoles.entries()];
nonInteractiveElementRoleSchemas = elementRoleEntries.reduce<
ARIARoleRelationConcept[]
>((accumulator, [elementSchema, roleSet]) => {
return accumulator.concat(
[...roleSet].every((role) => getNonInteractiveRoles().has(role))
? elementSchema
: [],
);
}, []);
}
return nonInteractiveElementRoleSchemas;
}
export function getNonInteractiveRoles(): Set<ARIARoleDefinitionKey> {
if (nonInteractiveRoles === null) {
const roleKeys = [...roles.keys()];
nonInteractiveRoles = new Set<ARIARoleDefinitionKey>(
roleKeys
.filter((name) => {
const role = roles.get(name);
return (
role &&
!role.abstract &&
// 'toolbar' does not descend from widget, but it does support
// aria-activedescendant, thus in practice we treat it as a widget.
name !== 'toolbar' &&
!role.superClass.some((classes) => classes.includes('widget'))
);
})
.concat(
// The `progressbar` is descended from `widget`, but in practice, its
// value is always `readonly`, so we treat it as a non-interactive role.
'progressbar',
),
);
}
return nonInteractiveRoles;
}