| OLD | NEW |
| 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 23 matching lines...) Expand all Loading... |
| 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 // Keeps track of new nodes created during this update. | 39 // Keeps track of new nodes created during this update. |
| 40 std::set<AXNode*> new_nodes; | 40 std::set<AXNode*> new_nodes; |
| 41 | 41 |
| 42 // The new root in this update, if any. | 42 // The new root in this update, if any. |
| 43 AXNode* new_root; | 43 AXNode* new_root; |
| 44 |
| 45 // Keeps track of any nodes removed. Used to identify re-parented nodes. |
| 46 std::set<int> removed_node_ids; |
| 44 }; | 47 }; |
| 45 | 48 |
| 46 AXTreeDelegate::AXTreeDelegate() { | 49 AXTreeDelegate::AXTreeDelegate() { |
| 47 } | 50 } |
| 48 | 51 |
| 49 AXTreeDelegate::~AXTreeDelegate() { | 52 AXTreeDelegate::~AXTreeDelegate() { |
| 50 } | 53 } |
| 51 | 54 |
| 52 AXTree::AXTree() | 55 AXTree::AXTree() |
| 53 : delegate_(NULL), root_(NULL) { | 56 : delegate_(NULL), root_(NULL) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } | 137 } |
| 135 return false; | 138 return false; |
| 136 } | 139 } |
| 137 | 140 |
| 138 if (delegate_) { | 141 if (delegate_) { |
| 139 std::set<AXNode*>& new_nodes = update_state.new_nodes; | 142 std::set<AXNode*>& new_nodes = update_state.new_nodes; |
| 140 std::vector<AXTreeDelegate::Change> changes; | 143 std::vector<AXTreeDelegate::Change> changes; |
| 141 changes.reserve(update.nodes.size()); | 144 changes.reserve(update.nodes.size()); |
| 142 for (size_t i = 0; i < update.nodes.size(); ++i) { | 145 for (size_t i = 0; i < update.nodes.size(); ++i) { |
| 143 AXNode* node = GetFromId(update.nodes[i].id); | 146 AXNode* node = GetFromId(update.nodes[i].id); |
| 144 if (new_nodes.find(node) != new_nodes.end()) { | 147 bool is_new_node = new_nodes.find(node) != new_nodes.end(); |
| 145 if (new_nodes.find(node->parent()) == new_nodes.end()) { | 148 bool is_reparented_node = |
| 146 changes.push_back( | 149 is_new_node && |
| 147 AXTreeDelegate::Change(node, AXTreeDelegate::SUBTREE_CREATED)); | 150 update_state.removed_node_ids.find(node->id()) != |
| 151 update_state.removed_node_ids.end(); |
| 152 |
| 153 AXTreeDelegate::ChangeType change = AXTreeDelegate::NODE_CHANGED; |
| 154 if (is_new_node) { |
| 155 bool is_subtree = new_nodes.find(node->parent()) == new_nodes.end(); |
| 156 if (is_reparented_node) { |
| 157 change = is_subtree ? AXTreeDelegate::SUBTREE_REPARENTED |
| 158 : AXTreeDelegate::NODE_REPARENTED; |
| 148 } else { | 159 } else { |
| 149 changes.push_back( | 160 change = is_subtree ? AXTreeDelegate::SUBTREE_CREATED |
| 150 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED)); | 161 : AXTreeDelegate::NODE_CREATED; |
| 151 } | 162 } |
| 152 } else { | |
| 153 changes.push_back( | |
| 154 AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED)); | |
| 155 } | 163 } |
| 164 changes.push_back(AXTreeDelegate::Change(node, change)); |
| 156 } | 165 } |
| 157 delegate_->OnAtomicUpdateFinished( | 166 delegate_->OnAtomicUpdateFinished( |
| 158 this, root_->id() != old_root_id, changes); | 167 this, root_->id() != old_root_id, changes); |
| 159 } | 168 } |
| 160 | 169 |
| 161 return true; | 170 return true; |
| 162 } | 171 } |
| 163 | 172 |
| 164 std::string AXTree::ToString() const { | 173 std::string AXTree::ToString() const { |
| 165 return "AXTree" + data_.ToString() + "\n" + TreeToStringHelper(root_, 0); | 174 return "AXTree" + data_.ToString() + "\n" + TreeToStringHelper(root_, 0); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 181 // This method updates one node in the tree based on serialized data | 190 // This method updates one node in the tree based on serialized data |
| 182 // received in an AXTreeUpdate. See AXTreeUpdate for pre and post | 191 // received in an AXTreeUpdate. See AXTreeUpdate for pre and post |
| 183 // conditions. | 192 // conditions. |
| 184 | 193 |
| 185 // Look up the node by id. If it's not found, then either the root | 194 // Look up the node by id. If it's not found, then either the root |
| 186 // of the tree is being swapped, or we're out of sync with the source | 195 // of the tree is being swapped, or we're out of sync with the source |
| 187 // and this is a serious error. | 196 // and this is a serious error. |
| 188 AXNode* node = GetFromId(src.id); | 197 AXNode* node = GetFromId(src.id); |
| 189 if (node) { | 198 if (node) { |
| 190 update_state->pending_nodes.erase(node); | 199 update_state->pending_nodes.erase(node); |
| 191 if (delegate_) | 200 if (delegate_ && |
| 201 update_state->new_nodes.find(node) == update_state->new_nodes.end()) |
| 192 delegate_->OnNodeDataWillChange(this, node->data(), src); | 202 delegate_->OnNodeDataWillChange(this, node->data(), src); |
| 193 node->SetData(src); | 203 node->SetData(src); |
| 194 } else { | 204 } else { |
| 195 if (!is_new_root) { | 205 if (!is_new_root) { |
| 196 error_ = base::StringPrintf( | 206 error_ = base::StringPrintf( |
| 197 "%d is not in the tree and not the new root", src.id); | 207 "%d is not in the tree and not the new root", src.id); |
| 198 return false; | 208 return false; |
| 199 } | 209 } |
| 200 | 210 |
| 201 update_state->new_root = CreateNode(NULL, src.id, 0); | 211 update_state->new_root = CreateNode(NULL, src.id, 0); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 254 |
| 245 void AXTree::DestroyNodeAndSubtree(AXNode* node, | 255 void AXTree::DestroyNodeAndSubtree(AXNode* node, |
| 246 AXTreeUpdateState* update_state) { | 256 AXTreeUpdateState* update_state) { |
| 247 if (delegate_) | 257 if (delegate_) |
| 248 delegate_->OnNodeWillBeDeleted(this, node); | 258 delegate_->OnNodeWillBeDeleted(this, node); |
| 249 id_map_.erase(node->id()); | 259 id_map_.erase(node->id()); |
| 250 for (int i = 0; i < node->child_count(); ++i) | 260 for (int i = 0; i < node->child_count(); ++i) |
| 251 DestroyNodeAndSubtree(node->ChildAtIndex(i), update_state); | 261 DestroyNodeAndSubtree(node->ChildAtIndex(i), update_state); |
| 252 if (update_state) { | 262 if (update_state) { |
| 253 update_state->pending_nodes.erase(node); | 263 update_state->pending_nodes.erase(node); |
| 264 update_state->removed_node_ids.insert(node->id()); |
| 254 } | 265 } |
| 255 node->Destroy(); | 266 node->Destroy(); |
| 256 } | 267 } |
| 257 | 268 |
| 258 bool AXTree::DeleteOldChildren(AXNode* node, | 269 bool AXTree::DeleteOldChildren(AXNode* node, |
| 259 const std::vector<int32_t>& new_child_ids, | 270 const std::vector<int32_t>& new_child_ids, |
| 260 AXTreeUpdateState* update_state) { | 271 AXTreeUpdateState* update_state) { |
| 261 // Create a set of child ids in |src| for fast lookup, and return false | 272 // Create a set of child ids in |src| for fast lookup, and return false |
| 262 // if a duplicate is found; | 273 // if a duplicate is found; |
| 263 std::set<int32_t> new_child_id_set; | 274 std::set<int32_t> new_child_id_set; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 update_state->pending_nodes.insert(child); | 320 update_state->pending_nodes.insert(child); |
| 310 update_state->new_nodes.insert(child); | 321 update_state->new_nodes.insert(child); |
| 311 } | 322 } |
| 312 new_children->push_back(child); | 323 new_children->push_back(child); |
| 313 } | 324 } |
| 314 | 325 |
| 315 return success; | 326 return success; |
| 316 } | 327 } |
| 317 | 328 |
| 318 } // namespace ui | 329 } // namespace ui |
| OLD | NEW |