| 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 <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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |