| 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> | 1072 ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>> |
| 1070 tree_source(tree_->CreateTreeSource()); | 1073 tree_source(tree_->CreateTreeSource()); |
| 1071 ui::AXTreeSerializer<const ui::AXNode*, | 1074 ui::AXTreeSerializer<const ui::AXNode*, |
| 1072 ui::AXNodeData, | 1075 ui::AXNodeData, |
| 1073 ui::AXTreeData> serializer(tree_source.get()); | 1076 ui::AXTreeData> serializer(tree_source.get()); |
| 1074 ui::AXTreeUpdate update; | 1077 ui::AXTreeUpdate update; |
| 1075 serializer.SerializeChanges(tree_->root(), &update); | 1078 serializer.SerializeChanges(tree_->root(), &update); |
| 1076 return update; | 1079 return update; |
| 1077 } | 1080 } |
| 1078 | 1081 |
| 1082 BrowserAccessibility* BrowserAccessibilityManager::CachingAsyncHitTest( |
| 1083 const gfx::Point& screen_point) { |
| 1084 BrowserAccessibilityManager* root_manager = GetRootManager(); |
| 1085 if (root_manager && root_manager != this) |
| 1086 return root_manager->CachingAsyncHitTest(screen_point); |
| 1087 |
| 1088 if (!delegate()) |
| 1089 return nullptr; |
| 1090 |
| 1091 // This triggers an asynchronous request to compute the true object that's |
| 1092 // under |screen_point|. |
| 1093 gfx::Point local_point = screen_point - GetViewBounds().OffsetFromOrigin(); |
| 1094 delegate()->AccessibilityHitTest(local_point); |
| 1095 |
| 1096 // Unfortunately we still have to return an answer synchronously because |
| 1097 // the APIs were designed that way. The best case scenario is that the |
| 1098 // screen point is within the bounds of the last result we got from a |
| 1099 // call to AccessibilityHitTest - in that case, we can return that object! |
| 1100 if (last_hover_bounds_.Contains(screen_point)) { |
| 1101 BrowserAccessibilityManager* manager = |
| 1102 BrowserAccessibilityManager::FromID(last_hover_ax_tree_id_); |
| 1103 if (manager) { |
| 1104 BrowserAccessibility* node = manager->GetFromID(last_hover_node_id_); |
| 1105 if (node) |
| 1106 return node; |
| 1107 } |
| 1108 } |
| 1109 |
| 1110 // If that test failed we have to fall back on searching the accessibility |
| 1111 // tree locally for the best bounding box match. This is generally right |
| 1112 // for simple pages but wrong in cases of z-index, overflow, and other |
| 1113 // more complicated layouts. The hope is that if the user is moving the |
| 1114 // mouse, this fallback will only be used transiently, and the asynchronous |
| 1115 // result will be used for the next call. |
| 1116 return GetRoot()->ApproximateHitTest(screen_point); |
| 1117 } |
| 1118 |
| 1119 void BrowserAccessibilityManager::CacheHitTestResult( |
| 1120 BrowserAccessibility* hit_test_result) { |
| 1121 // Walk up to the highest ancestor that's a leaf node; we don't want to |
| 1122 // return a node that's hidden from the tree. |
| 1123 BrowserAccessibility* parent = hit_test_result->GetParent(); |
| 1124 while (parent) { |
| 1125 if (parent->PlatformChildCount() == 0) |
| 1126 hit_test_result = parent; |
| 1127 parent = parent->GetParent(); |
| 1128 } |
| 1129 |
| 1130 last_hover_ax_tree_id_ = hit_test_result->manager()->ax_tree_id(); |
| 1131 last_hover_node_id_ = hit_test_result->GetId(); |
| 1132 last_hover_bounds_ = hit_test_result->GetScreenBoundsRect(); |
| 1133 } |
| 1134 |
| 1079 } // namespace content | 1135 } // namespace content |
| OLD | NEW |