Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 4 additions & 147 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ use std::{
/// is ordered roughly by expected usage frequency (with the notable exception
/// of [`Role::Unknown`]). This is more efficient in serialization formats
/// where integers use a variable-length encoding.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
#[cfg_attr(feature = "serde", serde(crate = "serde"))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum Role {
#[default]
Unknown,
InlineTextBox,
Cell,
Expand Down Expand Up @@ -654,14 +655,13 @@ pub struct TextSelection {
}

/// A single accessible object. A complete UI is represented as a tree of these.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
#[cfg_attr(feature = "serde", serde(crate = "serde"))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Node {
pub id: NodeId,
pub role: Role,
/// An affine transform to apply to any coordinates within this node
/// and its descendants, including the [`bounds`] field of this node.
Expand Down Expand Up @@ -1165,149 +1165,6 @@ pub struct Node {
pub text_indent: Option<f32>,
}

impl Node {
pub fn new(id: NodeId, role: Role) -> Node {
Node {
id,
role,
transform: None,
bounds: None,
children: Default::default(),
actions: EnumSet::new(),
name: None,
name_from: None,
description: None,
description_from: None,
value: None,
autofill_available: false,
expanded: None,
default: false,
editable: false,
focusable: false,
orientation: None,
hovered: false,
ignored: false,
invisible: false,
linked: false,
multiline: false,
multiselectable: false,
protected: false,
required: false,
visited: false,
busy: false,
nonatomic_text_field_root: false,
live_atomic: false,
modal: false,
canvas_has_fallback: false,
scrollable: false,
clickable: false,
clips_children: false,
not_user_selectable_style: false,
selected: None,
selected_from_focus: false,
grabbed: None,
drop_effects: EnumSet::new(),
is_line_breaking_object: false,
is_page_breaking_object: false,
has_aria_attribute: false,
touch_pass_through: false,
indirect_children: Default::default(),
active_descendant: None,
error_message: None,
in_page_link_target: None,
member_of: None,
next_on_line: None,
previous_on_line: None,
popup_for: None,
controls: Default::default(),
details: Default::default(),
described_by: Default::default(),
flow_to: Default::default(),
labelled_by: Default::default(),
radio_group: Default::default(),
markers: Default::default(),
text_direction: None,
character_offsets: Default::default(),
words: Default::default(),
custom_actions: Default::default(),
access_key: None,
invalid_state: None,
auto_complete: None,
checked_state: None,
checked_state_description: None,
class_name: None,
css_display: None,
font_family: None,
html_tag: None,
inner_html: None,
input_type: None,
key_shortcuts: None,
language: None,
live_relevant: None,
live: None,
placeholder: None,
aria_role: None,
role_description: None,
tooltip: None,
url: None,
default_action_verb: None,
scroll_x: None,
scroll_x_min: None,
scroll_x_max: None,
scroll_y: None,
scroll_y_min: None,
scroll_y_max: None,
text_selection: None,
aria_column_count: None,
aria_cell_column_index: None,
aria_cell_column_span: None,
aria_row_count: None,
aria_cell_row_index: None,
aria_cell_row_span: None,
table_row_count: None,
table_column_count: None,
table_header: None,
table_row_index: None,
table_row_header: None,
table_column_index: None,
table_column_header: None,
table_cell_column_index: None,
table_cell_column_span: None,
table_cell_row_index: None,
table_cell_row_span: None,
sort_direction: None,
hierarchical_level: None,
read_only: false,
disabled: false,
set_size: None,
pos_in_set: None,
color_value: None,
aria_current: None,
background_color: None,
foreground_color: None,
has_popup: None,
list_style: None,
text_align: None,
vertical_offset: None,
bold: false,
italic: false,
overline: None,
strikethrough: None,
underline: None,
previous_focus: None,
next_focus: None,
numeric_value: None,
min_numeric_value: None,
max_numeric_value: None,
numeric_value_step: None,
numeric_value_jump: None,
font_size: None,
font_weight: None,
text_indent: None,
}
}
}

/// The data associated with an accessibility tree that's global to the
/// tree and not associated with any particular node.
#[derive(Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -1364,7 +1221,7 @@ pub struct TreeUpdate {
/// placeholder must be updated within the same `TreeUpdate`, otherwise
/// it's a fatal error. This guarantees the tree is always complete
/// before or after a `TreeUpdate`.
pub nodes: Vec<Node>,
pub nodes: Vec<(NodeId, Node)>,

/// Rarely updated information about the tree as a whole. This may be omitted
/// if it has not changed since the previous update, but providing the same
Expand Down
65 changes: 39 additions & 26 deletions consumer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,28 @@ mod tests {

pub fn test_tree() -> Arc<crate::tree::Tree> {
let root = Node {
role: Role::RootWebArea,
children: vec![
PARAGRAPH_0_ID,
PARAGRAPH_1_IGNORED_ID,
PARAGRAPH_2_ID,
PARAGRAPH_3_IGNORED_ID,
],
..Node::new(ROOT_ID, Role::RootWebArea)
..Default::default()
};
let paragraph_0 = Node {
role: Role::Paragraph,
children: vec![STATIC_TEXT_0_0_IGNORED_ID],
..Node::new(PARAGRAPH_0_ID, Role::Paragraph)
..Default::default()
};
let static_text_0_0_ignored = Node {
role: Role::StaticText,
ignored: true,
name: Some("static_text_0_0_ignored".into()),
..Node::new(STATIC_TEXT_0_0_IGNORED_ID, Role::StaticText)
..Default::default()
};
let paragraph_1_ignored = Node {
role: Role::Paragraph,
transform: Some(Box::new(Affine::translate(Vec2::new(10.0, 40.0)))),
bounds: Some(Rect {
x0: 0.0,
Expand All @@ -75,73 +79,82 @@ mod tests {
}),
children: vec![STATIC_TEXT_1_0_ID],
ignored: true,
..Node::new(PARAGRAPH_1_IGNORED_ID, Role::Paragraph)
..Default::default()
};
let static_text_1_0 = Node {
role: Role::StaticText,
bounds: Some(Rect {
x0: 10.0,
y0: 10.0,
x1: 90.0,
y1: 30.0,
}),
name: Some("static_text_1_0".into()),
..Node::new(STATIC_TEXT_1_0_ID, Role::StaticText)
..Default::default()
};
let paragraph_2 = Node {
role: Role::Paragraph,
children: vec![STATIC_TEXT_2_0_ID],
..Node::new(PARAGRAPH_2_ID, Role::Paragraph)
..Default::default()
};
let static_text_2_0 = Node {
role: Role::StaticText,
name: Some("static_text_2_0".into()),
..Node::new(STATIC_TEXT_2_0_ID, Role::StaticText)
..Default::default()
};
let paragraph_3_ignored = Node {
role: Role::Paragraph,
children: vec![
EMPTY_CONTAINER_3_0_IGNORED_ID,
LINK_3_1_IGNORED_ID,
BUTTON_3_2_ID,
EMPTY_CONTAINER_3_3_IGNORED_ID,
],
ignored: true,
..Node::new(PARAGRAPH_3_IGNORED_ID, Role::Paragraph)
..Default::default()
};
let empty_container_3_0_ignored = Node {
role: Role::GenericContainer,
ignored: true,
..Node::new(EMPTY_CONTAINER_3_0_IGNORED_ID, Role::GenericContainer)
..Default::default()
};
let link_3_1_ignored = Node {
role: Role::Link,
children: vec![STATIC_TEXT_3_1_0_ID],
ignored: true,
linked: true,
..Node::new(LINK_3_1_IGNORED_ID, Role::Link)
..Default::default()
};
let static_text_3_1_0 = Node {
role: Role::StaticText,
name: Some("static_text_3_1_0".into()),
..Node::new(STATIC_TEXT_3_1_0_ID, Role::StaticText)
..Default::default()
};
let button_3_2 = Node {
role: Role::Button,
name: Some("button_3_2".into()),
..Node::new(BUTTON_3_2_ID, Role::Button)
..Default::default()
};
let empty_container_3_3_ignored = Node {
role: Role::GenericContainer,
ignored: true,
..Node::new(EMPTY_CONTAINER_3_3_IGNORED_ID, Role::GenericContainer)
..Default::default()
};
let initial_update = TreeUpdate {
nodes: vec![
root,
paragraph_0,
static_text_0_0_ignored,
paragraph_1_ignored,
static_text_1_0,
paragraph_2,
static_text_2_0,
paragraph_3_ignored,
empty_container_3_0_ignored,
link_3_1_ignored,
static_text_3_1_0,
button_3_2,
empty_container_3_3_ignored,
(ROOT_ID, root),
(PARAGRAPH_0_ID, paragraph_0),
(STATIC_TEXT_0_0_IGNORED_ID, static_text_0_0_ignored),
(PARAGRAPH_1_IGNORED_ID, paragraph_1_ignored),
(STATIC_TEXT_1_0_ID, static_text_1_0),
(PARAGRAPH_2_ID, paragraph_2),
(STATIC_TEXT_2_0_ID, static_text_2_0),
(PARAGRAPH_3_IGNORED_ID, paragraph_3_ignored),
(EMPTY_CONTAINER_3_0_IGNORED_ID, empty_container_3_0_ignored),
(LINK_3_1_IGNORED_ID, link_3_1_ignored),
(STATIC_TEXT_3_1_0_ID, static_text_3_1_0),
(BUTTON_3_2_ID, button_3_2),
(EMPTY_CONTAINER_3_3_IGNORED_ID, empty_container_3_3_ignored),
],
tree: Some(Tree::new(ROOT_ID)),
focus: None,
Expand Down
Loading