OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_accessibility_complete.h" | 5 #include "content/renderer/accessibility/renderer_accessibility_complete.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "content/renderer/accessibility/accessibility_node_serializer.h" | 11 #include "content/renderer/accessibility/accessibility_node_serializer.h" |
| 12 #include "content/renderer/accessibility/blink_ax_enum_conversion.h" |
12 #include "content/renderer/render_view_impl.h" | 13 #include "content/renderer/render_view_impl.h" |
13 #include "third_party/WebKit/public/web/WebAXObject.h" | 14 #include "third_party/WebKit/public/web/WebAXObject.h" |
14 #include "third_party/WebKit/public/web/WebDocument.h" | 15 #include "third_party/WebKit/public/web/WebDocument.h" |
15 #include "third_party/WebKit/public/web/WebFrame.h" | 16 #include "third_party/WebKit/public/web/WebFrame.h" |
16 #include "third_party/WebKit/public/web/WebInputElement.h" | 17 #include "third_party/WebKit/public/web/WebInputElement.h" |
17 #include "third_party/WebKit/public/web/WebNode.h" | 18 #include "third_party/WebKit/public/web/WebNode.h" |
18 #include "third_party/WebKit/public/web/WebView.h" | 19 #include "third_party/WebKit/public/web/WebView.h" |
| 20 #include "ui/accessibility/ax_tree.h" |
19 | 21 |
20 using blink::WebAXObject; | 22 using blink::WebAXObject; |
21 using blink::WebDocument; | 23 using blink::WebDocument; |
22 using blink::WebFrame; | 24 using blink::WebFrame; |
23 using blink::WebNode; | 25 using blink::WebNode; |
24 using blink::WebPoint; | 26 using blink::WebPoint; |
25 using blink::WebRect; | 27 using blink::WebRect; |
26 using blink::WebSize; | 28 using blink::WebSize; |
27 using blink::WebView; | 29 using blink::WebView; |
28 | 30 |
(...skipping 13 matching lines...) Expand all Loading... |
42 // APIs that compute the bounds of a range of text, it's a waste to | 44 // APIs that compute the bounds of a range of text, it's a waste to |
43 // include these in the AX tree. | 45 // include these in the AX tree. |
44 WebAXObject::enableInlineTextBoxAccessibility(); | 46 WebAXObject::enableInlineTextBoxAccessibility(); |
45 #endif | 47 #endif |
46 | 48 |
47 const WebDocument& document = GetMainDocument(); | 49 const WebDocument& document = GetMainDocument(); |
48 if (!document.isNull()) { | 50 if (!document.isNull()) { |
49 // It's possible that the webview has already loaded a webpage without | 51 // It's possible that the webview has already loaded a webpage without |
50 // accessibility being enabled. Initialize the browser's cached | 52 // accessibility being enabled. Initialize the browser's cached |
51 // accessibility tree by sending it a notification. | 53 // accessibility tree by sending it a notification. |
52 HandleWebAccessibilityEvent(document.accessibilityObject(), | 54 HandleAXEvent(document.accessibilityObject(), |
53 blink::WebAXEventLayoutComplete); | 55 ui::AX_EVENT_LAYOUT_COMPLETE); |
54 } | 56 } |
55 } | 57 } |
56 | 58 |
57 RendererAccessibilityComplete::~RendererAccessibilityComplete() { | 59 RendererAccessibilityComplete::~RendererAccessibilityComplete() { |
58 if (browser_root_) { | 60 if (browser_root_) { |
59 ClearBrowserTreeNode(browser_root_); | 61 ClearBrowserTreeNode(browser_root_); |
60 browser_id_map_.erase(browser_root_->id); | 62 browser_id_map_.erase(browser_root_->id); |
61 delete browser_root_; | 63 delete browser_root_; |
62 } | 64 } |
63 DCHECK(browser_id_map_.empty()); | 65 DCHECK(browser_id_map_.empty()); |
(...skipping 21 matching lines...) Expand all Loading... |
85 } | 87 } |
86 | 88 |
87 void RendererAccessibilityComplete::FocusedNodeChanged(const WebNode& node) { | 89 void RendererAccessibilityComplete::FocusedNodeChanged(const WebNode& node) { |
88 const WebDocument& document = GetMainDocument(); | 90 const WebDocument& document = GetMainDocument(); |
89 if (document.isNull()) | 91 if (document.isNull()) |
90 return; | 92 return; |
91 | 93 |
92 if (node.isNull()) { | 94 if (node.isNull()) { |
93 // When focus is cleared, implicitly focus the document. | 95 // When focus is cleared, implicitly focus the document. |
94 // TODO(dmazzoni): Make WebKit send this notification instead. | 96 // TODO(dmazzoni): Make WebKit send this notification instead. |
95 HandleWebAccessibilityEvent(document.accessibilityObject(), | 97 HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_BLUR); |
96 blink::WebAXEventBlur); | |
97 } | 98 } |
98 } | 99 } |
99 | 100 |
100 void RendererAccessibilityComplete::DidFinishLoad(blink::WebFrame* frame) { | 101 void RendererAccessibilityComplete::DidFinishLoad(blink::WebFrame* frame) { |
101 const WebDocument& document = GetMainDocument(); | 102 const WebDocument& document = GetMainDocument(); |
102 if (document.isNull()) | 103 if (document.isNull()) |
103 return; | 104 return; |
104 | 105 |
105 // Check to see if the root accessibility object has changed, to work | 106 // Check to see if the root accessibility object has changed, to work |
106 // around WebKit bugs that cause AXObjectCache to be cleared | 107 // around WebKit bugs that cause AXObjectCache to be cleared |
107 // unnecessarily. | 108 // unnecessarily. |
108 // TODO(dmazzoni): remove this once rdar://5794454 is fixed. | 109 // TODO(dmazzoni): remove this once rdar://5794454 is fixed. |
109 WebAXObject new_root = document.accessibilityObject(); | 110 WebAXObject new_root = document.accessibilityObject(); |
110 if (!browser_root_ || new_root.axID() != browser_root_->id) | 111 if (!browser_root_ || new_root.axID() != browser_root_->id) |
111 HandleWebAccessibilityEvent(new_root, blink::WebAXEventLayoutComplete); | 112 HandleAXEvent(new_root, ui::AX_EVENT_LAYOUT_COMPLETE); |
112 } | 113 } |
113 | 114 |
| 115 |
114 void RendererAccessibilityComplete::HandleWebAccessibilityEvent( | 116 void RendererAccessibilityComplete::HandleWebAccessibilityEvent( |
115 const blink::WebAXObject& obj, | 117 const blink::WebAXObject& obj, blink::WebAXEvent event) { |
116 blink::WebAXEvent event) { | 118 HandleAXEvent(obj, AXEventFromBlink(event)); |
| 119 } |
| 120 |
| 121 void RendererAccessibilityComplete::HandleAXEvent( |
| 122 const blink::WebAXObject& obj, ui::AXEvent event) { |
117 const WebDocument& document = GetMainDocument(); | 123 const WebDocument& document = GetMainDocument(); |
118 if (document.isNull()) | 124 if (document.isNull()) |
119 return; | 125 return; |
120 | 126 |
121 gfx::Size scroll_offset = document.frame()->scrollOffset(); | 127 gfx::Size scroll_offset = document.frame()->scrollOffset(); |
122 if (scroll_offset != last_scroll_offset_) { | 128 if (scroll_offset != last_scroll_offset_) { |
123 // Make sure the browser is always aware of the scroll position of | 129 // Make sure the browser is always aware of the scroll position of |
124 // the root document element by posting a generic notification that | 130 // the root document element by posting a generic notification that |
125 // will update it. | 131 // will update it. |
126 // TODO(dmazzoni): remove this as soon as | 132 // TODO(dmazzoni): remove this as soon as |
127 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed. | 133 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed. |
128 last_scroll_offset_ = scroll_offset; | 134 last_scroll_offset_ = scroll_offset; |
129 if (!obj.equals(document.accessibilityObject())) { | 135 if (!obj.equals(document.accessibilityObject())) { |
130 HandleWebAccessibilityEvent( | 136 HandleAXEvent(document.accessibilityObject(), |
131 document.accessibilityObject(), | 137 ui::AX_EVENT_LAYOUT_COMPLETE); |
132 blink::WebAXEventLayoutComplete); | |
133 } | 138 } |
134 } | 139 } |
135 | 140 |
136 // Add the accessibility object to our cache and ensure it's valid. | 141 // Add the accessibility object to our cache and ensure it's valid. |
137 AccessibilityHostMsg_EventParams acc_event; | 142 AccessibilityHostMsg_EventParams acc_event; |
138 acc_event.id = obj.axID(); | 143 acc_event.id = obj.axID(); |
139 acc_event.event_type = event; | 144 acc_event.event_type = event; |
140 | 145 |
141 // Discard duplicate accessibility events. | 146 // Discard duplicate accessibility events. |
142 for (uint32 i = 0; i < pending_events_.size(); ++i) { | 147 for (uint32 i = 0; i < pending_events_.size(); ++i) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 199 |
195 WebAXObject obj = document.accessibilityObjectFromID( | 200 WebAXObject obj = document.accessibilityObjectFromID( |
196 event.id); | 201 event.id); |
197 if (!obj.updateBackingStoreAndCheckValidity()) | 202 if (!obj.updateBackingStoreAndCheckValidity()) |
198 continue; | 203 continue; |
199 | 204 |
200 // When we get a "selected children changed" event, WebKit | 205 // When we get a "selected children changed" event, WebKit |
201 // doesn't also send us events for each child that changed | 206 // doesn't also send us events for each child that changed |
202 // selection state, so make sure we re-send that whole subtree. | 207 // selection state, so make sure we re-send that whole subtree. |
203 if (event.event_type == | 208 if (event.event_type == |
204 blink::WebAXEventSelectedChildrenChanged) { | 209 ui::AX_EVENT_SELECTED_CHILDREN_CHANGED) { |
205 base::hash_map<int32, BrowserTreeNode*>::iterator iter = | 210 base::hash_map<int32, BrowserTreeNode*>::iterator iter = |
206 browser_id_map_.find(obj.axID()); | 211 browser_id_map_.find(obj.axID()); |
207 if (iter != browser_id_map_.end()) | 212 if (iter != browser_id_map_.end()) |
208 ClearBrowserTreeNode(iter->second); | 213 ClearBrowserTreeNode(iter->second); |
209 } | 214 } |
210 | 215 |
211 // The browser may not have this object yet, for example if we get a | 216 // The browser may not have this object yet, for example if we get a |
212 // event on an object that was recently added, or if we get a | 217 // event on an object that was recently added, or if we get a |
213 // event on a node before the page has loaded. Work our way | 218 // event on a node before the page has loaded. Work our way |
214 // up the parent chain until we find a node the browser has, or until | 219 // up the parent chain until we find a node the browser has, or until |
215 // we reach the root. | 220 // we reach the root. |
216 WebAXObject root_object = document.accessibilityObject(); | 221 WebAXObject root_object = document.accessibilityObject(); |
217 int root_id = root_object.axID(); | 222 int root_id = root_object.axID(); |
218 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() && | 223 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() && |
219 !obj.isDetached() && | 224 !obj.isDetached() && |
220 obj.axID() != root_id) { | 225 obj.axID() != root_id) { |
221 obj = obj.parentObject(); | 226 obj = obj.parentObject(); |
222 if (event.event_type == | 227 if (event.event_type == |
223 blink::WebAXEventChildrenChanged) { | 228 ui::AX_EVENT_CHILDREN_CHANGED) { |
224 event.id = obj.axID(); | 229 event.id = obj.axID(); |
225 } | 230 } |
226 } | 231 } |
227 | 232 |
228 if (obj.isDetached()) { | 233 if (obj.isDetached()) { |
229 #ifndef NDEBUG | 234 #ifndef NDEBUG |
230 if (logging_) | 235 LOG(WARNING) << "Got event on object that is invalid or has" |
231 LOG(WARNING) << "Got event on object that is invalid or has" | 236 << " invalid ancestor. Id: " << obj.axID(); |
232 << " invalid ancestor. Id: " << obj.axID(); | |
233 #endif | 237 #endif |
234 continue; | 238 continue; |
235 } | 239 } |
236 | 240 |
237 // Another potential problem is that this event may be on an | 241 // Another potential problem is that this event may be on an |
238 // object that is detached from the tree. Determine if this node is not a | 242 // object that is detached from the tree. Determine if this node is not a |
239 // child of its parent, and if so move the event to the parent. | 243 // child of its parent, and if so move the event to the parent. |
240 // TODO(dmazzoni): see if this can be removed after | 244 // TODO(dmazzoni): see if this can be removed after |
241 // https://bugs.webkit.org/show_bug.cgi?id=68466 is fixed. | 245 // https://bugs.webkit.org/show_bug.cgi?id=68466 is fixed. |
242 if (obj.axID() != root_id) { | 246 if (obj.axID() != root_id) { |
(...skipping 26 matching lines...) Expand all Loading... |
269 root_object.startCachingComputedObjectAttributesUntilTreeMutates(); | 273 root_object.startCachingComputedObjectAttributesUntilTreeMutates(); |
270 | 274 |
271 AccessibilityHostMsg_EventParams event_msg; | 275 AccessibilityHostMsg_EventParams event_msg; |
272 event_msg.event_type = event.event_type; | 276 event_msg.event_type = event.event_type; |
273 event_msg.id = event.id; | 277 event_msg.id = event.id; |
274 std::set<int> ids_serialized; | 278 std::set<int> ids_serialized; |
275 SerializeChangedNodes(obj, &event_msg.nodes, &ids_serialized); | 279 SerializeChangedNodes(obj, &event_msg.nodes, &ids_serialized); |
276 event_msgs.push_back(event_msg); | 280 event_msgs.push_back(event_msg); |
277 | 281 |
278 #ifndef NDEBUG | 282 #ifndef NDEBUG |
279 if (logging_) { | 283 ui::AXTree tree; |
280 AccessibilityNodeDataTreeNode tree; | 284 ui::AXTreeUpdate update; |
281 MakeAccessibilityNodeDataTree(event_msg.nodes, &tree); | 285 update.nodes = event_msg.nodes; |
282 VLOG(0) << "Accessibility update: \n" | 286 tree.Unserialize(update); |
283 << "routing id=" << routing_id() | 287 VLOG(0) << "Accessibility update: \n" |
284 << " event=" | 288 << "routing id=" << routing_id() |
285 << AccessibilityEventToString(event.event_type) | 289 << " event=" |
286 << "\n" << tree.DebugString(true); | 290 << AccessibilityEventToString(event.event_type) |
287 } | 291 << "\n" << tree.ToString(); |
288 #endif | 292 #endif |
289 } | 293 } |
290 | 294 |
291 Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs)); | 295 Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs)); |
292 | 296 |
293 SendLocationChanges(); | 297 SendLocationChanges(); |
294 } | 298 } |
295 | 299 |
296 void RendererAccessibilityComplete::SendLocationChanges() { | 300 void RendererAccessibilityComplete::SendLocationChanges() { |
297 std::queue<WebAXObject> objs_to_explore; | 301 std::queue<WebAXObject> objs_to_explore; |
(...skipping 30 matching lines...) Expand all Loading... |
328 Send(new AccessibilityHostMsg_LocationChanges(routing_id(), messages)); | 332 Send(new AccessibilityHostMsg_LocationChanges(routing_id(), messages)); |
329 } | 333 } |
330 | 334 |
331 RendererAccessibilityComplete::BrowserTreeNode* | 335 RendererAccessibilityComplete::BrowserTreeNode* |
332 RendererAccessibilityComplete::CreateBrowserTreeNode() { | 336 RendererAccessibilityComplete::CreateBrowserTreeNode() { |
333 return new RendererAccessibilityComplete::BrowserTreeNode(); | 337 return new RendererAccessibilityComplete::BrowserTreeNode(); |
334 } | 338 } |
335 | 339 |
336 void RendererAccessibilityComplete::SerializeChangedNodes( | 340 void RendererAccessibilityComplete::SerializeChangedNodes( |
337 const blink::WebAXObject& obj, | 341 const blink::WebAXObject& obj, |
338 std::vector<AccessibilityNodeData>* dst, | 342 std::vector<ui::AXNodeData>* dst, |
339 std::set<int>* ids_serialized) { | 343 std::set<int>* ids_serialized) { |
340 if (ids_serialized->find(obj.axID()) != ids_serialized->end()) | 344 if (ids_serialized->find(obj.axID()) != ids_serialized->end()) |
341 return; | 345 return; |
342 ids_serialized->insert(obj.axID()); | 346 ids_serialized->insert(obj.axID()); |
343 | 347 |
344 // This method has three responsibilities: | 348 // This method has three responsibilities: |
345 // 1. Serialize |obj| into an AccessibilityNodeData, and append it to | 349 // 1. Serialize |obj| into an ui::AXNodeData, and append it to |
346 // the end of the |dst| vector to be send to the browser process. | 350 // the end of the |dst| vector to be send to the browser process. |
347 // 2. Determine if |obj| has any new children that the browser doesn't | 351 // 2. Determine if |obj| has any new children that the browser doesn't |
348 // know about yet, and call SerializeChangedNodes recursively on those. | 352 // know about yet, and call SerializeChangedNodes recursively on those. |
349 // 3. Update our internal data structure that keeps track of what nodes | 353 // 3. Update our internal data structure that keeps track of what nodes |
350 // the browser knows about. | 354 // the browser knows about. |
351 | 355 |
352 // First, find the BrowserTreeNode for this id in our data structure where | 356 // First, find the BrowserTreeNode for this id in our data structure where |
353 // we keep track of what accessibility objects the browser already knows | 357 // we keep track of what accessibility objects the browser already knows |
354 // about. If we don't find it, then this must be the new root of the | 358 // about. If we don't find it, then this must be the new root of the |
355 // accessibility tree. | 359 // accessibility tree. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 if (new_child_ids.find(old_child_id) == new_child_ids.end()) { | 429 if (new_child_ids.find(old_child_id) == new_child_ids.end()) { |
426 browser_id_map_.erase(old_child_id); | 430 browser_id_map_.erase(old_child_id); |
427 ClearBrowserTreeNode(old_child); | 431 ClearBrowserTreeNode(old_child); |
428 delete old_child; | 432 delete old_child; |
429 } else { | 433 } else { |
430 browser_child_id_map[old_child_id] = old_child; | 434 browser_child_id_map[old_child_id] = old_child; |
431 } | 435 } |
432 } | 436 } |
433 | 437 |
434 // Serialize this node. This fills in all of the fields in | 438 // Serialize this node. This fills in all of the fields in |
435 // AccessibilityNodeData except child_ids, which we handle below. | 439 // ui::AXNodeData except child_ids, which we handle below. |
436 dst->push_back(AccessibilityNodeData()); | 440 dst->push_back(ui::AXNodeData()); |
437 AccessibilityNodeData* serialized_node = &dst->back(); | 441 ui::AXNodeData* serialized_node = &dst->back(); |
438 SerializeAccessibilityNode(obj, serialized_node); | 442 SerializeAccessibilityNode(obj, serialized_node); |
439 if (serialized_node->id == browser_root_->id) | 443 if (serialized_node->id == browser_root_->id) |
440 serialized_node->role = blink::WebAXRoleRootWebArea; | 444 serialized_node->role = ui::AX_ROLE_ROOT_WEB_AREA; |
441 | 445 |
442 // Iterate over the children, make note of the ones that are new | 446 // Iterate over the children, make note of the ones that are new |
443 // and need to be serialized, and update the BrowserTreeNode | 447 // and need to be serialized, and update the BrowserTreeNode |
444 // data structure to reflect the new tree. | 448 // data structure to reflect the new tree. |
445 std::vector<WebAXObject> children_to_serialize; | 449 std::vector<WebAXObject> children_to_serialize; |
446 int child_count = obj.childCount(); | 450 int child_count = obj.childCount(); |
447 browser_node->children.reserve(child_count); | 451 browser_node->children.reserve(child_count); |
448 for (int i = 0; i < child_count; i++) { | 452 for (int i = 0; i < child_count; i++) { |
449 WebAXObject child = obj.childAt(i); | 453 WebAXObject child = obj.childAt(i); |
450 int child_id = child.axID(); | 454 int child_id = child.axID(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 } | 495 } |
492 | 496 |
493 void RendererAccessibilityComplete::OnDoDefaultAction(int acc_obj_id) { | 497 void RendererAccessibilityComplete::OnDoDefaultAction(int acc_obj_id) { |
494 const WebDocument& document = GetMainDocument(); | 498 const WebDocument& document = GetMainDocument(); |
495 if (document.isNull()) | 499 if (document.isNull()) |
496 return; | 500 return; |
497 | 501 |
498 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); | 502 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); |
499 if (obj.isDetached()) { | 503 if (obj.isDetached()) { |
500 #ifndef NDEBUG | 504 #ifndef NDEBUG |
501 if (logging_) | 505 LOG(WARNING) << "DoDefaultAction on invalid object id " << acc_obj_id; |
502 LOG(WARNING) << "DoDefaultAction on invalid object id " << acc_obj_id; | |
503 #endif | 506 #endif |
504 return; | 507 return; |
505 } | 508 } |
506 | 509 |
507 obj.performDefaultAction(); | 510 obj.performDefaultAction(); |
508 } | 511 } |
509 | 512 |
510 void RendererAccessibilityComplete::OnScrollToMakeVisible( | 513 void RendererAccessibilityComplete::OnScrollToMakeVisible( |
511 int acc_obj_id, gfx::Rect subfocus) { | 514 int acc_obj_id, gfx::Rect subfocus) { |
512 const WebDocument& document = GetMainDocument(); | 515 const WebDocument& document = GetMainDocument(); |
513 if (document.isNull()) | 516 if (document.isNull()) |
514 return; | 517 return; |
515 | 518 |
516 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); | 519 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); |
517 if (obj.isDetached()) { | 520 if (obj.isDetached()) { |
518 #ifndef NDEBUG | 521 #ifndef NDEBUG |
519 if (logging_) | 522 LOG(WARNING) << "ScrollToMakeVisible on invalid object id " << acc_obj_id; |
520 LOG(WARNING) << "ScrollToMakeVisible on invalid object id " << acc_obj_id; | |
521 #endif | 523 #endif |
522 return; | 524 return; |
523 } | 525 } |
524 | 526 |
525 obj.scrollToMakeVisibleWithSubFocus( | 527 obj.scrollToMakeVisibleWithSubFocus( |
526 WebRect(subfocus.x(), subfocus.y(), | 528 WebRect(subfocus.x(), subfocus.y(), |
527 subfocus.width(), subfocus.height())); | 529 subfocus.width(), subfocus.height())); |
528 | 530 |
529 // Make sure the browser gets an event when the scroll | 531 // Make sure the browser gets an event when the scroll |
530 // position actually changes. | 532 // position actually changes. |
531 // TODO(dmazzoni): remove this once this bug is fixed: | 533 // TODO(dmazzoni): remove this once this bug is fixed: |
532 // https://bugs.webkit.org/show_bug.cgi?id=73460 | 534 // https://bugs.webkit.org/show_bug.cgi?id=73460 |
533 HandleWebAccessibilityEvent( | 535 HandleAXEvent(document.accessibilityObject(), |
534 document.accessibilityObject(), | 536 ui::AX_EVENT_LAYOUT_COMPLETE); |
535 blink::WebAXEventLayoutComplete); | |
536 } | 537 } |
537 | 538 |
538 void RendererAccessibilityComplete::OnScrollToPoint( | 539 void RendererAccessibilityComplete::OnScrollToPoint( |
539 int acc_obj_id, gfx::Point point) { | 540 int acc_obj_id, gfx::Point point) { |
540 const WebDocument& document = GetMainDocument(); | 541 const WebDocument& document = GetMainDocument(); |
541 if (document.isNull()) | 542 if (document.isNull()) |
542 return; | 543 return; |
543 | 544 |
544 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); | 545 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); |
545 if (obj.isDetached()) { | 546 if (obj.isDetached()) { |
546 #ifndef NDEBUG | 547 #ifndef NDEBUG |
547 if (logging_) | 548 LOG(WARNING) << "ScrollToPoint on invalid object id " << acc_obj_id; |
548 LOG(WARNING) << "ScrollToPoint on invalid object id " << acc_obj_id; | |
549 #endif | 549 #endif |
550 return; | 550 return; |
551 } | 551 } |
552 | 552 |
553 obj.scrollToGlobalPoint(WebPoint(point.x(), point.y())); | 553 obj.scrollToGlobalPoint(WebPoint(point.x(), point.y())); |
554 | 554 |
555 // Make sure the browser gets an event when the scroll | 555 // Make sure the browser gets an event when the scroll |
556 // position actually changes. | 556 // position actually changes. |
557 // TODO(dmazzoni): remove this once this bug is fixed: | 557 // TODO(dmazzoni): remove this once this bug is fixed: |
558 // https://bugs.webkit.org/show_bug.cgi?id=73460 | 558 // https://bugs.webkit.org/show_bug.cgi?id=73460 |
559 HandleWebAccessibilityEvent( | 559 HandleAXEvent(document.accessibilityObject(), |
560 document.accessibilityObject(), | 560 ui::AX_EVENT_LAYOUT_COMPLETE); |
561 blink::WebAXEventLayoutComplete); | |
562 } | 561 } |
563 | 562 |
564 void RendererAccessibilityComplete::OnSetTextSelection( | 563 void RendererAccessibilityComplete::OnSetTextSelection( |
565 int acc_obj_id, int start_offset, int end_offset) { | 564 int acc_obj_id, int start_offset, int end_offset) { |
566 const WebDocument& document = GetMainDocument(); | 565 const WebDocument& document = GetMainDocument(); |
567 if (document.isNull()) | 566 if (document.isNull()) |
568 return; | 567 return; |
569 | 568 |
570 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); | 569 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); |
571 if (obj.isDetached()) { | 570 if (obj.isDetached()) { |
572 #ifndef NDEBUG | 571 #ifndef NDEBUG |
573 if (logging_) | 572 LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id; |
574 LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id; | |
575 #endif | 573 #endif |
576 return; | 574 return; |
577 } | 575 } |
578 | 576 |
579 // TODO(dmazzoni): support elements other than <input>. | 577 // TODO(dmazzoni): support elements other than <input>. |
580 blink::WebNode node = obj.node(); | 578 blink::WebNode node = obj.node(); |
581 if (!node.isNull() && node.isElementNode()) { | 579 if (!node.isNull() && node.isElementNode()) { |
582 blink::WebElement element = node.to<blink::WebElement>(); | 580 blink::WebElement element = node.to<blink::WebElement>(); |
583 blink::WebInputElement* input_element = | 581 blink::WebInputElement* input_element = |
584 blink::toWebInputElement(&element); | 582 blink::toWebInputElement(&element); |
585 if (input_element && input_element->isTextField()) | 583 if (input_element && input_element->isTextField()) |
586 input_element->setSelectionRange(start_offset, end_offset); | 584 input_element->setSelectionRange(start_offset, end_offset); |
587 } | 585 } |
588 } | 586 } |
589 | 587 |
590 void RendererAccessibilityComplete::OnEventsAck() { | 588 void RendererAccessibilityComplete::OnEventsAck() { |
591 DCHECK(ack_pending_); | 589 DCHECK(ack_pending_); |
592 ack_pending_ = false; | 590 ack_pending_ = false; |
593 SendPendingAccessibilityEvents(); | 591 SendPendingAccessibilityEvents(); |
594 } | 592 } |
595 | 593 |
596 void RendererAccessibilityComplete::OnSetFocus(int acc_obj_id) { | 594 void RendererAccessibilityComplete::OnSetFocus(int acc_obj_id) { |
597 const WebDocument& document = GetMainDocument(); | 595 const WebDocument& document = GetMainDocument(); |
598 if (document.isNull()) | 596 if (document.isNull()) |
599 return; | 597 return; |
600 | 598 |
601 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); | 599 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id); |
602 if (obj.isDetached()) { | 600 if (obj.isDetached()) { |
603 #ifndef NDEBUG | 601 #ifndef NDEBUG |
604 if (logging_) { | 602 LOG(WARNING) << "OnSetAccessibilityFocus on invalid object id " |
605 LOG(WARNING) << "OnSetAccessibilityFocus on invalid object id " | 603 << acc_obj_id; |
606 << acc_obj_id; | |
607 } | |
608 #endif | 604 #endif |
609 return; | 605 return; |
610 } | 606 } |
611 | 607 |
612 WebAXObject root = document.accessibilityObject(); | 608 WebAXObject root = document.accessibilityObject(); |
613 if (root.isDetached()) { | 609 if (root.isDetached()) { |
614 #ifndef NDEBUG | 610 #ifndef NDEBUG |
615 if (logging_) { | 611 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid"; |
616 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid"; | |
617 } | |
618 #endif | 612 #endif |
619 return; | 613 return; |
620 } | 614 } |
621 | 615 |
622 // By convention, calling SetFocus on the root of the tree should clear the | 616 // By convention, calling SetFocus on the root of the tree should clear the |
623 // current focus. Otherwise set the focus to the new node. | 617 // current focus. Otherwise set the focus to the new node. |
624 if (acc_obj_id == root.axID()) | 618 if (acc_obj_id == root.axID()) |
625 render_view()->GetWebView()->clearFocusedNode(); | 619 render_view()->GetWebView()->clearFocusedNode(); |
626 else | 620 else |
627 obj.setFocused(true); | 621 obj.setFocused(true); |
628 } | 622 } |
629 | 623 |
630 void RendererAccessibilityComplete::OnFatalError() { | 624 void RendererAccessibilityComplete::OnFatalError() { |
631 CHECK(false) << "Invalid accessibility tree."; | 625 CHECK(false) << "Invalid accessibility tree."; |
632 } | 626 } |
633 | 627 |
634 } // namespace content | 628 } // namespace content |
OLD | NEW |