Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Side by Side Diff: content/renderer/accessibility/renderer_accessibility_complete.cc

Issue 23651003: Use Blink accessibility enums in Chromium (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/render_view_impl.h" 12 #include "content/renderer/render_view_impl.h"
13 #include "third_party/WebKit/public/web/WebAccessibilityObject.h" 13 #include "third_party/WebKit/public/web/WebAXObject.h"
14 #include "third_party/WebKit/public/web/WebDocument.h" 14 #include "third_party/WebKit/public/web/WebDocument.h"
15 #include "third_party/WebKit/public/web/WebFrame.h" 15 #include "third_party/WebKit/public/web/WebFrame.h"
16 #include "third_party/WebKit/public/web/WebInputElement.h" 16 #include "third_party/WebKit/public/web/WebInputElement.h"
17 #include "third_party/WebKit/public/web/WebNode.h" 17 #include "third_party/WebKit/public/web/WebNode.h"
18 #include "third_party/WebKit/public/web/WebView.h" 18 #include "third_party/WebKit/public/web/WebView.h"
19 19
20 using WebKit::WebAccessibilityNotification; 20 using WebKit::WebAXObject;
21 using WebKit::WebAccessibilityObject;
22 using WebKit::WebDocument; 21 using WebKit::WebDocument;
23 using WebKit::WebFrame; 22 using WebKit::WebFrame;
24 using WebKit::WebNode; 23 using WebKit::WebNode;
25 using WebKit::WebPoint; 24 using WebKit::WebPoint;
26 using WebKit::WebRect; 25 using WebKit::WebRect;
27 using WebKit::WebSize; 26 using WebKit::WebSize;
28 using WebKit::WebView; 27 using WebKit::WebView;
29 28
30 namespace content { 29 namespace content {
31 30
32 bool WebAccessibilityNotificationToAccessibilityNotification(
33 WebAccessibilityNotification notification,
34 AccessibilityNotification* type) {
35 switch (notification) {
36 case WebKit::WebAccessibilityNotificationActiveDescendantChanged:
37 *type = AccessibilityNotificationActiveDescendantChanged;
38 break;
39 case WebKit::WebAccessibilityNotificationAriaAttributeChanged:
40 *type = AccessibilityNotificationAriaAttributeChanged;
41 break;
42 case WebKit::WebAccessibilityNotificationAutocorrectionOccured:
43 *type = AccessibilityNotificationAutocorrectionOccurred;
44 break;
45 case WebKit::WebAccessibilityNotificationCheckedStateChanged:
46 *type = AccessibilityNotificationCheckStateChanged;
47 break;
48 case WebKit::WebAccessibilityNotificationChildrenChanged:
49 *type = AccessibilityNotificationChildrenChanged;
50 break;
51 case WebKit::WebAccessibilityNotificationFocusedUIElementChanged:
52 *type = AccessibilityNotificationFocusChanged;
53 break;
54 case WebKit::WebAccessibilityNotificationInvalidStatusChanged:
55 *type = AccessibilityNotificationInvalidStatusChanged;
56 break;
57 case WebKit::WebAccessibilityNotificationLayoutComplete:
58 *type = AccessibilityNotificationLayoutComplete;
59 break;
60 case WebKit::WebAccessibilityNotificationLiveRegionChanged:
61 *type = AccessibilityNotificationLiveRegionChanged;
62 break;
63 case WebKit::WebAccessibilityNotificationLoadComplete:
64 *type = AccessibilityNotificationLoadComplete;
65 break;
66 case WebKit::WebAccessibilityNotificationMenuListItemSelected:
67 *type = AccessibilityNotificationMenuListItemSelected;
68 break;
69 case WebKit::WebAccessibilityNotificationMenuListValueChanged:
70 *type = AccessibilityNotificationMenuListValueChanged;
71 break;
72 case WebKit::WebAccessibilityNotificationRowCollapsed:
73 *type = AccessibilityNotificationRowCollapsed;
74 break;
75 case WebKit::WebAccessibilityNotificationRowCountChanged:
76 *type = AccessibilityNotificationRowCountChanged;
77 break;
78 case WebKit::WebAccessibilityNotificationRowExpanded:
79 *type = AccessibilityNotificationRowExpanded;
80 break;
81 case WebKit::WebAccessibilityNotificationScrolledToAnchor:
82 *type = AccessibilityNotificationScrolledToAnchor;
83 break;
84 case WebKit::WebAccessibilityNotificationSelectedChildrenChanged:
85 *type = AccessibilityNotificationSelectedChildrenChanged;
86 break;
87 case WebKit::WebAccessibilityNotificationSelectedTextChanged:
88 *type = AccessibilityNotificationSelectedTextChanged;
89 break;
90 case WebKit::WebAccessibilityNotificationTextChanged:
91 *type = AccessibilityNotificationTextChanged;
92 break;
93 case WebKit::WebAccessibilityNotificationValueChanged:
94 *type = AccessibilityNotificationValueChanged;
95 break;
96 default:
97 DLOG(WARNING)
98 << "WebKit accessibility notification not handled in switch!";
99 return false;
100 }
101 return true;
102 }
103
104 RendererAccessibilityComplete::RendererAccessibilityComplete( 31 RendererAccessibilityComplete::RendererAccessibilityComplete(
105 RenderViewImpl* render_view) 32 RenderViewImpl* render_view)
106 : RendererAccessibility(render_view), 33 : RendererAccessibility(render_view),
107 weak_factory_(this), 34 weak_factory_(this),
108 browser_root_(NULL), 35 browser_root_(NULL),
109 last_scroll_offset_(gfx::Size()), 36 last_scroll_offset_(gfx::Size()),
110 ack_pending_(false) { 37 ack_pending_(false) {
111 WebAccessibilityObject::enableAccessibility(); 38 WebAXObject::enableAccessibility();
112 39
113 const WebDocument& document = GetMainDocument(); 40 const WebDocument& document = GetMainDocument();
114 if (!document.isNull()) { 41 if (!document.isNull()) {
115 // It's possible that the webview has already loaded a webpage without 42 // It's possible that the webview has already loaded a webpage without
116 // accessibility being enabled. Initialize the browser's cached 43 // accessibility being enabled. Initialize the browser's cached
117 // accessibility tree by sending it a notification. 44 // accessibility tree by sending it a notification.
118 HandleAccessibilityNotification( 45 HandleWebAccessibilityEvent(document.accessibilityObject(),
119 document.accessibilityObject(), 46 WebKit::WebAXEventLayoutComplete);
120 AccessibilityNotificationLayoutComplete);
121 } 47 }
122 } 48 }
123 49
124 RendererAccessibilityComplete::~RendererAccessibilityComplete() { 50 RendererAccessibilityComplete::~RendererAccessibilityComplete() {
125 } 51 }
126 52
127 bool RendererAccessibilityComplete::OnMessageReceived( 53 bool RendererAccessibilityComplete::OnMessageReceived(
128 const IPC::Message& message) { 54 const IPC::Message& message) {
129 bool handled = true; 55 bool handled = true;
130 IPC_BEGIN_MESSAGE_MAP(RendererAccessibilityComplete, message) 56 IPC_BEGIN_MESSAGE_MAP(RendererAccessibilityComplete, message)
131 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetFocus, OnSetFocus) 57 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetFocus, OnSetFocus)
132 IPC_MESSAGE_HANDLER(AccessibilityMsg_DoDefaultAction, 58 IPC_MESSAGE_HANDLER(AccessibilityMsg_DoDefaultAction,
133 OnDoDefaultAction) 59 OnDoDefaultAction)
134 IPC_MESSAGE_HANDLER(AccessibilityMsg_Notifications_ACK, 60 IPC_MESSAGE_HANDLER(AccessibilityMsg_Events_ACK,
135 OnNotificationsAck) 61 OnEventsAck)
136 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToMakeVisible, 62 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToMakeVisible,
137 OnScrollToMakeVisible) 63 OnScrollToMakeVisible)
138 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToPoint, 64 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToPoint,
139 OnScrollToPoint) 65 OnScrollToPoint)
140 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetTextSelection, 66 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetTextSelection,
141 OnSetTextSelection) 67 OnSetTextSelection)
142 IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError) 68 IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
143 IPC_MESSAGE_UNHANDLED(handled = false) 69 IPC_MESSAGE_UNHANDLED(handled = false)
144 IPC_END_MESSAGE_MAP() 70 IPC_END_MESSAGE_MAP()
145 return handled; 71 return handled;
146 } 72 }
147 73
148 void RendererAccessibilityComplete::FocusedNodeChanged(const WebNode& node) { 74 void RendererAccessibilityComplete::FocusedNodeChanged(const WebNode& node) {
149 const WebDocument& document = GetMainDocument(); 75 const WebDocument& document = GetMainDocument();
150 if (document.isNull()) 76 if (document.isNull())
151 return; 77 return;
152 78
153 if (node.isNull()) { 79 if (node.isNull()) {
154 // When focus is cleared, implicitly focus the document. 80 // When focus is cleared, implicitly focus the document.
155 // TODO(dmazzoni): Make WebKit send this notification instead. 81 // TODO(dmazzoni): Make WebKit send this notification instead.
156 HandleAccessibilityNotification( 82 HandleWebAccessibilityEvent(document.accessibilityObject(),
157 document.accessibilityObject(), 83 WebKit::WebAXEventBlur);
158 AccessibilityNotificationBlur);
159 } 84 }
160 } 85 }
161 86
162 void RendererAccessibilityComplete::DidFinishLoad(WebKit::WebFrame* frame) { 87 void RendererAccessibilityComplete::DidFinishLoad(WebKit::WebFrame* frame) {
163 const WebDocument& document = GetMainDocument(); 88 const WebDocument& document = GetMainDocument();
164 if (document.isNull()) 89 if (document.isNull())
165 return; 90 return;
166 91
167 // Check to see if the root accessibility object has changed, to work 92 // Check to see if the root accessibility object has changed, to work
168 // around WebKit bugs that cause AXObjectCache to be cleared 93 // around WebKit bugs that cause AXObjectCache to be cleared
169 // unnecessarily. 94 // unnecessarily.
170 // TODO(dmazzoni): remove this once rdar://5794454 is fixed. 95 // TODO(dmazzoni): remove this once rdar://5794454 is fixed.
171 WebAccessibilityObject new_root = document.accessibilityObject(); 96 WebAXObject new_root = document.accessibilityObject();
172 if (!browser_root_ || new_root.axID() != browser_root_->id) { 97 if (!browser_root_ || new_root.axID() != browser_root_->id)
173 HandleAccessibilityNotification( 98 HandleWebAccessibilityEvent(new_root, WebKit::WebAXEventLayoutComplete);
174 new_root,
175 AccessibilityNotificationLayoutComplete);
176 }
177 } 99 }
178 100
179 void RendererAccessibilityComplete::HandleWebAccessibilityNotification( 101 void RendererAccessibilityComplete::HandleWebAccessibilityEvent(
180 const WebAccessibilityObject& obj, 102 const WebKit::WebAXObject& obj,
181 WebAccessibilityNotification notification) { 103 WebKit::WebAXEvent event) {
182 AccessibilityNotification temp;
183 if (!WebAccessibilityNotificationToAccessibilityNotification(
184 notification, &temp)) {
185 return;
186 }
187
188 HandleAccessibilityNotification(obj, temp);
189 }
190
191 void RendererAccessibilityComplete::HandleAccessibilityNotification(
192 const WebKit::WebAccessibilityObject& obj,
193 AccessibilityNotification notification) {
194 const WebDocument& document = GetMainDocument(); 104 const WebDocument& document = GetMainDocument();
195 if (document.isNull()) 105 if (document.isNull())
196 return; 106 return;
197 107
198 gfx::Size scroll_offset = document.frame()->scrollOffset(); 108 gfx::Size scroll_offset = document.frame()->scrollOffset();
199 if (scroll_offset != last_scroll_offset_) { 109 if (scroll_offset != last_scroll_offset_) {
200 // Make sure the browser is always aware of the scroll position of 110 // Make sure the browser is always aware of the scroll position of
201 // the root document element by posting a generic notification that 111 // the root document element by posting a generic notification that
202 // will update it. 112 // will update it.
203 // TODO(dmazzoni): remove this as soon as 113 // TODO(dmazzoni): remove this as soon as
204 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed. 114 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed.
205 last_scroll_offset_ = scroll_offset; 115 last_scroll_offset_ = scroll_offset;
206 if (!obj.equals(document.accessibilityObject())) { 116 if (!obj.equals(document.accessibilityObject())) {
207 HandleAccessibilityNotification( 117 HandleWebAccessibilityEvent(
208 document.accessibilityObject(), 118 document.accessibilityObject(),
209 AccessibilityNotificationLayoutComplete); 119 WebKit::WebAXEventLayoutComplete);
210 } 120 }
211 } 121 }
212 122
213 // Add the accessibility object to our cache and ensure it's valid. 123 // Add the accessibility object to our cache and ensure it's valid.
214 AccessibilityHostMsg_NotificationParams acc_notification; 124 AccessibilityHostMsg_EventParams acc_event;
215 acc_notification.id = obj.axID(); 125 acc_event.id = obj.axID();
216 acc_notification.notification_type = notification; 126 acc_event.event_type = event;
217 127
218 // Discard duplicate accessibility notifications. 128 // Discard duplicate accessibility events.
219 for (uint32 i = 0; i < pending_notifications_.size(); ++i) { 129 for (uint32 i = 0; i < pending_events_.size(); ++i) {
220 if (pending_notifications_[i].id == acc_notification.id && 130 if (pending_events_[i].id == acc_event.id &&
221 pending_notifications_[i].notification_type == 131 pending_events_[i].event_type ==
222 acc_notification.notification_type) { 132 acc_event.event_type) {
223 return; 133 return;
224 } 134 }
225 } 135 }
226 pending_notifications_.push_back(acc_notification); 136 pending_events_.push_back(acc_event);
227 137
228 if (!ack_pending_ && !weak_factory_.HasWeakPtrs()) { 138 if (!ack_pending_ && !weak_factory_.HasWeakPtrs()) {
229 // When no accessibility notifications are in-flight post a task to send 139 // When no accessibility events are in-flight post a task to send
230 // the notifications to the browser. We use PostTask so that we can queue 140 // the events to the browser. We use PostTask so that we can queue
231 // up additional notifications. 141 // up additional events.
232 base::MessageLoop::current()->PostTask( 142 base::MessageLoop::current()->PostTask(
233 FROM_HERE, 143 FROM_HERE,
234 base::Bind(&RendererAccessibilityComplete:: 144 base::Bind(&RendererAccessibilityComplete::
235 SendPendingAccessibilityNotifications, 145 SendPendingAccessibilityEvents,
236 weak_factory_.GetWeakPtr())); 146 weak_factory_.GetWeakPtr()));
237 } 147 }
238 } 148 }
239 149
240 RendererAccessibilityComplete::BrowserTreeNode::BrowserTreeNode() : id(0) {} 150 RendererAccessibilityComplete::BrowserTreeNode::BrowserTreeNode() : id(0) {}
241 151
242 RendererAccessibilityComplete::BrowserTreeNode::~BrowserTreeNode() {} 152 RendererAccessibilityComplete::BrowserTreeNode::~BrowserTreeNode() {}
243 153
244 void RendererAccessibilityComplete::SendPendingAccessibilityNotifications() { 154 void RendererAccessibilityComplete::SendPendingAccessibilityEvents() {
245 const WebDocument& document = GetMainDocument(); 155 const WebDocument& document = GetMainDocument();
246 if (document.isNull()) 156 if (document.isNull())
247 return; 157 return;
248 158
249 if (pending_notifications_.empty()) 159 if (pending_events_.empty())
250 return; 160 return;
251 161
252 if (render_view_->is_swapped_out()) 162 if (render_view_->is_swapped_out())
253 return; 163 return;
254 164
255 ack_pending_ = true; 165 ack_pending_ = true;
256 166
257 // Make a copy of the notifications, because it's possible that 167 // Make a copy of the events, because it's possible that
258 // actions inside this loop will cause more notifications to be 168 // actions inside this loop will cause more events to be
259 // queued up. 169 // queued up.
260 std::vector<AccessibilityHostMsg_NotificationParams> src_notifications = 170 std::vector<AccessibilityHostMsg_EventParams> src_events =
261 pending_notifications_; 171 pending_events_;
262 pending_notifications_.clear(); 172 pending_events_.clear();
263 173
264 // Generate a notification message from each WebKit notification. 174 // Generate an event message from each WebKit event.
265 std::vector<AccessibilityHostMsg_NotificationParams> notification_msgs; 175 std::vector<AccessibilityHostMsg_EventParams> event_msgs;
266 176
267 // Loop over each notification and generate an updated notification message. 177 // Loop over each event and generate an updated event message.
268 for (size_t i = 0; i < src_notifications.size(); ++i) { 178 for (size_t i = 0; i < src_events.size(); ++i) {
269 AccessibilityHostMsg_NotificationParams& notification = 179 AccessibilityHostMsg_EventParams& event =
270 src_notifications[i]; 180 src_events[i];
271 181
272 WebAccessibilityObject obj = document.accessibilityObjectFromID( 182 WebAXObject obj = document.accessibilityObjectFromID(
273 notification.id); 183 event.id);
274 if (!obj.updateBackingStoreAndCheckValidity()) 184 if (!obj.updateBackingStoreAndCheckValidity())
275 continue; 185 continue;
276 186
277 // When we get a "selected children changed" notification, WebKit 187 // When we get a "selected children changed" event, WebKit
278 // doesn't also send us notifications for each child that changed 188 // doesn't also send us events for each child that changed
279 // selection state, so make sure we re-send that whole subtree. 189 // selection state, so make sure we re-send that whole subtree.
280 if (notification.notification_type == 190 if (event.event_type ==
281 AccessibilityNotificationSelectedChildrenChanged) { 191 WebKit::WebAXEventSelectedChildrenChanged) {
282 base::hash_map<int32, BrowserTreeNode*>::iterator iter = 192 base::hash_map<int32, BrowserTreeNode*>::iterator iter =
283 browser_id_map_.find(obj.axID()); 193 browser_id_map_.find(obj.axID());
284 if (iter != browser_id_map_.end()) 194 if (iter != browser_id_map_.end())
285 ClearBrowserTreeNode(iter->second); 195 ClearBrowserTreeNode(iter->second);
286 } 196 }
287 197
288 // The browser may not have this object yet, for example if we get a 198 // The browser may not have this object yet, for example if we get a
289 // notification on an object that was recently added, or if we get a 199 // event on an object that was recently added, or if we get a
290 // notification on a node before the page has loaded. Work our way 200 // event on a node before the page has loaded. Work our way
291 // up the parent chain until we find a node the browser has, or until 201 // up the parent chain until we find a node the browser has, or until
292 // we reach the root. 202 // we reach the root.
293 WebAccessibilityObject root_object = document.accessibilityObject(); 203 WebAXObject root_object = document.accessibilityObject();
294 int root_id = root_object.axID(); 204 int root_id = root_object.axID();
295 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() && 205 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() &&
296 !obj.isDetached() && 206 !obj.isDetached() &&
297 obj.axID() != root_id) { 207 obj.axID() != root_id) {
298 obj = obj.parentObject(); 208 obj = obj.parentObject();
299 if (notification.notification_type == 209 if (event.event_type ==
300 AccessibilityNotificationChildrenChanged) { 210 WebKit::WebAXEventChildrenChanged) {
301 notification.id = obj.axID(); 211 event.id = obj.axID();
302 } 212 }
303 } 213 }
304 214
305 if (obj.isDetached()) { 215 if (obj.isDetached()) {
306 #ifndef NDEBUG 216 #ifndef NDEBUG
307 if (logging_) 217 if (logging_)
308 LOG(WARNING) << "Got notification on object that is invalid or has" 218 LOG(WARNING) << "Got event on object that is invalid or has"
309 << " invalid ancestor. Id: " << obj.axID(); 219 << " invalid ancestor. Id: " << obj.axID();
310 #endif 220 #endif
311 continue; 221 continue;
312 } 222 }
313 223
314 // Another potential problem is that this notification may be on an 224 // Another potential problem is that this event may be on an
315 // object that is detached from the tree. Determine if this node is not a 225 // object that is detached from the tree. Determine if this node is not a
316 // child of its parent, and if so move the notification to the parent. 226 // child of its parent, and if so move the event to the parent.
317 // TODO(dmazzoni): see if this can be removed after 227 // TODO(dmazzoni): see if this can be removed after
318 // https://bugs.webkit.org/show_bug.cgi?id=68466 is fixed. 228 // https://bugs.webkit.org/show_bug.cgi?id=68466 is fixed.
319 if (obj.axID() != root_id) { 229 if (obj.axID() != root_id) {
320 WebAccessibilityObject parent = obj.parentObject(); 230 WebAXObject parent = obj.parentObject();
321 while (!parent.isDetached() && 231 while (!parent.isDetached() &&
322 parent.accessibilityIsIgnored()) { 232 parent.accessibilityIsIgnored()) {
323 parent = parent.parentObject(); 233 parent = parent.parentObject();
324 } 234 }
325 235
326 if (parent.isDetached()) { 236 if (parent.isDetached()) {
327 NOTREACHED(); 237 NOTREACHED();
328 continue; 238 continue;
329 } 239 }
330 bool is_child_of_parent = false; 240 bool is_child_of_parent = false;
331 for (unsigned int i = 0; i < parent.childCount(); ++i) { 241 for (unsigned int i = 0; i < parent.childCount(); ++i) {
332 if (parent.childAt(i).equals(obj)) { 242 if (parent.childAt(i).equals(obj)) {
333 is_child_of_parent = true; 243 is_child_of_parent = true;
334 break; 244 break;
335 } 245 }
336 } 246 }
337 247
338 if (!is_child_of_parent) { 248 if (!is_child_of_parent) {
339 obj = parent; 249 obj = parent;
340 notification.id = obj.axID(); 250 event.id = obj.axID();
341 } 251 }
342 } 252 }
343 253
344 // Allow WebKit to cache intermediate results since we're doing a bunch 254 // Allow WebKit to cache intermediate results since we're doing a bunch
345 // of read-only queries at once. 255 // of read-only queries at once.
346 root_object.startCachingComputedObjectAttributesUntilTreeMutates(); 256 root_object.startCachingComputedObjectAttributesUntilTreeMutates();
347 257
348 AccessibilityHostMsg_NotificationParams notification_msg; 258 AccessibilityHostMsg_EventParams event_msg;
349 notification_msg.notification_type = notification.notification_type; 259 event_msg.event_type = event.event_type;
350 notification_msg.id = notification.id; 260 event_msg.id = event.id;
351 SerializeChangedNodes(obj, &notification_msg.nodes); 261 SerializeChangedNodes(obj, &event_msg.nodes);
352 notification_msgs.push_back(notification_msg); 262 event_msgs.push_back(event_msg);
353 263
354 #ifndef NDEBUG 264 #ifndef NDEBUG
355 if (logging_) { 265 if (logging_) {
356 AccessibilityNodeDataTreeNode tree; 266 AccessibilityNodeDataTreeNode tree;
357 MakeAccessibilityNodeDataTree(notification_msg.nodes, &tree); 267 MakeAccessibilityNodeDataTree(event_msg.nodes, &tree);
358 LOG(INFO) << "Accessibility update: \n" 268 LOG(INFO) << "Accessibility update: \n"
359 << "routing id=" << routing_id() 269 << "routing id=" << routing_id()
360 << " notification=" 270 << " event="
361 << AccessibilityNotificationToString(notification.notification_type) 271 << AccessibilityEventToString(event.event_type)
362 << "\n" << tree.DebugString(true); 272 << "\n" << tree.DebugString(true);
363 } 273 }
364 #endif 274 #endif
365 } 275 }
366 276
367 AppendLocationChangeNotifications(&notification_msgs); 277 AppendLocationChangeEvents(&event_msgs);
368 278
369 Send(new AccessibilityHostMsg_Notifications(routing_id(), notification_msgs)); 279 Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs));
370 } 280 }
371 281
372 void RendererAccessibilityComplete::AppendLocationChangeNotifications( 282 void RendererAccessibilityComplete::AppendLocationChangeEvents(
373 std::vector<AccessibilityHostMsg_NotificationParams>* notification_msgs) { 283 std::vector<AccessibilityHostMsg_EventParams>* event_msgs) {
374 std::queue<WebAccessibilityObject> objs_to_explore; 284 std::queue<WebAXObject> objs_to_explore;
375 std::vector<BrowserTreeNode*> location_changes; 285 std::vector<BrowserTreeNode*> location_changes;
376 WebAccessibilityObject root_object = GetMainDocument().accessibilityObject(); 286 WebAXObject root_object = GetMainDocument().accessibilityObject();
377 objs_to_explore.push(root_object); 287 objs_to_explore.push(root_object);
378 288
379 while (objs_to_explore.size()) { 289 while (objs_to_explore.size()) {
380 WebAccessibilityObject obj = objs_to_explore.front(); 290 WebAXObject obj = objs_to_explore.front();
381 objs_to_explore.pop(); 291 objs_to_explore.pop();
382 int id = obj.axID(); 292 int id = obj.axID();
383 if (browser_id_map_.find(id) != browser_id_map_.end()) { 293 if (browser_id_map_.find(id) != browser_id_map_.end()) {
384 BrowserTreeNode* browser_node = browser_id_map_[id]; 294 BrowserTreeNode* browser_node = browser_id_map_[id];
385 gfx::Rect new_location = obj.boundingBoxRect(); 295 gfx::Rect new_location = obj.boundingBoxRect();
386 if (browser_node->location != new_location) { 296 if (browser_node->location != new_location) {
387 browser_node->location = new_location; 297 browser_node->location = new_location;
388 location_changes.push_back(browser_node); 298 location_changes.push_back(browser_node);
389 } 299 }
390 } 300 }
391 301
392 for (unsigned i = 0; i < obj.childCount(); ++i) 302 for (unsigned i = 0; i < obj.childCount(); ++i)
393 objs_to_explore.push(obj.childAt(i)); 303 objs_to_explore.push(obj.childAt(i));
394 } 304 }
395 305
396 if (location_changes.size() == 0) 306 if (location_changes.size() == 0)
397 return; 307 return;
398 308
399 AccessibilityHostMsg_NotificationParams notification_msg; 309 AccessibilityHostMsg_EventParams event_msg;
400 notification_msg.notification_type = 310 event_msg.event_type = static_cast<WebKit::WebAXEvent>(-1);
401 static_cast<AccessibilityNotification>(-1); 311 event_msg.id = root_object.axID();
402 notification_msg.id = root_object.axID(); 312 event_msg.nodes.resize(location_changes.size());
403 notification_msg.nodes.resize(location_changes.size());
404 for (size_t i = 0; i < location_changes.size(); i++) { 313 for (size_t i = 0; i < location_changes.size(); i++) {
405 AccessibilityNodeData& serialized_node = notification_msg.nodes[i]; 314 AccessibilityNodeData& serialized_node = event_msg.nodes[i];
406 serialized_node.id = location_changes[i]->id; 315 serialized_node.id = location_changes[i]->id;
407 serialized_node.location = location_changes[i]->location; 316 serialized_node.location = location_changes[i]->location;
408 serialized_node.AddBoolAttribute( 317 serialized_node.AddBoolAttribute(
409 AccessibilityNodeData::ATTR_UPDATE_LOCATION_ONLY, true); 318 AccessibilityNodeData::ATTR_UPDATE_LOCATION_ONLY, true);
410 } 319 }
411 320
412 notification_msgs->push_back(notification_msg); 321 event_msgs->push_back(event_msg);
413 } 322 }
414 323
415 RendererAccessibilityComplete::BrowserTreeNode* 324 RendererAccessibilityComplete::BrowserTreeNode*
416 RendererAccessibilityComplete::CreateBrowserTreeNode() { 325 RendererAccessibilityComplete::CreateBrowserTreeNode() {
417 return new RendererAccessibilityComplete::BrowserTreeNode(); 326 return new RendererAccessibilityComplete::BrowserTreeNode();
418 } 327 }
419 328
420 void RendererAccessibilityComplete::SerializeChangedNodes( 329 void RendererAccessibilityComplete::SerializeChangedNodes(
421 const WebKit::WebAccessibilityObject& obj, 330 const WebKit::WebAXObject& obj,
422 std::vector<AccessibilityNodeData>* dst) { 331 std::vector<AccessibilityNodeData>* dst) {
423 // This method has three responsibilities: 332 // This method has three responsibilities:
424 // 1. Serialize |obj| into an AccessibilityNodeData, and append it to 333 // 1. Serialize |obj| into an AccessibilityNodeData, and append it to
425 // the end of the |dst| vector to be send to the browser process. 334 // the end of the |dst| vector to be send to the browser process.
426 // 2. Determine if |obj| has any new children that the browser doesn't 335 // 2. Determine if |obj| has any new children that the browser doesn't
427 // know about yet, and call SerializeChangedNodes recursively on those. 336 // know about yet, and call SerializeChangedNodes recursively on those.
428 // 3. Update our internal data structure that keeps track of what nodes 337 // 3. Update our internal data structure that keeps track of what nodes
429 // the browser knows about. 338 // the browser knows about.
430 339
431 // First, find the BrowserTreeNode for this id in our data structure where 340 // First, find the BrowserTreeNode for this id in our data structure where
(...skipping 21 matching lines...) Expand all
453 362
454 // Iterate over the ids of the children of |obj|. 363 // Iterate over the ids of the children of |obj|.
455 // Create a set of the child ids so we can quickly look 364 // Create a set of the child ids so we can quickly look
456 // up which children are new and which ones were there before. 365 // up which children are new and which ones were there before.
457 // Also catch the case where a child is already in the browser tree 366 // Also catch the case where a child is already in the browser tree
458 // data structure with a different parent, and make sure the old parent 367 // data structure with a different parent, and make sure the old parent
459 // clears this node first. 368 // clears this node first.
460 base::hash_set<int32> new_child_ids; 369 base::hash_set<int32> new_child_ids;
461 const WebDocument& document = GetMainDocument(); 370 const WebDocument& document = GetMainDocument();
462 for (unsigned i = 0; i < obj.childCount(); i++) { 371 for (unsigned i = 0; i < obj.childCount(); i++) {
463 WebAccessibilityObject child = obj.childAt(i); 372 WebAXObject child = obj.childAt(i);
464 if (ShouldIncludeChildNode(obj, child)) { 373 if (ShouldIncludeChildNode(obj, child)) {
465 int new_child_id = child.axID(); 374 int new_child_id = child.axID();
466 new_child_ids.insert(new_child_id); 375 new_child_ids.insert(new_child_id);
467 376
468 BrowserTreeNode* child = browser_id_map_[new_child_id]; 377 BrowserTreeNode* child = browser_id_map_[new_child_id];
469 if (child && child->parent != browser_node) { 378 if (child && child->parent != browser_node) {
470 // The child is being reparented. Find the WebKit accessibility 379 // The child is being reparented. Find the WebKit accessibility
471 // object corresponding to the old parent, or the closest ancestor 380 // object corresponding to the old parent, or the closest ancestor
472 // still in the tree. 381 // still in the tree.
473 BrowserTreeNode* parent = child->parent; 382 BrowserTreeNode* parent = child->parent;
474 WebAccessibilityObject parent_obj; 383 WebAXObject parent_obj;
475 while (parent) { 384 while (parent) {
476 parent_obj = document.accessibilityObjectFromID(parent->id); 385 parent_obj = document.accessibilityObjectFromID(parent->id);
477 if (!parent_obj.isDetached()) 386 if (!parent_obj.isDetached())
478 break; 387 break;
479 parent = parent->parent; 388 parent = parent->parent;
480 } 389 }
481 CHECK(parent); 390 CHECK(parent);
482 // Call SerializeChangedNodes recursively on the old parent, 391 // Call SerializeChangedNodes recursively on the old parent,
483 // so that the update that clears |child| from its old parent 392 // so that the update that clears |child| from its old parent
484 // occurs stricly before the update that adds |child| to its 393 // occurs stricly before the update that adds |child| to its
(...skipping 23 matching lines...) Expand all
508 browser_child_id_map[old_child_id] = old_child; 417 browser_child_id_map[old_child_id] = old_child;
509 } 418 }
510 } 419 }
511 420
512 // Serialize this node. This fills in all of the fields in 421 // Serialize this node. This fills in all of the fields in
513 // AccessibilityNodeData except child_ids, which we handle below. 422 // AccessibilityNodeData except child_ids, which we handle below.
514 dst->push_back(AccessibilityNodeData()); 423 dst->push_back(AccessibilityNodeData());
515 AccessibilityNodeData* serialized_node = &dst->back(); 424 AccessibilityNodeData* serialized_node = &dst->back();
516 SerializeAccessibilityNode(obj, serialized_node); 425 SerializeAccessibilityNode(obj, serialized_node);
517 if (serialized_node->id == browser_root_->id) 426 if (serialized_node->id == browser_root_->id)
518 serialized_node->role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; 427 serialized_node->role = WebKit::WebAXRoleRootWebArea;
519 428
520 // Iterate over the children, make note of the ones that are new 429 // Iterate over the children, make note of the ones that are new
521 // and need to be serialized, and update the BrowserTreeNode 430 // and need to be serialized, and update the BrowserTreeNode
522 // data structure to reflect the new tree. 431 // data structure to reflect the new tree.
523 std::vector<WebAccessibilityObject> children_to_serialize; 432 std::vector<WebAXObject> children_to_serialize;
524 int child_count = obj.childCount(); 433 int child_count = obj.childCount();
525 browser_node->children.reserve(child_count); 434 browser_node->children.reserve(child_count);
526 for (int i = 0; i < child_count; i++) { 435 for (int i = 0; i < child_count; i++) {
527 WebAccessibilityObject child = obj.childAt(i); 436 WebAXObject child = obj.childAt(i);
528 int child_id = child.axID(); 437 int child_id = child.axID();
529 438
530 // Checks to make sure the child is valid, attached to this node, 439 // Checks to make sure the child is valid, attached to this node,
531 // and one we want to include in the tree. 440 // and one we want to include in the tree.
532 if (!ShouldIncludeChildNode(obj, child)) 441 if (!ShouldIncludeChildNode(obj, child))
533 continue; 442 continue;
534 443
535 // No need to do anything more with children that aren't new; 444 // No need to do anything more with children that aren't new;
536 // the browser will reuse its existing object. 445 // the browser will reuse its existing object.
537 if (new_child_ids.find(child_id) == new_child_ids.end()) 446 if (new_child_ids.find(child_id) == new_child_ids.end())
(...skipping 29 matching lines...) Expand all
567 delete browser_node->children[i]; 476 delete browser_node->children[i];
568 } 477 }
569 browser_node->children.clear(); 478 browser_node->children.clear();
570 } 479 }
571 480
572 void RendererAccessibilityComplete::OnDoDefaultAction(int acc_obj_id) { 481 void RendererAccessibilityComplete::OnDoDefaultAction(int acc_obj_id) {
573 const WebDocument& document = GetMainDocument(); 482 const WebDocument& document = GetMainDocument();
574 if (document.isNull()) 483 if (document.isNull())
575 return; 484 return;
576 485
577 WebAccessibilityObject obj = document.accessibilityObjectFromID(acc_obj_id); 486 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
578 if (obj.isDetached()) { 487 if (obj.isDetached()) {
579 #ifndef NDEBUG 488 #ifndef NDEBUG
580 if (logging_) 489 if (logging_)
581 LOG(WARNING) << "DoDefaultAction on invalid object id " << acc_obj_id; 490 LOG(WARNING) << "DoDefaultAction on invalid object id " << acc_obj_id;
582 #endif 491 #endif
583 return; 492 return;
584 } 493 }
585 494
586 obj.performDefaultAction(); 495 obj.performDefaultAction();
587 } 496 }
588 497
589 void RendererAccessibilityComplete::OnScrollToMakeVisible( 498 void RendererAccessibilityComplete::OnScrollToMakeVisible(
590 int acc_obj_id, gfx::Rect subfocus) { 499 int acc_obj_id, gfx::Rect subfocus) {
591 const WebDocument& document = GetMainDocument(); 500 const WebDocument& document = GetMainDocument();
592 if (document.isNull()) 501 if (document.isNull())
593 return; 502 return;
594 503
595 WebAccessibilityObject obj = document.accessibilityObjectFromID(acc_obj_id); 504 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
596 if (obj.isDetached()) { 505 if (obj.isDetached()) {
597 #ifndef NDEBUG 506 #ifndef NDEBUG
598 if (logging_) 507 if (logging_)
599 LOG(WARNING) << "ScrollToMakeVisible on invalid object id " << acc_obj_id; 508 LOG(WARNING) << "ScrollToMakeVisible on invalid object id " << acc_obj_id;
600 #endif 509 #endif
601 return; 510 return;
602 } 511 }
603 512
604 obj.scrollToMakeVisibleWithSubFocus( 513 obj.scrollToMakeVisibleWithSubFocus(
605 WebRect(subfocus.x(), subfocus.y(), 514 WebRect(subfocus.x(), subfocus.y(),
606 subfocus.width(), subfocus.height())); 515 subfocus.width(), subfocus.height()));
607 516
608 // Make sure the browser gets a notification when the scroll 517 // Make sure the browser gets an event when the scroll
609 // position actually changes. 518 // position actually changes.
610 // TODO(dmazzoni): remove this once this bug is fixed: 519 // TODO(dmazzoni): remove this once this bug is fixed:
611 // https://bugs.webkit.org/show_bug.cgi?id=73460 520 // https://bugs.webkit.org/show_bug.cgi?id=73460
612 HandleAccessibilityNotification( 521 HandleWebAccessibilityEvent(
613 document.accessibilityObject(), 522 document.accessibilityObject(),
614 AccessibilityNotificationLayoutComplete); 523 WebKit::WebAXEventLayoutComplete);
615 } 524 }
616 525
617 void RendererAccessibilityComplete::OnScrollToPoint( 526 void RendererAccessibilityComplete::OnScrollToPoint(
618 int acc_obj_id, gfx::Point point) { 527 int acc_obj_id, gfx::Point point) {
619 const WebDocument& document = GetMainDocument(); 528 const WebDocument& document = GetMainDocument();
620 if (document.isNull()) 529 if (document.isNull())
621 return; 530 return;
622 531
623 WebAccessibilityObject obj = document.accessibilityObjectFromID(acc_obj_id); 532 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
624 if (obj.isDetached()) { 533 if (obj.isDetached()) {
625 #ifndef NDEBUG 534 #ifndef NDEBUG
626 if (logging_) 535 if (logging_)
627 LOG(WARNING) << "ScrollToPoint on invalid object id " << acc_obj_id; 536 LOG(WARNING) << "ScrollToPoint on invalid object id " << acc_obj_id;
628 #endif 537 #endif
629 return; 538 return;
630 } 539 }
631 540
632 obj.scrollToGlobalPoint(WebPoint(point.x(), point.y())); 541 obj.scrollToGlobalPoint(WebPoint(point.x(), point.y()));
633 542
634 // Make sure the browser gets a notification when the scroll 543 // Make sure the browser gets an event when the scroll
635 // position actually changes. 544 // position actually changes.
636 // TODO(dmazzoni): remove this once this bug is fixed: 545 // TODO(dmazzoni): remove this once this bug is fixed:
637 // https://bugs.webkit.org/show_bug.cgi?id=73460 546 // https://bugs.webkit.org/show_bug.cgi?id=73460
638 HandleAccessibilityNotification( 547 HandleWebAccessibilityEvent(
639 document.accessibilityObject(), 548 document.accessibilityObject(),
640 AccessibilityNotificationLayoutComplete); 549 WebKit::WebAXEventLayoutComplete);
641 } 550 }
642 551
643 void RendererAccessibilityComplete::OnSetTextSelection( 552 void RendererAccessibilityComplete::OnSetTextSelection(
644 int acc_obj_id, int start_offset, int end_offset) { 553 int acc_obj_id, int start_offset, int end_offset) {
645 const WebDocument& document = GetMainDocument(); 554 const WebDocument& document = GetMainDocument();
646 if (document.isNull()) 555 if (document.isNull())
647 return; 556 return;
648 557
649 WebAccessibilityObject obj = document.accessibilityObjectFromID(acc_obj_id); 558 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
650 if (obj.isDetached()) { 559 if (obj.isDetached()) {
651 #ifndef NDEBUG 560 #ifndef NDEBUG
652 if (logging_) 561 if (logging_)
653 LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id; 562 LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id;
654 #endif 563 #endif
655 return; 564 return;
656 } 565 }
657 566
658 // TODO(dmazzoni): support elements other than <input>. 567 // TODO(dmazzoni): support elements other than <input>.
659 WebKit::WebNode node = obj.node(); 568 WebKit::WebNode node = obj.node();
660 if (!node.isNull() && node.isElementNode()) { 569 if (!node.isNull() && node.isElementNode()) {
661 WebKit::WebElement element = node.to<WebKit::WebElement>(); 570 WebKit::WebElement element = node.to<WebKit::WebElement>();
662 WebKit::WebInputElement* input_element = 571 WebKit::WebInputElement* input_element =
663 WebKit::toWebInputElement(&element); 572 WebKit::toWebInputElement(&element);
664 if (input_element && input_element->isTextField()) 573 if (input_element && input_element->isTextField())
665 input_element->setSelectionRange(start_offset, end_offset); 574 input_element->setSelectionRange(start_offset, end_offset);
666 } 575 }
667 } 576 }
668 577
669 void RendererAccessibilityComplete::OnNotificationsAck() { 578 void RendererAccessibilityComplete::OnEventsAck() {
670 DCHECK(ack_pending_); 579 DCHECK(ack_pending_);
671 ack_pending_ = false; 580 ack_pending_ = false;
672 SendPendingAccessibilityNotifications(); 581 SendPendingAccessibilityEvents();
673 } 582 }
674 583
675 void RendererAccessibilityComplete::OnSetFocus(int acc_obj_id) { 584 void RendererAccessibilityComplete::OnSetFocus(int acc_obj_id) {
676 const WebDocument& document = GetMainDocument(); 585 const WebDocument& document = GetMainDocument();
677 if (document.isNull()) 586 if (document.isNull())
678 return; 587 return;
679 588
680 WebAccessibilityObject obj = document.accessibilityObjectFromID(acc_obj_id); 589 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
681 if (obj.isDetached()) { 590 if (obj.isDetached()) {
682 #ifndef NDEBUG 591 #ifndef NDEBUG
683 if (logging_) { 592 if (logging_) {
684 LOG(WARNING) << "OnSetAccessibilityFocus on invalid object id " 593 LOG(WARNING) << "OnSetAccessibilityFocus on invalid object id "
685 << acc_obj_id; 594 << acc_obj_id;
686 } 595 }
687 #endif 596 #endif
688 return; 597 return;
689 } 598 }
690 599
691 WebAccessibilityObject root = document.accessibilityObject(); 600 WebAXObject root = document.accessibilityObject();
692 if (root.isDetached()) { 601 if (root.isDetached()) {
693 #ifndef NDEBUG 602 #ifndef NDEBUG
694 if (logging_) { 603 if (logging_) {
695 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid"; 604 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid";
696 } 605 }
697 #endif 606 #endif
698 return; 607 return;
699 } 608 }
700 609
701 // By convention, calling SetFocus on the root of the tree should clear the 610 // By convention, calling SetFocus on the root of the tree should clear the
702 // current focus. Otherwise set the focus to the new node. 611 // current focus. Otherwise set the focus to the new node.
703 if (acc_obj_id == root.axID()) 612 if (acc_obj_id == root.axID())
704 render_view()->GetWebView()->clearFocusedNode(); 613 render_view()->GetWebView()->clearFocusedNode();
705 else 614 else
706 obj.setFocused(true); 615 obj.setFocused(true);
707 } 616 }
708 617
709 void RendererAccessibilityComplete::OnFatalError() { 618 void RendererAccessibilityComplete::OnFatalError() {
710 CHECK(false) << "Invalid accessibility tree."; 619 CHECK(false) << "Invalid accessibility tree.";
711 } 620 }
712 621
713 } // namespace content 622 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698