OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/accessibility/blink_ax_tree_source.h" | 5 #include "content/renderer/accessibility/blink_ax_tree_source.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 AXContentNodeData* dst) { | 106 AXContentNodeData* dst) { |
107 std::vector<int32_t> ids; | 107 std::vector<int32_t> ids; |
108 for(size_t i = 0; i < objects.size(); i++) | 108 for(size_t i = 0; i < objects.size(); i++) |
109 ids.push_back(objects[i].axID()); | 109 ids.push_back(objects[i].axID()); |
110 if (ids.size() > 0) | 110 if (ids.size() > 0) |
111 dst->AddIntListAttribute(attr, ids); | 111 dst->AddIntListAttribute(attr, ids); |
112 } | 112 } |
113 | 113 |
114 } // namespace | 114 } // namespace |
115 | 115 |
| 116 ScopedFreezeBlinkAXTreeSource::ScopedFreezeBlinkAXTreeSource( |
| 117 BlinkAXTreeSource* tree_source) |
| 118 : tree_source_(tree_source) { |
| 119 tree_source_->Freeze(); |
| 120 } |
| 121 |
| 122 ScopedFreezeBlinkAXTreeSource::~ScopedFreezeBlinkAXTreeSource() { |
| 123 tree_source_->Thaw(); |
| 124 } |
| 125 |
116 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) | 126 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) |
117 : render_frame_(render_frame), | 127 : render_frame_(render_frame), |
118 accessibility_focus_id_(-1) { | 128 accessibility_focus_id_(-1), |
119 } | 129 frozen_(false) {} |
120 | 130 |
121 BlinkAXTreeSource::~BlinkAXTreeSource() { | 131 BlinkAXTreeSource::~BlinkAXTreeSource() { |
122 } | 132 } |
123 | 133 |
| 134 void BlinkAXTreeSource::Freeze() { |
| 135 CHECK(!frozen_); |
| 136 frozen_ = true; |
| 137 |
| 138 if (render_frame_ && render_frame_->GetWebFrame()) |
| 139 document_ = render_frame_->GetWebFrame()->document(); |
| 140 else |
| 141 document_ = WebDocument(); |
| 142 |
| 143 root_ = ComputeRoot(); |
| 144 |
| 145 if (!document_.isNull()) |
| 146 focus_ = document_.focusedAccessibilityObject(); |
| 147 else |
| 148 focus_ = WebAXObject(); |
| 149 } |
| 150 |
| 151 void BlinkAXTreeSource::Thaw() { |
| 152 CHECK(frozen_); |
| 153 frozen_ = false; |
| 154 } |
| 155 |
124 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { | 156 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { |
125 root_ = root; | 157 CHECK(!frozen_); |
| 158 explicit_root_ = root; |
126 } | 159 } |
127 | 160 |
128 bool BlinkAXTreeSource::IsInTree(blink::WebAXObject node) const { | 161 bool BlinkAXTreeSource::IsInTree(blink::WebAXObject node) const { |
129 const blink::WebAXObject& root = GetRoot(); | 162 CHECK(frozen_); |
130 while (IsValid(node)) { | 163 while (IsValid(node)) { |
131 if (node.equals(root)) | 164 if (node.equals(root())) |
132 return true; | 165 return true; |
133 node = GetParent(node); | 166 node = GetParent(node); |
134 } | 167 } |
135 return false; | 168 return false; |
136 } | 169 } |
137 | 170 |
138 bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const { | 171 bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const { |
139 blink::WebDocument document = BlinkAXTreeSource::GetMainDocument(); | 172 CHECK(frozen_); |
140 const blink::WebAXObject& root = GetRoot(); | 173 tree_data->doctype = "html"; |
| 174 tree_data->loaded = root().isLoaded(); |
| 175 tree_data->loading_progress = root().estimatedLoadingProgress(); |
| 176 tree_data->mimetype = |
| 177 document().isXHTMLDocument() ? "text/xhtml" : "text/html"; |
| 178 tree_data->title = document().title().utf8(); |
| 179 tree_data->url = document().url().string().utf8(); |
141 | 180 |
142 tree_data->doctype = "html"; | 181 if (!focus().isNull()) |
143 tree_data->loaded = root.isLoaded(); | 182 tree_data->focus_id = focus().axID(); |
144 tree_data->loading_progress = root.estimatedLoadingProgress(); | |
145 tree_data->mimetype = document.isXHTMLDocument() ? "text/xhtml" : "text/html"; | |
146 tree_data->title = document.title().utf8(); | |
147 tree_data->url = document.url().string().utf8(); | |
148 | |
149 WebAXObject focus = document.focusedAccessibilityObject(); | |
150 if (!focus.isNull()) | |
151 tree_data->focus_id = focus.axID(); | |
152 | 183 |
153 WebAXObject anchor_object, focus_object; | 184 WebAXObject anchor_object, focus_object; |
154 int anchor_offset, focus_offset; | 185 int anchor_offset, focus_offset; |
155 blink::WebAXTextAffinity anchor_affinity, focus_affinity; | 186 blink::WebAXTextAffinity anchor_affinity, focus_affinity; |
156 root.selection(anchor_object, anchor_offset, anchor_affinity, | 187 root().selection(anchor_object, anchor_offset, anchor_affinity, focus_object, |
157 focus_object, focus_offset, focus_affinity); | 188 focus_offset, focus_affinity); |
158 if (!anchor_object.isNull() && !focus_object.isNull() && | 189 if (!anchor_object.isNull() && !focus_object.isNull() && |
159 anchor_offset >= 0 && focus_offset >= 0) { | 190 anchor_offset >= 0 && focus_offset >= 0) { |
160 int32_t anchor_id = anchor_object.axID(); | 191 int32_t anchor_id = anchor_object.axID(); |
161 int32_t focus_id = focus_object.axID(); | 192 int32_t focus_id = focus_object.axID(); |
162 tree_data->sel_anchor_object_id = anchor_id; | 193 tree_data->sel_anchor_object_id = anchor_id; |
163 tree_data->sel_anchor_offset = anchor_offset; | 194 tree_data->sel_anchor_offset = anchor_offset; |
164 tree_data->sel_focus_object_id = focus_id; | 195 tree_data->sel_focus_object_id = focus_id; |
165 tree_data->sel_focus_offset = focus_offset; | 196 tree_data->sel_focus_offset = focus_offset; |
166 tree_data->sel_anchor_affinity = AXTextAffinityFromBlink(anchor_affinity); | 197 tree_data->sel_anchor_affinity = AXTextAffinityFromBlink(anchor_affinity); |
167 tree_data->sel_focus_affinity = AXTextAffinityFromBlink(focus_affinity); | 198 tree_data->sel_focus_affinity = AXTextAffinityFromBlink(focus_affinity); |
168 } | 199 } |
169 | 200 |
170 // Get the tree ID for this frame and the parent frame. | 201 // Get the tree ID for this frame and the parent frame. |
171 WebLocalFrame* web_frame = document.frame(); | 202 WebLocalFrame* web_frame = document().frame(); |
172 if (web_frame) { | 203 if (web_frame) { |
173 RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame); | 204 RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame); |
174 tree_data->routing_id = render_frame->GetRoutingID(); | 205 tree_data->routing_id = render_frame->GetRoutingID(); |
175 | 206 |
176 // Get the tree ID for the parent frame. | 207 // Get the tree ID for the parent frame. |
177 blink::WebFrame* parent_web_frame = web_frame->parent(); | 208 blink::WebFrame* parent_web_frame = web_frame->parent(); |
178 if (parent_web_frame) { | 209 if (parent_web_frame) { |
179 tree_data->parent_routing_id = | 210 tree_data->parent_routing_id = |
180 GetRoutingIdForFrameOrProxy(parent_web_frame); | 211 GetRoutingIdForFrameOrProxy(parent_web_frame); |
181 } | 212 } |
182 } | 213 } |
183 | 214 |
184 return true; | 215 return true; |
185 } | 216 } |
186 | 217 |
187 blink::WebAXObject BlinkAXTreeSource::GetRoot() const { | 218 blink::WebAXObject BlinkAXTreeSource::GetRoot() const { |
188 if (!root_.isNull()) | 219 if (frozen_) |
189 return root_; | 220 return root_; |
190 return GetMainDocument().accessibilityObject(); | 221 else |
| 222 return ComputeRoot(); |
191 } | 223 } |
192 | 224 |
193 blink::WebAXObject BlinkAXTreeSource::GetFromId(int32_t id) const { | 225 blink::WebAXObject BlinkAXTreeSource::GetFromId(int32_t id) const { |
194 return GetMainDocument().accessibilityObjectFromID(id); | 226 return GetMainDocument().accessibilityObjectFromID(id); |
195 } | 227 } |
196 | 228 |
197 int32_t BlinkAXTreeSource::GetId(blink::WebAXObject node) const { | 229 int32_t BlinkAXTreeSource::GetId(blink::WebAXObject node) const { |
198 return node.axID(); | 230 return node.axID(); |
199 } | 231 } |
200 | 232 |
201 void BlinkAXTreeSource::GetChildren( | 233 void BlinkAXTreeSource::GetChildren( |
202 blink::WebAXObject parent, | 234 blink::WebAXObject parent, |
203 std::vector<blink::WebAXObject>* out_children) const { | 235 std::vector<blink::WebAXObject>* out_children) const { |
| 236 CHECK(frozen_); |
| 237 |
204 if (parent.role() == blink::WebAXRoleStaticText) { | 238 if (parent.role() == blink::WebAXRoleStaticText) { |
| 239 int32_t focus_id = focus().axID(); |
205 blink::WebAXObject ancestor = parent; | 240 blink::WebAXObject ancestor = parent; |
206 while (!ancestor.isDetached()) { | 241 while (!ancestor.isDetached()) { |
207 int32_t focus_id = GetMainDocument().focusedAccessibilityObject().axID(); | |
208 if (ancestor.axID() == accessibility_focus_id_ || | 242 if (ancestor.axID() == accessibility_focus_id_ || |
209 (ancestor.axID() == focus_id && ancestor.isEditable())) { | 243 (ancestor.axID() == focus_id && ancestor.isEditable())) { |
210 parent.loadInlineTextBoxes(); | 244 parent.loadInlineTextBoxes(); |
211 break; | 245 break; |
212 } | 246 } |
213 ancestor = ancestor.parentObject(); | 247 ancestor = ancestor.parentObject(); |
214 } | 248 } |
215 } | 249 } |
216 | 250 |
217 bool is_iframe = false; | 251 bool is_iframe = false; |
(...skipping 12 matching lines...) Expand all Loading... |
230 // As an exception, include children of an iframe element. | 264 // As an exception, include children of an iframe element. |
231 if (!is_iframe && !IsParentUnignoredOf(parent, child)) | 265 if (!is_iframe && !IsParentUnignoredOf(parent, child)) |
232 continue; | 266 continue; |
233 | 267 |
234 out_children->push_back(child); | 268 out_children->push_back(child); |
235 } | 269 } |
236 } | 270 } |
237 | 271 |
238 blink::WebAXObject BlinkAXTreeSource::GetParent( | 272 blink::WebAXObject BlinkAXTreeSource::GetParent( |
239 blink::WebAXObject node) const { | 273 blink::WebAXObject node) const { |
| 274 CHECK(frozen_); |
| 275 |
240 // Blink returns ignored objects when walking up the parent chain, | 276 // Blink returns ignored objects when walking up the parent chain, |
241 // we have to skip those here. Also, stop when we get to the root | 277 // we have to skip those here. Also, stop when we get to the root |
242 // element. | 278 // element. |
243 blink::WebAXObject root = GetRoot(); | |
244 do { | 279 do { |
245 if (node.equals(root)) | 280 if (node.equals(root())) |
246 return blink::WebAXObject(); | 281 return blink::WebAXObject(); |
247 node = node.parentObject(); | 282 node = node.parentObject(); |
248 } while (!node.isDetached() && node.accessibilityIsIgnored()); | 283 } while (!node.isDetached() && node.accessibilityIsIgnored()); |
249 | 284 |
250 return node; | 285 return node; |
251 } | 286 } |
252 | 287 |
253 bool BlinkAXTreeSource::IsValid(blink::WebAXObject node) const { | 288 bool BlinkAXTreeSource::IsValid(blink::WebAXObject node) const { |
254 return !node.isDetached(); // This also checks if it's null. | 289 return !node.isDetached(); // This also checks if it's null. |
255 } | 290 } |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); | 726 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); |
692 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); | 727 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); |
693 | 728 |
694 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); | 729 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); |
695 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); | 730 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); |
696 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); | 731 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); |
697 } | 732 } |
698 } | 733 } |
699 | 734 |
700 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { | 735 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { |
701 if (render_frame_ && render_frame_->GetWebFrame()) | 736 CHECK(frozen_); |
702 return render_frame_->GetWebFrame()->document(); | 737 return document_; |
703 return WebDocument(); | 738 } |
| 739 |
| 740 WebAXObject BlinkAXTreeSource::ComputeRoot() const { |
| 741 if (!explicit_root_.isNull()) |
| 742 return explicit_root_; |
| 743 |
| 744 if (!render_frame_ || !render_frame_->GetWebFrame()) |
| 745 return WebAXObject(); |
| 746 |
| 747 WebDocument document = render_frame_->GetWebFrame()->document(); |
| 748 if (!document.isNull()) |
| 749 return document.accessibilityObject(); |
| 750 |
| 751 return WebAXObject(); |
704 } | 752 } |
705 | 753 |
706 } // namespace content | 754 } // namespace content |
OLD | NEW |