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

Side by Side Diff: ui/accessibility/ax_tree.cc

Issue 1716663002: Add a treeChange type to Automation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « ui/accessibility/ax_tree.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "ui/accessibility/ax_tree.h" 5 #include "ui/accessibility/ax_tree.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 10
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 root_ = nullptr; 106 root_ = nullptr;
107 DestroySubtree(old_root, &update_state); 107 DestroySubtree(old_root, &update_state);
108 } else { 108 } else {
109 for (int i = 0; i < node->child_count(); ++i) 109 for (int i = 0; i < node->child_count(); ++i)
110 DestroySubtree(node->ChildAtIndex(i), &update_state); 110 DestroySubtree(node->ChildAtIndex(i), &update_state);
111 std::vector<AXNode*> children; 111 std::vector<AXNode*> children;
112 node->SwapChildren(children); 112 node->SwapChildren(children);
113 update_state.pending_nodes.insert(node); 113 update_state.pending_nodes.insert(node);
114 } 114 }
115 } 115 }
116 std::set<int> node_created_ids;
117 std::set<int> text_changed_ids;
118 for (size_t i = 0; i < update.nodes.size(); ++i) {
119 AXNode* original_node = GetFromId(update.nodes[i].id);
120 std::string original_text;
121 if (original_node)
122 original_text = original_node->data().GetStringAttribute(AX_ATTR_NAME);
116 123
117 for (size_t i = 0; i < update.nodes.size(); ++i) {
118 if (!UpdateNode(update.nodes[i], &update_state)) 124 if (!UpdateNode(update.nodes[i], &update_state))
119 return false; 125 return false;
126
127 AXNode* updated_node = GetFromId(update.nodes[i].id);
128 std::string updated_text;
129 if (updated_node)
130 updated_text = updated_node->data().GetStringAttribute(AX_ATTR_NAME);
131 if (!original_node && updated_node)
132 node_created_ids.insert(update.nodes[i].id);
133 if (!original_text.empty() && !updated_text.empty() &&
134 updated_text != original_text) {
135 text_changed_ids.insert(update.nodes[i].id);
136 }
120 } 137 }
121 138
122 if (!update_state.pending_nodes.empty()) { 139 if (!update_state.pending_nodes.empty()) {
123 error_ = "Nodes left pending by the update:"; 140 error_ = "Nodes left pending by the update:";
124 for (std::set<AXNode*>::iterator iter = update_state.pending_nodes.begin(); 141 for (std::set<AXNode*>::iterator iter = update_state.pending_nodes.begin();
125 iter != update_state.pending_nodes.end(); ++iter) { 142 iter != update_state.pending_nodes.end(); ++iter) {
126 error_ += base::StringPrintf(" %d", (*iter)->id()); 143 error_ += base::StringPrintf(" %d", (*iter)->id());
127 } 144 }
128 return false; 145 return false;
129 } 146 }
130 147
131 if (delegate_) { 148 if (delegate_) {
132 std::set<AXNode*>& new_nodes = update_state.new_nodes; 149 std::set<AXNode*>& new_nodes = update_state.new_nodes;
133 std::vector<AXTreeDelegate::Change> changes; 150 std::vector<AXTreeDelegate::Change> changes;
134 changes.reserve(update.nodes.size()); 151 changes.reserve(update.nodes.size());
135 for (size_t i = 0; i < update.nodes.size(); ++i) { 152 for (size_t i = 0; i < update.nodes.size(); ++i) {
136 AXNode* node = GetFromId(update.nodes[i].id); 153 AXNode* node = GetFromId(update.nodes[i].id);
137 if (new_nodes.find(node) != new_nodes.end()) { 154 if (new_nodes.find(node) != new_nodes.end()) {
138 if (new_nodes.find(node->parent()) == new_nodes.end()) { 155 if (new_nodes.find(node->parent()) == new_nodes.end()) {
139 changes.push_back( 156 changes.push_back(
140 AXTreeDelegate::Change(node, AXTreeDelegate::SUBTREE_CREATED)); 157 AXTreeDelegate::Change(node, AXTreeDelegate::SUBTREE_CREATED));
141 } else { 158 } else {
142 changes.push_back( 159 // Node creation based on |new_nodes| is sometimes unreliable. Define
143 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED)); 160 // creation based on this tree.
161 if (node_created_ids.find(node->data().id) !=
162 node_created_ids.end()) {
163 changes.push_back(
164 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED));
165 }
144 } 166 }
145 } else { 167 } else {
146 changes.push_back( 168 if (text_changed_ids.find(node->data().id) == text_changed_ids.end()) {
147 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED)); 169 changes.push_back(
170 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED));
171 } else {
172 changes.push_back(
173 AXTreeDelegate::Change(node, AXTreeDelegate::TEXT_CHANGED));
174 }
148 } 175 }
149 } 176 }
150 delegate_->OnAtomicUpdateFinished( 177 delegate_->OnAtomicUpdateFinished(
151 this, root_->id() != old_root_id, changes); 178 this, root_->id() != old_root_id, changes);
152 } 179 }
153 180
154 return true; 181 return true;
155 } 182 }
156 183
157 std::string AXTree::ToString() const { 184 std::string AXTree::ToString() const {
(...skipping 15 matching lines...) Expand all
173 // This method updates one node in the tree based on serialized data 200 // This method updates one node in the tree based on serialized data
174 // received in an AXTreeUpdate. See AXTreeUpdate for pre and post 201 // received in an AXTreeUpdate. See AXTreeUpdate for pre and post
175 // conditions. 202 // conditions.
176 203
177 // Look up the node by id. If it's not found, then either the root 204 // Look up the node by id. If it's not found, then either the root
178 // of the tree is being swapped, or we're out of sync with the source 205 // of the tree is being swapped, or we're out of sync with the source
179 // and this is a serious error. 206 // and this is a serious error.
180 AXNode* node = GetFromId(src.id); 207 AXNode* node = GetFromId(src.id);
181 if (node) { 208 if (node) {
182 update_state->pending_nodes.erase(node); 209 update_state->pending_nodes.erase(node);
183 node->SetData(src); 210 node->SetData(src);
dmazzoni 2016/02/19 04:17:32 I think this would be the place to hook it. Right
184 } else { 211 } else {
185 if (src.role != AX_ROLE_ROOT_WEB_AREA && 212 if (src.role != AX_ROLE_ROOT_WEB_AREA &&
186 src.role != AX_ROLE_DESKTOP) { 213 src.role != AX_ROLE_DESKTOP) {
187 error_ = base::StringPrintf( 214 error_ = base::StringPrintf(
188 "%d is not in the tree and not the new root", src.id); 215 "%d is not in the tree and not the new root", src.id);
189 return false; 216 return false;
190 } 217 }
191 if (update_state->new_root) { 218 if (update_state->new_root) {
192 error_ = "Tree update contains two new roots"; 219 error_ = "Tree update contains two new roots";
193 return false; 220 return false;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 update_state->pending_nodes.insert(child); 332 update_state->pending_nodes.insert(child);
306 update_state->new_nodes.insert(child); 333 update_state->new_nodes.insert(child);
307 } 334 }
308 new_children->push_back(child); 335 new_children->push_back(child);
309 } 336 }
310 337
311 return success; 338 return success;
312 } 339 }
313 340
314 } // namespace ui 341 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accessibility/ax_tree.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698