| 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/browser/accessibility/browser_accessibility_manager.h" | 5 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 osk_state_ = OSK_ALLOWED; | 391 osk_state_ = OSK_ALLOWED; |
| 392 } | 392 } |
| 393 | 393 |
| 394 // We already handled all focus events above. | 394 // We already handled all focus events above. |
| 395 continue; | 395 continue; |
| 396 } | 396 } |
| 397 | 397 |
| 398 // Fire the native event. | 398 // Fire the native event. |
| 399 BrowserAccessibility* event_target = GetFromAXNode(node); | 399 BrowserAccessibility* event_target = GetFromAXNode(node); |
| 400 if (event_target) { | 400 if (event_target) { |
| 401 if (event_type == ui::AX_EVENT_HOVER) |
| 402 GetRootManager()->CacheHitTestResult(event_target); |
| 403 |
| 401 NotifyAccessibilityEvent( | 404 NotifyAccessibilityEvent( |
| 402 BrowserAccessibilityEvent::FromBlink, | 405 BrowserAccessibilityEvent::FromBlink, |
| 403 event_type, | 406 event_type, |
| 404 event_target); | 407 event_target); |
| 405 } | 408 } |
| 406 } | 409 } |
| 407 } | 410 } |
| 408 | 411 |
| 409 void BrowserAccessibilityManager::OnLocationChanges( | 412 void BrowserAccessibilityManager::OnLocationChanges( |
| 410 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { | 413 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> | 1091 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> |
| 1089 tree_source(tree_->CreateTreeSource()); | 1092 tree_source(tree_->CreateTreeSource()); |
| 1090 ui::AXTreeSerializer<const ui::AXNode*, | 1093 ui::AXTreeSerializer<const ui::AXNode*, |
| 1091 ui::AXNodeData, | 1094 ui::AXNodeData, |
| 1092 ui::AXTreeData> serializer(tree_source.get()); | 1095 ui::AXTreeData> serializer(tree_source.get()); |
| 1093 ui::AXTreeUpdate update; | 1096 ui::AXTreeUpdate update; |
| 1094 serializer.SerializeChanges(tree_->root(), &update); | 1097 serializer.SerializeChanges(tree_->root(), &update); |
| 1095 return update; | 1098 return update; |
| 1096 } | 1099 } |
| 1097 | 1100 |
| 1101 BrowserAccessibility* BrowserAccessibilityManager::CachingAsyncHitTest( |
| 1102 const gfx::Point& screen_point) { |
| 1103 BrowserAccessibilityManager* root_manager = GetRootManager(); |
| 1104 if (root_manager && root_manager != this) |
| 1105 return root_manager->CachingAsyncHitTest(screen_point); |
| 1106 |
| 1107 if (delegate()) { |
| 1108 // This triggers an asynchronous request to compute the true object that's |
| 1109 // under |screen_point|. |
| 1110 gfx::Point local_point = screen_point - GetViewBounds().OffsetFromOrigin(); |
| 1111 delegate()->AccessibilityHitTest(local_point); |
| 1112 |
| 1113 // Unfortunately we still have to return an answer synchronously because |
| 1114 // the APIs were designed that way. The best case scenario is that the |
| 1115 // screen point is within the bounds of the last result we got from a |
| 1116 // call to AccessibilityHitTest - in that case, we can return that object! |
| 1117 if (last_hover_bounds_.Contains(screen_point)) { |
| 1118 BrowserAccessibilityManager* manager = |
| 1119 BrowserAccessibilityManager::FromID(last_hover_ax_tree_id_); |
| 1120 if (manager) { |
| 1121 BrowserAccessibility* node = manager->GetFromID(last_hover_node_id_); |
| 1122 if (node) |
| 1123 return node; |
| 1124 } |
| 1125 } |
| 1126 } |
| 1127 |
| 1128 // If that test failed we have to fall back on searching the accessibility |
| 1129 // tree locally for the best bounding box match. This is generally right |
| 1130 // for simple pages but wrong in cases of z-index, overflow, and other |
| 1131 // more complicated layouts. The hope is that if the user is moving the |
| 1132 // mouse, this fallback will only be used transiently, and the asynchronous |
| 1133 // result will be used for the next call. |
| 1134 return GetRoot()->ApproximateHitTest(screen_point); |
| 1135 } |
| 1136 |
| 1137 void BrowserAccessibilityManager::CacheHitTestResult( |
| 1138 BrowserAccessibility* hit_test_result) { |
| 1139 // Walk up to the highest ancestor that's a leaf node; we don't want to |
| 1140 // return a node that's hidden from the tree. |
| 1141 BrowserAccessibility* parent = hit_test_result->GetParent(); |
| 1142 while (parent) { |
| 1143 if (parent->PlatformChildCount() == 0) |
| 1144 hit_test_result = parent; |
| 1145 parent = parent->GetParent(); |
| 1146 } |
| 1147 |
| 1148 last_hover_ax_tree_id_ = hit_test_result->manager()->ax_tree_id(); |
| 1149 last_hover_node_id_ = hit_test_result->GetId(); |
| 1150 last_hover_bounds_ = hit_test_result->GetScreenBoundsRect(); |
| 1151 } |
| 1152 |
| 1098 } // namespace content | 1153 } // namespace content |
| OLD | NEW |