7
7
import { AXObjects , AXObjectRoles , elementAXObjects } from 'axobject-query' ;
8
8
import Attribute from '../nodes/Attribute' ;
9
9
10
- const non_abstract_roles = [ ...roles_map . keys ( ) ] . filter ( ( name ) => ! roles_map . get ( name ) . abstract ) ;
10
+ const aria_roles = roles_map . keys ( ) ;
11
+ const abstract_roles = new Set ( aria_roles . filter ( role => roles_map . get ( role ) . abstract ) ) ;
12
+ const non_abstract_roles = aria_roles . filter ( ( name ) => ! abstract_roles . has ( name ) ) ;
11
13
12
14
const non_interactive_roles = new Set (
13
15
non_abstract_roles
@@ -40,6 +42,10 @@ export function is_interactive_roles(role: ARIARoleDefinitionKey) {
40
42
return interactive_roles . has ( role ) ;
41
43
}
42
44
45
+ export function is_abstract_role ( role : ARIARoleDefinitionKey ) {
46
+ return abstract_roles . has ( role ) ;
47
+ }
48
+
43
49
const presentation_roles = new Set ( [ 'presentation' , 'none' ] ) ;
44
50
45
51
export function is_presentation_role ( role : ARIARoleDefinitionKey ) {
@@ -65,7 +71,7 @@ export function is_hidden_from_screen_reader(tag_name: string, attribute_map: Ma
65
71
const non_interactive_element_role_schemas : ARIARoleRelationConcept [ ] = [ ] ;
66
72
67
73
elementRoles . entries ( ) . forEach ( ( [ schema , roles ] ) => {
68
- if ( [ ...roles ] . every ( ( role ) => non_interactive_roles . has ( role ) ) ) {
74
+ if ( [ ...roles ] . every ( ( role ) => role !== 'generic' && non_interactive_roles . has ( role ) ) ) {
69
75
non_interactive_element_role_schemas . push ( schema ) ;
70
76
}
71
77
} ) ;
@@ -82,6 +88,10 @@ const interactive_ax_objects = new Set(
82
88
[ ...AXObjects . keys ( ) ] . filter ( ( name ) => AXObjects . get ( name ) . type === 'widget' )
83
89
) ;
84
90
91
+ const non_interactive_ax_objects = new Set (
92
+ [ ...AXObjects . keys ( ) ] . filter ( ( name ) => [ 'windows' , 'structure' ] . includes ( AXObjects . get ( name ) . type ) )
93
+ ) ;
94
+
85
95
const interactive_element_ax_object_schemas : ARIARoleRelationConcept [ ] = [ ] ;
86
96
87
97
elementAXObjects . entries ( ) . forEach ( ( [ schema , ax_object ] ) => {
@@ -90,6 +100,14 @@ elementAXObjects.entries().forEach(([schema, ax_object]) => {
90
100
}
91
101
} ) ;
92
102
103
+ const non_interactive_element_ax_object_schemas : ARIARoleRelationConcept [ ] = [ ] ;
104
+
105
+ elementAXObjects . entries ( ) . forEach ( ( [ schema , ax_object ] ) => {
106
+ if ( [ ...ax_object ] . every ( ( role ) => non_interactive_ax_objects . has ( role ) ) ) {
107
+ non_interactive_element_ax_object_schemas . push ( schema ) ;
108
+ }
109
+ } ) ;
110
+
93
111
function match_schema (
94
112
schema : ARIARoleRelationConcept ,
95
113
tag_name : string ,
@@ -110,35 +128,62 @@ function match_schema(
110
128
} ) ;
111
129
}
112
130
113
- export function is_interactive_element (
131
+ export enum ElementInteractivity {
132
+ Interactive = 'interactive' ,
133
+ NonInteractive = 'non-interactive' ,
134
+ Static = 'static' ,
135
+ }
136
+
137
+ export function element_interactivity (
114
138
tag_name : string ,
115
139
attribute_map : Map < string , Attribute >
116
- ) : boolean {
140
+ ) : ElementInteractivity {
117
141
if (
118
142
interactive_element_role_schemas . some ( ( schema ) =>
119
143
match_schema ( schema , tag_name , attribute_map )
120
144
)
121
145
) {
122
- return true ;
146
+ return ElementInteractivity . Interactive ;
123
147
}
124
148
125
149
if (
150
+ tag_name !== 'header' &&
126
151
non_interactive_element_role_schemas . some ( ( schema ) =>
127
152
match_schema ( schema , tag_name , attribute_map )
128
153
)
129
154
) {
130
- return false ;
155
+ return ElementInteractivity . NonInteractive ;
131
156
}
132
157
133
158
if (
134
159
interactive_element_ax_object_schemas . some ( ( schema ) =>
135
160
match_schema ( schema , tag_name , attribute_map )
136
161
)
137
162
) {
138
- return true ;
163
+ return ElementInteractivity . Interactive ;
139
164
}
140
165
141
- return false ;
166
+ if (
167
+ non_interactive_element_ax_object_schemas . some ( ( schema ) =>
168
+ match_schema ( schema , tag_name , attribute_map )
169
+ )
170
+ ) {
171
+ return ElementInteractivity . NonInteractive ;
172
+ }
173
+
174
+ return ElementInteractivity . Static ;
175
+ }
176
+
177
+ export function is_interactive_element ( tag_name : string , attribute_map : Map < string , Attribute > ) : boolean {
178
+ return element_interactivity ( tag_name , attribute_map ) === ElementInteractivity . Interactive ;
179
+ }
180
+
181
+ export function is_non_interactive_element ( tag_name : string , attribute_map : Map < string , Attribute > ) : boolean {
182
+ return element_interactivity ( tag_name , attribute_map ) === ElementInteractivity . NonInteractive ;
183
+ }
184
+
185
+ export function is_static_element ( tag_name : string , attribute_map : Map < string , Attribute > ) : boolean {
186
+ return element_interactivity ( tag_name , attribute_map ) === ElementInteractivity . Static ;
142
187
}
143
188
144
189
export function is_semantic_role_element ( role : ARIARoleDefinitionKey , tag_name : string , attribute_map : Map < string , Attribute > ) {
0 commit comments