1// Copyright 2021 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6pub(crate) mod tree;
7pub use tree::{ChangeHandler as TreeChangeHandler, State as TreeState, Tree};
8
9pub(crate) mod node;
10pub use node::{DetachedNode, Node, NodeState};
11
12pub(crate) mod filters;
13pub use filters::{
14 common_filter, common_filter_detached, common_filter_with_root_exception, FilterResult,
15};
16
17pub(crate) mod iterators;
18
19pub(crate) mod text;
20pub use text::{
21 AttributeValue as TextAttributeValue, Position as TextPosition, Range as TextRange,
22 WeakRange as WeakTextRange,
23};
24
25#[cfg(test)]
26mod tests {
27 use accesskit::{
28 Affine, NodeBuilder, NodeClassSet, NodeId, Rect, Role, Tree, TreeUpdate, Vec2,
29 };
30
31 use crate::FilterResult;
32
33 pub const ROOT_ID: NodeId = NodeId(0);
34 pub const PARAGRAPH_0_ID: NodeId = NodeId(1);
35 pub const STATIC_TEXT_0_0_IGNORED_ID: NodeId = NodeId(2);
36 pub const PARAGRAPH_1_IGNORED_ID: NodeId = NodeId(3);
37 pub const STATIC_TEXT_1_0_ID: NodeId = NodeId(4);
38 pub const PARAGRAPH_2_ID: NodeId = NodeId(5);
39 pub const STATIC_TEXT_2_0_ID: NodeId = NodeId(6);
40 pub const PARAGRAPH_3_IGNORED_ID: NodeId = NodeId(7);
41 pub const EMPTY_CONTAINER_3_0_IGNORED_ID: NodeId = NodeId(8);
42 pub const LINK_3_1_IGNORED_ID: NodeId = NodeId(9);
43 pub const STATIC_TEXT_3_1_0_ID: NodeId = NodeId(10);
44 pub const BUTTON_3_2_ID: NodeId = NodeId(11);
45 pub const EMPTY_CONTAINER_3_3_IGNORED_ID: NodeId = NodeId(12);
46
47 pub fn test_tree() -> crate::tree::Tree {
48 let mut classes = NodeClassSet::new();
49 let root = {
50 let mut builder = NodeBuilder::new(Role::RootWebArea);
51 builder.set_children(vec![
52 PARAGRAPH_0_ID,
53 PARAGRAPH_1_IGNORED_ID,
54 PARAGRAPH_2_ID,
55 PARAGRAPH_3_IGNORED_ID,
56 ]);
57 builder.build(&mut classes)
58 };
59 let paragraph_0 = {
60 let mut builder = NodeBuilder::new(Role::Paragraph);
61 builder.set_children(vec![STATIC_TEXT_0_0_IGNORED_ID]);
62 builder.build(&mut classes)
63 };
64 let static_text_0_0_ignored = {
65 let mut builder = NodeBuilder::new(Role::StaticText);
66 builder.set_name("static_text_0_0_ignored");
67 builder.build(&mut classes)
68 };
69 let paragraph_1_ignored = {
70 let mut builder = NodeBuilder::new(Role::Paragraph);
71 builder.set_transform(Affine::translate(Vec2::new(10.0, 40.0)));
72 builder.set_bounds(Rect {
73 x0: 0.0,
74 y0: 0.0,
75 x1: 800.0,
76 y1: 40.0,
77 });
78 builder.set_children(vec![STATIC_TEXT_1_0_ID]);
79 builder.build(&mut classes)
80 };
81 let static_text_1_0 = {
82 let mut builder = NodeBuilder::new(Role::StaticText);
83 builder.set_bounds(Rect {
84 x0: 10.0,
85 y0: 10.0,
86 x1: 90.0,
87 y1: 30.0,
88 });
89 builder.set_name("static_text_1_0");
90 builder.build(&mut classes)
91 };
92 let paragraph_2 = {
93 let mut builder = NodeBuilder::new(Role::Paragraph);
94 builder.set_children(vec![STATIC_TEXT_2_0_ID]);
95 builder.build(&mut classes)
96 };
97 let static_text_2_0 = {
98 let mut builder = NodeBuilder::new(Role::StaticText);
99 builder.set_name("static_text_2_0");
100 builder.build(&mut classes)
101 };
102 let paragraph_3_ignored = {
103 let mut builder = NodeBuilder::new(Role::Paragraph);
104 builder.set_children(vec![
105 EMPTY_CONTAINER_3_0_IGNORED_ID,
106 LINK_3_1_IGNORED_ID,
107 BUTTON_3_2_ID,
108 EMPTY_CONTAINER_3_3_IGNORED_ID,
109 ]);
110 builder.build(&mut classes)
111 };
112 let empty_container_3_0_ignored =
113 NodeBuilder::new(Role::GenericContainer).build(&mut classes);
114 let link_3_1_ignored = {
115 let mut builder = NodeBuilder::new(Role::Link);
116 builder.set_children(vec![STATIC_TEXT_3_1_0_ID]);
117 builder.set_linked();
118 builder.build(&mut classes)
119 };
120 let static_text_3_1_0 = {
121 let mut builder = NodeBuilder::new(Role::StaticText);
122 builder.set_name("static_text_3_1_0");
123 builder.build(&mut classes)
124 };
125 let button_3_2 = {
126 let mut builder = NodeBuilder::new(Role::Button);
127 builder.set_name("button_3_2");
128 builder.build(&mut classes)
129 };
130 let empty_container_3_3_ignored =
131 NodeBuilder::new(Role::GenericContainer).build(&mut classes);
132 let initial_update = TreeUpdate {
133 nodes: vec![
134 (ROOT_ID, root),
135 (PARAGRAPH_0_ID, paragraph_0),
136 (STATIC_TEXT_0_0_IGNORED_ID, static_text_0_0_ignored),
137 (PARAGRAPH_1_IGNORED_ID, paragraph_1_ignored),
138 (STATIC_TEXT_1_0_ID, static_text_1_0),
139 (PARAGRAPH_2_ID, paragraph_2),
140 (STATIC_TEXT_2_0_ID, static_text_2_0),
141 (PARAGRAPH_3_IGNORED_ID, paragraph_3_ignored),
142 (EMPTY_CONTAINER_3_0_IGNORED_ID, empty_container_3_0_ignored),
143 (LINK_3_1_IGNORED_ID, link_3_1_ignored),
144 (STATIC_TEXT_3_1_0_ID, static_text_3_1_0),
145 (BUTTON_3_2_ID, button_3_2),
146 (EMPTY_CONTAINER_3_3_IGNORED_ID, empty_container_3_3_ignored),
147 ],
148 tree: Some(Tree::new(ROOT_ID)),
149 focus: ROOT_ID,
150 };
151 crate::tree::Tree::new(initial_update, false)
152 }
153
154 pub fn test_tree_filter(node: &crate::Node) -> FilterResult {
155 let id = node.id();
156 if id == STATIC_TEXT_0_0_IGNORED_ID
157 || id == PARAGRAPH_1_IGNORED_ID
158 || id == PARAGRAPH_3_IGNORED_ID
159 || id == EMPTY_CONTAINER_3_0_IGNORED_ID
160 || id == LINK_3_1_IGNORED_ID
161 || id == EMPTY_CONTAINER_3_3_IGNORED_ID
162 {
163 FilterResult::ExcludeNode
164 } else {
165 FilterResult::Include
166 }
167 }
168}
169