| 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 |