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 |