Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/renderer/extensions/automation_internal_custom_bindings.cc

Issue 1761633002: One accessibility tree per frame. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix is-richly-editable test Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
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
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
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(
907 ui::AXNode* node,
908 TreeCache** in_out_cache) {
909 if (node->parent())
910 return node->parent();
911
912 int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id;
913 if (parent_tree_id < 0)
914 return nullptr;
915
916 TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id);
917 if (!parent_cache)
918 return nullptr;
919
920 // Try to use the cached parent node from the most recent time this
921 // was called.
922 if (parent_cache->parent_node_id_from_parent_tree > 0) {
923 ui::AXNode* parent = parent_cache->tree.GetFromId(
924 parent_cache->parent_node_id_from_parent_tree);
925 if (parent) {
926 int parent_child_tree_id =
927 parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
928 if (parent_child_tree_id == (*in_out_cache)->tree_id) {
929 *in_out_cache = parent_cache;
930 return parent;
931 }
932 }
933 }
934
935 // If that fails, search for it and cache it for next time.
936 ui::AXNode* parent = FindNodeWithChildTreeId(parent_cache->tree.root(),
937 (*in_out_cache)->tree_id);
938 if (parent) {
939 (*in_out_cache)->parent_node_id_from_parent_tree = parent->id();
940 *in_out_cache = parent_cache;
941 return parent;
942 }
943
944 return nullptr;
945 }
946
881 void AutomationInternalCustomBindings::RouteTreeIDFunction( 947 void AutomationInternalCustomBindings::RouteTreeIDFunction(
882 const std::string& name, 948 const std::string& name,
883 TreeIDFunction callback) { 949 TreeIDFunction callback) {
884 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback); 950 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback);
885 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper)); 951 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper));
886 } 952 }
887 953
888 void AutomationInternalCustomBindings::RouteNodeIDFunction( 954 void AutomationInternalCustomBindings::RouteNodeIDFunction(
889 const std::string& name, 955 const std::string& name,
890 NodeIDFunction callback) { 956 NodeIDFunction callback) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 const ExtensionMsg_AccessibilityEventParams& params, 1012 const ExtensionMsg_AccessibilityEventParams& params,
947 bool is_active_profile) { 1013 bool is_active_profile) {
948 is_active_profile_ = is_active_profile; 1014 is_active_profile_ = is_active_profile;
949 int tree_id = params.tree_id; 1015 int tree_id = params.tree_id;
950 TreeCache* cache; 1016 TreeCache* cache;
951 auto iter = tree_id_to_tree_cache_map_.find(tree_id); 1017 auto iter = tree_id_to_tree_cache_map_.find(tree_id);
952 if (iter == tree_id_to_tree_cache_map_.end()) { 1018 if (iter == tree_id_to_tree_cache_map_.end()) {
953 cache = new TreeCache(); 1019 cache = new TreeCache();
954 cache->tab_id = -1; 1020 cache->tab_id = -1;
955 cache->tree_id = params.tree_id; 1021 cache->tree_id = params.tree_id;
1022 cache->parent_node_id_from_parent_tree = -1;
956 cache->tree.SetDelegate(this); 1023 cache->tree.SetDelegate(this);
1024 cache->owner = this;
957 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); 1025 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)); 1026 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache));
959 } else { 1027 } else {
960 cache = iter->second; 1028 cache = iter->second;
961 } 1029 }
962 1030
963 // Update the internal state whether it's the active profile or not. 1031 // Update the internal state whether it's the active profile or not.
964 cache->location_offset = params.location_offset; 1032 cache->location_offset = params.location_offset;
965 deleted_node_ids_.clear(); 1033 deleted_node_ids_.clear();
966 if (!cache->tree.Unserialize(params.update)) { 1034 if (!cache->tree.Unserialize(params.update)) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); 1228 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U));
1161 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); 1229 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id));
1162 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); 1230 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size()));
1163 args->Set(1U, nodes); 1231 args->Set(1U, nodes);
1164 for (size_t i = 0; i < ids.size(); ++i) 1232 for (size_t i = 0; i < ids.size(); ++i)
1165 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); 1233 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i]));
1166 context()->DispatchEvent("automationInternal.onNodesRemoved", args); 1234 context()->DispatchEvent("automationInternal.onNodesRemoved", args);
1167 } 1235 }
1168 1236
1169 } // namespace extensions 1237 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698