Skip to main content

browser_protocol/accessibility/
mod.rs

1use serde::{Serialize, Deserialize};
2use serde_json::Value as JsonValue;
3
4/// Unique accessibility node identifier.
5
6pub type AXNodeId = String;
7
8/// Enum of possible property types.
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
11pub enum AXValueType {
12    #[default]
13    Boolean,
14    Tristate,
15    BooleanOrUndefined,
16    Idref,
17    IdrefList,
18    Integer,
19    Node,
20    NodeList,
21    Number,
22    String,
23    ComputedString,
24    Token,
25    TokenList,
26    DomRelation,
27    Role,
28    InternalRole,
29    ValueUndefined,
30}
31
32/// Enum of possible property sources.
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
35pub enum AXValueSourceType {
36    #[default]
37    Attribute,
38    Implicit,
39    Style,
40    Contents,
41    Placeholder,
42    RelatedElement,
43}
44
45/// Enum of possible native property sources (as a subtype of a particular AXValueSourceType).
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
48pub enum AXValueNativeSourceType {
49    #[default]
50    Description,
51    Figcaption,
52    Label,
53    Labelfor,
54    Labelwrapped,
55    Legend,
56    Rubyannotation,
57    Tablecaption,
58    Title,
59    Other,
60}
61
62/// A single source for a computed AX property.
63
64#[derive(Debug, Clone, Serialize, Deserialize, Default)]
65#[serde(rename_all = "camelCase")]
66pub struct AXValueSource {
67    /// What type of source this is.
68
69    #[serde(rename = "type")]
70    pub type_: AXValueSourceType,
71    /// The value of this property source.
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub value: Option<AXValue>,
75    /// The name of the relevant attribute, if any.
76
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub attribute: Option<String>,
79    /// The value of the relevant attribute, if any.
80
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub attributeValue: Option<AXValue>,
83    /// Whether this source is superseded by a higher priority source.
84
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub superseded: Option<bool>,
87    /// The native markup source for this value, e.g. a '\<label\>' element.
88
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub nativeSource: Option<AXValueNativeSourceType>,
91    /// The value, such as a node or node list, of the native source.
92
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub nativeSourceValue: Option<AXValue>,
95    /// Whether the value for this property is invalid.
96
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub invalid: Option<bool>,
99    /// Reason for the value being invalid, if it is.
100
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub invalidReason: Option<String>,
103}
104
105
106#[derive(Debug, Clone, Serialize, Deserialize, Default)]
107#[serde(rename_all = "camelCase")]
108pub struct AXRelatedNode {
109    /// The BackendNodeId of the related DOM node.
110
111    pub backendDOMNodeId: crate::dom::BackendNodeId,
112    /// The IDRef value provided, if any.
113
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub idref: Option<String>,
116    /// The text alternative of this node in the current context.
117
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub text: Option<String>,
120}
121
122
123#[derive(Debug, Clone, Serialize, Deserialize, Default)]
124#[serde(rename_all = "camelCase")]
125pub struct AXProperty {
126    /// The name of this property.
127
128    pub name: AXPropertyName,
129    /// The value of this property.
130
131    pub value: AXValue,
132}
133
134/// A single computed AX property.
135
136#[derive(Debug, Clone, Serialize, Deserialize, Default)]
137#[serde(rename_all = "camelCase")]
138pub struct AXValue {
139    /// The type of this value.
140
141    #[serde(rename = "type")]
142    pub type_: AXValueType,
143    /// The computed value of this property.
144
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub value: Option<JsonValue>,
147    /// One or more related nodes, if applicable.
148
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub relatedNodes: Option<Vec<AXRelatedNode>>,
151    /// The sources which contributed to the computation of this property.
152
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub sources: Option<Vec<AXValueSource>>,
155}
156
157/// Values of AXProperty name:
158/// - from 'busy' to 'roledescription': states which apply to every AX node
159/// - from 'live' to 'root': attributes which apply to nodes in live regions
160/// - from 'autocomplete' to 'valuetext': attributes which apply to widgets
161/// - from 'checked' to 'selected': states which apply to widgets
162/// - from 'activedescendant' to 'owns': relationships between elements other than parent/child/sibling
163/// - from 'activeFullscreenElement' to 'uninteresting': reasons why this noode is hidden
164
165#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
166pub enum AXPropertyName {
167    #[default]
168    Actions,
169    Busy,
170    Disabled,
171    Editable,
172    Focusable,
173    Focused,
174    Hidden,
175    HiddenRoot,
176    Invalid,
177    Keyshortcuts,
178    Settable,
179    Roledescription,
180    Live,
181    Atomic,
182    Relevant,
183    Root,
184    Autocomplete,
185    HasPopup,
186    Level,
187    Multiselectable,
188    Orientation,
189    Multiline,
190    Readonly,
191    Required,
192    Valuemin,
193    Valuemax,
194    Valuetext,
195    Checked,
196    Expanded,
197    Modal,
198    Pressed,
199    Selected,
200    Activedescendant,
201    Controls,
202    Describedby,
203    Details,
204    Errormessage,
205    Flowto,
206    Labelledby,
207    Owns,
208    Url,
209    ActiveFullscreenElement,
210    ActiveModalDialog,
211    ActiveAriaModalDialog,
212    AriaHiddenElement,
213    AriaHiddenSubtree,
214    EmptyAlt,
215    EmptyText,
216    InertElement,
217    InertSubtree,
218    LabelContainer,
219    LabelFor,
220    NotRendered,
221    NotVisible,
222    PresentationalRole,
223    ProbablyPresentational,
224    InactiveCarouselTabContent,
225    Uninteresting,
226}
227
228/// A node in the accessibility tree.
229
230#[derive(Debug, Clone, Serialize, Deserialize, Default)]
231#[serde(rename_all = "camelCase")]
232pub struct AXNode {
233    /// Unique identifier for this node.
234
235    pub nodeId: AXNodeId,
236    /// Whether this node is ignored for accessibility
237
238    pub ignored: bool,
239    /// Collection of reasons why this node is hidden.
240
241    #[serde(skip_serializing_if = "Option::is_none")]
242    pub ignoredReasons: Option<Vec<AXProperty>>,
243    /// This 'Node''s role, whether explicit or implicit.
244
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub role: Option<AXValue>,
247    /// This 'Node''s Chrome raw role.
248
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub chromeRole: Option<AXValue>,
251    /// The accessible name for this 'Node'.
252
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub name: Option<AXValue>,
255    /// The accessible description for this 'Node'.
256
257    #[serde(skip_serializing_if = "Option::is_none")]
258    pub description: Option<AXValue>,
259    /// The value for this 'Node'.
260
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub value: Option<AXValue>,
263    /// All other properties
264
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub properties: Option<Vec<AXProperty>>,
267    /// ID for this node's parent.
268
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub parentId: Option<AXNodeId>,
271    /// IDs for each of this node's child nodes.
272
273    #[serde(skip_serializing_if = "Option::is_none")]
274    pub childIds: Option<Vec<AXNodeId>>,
275    /// The backend ID for the associated DOM node, if any.
276
277    #[serde(skip_serializing_if = "Option::is_none")]
278    pub backendDOMNodeId: Option<crate::dom::BackendNodeId>,
279    /// The frame ID for the frame associated with this nodes document.
280
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub frameId: Option<crate::page::FrameId>,
283}
284
285/// Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.
286
287#[derive(Debug, Clone, Serialize, Deserialize, Default)]
288#[serde(rename_all = "camelCase")]
289pub struct GetPartialAXTreeParams {
290    /// Identifier of the node to get the partial accessibility tree for.
291
292    #[serde(skip_serializing_if = "Option::is_none")]
293    pub nodeId: Option<crate::dom::NodeId>,
294    /// Identifier of the backend node to get the partial accessibility tree for.
295
296    #[serde(skip_serializing_if = "Option::is_none")]
297    pub backendNodeId: Option<crate::dom::BackendNodeId>,
298    /// JavaScript object id of the node wrapper to get the partial accessibility tree for.
299
300    #[serde(skip_serializing_if = "Option::is_none")]
301    pub objectId: Option<crate::runtime::RemoteObjectId>,
302    /// Whether to fetch this node's ancestors, siblings and children. Defaults to true.
303
304    #[serde(skip_serializing_if = "Option::is_none")]
305    pub fetchRelatives: Option<bool>,
306}
307
308/// Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.
309
310#[derive(Debug, Clone, Serialize, Deserialize, Default)]
311#[serde(rename_all = "camelCase")]
312pub struct GetPartialAXTreeReturns {
313    /// The 'Accessibility.AXNode' for this DOM node, if it exists, plus its ancestors, siblings and
314    /// children, if requested.
315
316    pub nodes: Vec<AXNode>,
317}
318
319/// Fetches the entire accessibility tree for the root Document
320
321#[derive(Debug, Clone, Serialize, Deserialize, Default)]
322#[serde(rename_all = "camelCase")]
323pub struct GetFullAXTreeParams {
324    /// The maximum depth at which descendants of the root node should be retrieved.
325    /// If omitted, the full tree is returned.
326
327    #[serde(skip_serializing_if = "Option::is_none")]
328    pub depth: Option<i64>,
329    /// The frame for whose document the AX tree should be retrieved.
330    /// If omitted, the root frame is used.
331
332    #[serde(skip_serializing_if = "Option::is_none")]
333    pub frameId: Option<crate::page::FrameId>,
334}
335
336/// Fetches the entire accessibility tree for the root Document
337
338#[derive(Debug, Clone, Serialize, Deserialize, Default)]
339#[serde(rename_all = "camelCase")]
340pub struct GetFullAXTreeReturns {
341
342    pub nodes: Vec<AXNode>,
343}
344
345/// Fetches the root node.
346/// Requires 'enable()' to have been called previously.
347
348#[derive(Debug, Clone, Serialize, Deserialize, Default)]
349#[serde(rename_all = "camelCase")]
350pub struct GetRootAXNodeParams {
351    /// The frame in whose document the node resides.
352    /// If omitted, the root frame is used.
353
354    #[serde(skip_serializing_if = "Option::is_none")]
355    pub frameId: Option<crate::page::FrameId>,
356}
357
358/// Fetches the root node.
359/// Requires 'enable()' to have been called previously.
360
361#[derive(Debug, Clone, Serialize, Deserialize, Default)]
362#[serde(rename_all = "camelCase")]
363pub struct GetRootAXNodeReturns {
364
365    pub node: AXNode,
366}
367
368/// Fetches a node and all ancestors up to and including the root.
369/// Requires 'enable()' to have been called previously.
370
371#[derive(Debug, Clone, Serialize, Deserialize, Default)]
372#[serde(rename_all = "camelCase")]
373pub struct GetAXNodeAndAncestorsParams {
374    /// Identifier of the node to get.
375
376    #[serde(skip_serializing_if = "Option::is_none")]
377    pub nodeId: Option<crate::dom::NodeId>,
378    /// Identifier of the backend node to get.
379
380    #[serde(skip_serializing_if = "Option::is_none")]
381    pub backendNodeId: Option<crate::dom::BackendNodeId>,
382    /// JavaScript object id of the node wrapper to get.
383
384    #[serde(skip_serializing_if = "Option::is_none")]
385    pub objectId: Option<crate::runtime::RemoteObjectId>,
386}
387
388/// Fetches a node and all ancestors up to and including the root.
389/// Requires 'enable()' to have been called previously.
390
391#[derive(Debug, Clone, Serialize, Deserialize, Default)]
392#[serde(rename_all = "camelCase")]
393pub struct GetAXNodeAndAncestorsReturns {
394
395    pub nodes: Vec<AXNode>,
396}
397
398/// Fetches a particular accessibility node by AXNodeId.
399/// Requires 'enable()' to have been called previously.
400
401#[derive(Debug, Clone, Serialize, Deserialize, Default)]
402#[serde(rename_all = "camelCase")]
403pub struct GetChildAXNodesParams {
404
405    pub id: AXNodeId,
406    /// The frame in whose document the node resides.
407    /// If omitted, the root frame is used.
408
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub frameId: Option<crate::page::FrameId>,
411}
412
413/// Fetches a particular accessibility node by AXNodeId.
414/// Requires 'enable()' to have been called previously.
415
416#[derive(Debug, Clone, Serialize, Deserialize, Default)]
417#[serde(rename_all = "camelCase")]
418pub struct GetChildAXNodesReturns {
419
420    pub nodes: Vec<AXNode>,
421}
422
423/// Query a DOM node's accessibility subtree for accessible name and role.
424/// This command computes the name and role for all nodes in the subtree, including those that are
425/// ignored for accessibility, and returns those that match the specified name and role. If no DOM
426/// node is specified, or the DOM node does not exist, the command returns an error. If neither
427/// 'accessibleName' or 'role' is specified, it returns all the accessibility nodes in the subtree.
428
429#[derive(Debug, Clone, Serialize, Deserialize, Default)]
430#[serde(rename_all = "camelCase")]
431pub struct QueryAXTreeParams {
432    /// Identifier of the node for the root to query.
433
434    #[serde(skip_serializing_if = "Option::is_none")]
435    pub nodeId: Option<crate::dom::NodeId>,
436    /// Identifier of the backend node for the root to query.
437
438    #[serde(skip_serializing_if = "Option::is_none")]
439    pub backendNodeId: Option<crate::dom::BackendNodeId>,
440    /// JavaScript object id of the node wrapper for the root to query.
441
442    #[serde(skip_serializing_if = "Option::is_none")]
443    pub objectId: Option<crate::runtime::RemoteObjectId>,
444    /// Find nodes with this computed name.
445
446    #[serde(skip_serializing_if = "Option::is_none")]
447    pub accessibleName: Option<String>,
448    /// Find nodes with this computed role.
449
450    #[serde(skip_serializing_if = "Option::is_none")]
451    pub role: Option<String>,
452}
453
454/// Query a DOM node's accessibility subtree for accessible name and role.
455/// This command computes the name and role for all nodes in the subtree, including those that are
456/// ignored for accessibility, and returns those that match the specified name and role. If no DOM
457/// node is specified, or the DOM node does not exist, the command returns an error. If neither
458/// 'accessibleName' or 'role' is specified, it returns all the accessibility nodes in the subtree.
459
460#[derive(Debug, Clone, Serialize, Deserialize, Default)]
461#[serde(rename_all = "camelCase")]
462pub struct QueryAXTreeReturns {
463    /// A list of 'Accessibility.AXNode' matching the specified attributes,
464    /// including nodes that are ignored for accessibility.
465
466    pub nodes: Vec<AXNode>,
467}