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

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

Issue 2080573003: Track all changed nodes during an update (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Exhaustive approach. Created 4 years, 3 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 | « no previous file | 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 18 matching lines...) Expand all
29 // Intermediate state to keep track of during a tree update. 29 // Intermediate state to keep track of during a tree update.
30 struct AXTreeUpdateState { 30 struct AXTreeUpdateState {
31 AXTreeUpdateState() : new_root(nullptr) {} 31 AXTreeUpdateState() : new_root(nullptr) {}
32 32
33 // During an update, this keeps track of all nodes that have been 33 // During an update, this keeps track of all nodes that have been
34 // implicitly referenced as part of this update, but haven't been 34 // implicitly referenced as part of this update, but haven't been
35 // updated yet. It's an error if there are any pending nodes at the 35 // updated yet. It's an error if there are any pending nodes at the
36 // end of Unserialize. 36 // end of Unserialize.
37 std::set<AXNode*> pending_nodes; 37 std::set<AXNode*> pending_nodes;
38 38
39 // This is similar to above, but we store node ids here because this list gets
40 // generated before any nodes get created or re-used. Its purpose is to allow
41 // us to know what nodes will be updated so we can make more intelligent
42 // decisions about when to notify delegates of removals or reparenting.
43 std::set<int> changed_node_ids;
44
39 // Keeps track of new nodes created during this update. 45 // Keeps track of new nodes created during this update.
40 std::set<AXNode*> new_nodes; 46 std::set<AXNode*> new_nodes;
41 47
42 // The new root in this update, if any. 48 // The new root in this update, if any.
43 AXNode* new_root; 49 AXNode* new_root;
44 50
45 // Keeps track of any nodes removed. Used to identify re-parented nodes. 51 // Keeps track of any nodes removed. Used to identify re-parented nodes.
46 std::set<int> removed_node_ids; 52 std::set<int> removed_node_ids;
47 }; 53 };
48 54
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 void AXTree::UpdateData(const AXTreeData& data) { 91 void AXTree::UpdateData(const AXTreeData& data) {
86 data_ = data; 92 data_ = data;
87 if (delegate_) 93 if (delegate_)
88 delegate_->OnTreeDataChanged(this); 94 delegate_->OnTreeDataChanged(this);
89 } 95 }
90 96
91 bool AXTree::Unserialize(const AXTreeUpdate& update) { 97 bool AXTree::Unserialize(const AXTreeUpdate& update) {
92 AXTreeUpdateState update_state; 98 AXTreeUpdateState update_state;
93 int32_t old_root_id = root_ ? root_->id() : 0; 99 int32_t old_root_id = root_ ? root_->id() : 0;
94 100
101 // First, make a note of any nodes we will touch as part of this update
102 // including implicitly via parent/child relationships.
103 for (size_t i = 0; i < update.nodes.size(); ++i) {
104 update_state.changed_node_ids.insert(update.nodes[i].id);
105 for (size_t j = 0; j < update.nodes[i].child_ids.size(); ++j)
106 update_state.changed_node_ids.insert(update.nodes[i].child_ids[j]);
107 }
108
95 if (update.has_tree_data) 109 if (update.has_tree_data)
96 UpdateData(update.tree_data); 110 UpdateData(update.tree_data);
97 111
98 if (update.node_id_to_clear != 0) { 112 if (update.node_id_to_clear != 0) {
99 AXNode* node = GetFromId(update.node_id_to_clear); 113 AXNode* node = GetFromId(update.node_id_to_clear);
100 if (!node) { 114 if (!node) {
101 error_ = base::StringPrintf("Bad node_id_to_clear: %d", 115 error_ = base::StringPrintf("Bad node_id_to_clear: %d",
102 update.node_id_to_clear); 116 update.node_id_to_clear);
103 return false; 117 return false;
104 } 118 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 root_ = node; 254 root_ = node;
241 if (old_root) 255 if (old_root)
242 DestroySubtree(old_root, update_state); 256 DestroySubtree(old_root, update_state);
243 } 257 }
244 258
245 return success; 259 return success;
246 } 260 }
247 261
248 void AXTree::DestroySubtree(AXNode* node, 262 void AXTree::DestroySubtree(AXNode* node,
249 AXTreeUpdateState* update_state) { 263 AXTreeUpdateState* update_state) {
250 if (delegate_) 264 if (delegate_ && (!update_state ||
dmazzoni 2016/09/06 22:49:44 I don't think we support |update_state| being null
David Tseng 2016/09/07 16:37:01 Alright, done, DestroySubtree only gets called fro
265 update_state->changed_node_ids.find(node->id()) ==
266 update_state->changed_node_ids.end()))
251 delegate_->OnSubtreeWillBeDeleted(this, node); 267 delegate_->OnSubtreeWillBeDeleted(this, node);
252 DestroyNodeAndSubtree(node, update_state); 268 DestroyNodeAndSubtree(node, update_state);
253 } 269 }
254 270
255 void AXTree::DestroyNodeAndSubtree(AXNode* node, 271 void AXTree::DestroyNodeAndSubtree(AXNode* node,
256 AXTreeUpdateState* update_state) { 272 AXTreeUpdateState* update_state) {
257 if (delegate_) 273 if (delegate_ && (!update_state ||
274 update_state->changed_node_ids.find(node->id()) ==
275 update_state->changed_node_ids.end()))
258 delegate_->OnNodeWillBeDeleted(this, node); 276 delegate_->OnNodeWillBeDeleted(this, node);
259 id_map_.erase(node->id()); 277 id_map_.erase(node->id());
260 for (int i = 0; i < node->child_count(); ++i) 278 for (int i = 0; i < node->child_count(); ++i)
261 DestroyNodeAndSubtree(node->ChildAtIndex(i), update_state); 279 DestroyNodeAndSubtree(node->ChildAtIndex(i), update_state);
262 if (update_state) { 280 if (update_state) {
263 update_state->pending_nodes.erase(node); 281 update_state->pending_nodes.erase(node);
264 update_state->removed_node_ids.insert(node->id()); 282 update_state->removed_node_ids.insert(node->id());
265 } 283 }
266 node->Destroy(); 284 node->Destroy();
267 } 285 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 update_state->pending_nodes.insert(child); 338 update_state->pending_nodes.insert(child);
321 update_state->new_nodes.insert(child); 339 update_state->new_nodes.insert(child);
322 } 340 }
323 new_children->push_back(child); 341 new_children->push_back(child);
324 } 342 }
325 343
326 return success; 344 return success;
327 } 345 }
328 346
329 } // namespace ui 347 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698