Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/renderer/extensions/automation_internal_custom_bindings.h" | 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 if (parent->data().role == ui::AX_ROLE_WEB_AREA || | 129 if (parent->data().role == ui::AX_ROLE_WEB_AREA || |
| 130 parent->data().role == ui::AX_ROLE_ROOT_WEB_AREA) { | 130 parent->data().role == ui::AX_ROLE_ROOT_WEB_AREA) { |
| 131 int sx = 0; | 131 int sx = 0; |
| 132 int sy = 0; | 132 int sy = 0; |
| 133 if (parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && | 133 if (parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && |
| 134 parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { | 134 parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { |
| 135 bounds.Offset(-sx, -sy); | 135 bounds.Offset(-sx, -sy); |
| 136 } | 136 } |
| 137 need_to_offset_web_area = true; | 137 need_to_offset_web_area = true; |
| 138 } | 138 } |
| 139 parent = parent->parent(); | 139 parent = cache->owner->GetParent(parent, &cache); |
| 140 } | 140 } |
| 141 | 141 |
| 142 return bounds; | 142 return bounds; |
| 143 } | 143 } |
| 144 | 144 |
| 145 ui::AXNode* FindNodeWithChildTreeId(ui::AXNode* node, int child_tree_id) { | |
|
David Tseng
2016/03/04 16:50:20
Would it make sense to have the AXTree maintain a
dmazzoni
2016/03/07 21:35:31
I debated that but I'm not convinced it would actu
| |
| 146 if (child_tree_id == node->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) | |
| 147 return node; | |
| 148 | |
| 149 for (int i = 0; i < node->child_count(); ++i) { | |
| 150 ui::AXNode* result = | |
| 151 FindNodeWithChildTreeId(node->ChildAtIndex(i), child_tree_id); | |
| 152 if (result) | |
| 153 return result; | |
| 154 } | |
| 155 | |
| 156 return nullptr; | |
| 157 } | |
| 158 | |
| 145 // | 159 // |
| 146 // Helper class that helps implement bindings for a JavaScript function | 160 // Helper class that helps implement bindings for a JavaScript function |
| 147 // that takes a single input argument consisting of a Tree ID. Looks up | 161 // that takes a single input argument consisting of a Tree ID. Looks up |
| 148 // the TreeCache and passes it to the function passed to the constructor. | 162 // the TreeCache and passes it to the function passed to the constructor. |
| 149 // | 163 // |
| 150 | 164 |
| 151 typedef void (*TreeIDFunction)(v8::Isolate* isolate, | 165 typedef void (*TreeIDFunction)(v8::Isolate* isolate, |
| 152 v8::ReturnValue<v8::Value> result, | 166 v8::ReturnValue<v8::Value> result, |
| 153 TreeCache* cache); | 167 TreeCache* cache); |
| 154 | 168 |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 } | 778 } |
| 765 | 779 |
| 766 bool AutomationInternalCustomBindings::GetFocusInternal(TreeCache* cache, | 780 bool AutomationInternalCustomBindings::GetFocusInternal(TreeCache* cache, |
| 767 TreeCache** out_cache, | 781 TreeCache** out_cache, |
| 768 ui::AXNode** out_node) { | 782 ui::AXNode** out_node) { |
| 769 int focus_id = cache->tree.data().focus_id; | 783 int focus_id = cache->tree.data().focus_id; |
| 770 ui::AXNode* focus = cache->tree.GetFromId(focus_id); | 784 ui::AXNode* focus = cache->tree.GetFromId(focus_id); |
| 771 if (!focus) | 785 if (!focus) |
| 772 return false; | 786 return false; |
| 773 | 787 |
| 788 // If the focused node is the owner of a child tree, that indicates | |
| 789 // a node within the child tree is the one that actually has focus. | |
| 774 while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) { | 790 while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) { |
| 775 // Try to keep following focus recursively, by letting |tree_id| be the | 791 // Try to keep following focus recursively, by letting |tree_id| be the |
| 776 // new subtree to search in, while keeping |focus_tree_id| set to the tree | 792 // new subtree to search in, while keeping |focus_tree_id| set to the tree |
| 777 // where we know we found a focused node. | 793 // where we know we found a focused node. |
| 778 int child_tree_id = | 794 int child_tree_id = |
| 779 focus->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID); | 795 focus->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID); |
| 780 | 796 |
| 781 TreeCache* child_cache = GetTreeCacheFromTreeID(child_tree_id); | 797 TreeCache* child_cache = GetTreeCacheFromTreeID(child_tree_id); |
| 782 if (!child_cache) | 798 if (!child_cache) |
| 783 break; | 799 break; |
| 784 | 800 |
| 801 // If the child cache is a frame tree that indicates a focused frame, | |
| 802 // jump to that frame if possible. | |
| 803 if (child_cache->tree.data().focused_tree_id > 0) { | |
| 804 TreeCache* focused_cache = | |
| 805 GetTreeCacheFromTreeID(child_cache->tree.data().focused_tree_id); | |
| 806 if (focused_cache) | |
| 807 child_cache = focused_cache; | |
| 808 } | |
| 809 | |
| 785 int child_focus_id = child_cache->tree.data().focus_id; | 810 int child_focus_id = child_cache->tree.data().focus_id; |
| 786 ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id); | 811 ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id); |
| 787 if (!child_focus) | 812 if (!child_focus) |
| 788 break; | 813 break; |
| 789 | 814 |
| 790 focus = child_focus; | 815 focus = child_focus; |
| 791 cache = child_cache; | 816 cache = child_cache; |
| 792 } | 817 } |
| 793 | 818 |
| 794 *out_cache = cache; | 819 *out_cache = cache; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 871 | 896 |
| 872 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { | 897 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { |
| 873 tree_change_observer_overall_filter_ = | 898 tree_change_observer_overall_filter_ = |
| 874 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; | 899 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; |
| 875 for (const auto& observer : tree_change_observers_) { | 900 for (const auto& observer : tree_change_observers_) { |
| 876 tree_change_observer_overall_filter_ = | 901 tree_change_observer_overall_filter_ = |
| 877 std::max(observer.filter, tree_change_observer_overall_filter_); | 902 std::max(observer.filter, tree_change_observer_overall_filter_); |
| 878 } | 903 } |
| 879 } | 904 } |
| 880 | 905 |
| 906 ui::AXNode* AutomationInternalCustomBindings::GetParent(ui::AXNode* node, | |
| 907 TreeCache** cache) { | |
|
David Tseng
2016/03/04 16:50:20
out_cache
dmazzoni
2016/03/07 21:35:31
Made it in_out_cache
| |
| 908 if (node->parent()) | |
| 909 return node->parent(); | |
| 910 | |
| 911 int parent_tree_id = (*cache)->tree.data().parent_tree_id; | |
| 912 if (parent_tree_id <= 0) | |
|
David Tseng
2016/03/04 16:50:20
Doesn't the desktop tree have id 0?
dmazzoni
2016/03/07 21:35:32
Done.
| |
| 913 return nullptr; | |
| 914 | |
| 915 TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id); | |
| 916 if (!parent_cache) | |
|
David Tseng
2016/03/04 16:50:20
Should |cache| be set to nullptr?
dmazzoni
2016/03/07 21:35:32
No, because it's an input and output parameter
| |
| 917 return nullptr; | |
| 918 | |
| 919 // Try to use the cached parent node from the most recent time this | |
| 920 // was called. | |
| 921 if (parent_cache->parent_node_id_from_parent_tree > 0) { | |
| 922 ui::AXNode* parent = parent_cache->tree.GetFromId( | |
| 923 parent_cache->parent_node_id_from_parent_tree); | |
| 924 if (parent) { | |
| 925 int parent_child_tree_id = | |
| 926 parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID); | |
| 927 if (parent_child_tree_id == (*cache)->tree_id) { | |
| 928 *cache = parent_cache; | |
| 929 return parent; | |
| 930 } | |
| 931 } | |
| 932 } | |
| 933 | |
| 934 // If that fails, search for it and cache it for next time. | |
| 935 ui::AXNode* parent = | |
| 936 FindNodeWithChildTreeId(parent_cache->tree.root(), (*cache)->tree_id); | |
| 937 if (parent) { | |
|
David Tseng
2016/03/04 16:50:20
Is it an error if |parent| is null?
dmazzoni
2016/03/07 21:35:32
No, it's possible the child frame is loaded before
| |
| 938 (*cache)->parent_node_id_from_parent_tree = parent->id(); | |
| 939 *cache = parent_cache; | |
| 940 return parent; | |
| 941 } | |
| 942 | |
| 943 return nullptr; | |
| 944 } | |
| 945 | |
| 881 void AutomationInternalCustomBindings::RouteTreeIDFunction( | 946 void AutomationInternalCustomBindings::RouteTreeIDFunction( |
| 882 const std::string& name, | 947 const std::string& name, |
| 883 TreeIDFunction callback) { | 948 TreeIDFunction callback) { |
| 884 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback); | 949 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback); |
| 885 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper)); | 950 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper)); |
| 886 } | 951 } |
| 887 | 952 |
| 888 void AutomationInternalCustomBindings::RouteNodeIDFunction( | 953 void AutomationInternalCustomBindings::RouteNodeIDFunction( |
| 889 const std::string& name, | 954 const std::string& name, |
| 890 NodeIDFunction callback) { | 955 NodeIDFunction callback) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 const ExtensionMsg_AccessibilityEventParams& params, | 1011 const ExtensionMsg_AccessibilityEventParams& params, |
| 947 bool is_active_profile) { | 1012 bool is_active_profile) { |
| 948 is_active_profile_ = is_active_profile; | 1013 is_active_profile_ = is_active_profile; |
| 949 int tree_id = params.tree_id; | 1014 int tree_id = params.tree_id; |
| 950 TreeCache* cache; | 1015 TreeCache* cache; |
| 951 auto iter = tree_id_to_tree_cache_map_.find(tree_id); | 1016 auto iter = tree_id_to_tree_cache_map_.find(tree_id); |
| 952 if (iter == tree_id_to_tree_cache_map_.end()) { | 1017 if (iter == tree_id_to_tree_cache_map_.end()) { |
| 953 cache = new TreeCache(); | 1018 cache = new TreeCache(); |
| 954 cache->tab_id = -1; | 1019 cache->tab_id = -1; |
| 955 cache->tree_id = params.tree_id; | 1020 cache->tree_id = params.tree_id; |
| 1021 cache->parent_node_id_from_parent_tree = -1; | |
| 956 cache->tree.SetDelegate(this); | 1022 cache->tree.SetDelegate(this); |
| 1023 cache->owner = this; | |
| 957 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); | 1024 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); |
| 958 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); | 1025 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); |
| 959 } else { | 1026 } else { |
| 960 cache = iter->second; | 1027 cache = iter->second; |
| 961 } | 1028 } |
| 962 | 1029 |
| 963 // Update the internal state whether it's the active profile or not. | 1030 // Update the internal state whether it's the active profile or not. |
| 964 cache->location_offset = params.location_offset; | 1031 cache->location_offset = params.location_offset; |
| 965 deleted_node_ids_.clear(); | 1032 deleted_node_ids_.clear(); |
| 966 if (!cache->tree.Unserialize(params.update)) { | 1033 if (!cache->tree.Unserialize(params.update)) { |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1160 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); | 1227 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); |
| 1161 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); | 1228 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); |
| 1162 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); | 1229 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); |
| 1163 args->Set(1U, nodes); | 1230 args->Set(1U, nodes); |
| 1164 for (size_t i = 0; i < ids.size(); ++i) | 1231 for (size_t i = 0; i < ids.size(); ++i) |
| 1165 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); | 1232 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); |
| 1166 context()->DispatchEvent("automationInternal.onNodesRemoved", args); | 1233 context()->DispatchEvent("automationInternal.onNodesRemoved", args); |
| 1167 } | 1234 } |
| 1168 | 1235 |
| 1169 } // namespace extensions | 1236 } // namespace extensions |
| OLD | NEW |