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

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

Issue 830943004: Improve the notifications sent from AXTree updates. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address feedback, add missing call to parent class Created 5 years, 11 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') | ui/accessibility/ax_tree_unittest.cc » ('j') | 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 <set> 7 #include <set>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 int32 old_root_id = root_ ? root_->id() : 0; 81 int32 old_root_id = root_ ? root_->id() : 0;
82 82
83 if (update.node_id_to_clear != 0) { 83 if (update.node_id_to_clear != 0) {
84 AXNode* node = GetFromId(update.node_id_to_clear); 84 AXNode* node = GetFromId(update.node_id_to_clear);
85 if (!node) { 85 if (!node) {
86 error_ = base::StringPrintf("Bad node_id_to_clear: %d", 86 error_ = base::StringPrintf("Bad node_id_to_clear: %d",
87 update.node_id_to_clear); 87 update.node_id_to_clear);
88 return false; 88 return false;
89 } 89 }
90 if (node == root_) { 90 if (node == root_) {
91 DestroyNodeAndSubtree(root_); 91 DestroySubtree(root_);
92 root_ = NULL; 92 root_ = NULL;
93 } else { 93 } else {
94 for (int i = 0; i < node->child_count(); ++i) 94 for (int i = 0; i < node->child_count(); ++i)
95 DestroyNodeAndSubtree(node->ChildAtIndex(i)); 95 DestroySubtree(node->ChildAtIndex(i));
96 std::vector<AXNode*> children; 96 std::vector<AXNode*> children;
97 node->SwapChildren(children); 97 node->SwapChildren(children);
98 update_state.pending_nodes.insert(node); 98 update_state.pending_nodes.insert(node);
99 } 99 }
100 } 100 }
101 101
102 for (size_t i = 0; i < update.nodes.size(); ++i) { 102 for (size_t i = 0; i < update.nodes.size(); ++i) {
103 if (!UpdateNode(update.nodes[i], &update_state)) 103 if (!UpdateNode(update.nodes[i], &update_state))
104 return false; 104 return false;
105 } 105 }
106 106
107 if (!update_state.pending_nodes.empty()) { 107 if (!update_state.pending_nodes.empty()) {
108 error_ = "Nodes left pending by the update:"; 108 error_ = "Nodes left pending by the update:";
109 for (std::set<AXNode*>::iterator iter = update_state.pending_nodes.begin(); 109 for (std::set<AXNode*>::iterator iter = update_state.pending_nodes.begin();
110 iter != update_state.pending_nodes.end(); ++iter) { 110 iter != update_state.pending_nodes.end(); ++iter) {
111 error_ += base::StringPrintf(" %d", (*iter)->id()); 111 error_ += base::StringPrintf(" %d", (*iter)->id());
112 } 112 }
113 return false; 113 return false;
114 } 114 }
115 115
116 if (delegate_) { 116 if (delegate_) {
117 std::set<AXNode*>& new_nodes = update_state.new_nodes;
118 std::vector<AXTreeDelegate::Change> changes;
119 changes.reserve(update.nodes.size());
117 for (size_t i = 0; i < update.nodes.size(); ++i) { 120 for (size_t i = 0; i < update.nodes.size(); ++i) {
118 AXNode* node = GetFromId(update.nodes[i].id); 121 AXNode* node = GetFromId(update.nodes[i].id);
119 if (update_state.new_nodes.find(node) != update_state.new_nodes.end()) { 122 if (new_nodes.find(node) != new_nodes.end()) {
120 delegate_->OnNodeCreationFinished(node); 123 if (new_nodes.find(node->parent()) == new_nodes.end()) {
121 update_state.new_nodes.erase(node); 124 changes.push_back(
125 AXTreeDelegate::Change(node, AXTreeDelegate::SUBTREE_CREATED));
126 } else {
127 changes.push_back(
128 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED));
129 }
122 } else { 130 } else {
123 delegate_->OnNodeChangeFinished(node); 131 changes.push_back(
132 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED));
124 } 133 }
125 } 134 }
126 if (root_->id() != old_root_id) 135 delegate_->OnAtomicUpdateFinished(root_->id() != old_root_id, changes);
127 delegate_->OnRootChanged(root_);
128 } 136 }
129 137
130 return true; 138 return true;
131 } 139 }
132 140
133 std::string AXTree::ToString() const { 141 std::string AXTree::ToString() const {
134 return TreeToStringHelper(root_, 0); 142 return TreeToStringHelper(root_, 0);
135 } 143 }
136 144
137 AXNode* AXTree::CreateNode( 145 AXNode* AXTree::CreateNode(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 node->SetData(src); 177 node->SetData(src);
170 } 178 }
171 179
172 if (delegate_) 180 if (delegate_)
173 delegate_->OnNodeChanged(node); 181 delegate_->OnNodeChanged(node);
174 182
175 // First, delete nodes that used to be children of this node but aren't 183 // First, delete nodes that used to be children of this node but aren't
176 // anymore. 184 // anymore.
177 if (!DeleteOldChildren(node, src.child_ids)) { 185 if (!DeleteOldChildren(node, src.child_ids)) {
178 if (new_root) 186 if (new_root)
179 DestroyNodeAndSubtree(new_root); 187 DestroySubtree(new_root);
180 return false; 188 return false;
181 } 189 }
182 190
183 // Now build a new children vector, reusing nodes when possible, 191 // Now build a new children vector, reusing nodes when possible,
184 // and swap it in. 192 // and swap it in.
185 std::vector<AXNode*> new_children; 193 std::vector<AXNode*> new_children;
186 bool success = CreateNewChildVector( 194 bool success = CreateNewChildVector(
187 node, src.child_ids, &new_children, update_state); 195 node, src.child_ids, &new_children, update_state);
188 node->SwapChildren(new_children); 196 node->SwapChildren(new_children);
189 197
190 // Update the root of the tree if needed. 198 // Update the root of the tree if needed.
191 if (src.role == AX_ROLE_ROOT_WEB_AREA && 199 if (src.role == AX_ROLE_ROOT_WEB_AREA &&
192 (!root_ || root_->id() != src.id)) { 200 (!root_ || root_->id() != src.id)) {
193 if (root_) 201 if (root_)
194 DestroyNodeAndSubtree(root_); 202 DestroySubtree(root_);
195 root_ = node; 203 root_ = node;
196 } 204 }
197 205
198 return success; 206 return success;
199 } 207 }
200 208
209 void AXTree::DestroySubtree(AXNode* node) {
210 if (delegate_)
211 delegate_->OnSubtreeWillBeDeleted(node);
212 DestroyNodeAndSubtree(node);
213 }
214
201 void AXTree::DestroyNodeAndSubtree(AXNode* node) { 215 void AXTree::DestroyNodeAndSubtree(AXNode* node) {
202 id_map_.erase(node->id()); 216 id_map_.erase(node->id());
203 for (int i = 0; i < node->child_count(); ++i) 217 for (int i = 0; i < node->child_count(); ++i)
204 DestroyNodeAndSubtree(node->ChildAtIndex(i)); 218 DestroyNodeAndSubtree(node->ChildAtIndex(i));
205 if (delegate_) 219 if (delegate_)
206 delegate_->OnNodeWillBeDeleted(node); 220 delegate_->OnNodeWillBeDeleted(node);
207 node->Destroy(); 221 node->Destroy();
208 } 222 }
209 223
210 bool AXTree::DeleteOldChildren(AXNode* node, 224 bool AXTree::DeleteOldChildren(AXNode* node,
211 const std::vector<int32> new_child_ids) { 225 const std::vector<int32> new_child_ids) {
212 // Create a set of child ids in |src| for fast lookup, and return false 226 // Create a set of child ids in |src| for fast lookup, and return false
213 // if a duplicate is found; 227 // if a duplicate is found;
214 std::set<int32> new_child_id_set; 228 std::set<int32> new_child_id_set;
215 for (size_t i = 0; i < new_child_ids.size(); ++i) { 229 for (size_t i = 0; i < new_child_ids.size(); ++i) {
216 if (new_child_id_set.find(new_child_ids[i]) != new_child_id_set.end()) { 230 if (new_child_id_set.find(new_child_ids[i]) != new_child_id_set.end()) {
217 error_ = base::StringPrintf("Node %d has duplicate child id %d", 231 error_ = base::StringPrintf("Node %d has duplicate child id %d",
218 node->id(), new_child_ids[i]); 232 node->id(), new_child_ids[i]);
219 return false; 233 return false;
220 } 234 }
221 new_child_id_set.insert(new_child_ids[i]); 235 new_child_id_set.insert(new_child_ids[i]);
222 } 236 }
223 237
224 // Delete the old children. 238 // Delete the old children.
225 const std::vector<AXNode*>& old_children = node->children(); 239 const std::vector<AXNode*>& old_children = node->children();
226 for (size_t i = 0; i < old_children.size(); ++i) { 240 for (size_t i = 0; i < old_children.size(); ++i) {
227 int old_id = old_children[i]->id(); 241 int old_id = old_children[i]->id();
228 if (new_child_id_set.find(old_id) == new_child_id_set.end()) 242 if (new_child_id_set.find(old_id) == new_child_id_set.end())
229 DestroyNodeAndSubtree(old_children[i]); 243 DestroySubtree(old_children[i]);
230 } 244 }
231 245
232 return true; 246 return true;
233 } 247 }
234 248
235 bool AXTree::CreateNewChildVector(AXNode* node, 249 bool AXTree::CreateNewChildVector(AXNode* node,
236 const std::vector<int32> new_child_ids, 250 const std::vector<int32> new_child_ids,
237 std::vector<AXNode*>* new_children, 251 std::vector<AXNode*>* new_children,
238 AXTreeUpdateState* update_state) { 252 AXTreeUpdateState* update_state) {
239 bool success = true; 253 bool success = true;
(...skipping 20 matching lines...) Expand all
260 update_state->pending_nodes.insert(child); 274 update_state->pending_nodes.insert(child);
261 update_state->new_nodes.insert(child); 275 update_state->new_nodes.insert(child);
262 } 276 }
263 new_children->push_back(child); 277 new_children->push_back(child);
264 } 278 }
265 279
266 return success; 280 return success;
267 } 281 }
268 282
269 } // namespace ui 283 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accessibility/ax_tree.h ('k') | ui/accessibility/ax_tree_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698