Chromium Code Reviews| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 AXContentNodeData* dst) { | 104 AXContentNodeData* dst) { |
| 105 std::vector<int32_t> ids; | 105 std::vector<int32_t> ids; |
| 106 for(size_t i = 0; i < objects.size(); i++) | 106 for(size_t i = 0; i < objects.size(); i++) |
| 107 ids.push_back(objects[i].axID()); | 107 ids.push_back(objects[i].axID()); |
| 108 if (ids.size() > 0) | 108 if (ids.size() > 0) |
| 109 dst->AddIntListAttribute(attr, ids); | 109 dst->AddIntListAttribute(attr, ids); |
| 110 } | 110 } |
| 111 | 111 |
| 112 } // namespace | 112 } // namespace |
| 113 | 113 |
| 114 ScopedFreezeBlinkAXTreeSource::ScopedFreezeBlinkAXTreeSource( | |
| 115 BlinkAXTreeSource* tree_source) | |
| 116 : tree_source_(tree_source) { | |
| 117 tree_source_->Freeze(); | |
| 118 } | |
|
David Tseng
2016/09/07 18:59:27
nit: indent
dmazzoni
2016/09/08 05:26:43
I'm not 100% sure what indentation error you saw,
| |
| 119 | |
| 120 ScopedFreezeBlinkAXTreeSource::~ScopedFreezeBlinkAXTreeSource() { | |
| 121 tree_source_->Thaw(); | |
| 122 } | |
| 123 | |
| 114 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) | 124 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) |
| 115 : render_frame_(render_frame), | 125 : render_frame_(render_frame), |
| 116 accessibility_focus_id_(-1) { | 126 accessibility_focus_id_(-1), |
| 127 frozen_(false) { | |
| 117 } | 128 } |
| 118 | 129 |
| 119 BlinkAXTreeSource::~BlinkAXTreeSource() { | 130 BlinkAXTreeSource::~BlinkAXTreeSource() { |
| 120 } | 131 } |
| 121 | 132 |
| 133 void BlinkAXTreeSource::Freeze() { | |
| 134 CHECK(!frozen_); | |
| 135 | |
| 136 if (render_frame_ && render_frame_->GetWebFrame()) | |
| 137 document_ = render_frame_->GetWebFrame()->document(); | |
| 138 else | |
| 139 document_ = WebDocument(); | |
| 140 | |
| 141 if (!explicit_root_.isNull()) | |
| 142 root_ = explicit_root_; | |
| 143 else if (!document_.isNull()) | |
| 144 root_ = document_.accessibilityObject(); | |
| 145 else | |
| 146 root_ = WebAXObject(); | |
| 147 | |
| 148 if (!document_.isNull()) | |
| 149 focus_ = document_.focusedAccessibilityObject(); | |
| 150 else | |
| 151 focus_ = WebAXObject(); | |
| 152 | |
| 153 frozen_ = true; | |
| 154 } | |
| 155 | |
|
David Tseng
2016/09/07 18:59:27
Could we move this to the beginning of the functio
dmazzoni
2016/09/08 05:26:43
Sure, done.
| |
| 156 void BlinkAXTreeSource::Thaw() { | |
| 157 CHECK(frozen_); | |
| 158 frozen_ = false; | |
| 159 } | |
| 160 | |
| 122 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { | 161 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { |
| 123 root_ = root; | 162 CHECK(!frozen_); |
| 163 explicit_root_ = root; | |
| 124 } | 164 } |
| 125 | 165 |
| 126 bool BlinkAXTreeSource::IsInTree(blink::WebAXObject node) const { | 166 bool BlinkAXTreeSource::IsInTree(blink::WebAXObject node) const { |
| 127 const blink::WebAXObject& root = GetRoot(); | 167 CHECK(frozen_); |
| 128 while (IsValid(node)) { | 168 while (IsValid(node)) { |
| 129 if (node.equals(root)) | 169 if (node.equals(root_)) |
| 130 return true; | 170 return true; |
| 131 node = GetParent(node); | 171 node = GetParent(node); |
| 132 } | 172 } |
| 133 return false; | 173 return false; |
| 134 } | 174 } |
| 135 | 175 |
| 136 bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const { | 176 bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const { |
| 137 blink::WebDocument document = BlinkAXTreeSource::GetMainDocument(); | 177 CHECK(frozen_); |
| 138 const blink::WebAXObject& root = GetRoot(); | 178 tree_data->doctype = "html"; |
| 179 tree_data->loaded = root_.isLoaded(); | |
| 180 tree_data->loading_progress = root_.estimatedLoadingProgress(); | |
| 181 tree_data->mimetype = | |
| 182 document_.isXHTMLDocument() ? "text/xhtml" : "text/html"; | |
| 183 tree_data->title = document_.title().utf8(); | |
| 184 tree_data->url = document_.url().string().utf8(); | |
| 139 | 185 |
| 140 tree_data->doctype = "html"; | 186 if (!focus_.isNull()) |
| 141 tree_data->loaded = root.isLoaded(); | 187 tree_data->focus_id = focus_.axID(); |
| 142 tree_data->loading_progress = root.estimatedLoadingProgress(); | |
| 143 tree_data->mimetype = document.isXHTMLDocument() ? "text/xhtml" : "text/html"; | |
| 144 tree_data->title = document.title().utf8(); | |
| 145 tree_data->url = document.url().string().utf8(); | |
| 146 | |
| 147 WebAXObject focus = document.focusedAccessibilityObject(); | |
| 148 if (!focus.isNull()) | |
| 149 tree_data->focus_id = focus.axID(); | |
| 150 | 188 |
| 151 WebAXObject anchor_object, focus_object; | 189 WebAXObject anchor_object, focus_object; |
| 152 int anchor_offset, focus_offset; | 190 int anchor_offset, focus_offset; |
| 153 blink::WebAXTextAffinity anchor_affinity, focus_affinity; | 191 blink::WebAXTextAffinity anchor_affinity, focus_affinity; |
| 154 root.selection(anchor_object, anchor_offset, anchor_affinity, | 192 root_.selection(anchor_object, anchor_offset, anchor_affinity, |
| 155 focus_object, focus_offset, focus_affinity); | 193 focus_object, focus_offset, focus_affinity); |
| 156 if (!anchor_object.isNull() && !focus_object.isNull() && | 194 if (!anchor_object.isNull() && !focus_object.isNull() && |
| 157 anchor_offset >= 0 && focus_offset >= 0) { | 195 anchor_offset >= 0 && focus_offset >= 0) { |
| 158 int32_t anchor_id = anchor_object.axID(); | 196 int32_t anchor_id = anchor_object.axID(); |
| 159 int32_t focus_id = focus_object.axID(); | 197 int32_t focus_id = focus_object.axID(); |
| 160 tree_data->sel_anchor_object_id = anchor_id; | 198 tree_data->sel_anchor_object_id = anchor_id; |
| 161 tree_data->sel_anchor_offset = anchor_offset; | 199 tree_data->sel_anchor_offset = anchor_offset; |
| 162 tree_data->sel_focus_object_id = focus_id; | 200 tree_data->sel_focus_object_id = focus_id; |
| 163 tree_data->sel_focus_offset = focus_offset; | 201 tree_data->sel_focus_offset = focus_offset; |
| 164 tree_data->sel_anchor_affinity = AXTextAffinityFromBlink(anchor_affinity); | 202 tree_data->sel_anchor_affinity = AXTextAffinityFromBlink(anchor_affinity); |
| 165 tree_data->sel_focus_affinity = AXTextAffinityFromBlink(focus_affinity); | 203 tree_data->sel_focus_affinity = AXTextAffinityFromBlink(focus_affinity); |
| 166 } | 204 } |
| 167 | 205 |
| 168 // Get the tree ID for this frame and the parent frame. | 206 // Get the tree ID for this frame and the parent frame. |
| 169 WebLocalFrame* web_frame = document.frame(); | 207 WebLocalFrame* web_frame = document_.frame(); |
| 170 if (web_frame) { | 208 if (web_frame) { |
| 171 RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame); | 209 RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame); |
| 172 tree_data->routing_id = render_frame->GetRoutingID(); | 210 tree_data->routing_id = render_frame->GetRoutingID(); |
| 173 | 211 |
| 174 // Get the tree ID for the parent frame. | 212 // Get the tree ID for the parent frame. |
| 175 blink::WebFrame* parent_web_frame = web_frame->parent(); | 213 blink::WebFrame* parent_web_frame = web_frame->parent(); |
| 176 if (parent_web_frame) { | 214 if (parent_web_frame) { |
| 177 tree_data->parent_routing_id = | 215 tree_data->parent_routing_id = |
| 178 GetRoutingIdForFrameOrProxy(parent_web_frame); | 216 GetRoutingIdForFrameOrProxy(parent_web_frame); |
| 179 } | 217 } |
| 180 } | 218 } |
| 181 | 219 |
| 182 return true; | 220 return true; |
| 183 } | 221 } |
| 184 | 222 |
| 185 blink::WebAXObject BlinkAXTreeSource::GetRoot() const { | 223 blink::WebAXObject BlinkAXTreeSource::GetRoot() const { |
| 186 if (!root_.isNull()) | 224 CHECK(frozen_); |
| 187 return root_; | 225 return root_; |
| 188 return GetMainDocument().accessibilityObject(); | |
| 189 } | 226 } |
| 190 | 227 |
| 191 blink::WebAXObject BlinkAXTreeSource::GetFromId(int32_t id) const { | 228 blink::WebAXObject BlinkAXTreeSource::GetFromId(int32_t id) const { |
| 192 return GetMainDocument().accessibilityObjectFromID(id); | 229 return GetMainDocument().accessibilityObjectFromID(id); |
| 193 } | 230 } |
| 194 | 231 |
| 195 int32_t BlinkAXTreeSource::GetId(blink::WebAXObject node) const { | 232 int32_t BlinkAXTreeSource::GetId(blink::WebAXObject node) const { |
| 196 return node.axID(); | 233 return node.axID(); |
| 197 } | 234 } |
| 198 | 235 |
| 199 void BlinkAXTreeSource::GetChildren( | 236 void BlinkAXTreeSource::GetChildren( |
| 200 blink::WebAXObject parent, | 237 blink::WebAXObject parent, |
| 201 std::vector<blink::WebAXObject>* out_children) const { | 238 std::vector<blink::WebAXObject>* out_children) const { |
| 239 CHECK(frozen_); | |
| 240 | |
| 202 if (parent.role() == blink::WebAXRoleStaticText) { | 241 if (parent.role() == blink::WebAXRoleStaticText) { |
| 203 blink::WebAXObject ancestor = parent; | 242 blink::WebAXObject ancestor = parent; |
| 204 while (!ancestor.isDetached()) { | 243 while (!ancestor.isDetached()) { |
| 205 int32_t focus_id = GetMainDocument().focusedAccessibilityObject().axID(); | 244 int32_t focus_id = focus_.axID(); |
| 206 if (ancestor.axID() == accessibility_focus_id_ || | 245 if (ancestor.axID() == accessibility_focus_id_ || |
| 207 (ancestor.axID() == focus_id && ancestor.isEditable())) { | 246 (ancestor.axID() == focus_id && ancestor.isEditable())) { |
| 208 parent.loadInlineTextBoxes(); | 247 parent.loadInlineTextBoxes(); |
| 209 break; | 248 break; |
| 210 } | 249 } |
| 211 ancestor = ancestor.parentObject(); | 250 ancestor = ancestor.parentObject(); |
| 212 } | 251 } |
| 213 } | 252 } |
| 214 | 253 |
| 215 bool is_iframe = false; | 254 bool is_iframe = false; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 228 // As an exception, include children of an iframe element. | 267 // As an exception, include children of an iframe element. |
| 229 if (!is_iframe && !IsParentUnignoredOf(parent, child)) | 268 if (!is_iframe && !IsParentUnignoredOf(parent, child)) |
| 230 continue; | 269 continue; |
| 231 | 270 |
| 232 out_children->push_back(child); | 271 out_children->push_back(child); |
| 233 } | 272 } |
| 234 } | 273 } |
| 235 | 274 |
| 236 blink::WebAXObject BlinkAXTreeSource::GetParent( | 275 blink::WebAXObject BlinkAXTreeSource::GetParent( |
| 237 blink::WebAXObject node) const { | 276 blink::WebAXObject node) const { |
| 277 CHECK(frozen_); | |
| 278 | |
| 238 // Blink returns ignored objects when walking up the parent chain, | 279 // Blink returns ignored objects when walking up the parent chain, |
| 239 // we have to skip those here. Also, stop when we get to the root | 280 // we have to skip those here. Also, stop when we get to the root |
| 240 // element. | 281 // element. |
| 241 blink::WebAXObject root = GetRoot(); | |
| 242 do { | 282 do { |
| 243 if (node.equals(root)) | 283 if (node.equals(root_)) |
| 244 return blink::WebAXObject(); | 284 return blink::WebAXObject(); |
| 245 node = node.parentObject(); | 285 node = node.parentObject(); |
| 246 } while (!node.isDetached() && node.accessibilityIsIgnored()); | 286 } while (!node.isDetached() && node.accessibilityIsIgnored()); |
| 247 | 287 |
| 248 return node; | 288 return node; |
| 249 } | 289 } |
| 250 | 290 |
| 251 bool BlinkAXTreeSource::IsValid(blink::WebAXObject node) const { | 291 bool BlinkAXTreeSource::IsValid(blink::WebAXObject node) const { |
| 252 return !node.isDetached(); // This also checks if it's null. | 292 return !node.isDetached(); // This also checks if it's null. |
| 253 } | 293 } |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); | 722 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); |
| 683 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); | 723 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); |
| 684 | 724 |
| 685 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); | 725 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); |
| 686 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); | 726 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); |
| 687 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); | 727 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); |
| 688 } | 728 } |
| 689 } | 729 } |
| 690 | 730 |
| 691 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { | 731 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { |
| 692 if (render_frame_ && render_frame_->GetWebFrame()) | 732 CHECK(frozen_); |
| 693 return render_frame_->GetWebFrame()->document(); | 733 return document_; |
| 694 return WebDocument(); | |
| 695 } | 734 } |
| 696 | 735 |
| 697 } // namespace content | 736 } // namespace content |
| OLD | NEW |