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 | |
6 | pub(crate) mod tree; |
7 | pub use tree::{ChangeHandler as TreeChangeHandler, State as TreeState, Tree}; |
8 | |
9 | pub(crate) mod node; |
10 | pub use node::{DetachedNode, Node, NodeState}; |
11 | |
12 | pub(crate) mod filters; |
13 | pub use filters::{ |
14 | common_filter, common_filter_detached, common_filter_with_root_exception, FilterResult, |
15 | }; |
16 | |
17 | pub(crate) mod iterators; |
18 | |
19 | pub(crate) mod text; |
20 | pub use text::{ |
21 | AttributeValue as TextAttributeValue, Position as TextPosition, Range as TextRange, |
22 | WeakRange as WeakTextRange, |
23 | }; |
24 | |
25 | #[cfg (test)] |
26 | mod 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 | |