Chromium Code Reviews| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |