OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/command_line.h" | 5 #include "base/command_line.h" |
6 #include "content/common/view_messages.h" | 6 #include "content/common/view_messages.h" |
7 #include "content/public/common/content_switches.h" | 7 #include "content/public/common/content_switches.h" |
8 #include "content/renderer/render_view_impl.h" | 8 #include "content/renderer/render_view_impl.h" |
9 #include "content/renderer/renderer_accessibility.h" | 9 #include "content/renderer/renderer_accessibility.h" |
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" | 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 79 } |
80 return true; | 80 return true; |
81 } | 81 } |
82 | 82 |
83 RendererAccessibility::RendererAccessibility(RenderViewImpl* render_view) | 83 RendererAccessibility::RendererAccessibility(RenderViewImpl* render_view) |
84 : content::RenderViewObserver(render_view), | 84 : content::RenderViewObserver(render_view), |
85 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 85 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
86 browser_root_(NULL), | 86 browser_root_(NULL), |
87 last_scroll_offset_(gfx::Size()), | 87 last_scroll_offset_(gfx::Size()), |
88 ack_pending_(false), | 88 ack_pending_(false), |
89 logging_(false), | 89 logging_(false) { |
90 sent_load_complete_(false) { | |
91 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 90 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
92 if (command_line.HasSwitch(switches::kEnableAccessibility)) | 91 if (command_line.HasSwitch(switches::kEnableAccessibility)) |
93 WebAccessibilityObject::enableAccessibility(); | 92 WebAccessibilityObject::enableAccessibility(); |
94 if (command_line.HasSwitch(switches::kEnableAccessibilityLogging)) | 93 if (command_line.HasSwitch(switches::kEnableAccessibilityLogging)) |
95 logging_ = true; | 94 logging_ = true; |
96 } | 95 } |
97 | 96 |
98 RendererAccessibility::~RendererAccessibility() { | 97 RendererAccessibility::~RendererAccessibility() { |
99 } | 98 } |
100 | 99 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 return; | 141 return; |
143 | 142 |
144 // Check to see if the root accessibility object has changed, to work | 143 // Check to see if the root accessibility object has changed, to work |
145 // around WebKit bugs that cause AXObjectCache to be cleared | 144 // around WebKit bugs that cause AXObjectCache to be cleared |
146 // unnecessarily. | 145 // unnecessarily. |
147 // TODO(dmazzoni): remove this once rdar://5794454 is fixed. | 146 // TODO(dmazzoni): remove this once rdar://5794454 is fixed. |
148 WebAccessibilityObject new_root = document.accessibilityObject(); | 147 WebAccessibilityObject new_root = document.accessibilityObject(); |
149 if (!browser_root_ || new_root.axID() != browser_root_->id) { | 148 if (!browser_root_ || new_root.axID() != browser_root_->id) { |
150 PostAccessibilityNotification( | 149 PostAccessibilityNotification( |
151 new_root, | 150 new_root, |
152 WebKit::WebAccessibilityNotificationLoadComplete); | 151 WebKit::WebAccessibilityNotificationLayoutComplete); |
153 } | 152 } |
154 } | 153 } |
155 | 154 |
156 void RendererAccessibility::PostAccessibilityNotification( | 155 void RendererAccessibility::PostAccessibilityNotification( |
157 const WebAccessibilityObject& obj, | 156 const WebAccessibilityObject& obj, |
158 WebAccessibilityNotification notification) { | 157 WebAccessibilityNotification notification) { |
159 if (!WebAccessibilityObject::accessibilityEnabled()) | 158 if (!WebAccessibilityObject::accessibilityEnabled()) |
160 return; | 159 return; |
161 | 160 |
162 const WebDocument& document = GetMainDocument(); | 161 const WebDocument& document = GetMainDocument(); |
163 if (document.isNull()) | 162 if (document.isNull()) |
164 return; | 163 return; |
165 | 164 |
166 if (notification != WebKit::WebAccessibilityNotificationLoadComplete && | |
167 !sent_load_complete_) { | |
168 // Load complete should be our first notification sent. Send it manually | |
169 // in cases where we don't get it first to avoid focus problems. | |
170 PostAccessibilityNotification( | |
171 document.accessibilityObject(), | |
172 WebKit::WebAccessibilityNotificationLoadComplete); | |
173 } | |
174 | |
175 gfx::Size scroll_offset = document.frame()->scrollOffset(); | 165 gfx::Size scroll_offset = document.frame()->scrollOffset(); |
176 if (scroll_offset != last_scroll_offset_) { | 166 if (scroll_offset != last_scroll_offset_) { |
177 // Make sure the browser is always aware of the scroll position of | 167 // Make sure the browser is always aware of the scroll position of |
178 // the root document element by posting a generic notification that | 168 // the root document element by posting a generic notification that |
179 // will update it. | 169 // will update it. |
180 // TODO(dmazzoni): remove this as soon as | 170 // TODO(dmazzoni): remove this as soon as |
181 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed. | 171 // https://bugs.webkit.org/show_bug.cgi?id=73460 is fixed. |
182 last_scroll_offset_ = scroll_offset; | 172 last_scroll_offset_ = scroll_offset; |
183 PostAccessibilityNotification( | 173 PostAccessibilityNotification( |
184 document.accessibilityObject(), | 174 document.accessibilityObject(), |
185 WebKit::WebAccessibilityNotificationLayoutComplete); | 175 WebKit::WebAccessibilityNotificationLayoutComplete); |
186 } | 176 } |
187 | 177 |
188 if (notification == WebKit::WebAccessibilityNotificationLoadComplete) | |
189 sent_load_complete_ = true; | |
190 | |
191 // Add the accessibility object to our cache and ensure it's valid. | 178 // Add the accessibility object to our cache and ensure it's valid. |
192 Notification acc_notification; | 179 Notification acc_notification; |
193 acc_notification.id = obj.axID(); | 180 acc_notification.id = obj.axID(); |
194 acc_notification.type = notification; | 181 acc_notification.type = notification; |
195 | 182 |
196 ViewHostMsg_AccEvent::Value temp; | 183 ViewHostMsg_AccEvent::Value temp; |
197 if (!WebAccessibilityNotificationToViewHostMsg(notification, &temp)) | 184 if (!WebAccessibilityNotificationToViewHostMsg(notification, &temp)) |
198 return; | 185 return; |
199 | 186 |
200 // Discard duplicate accessibility notifications. | 187 // Discard duplicate accessibility notifications. |
(...skipping 22 matching lines...) Expand all Loading... |
223 return; | 210 return; |
224 | 211 |
225 if (pending_notifications_.empty()) | 212 if (pending_notifications_.empty()) |
226 return; | 213 return; |
227 | 214 |
228 // Send all pending accessibility notifications. | 215 // Send all pending accessibility notifications. |
229 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; | 216 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; |
230 for (size_t i = 0; i < pending_notifications_.size(); ++i) { | 217 for (size_t i = 0; i < pending_notifications_.size(); ++i) { |
231 Notification& notification = pending_notifications_[i]; | 218 Notification& notification = pending_notifications_[i]; |
232 | 219 |
233 bool includes_children = ShouldIncludeChildren(notification); | 220 // TODO(dtseng): Come up with a cleaner way of deciding to include children. |
| 221 int root_id = document.accessibilityObject().axID(); |
| 222 bool includes_children = ShouldIncludeChildren(notification) || |
| 223 root_id == notification.id; |
234 WebAccessibilityObject obj = document.accessibilityObjectFromID( | 224 WebAccessibilityObject obj = document.accessibilityObjectFromID( |
235 notification.id); | 225 notification.id); |
236 | 226 |
237 // The browser may not have this object yet, for example if we get a | 227 // The browser may not have this object yet, for example if we get a |
238 // notification on an object that was recently added, or if we get a | 228 // notification on an object that was recently added, or if we get a |
239 // notification on a node before the page has loaded. Work our way | 229 // notification on a node before the page has loaded. Work our way |
240 // up the parent chain until we find a node the browser has, or until | 230 // up the parent chain until we find a node the browser has, or until |
241 // we reach the root. | 231 // we reach the root. |
242 int root_id = document.accessibilityObject().axID(); | |
243 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() && | 232 while (browser_id_map_.find(obj.axID()) == browser_id_map_.end() && |
244 obj.isValid() && | 233 obj.isValid() && |
245 obj.axID() != root_id) { | 234 obj.axID() != root_id) { |
246 obj = obj.parentObject(); | 235 obj = obj.parentObject(); |
247 includes_children = true; | 236 includes_children = true; |
248 if (notification.type == | 237 if (notification.type == |
249 WebKit::WebAccessibilityNotificationChildrenChanged) { | 238 WebKit::WebAccessibilityNotificationChildrenChanged) { |
250 notification.id = obj.axID(); | 239 notification.id = obj.axID(); |
251 } | 240 } |
252 } | 241 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 | 450 |
462 WebAccessibilityObject::enableAccessibility(); | 451 WebAccessibilityObject::enableAccessibility(); |
463 | 452 |
464 const WebDocument& document = GetMainDocument(); | 453 const WebDocument& document = GetMainDocument(); |
465 if (!document.isNull()) { | 454 if (!document.isNull()) { |
466 // It's possible that the webview has already loaded a webpage without | 455 // It's possible that the webview has already loaded a webpage without |
467 // accessibility being enabled. Initialize the browser's cached | 456 // accessibility being enabled. Initialize the browser's cached |
468 // accessibility tree by sending it a 'load complete' notification. | 457 // accessibility tree by sending it a 'load complete' notification. |
469 PostAccessibilityNotification( | 458 PostAccessibilityNotification( |
470 document.accessibilityObject(), | 459 document.accessibilityObject(), |
471 WebKit::WebAccessibilityNotificationLoadComplete); | 460 WebKit::WebAccessibilityNotificationLayoutComplete); |
472 } | 461 } |
473 } | 462 } |
474 | 463 |
475 void RendererAccessibility::OnSetAccessibilityFocus(int acc_obj_id) { | 464 void RendererAccessibility::OnSetAccessibilityFocus(int acc_obj_id) { |
476 if (!WebAccessibilityObject::accessibilityEnabled()) | 465 if (!WebAccessibilityObject::accessibilityEnabled()) |
477 return; | 466 return; |
478 | 467 |
479 const WebDocument& document = GetMainDocument(); | 468 const WebDocument& document = GetMainDocument(); |
480 if (document.isNull()) | 469 if (document.isNull()) |
481 return; | 470 return; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 | 512 |
524 WebDocument RendererAccessibility::GetMainDocument() { | 513 WebDocument RendererAccessibility::GetMainDocument() { |
525 WebView* view = render_view()->GetWebView(); | 514 WebView* view = render_view()->GetWebView(); |
526 WebFrame* main_frame = view ? view->mainFrame() : NULL; | 515 WebFrame* main_frame = view ? view->mainFrame() : NULL; |
527 | 516 |
528 if (main_frame) | 517 if (main_frame) |
529 return main_frame->document(); | 518 return main_frame->document(); |
530 else | 519 else |
531 return WebDocument(); | 520 return WebDocument(); |
532 } | 521 } |
OLD | NEW |