Index: ui/accessibility/ax_tree.cc |
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc |
index bd879eaac441754030ef96bae00cdbec65370f2d..3958a4db241d5dc5d4a784679c412f4c1c275774 100644 |
--- a/ui/accessibility/ax_tree.cc |
+++ b/ui/accessibility/ax_tree.cc |
@@ -113,10 +113,27 @@ bool AXTree::Unserialize(const AXTreeUpdate& update) { |
update_state.pending_nodes.insert(node); |
} |
} |
- |
+ std::set<int> node_created_ids; |
+ std::set<int> text_changed_ids; |
for (size_t i = 0; i < update.nodes.size(); ++i) { |
+ AXNode* original_node = GetFromId(update.nodes[i].id); |
+ std::string original_text; |
+ if (original_node) |
+ original_text = original_node->data().GetStringAttribute(AX_ATTR_NAME); |
+ |
if (!UpdateNode(update.nodes[i], &update_state)) |
return false; |
+ |
+ AXNode* updated_node = GetFromId(update.nodes[i].id); |
+ std::string updated_text; |
+ if (updated_node) |
+ updated_text = updated_node->data().GetStringAttribute(AX_ATTR_NAME); |
+ if (!original_node && updated_node) |
+ node_created_ids.insert(update.nodes[i].id); |
+ if (!original_text.empty() && !updated_text.empty() && |
+ updated_text != original_text) { |
+ text_changed_ids.insert(update.nodes[i].id); |
+ } |
} |
if (!update_state.pending_nodes.empty()) { |
@@ -139,12 +156,22 @@ bool AXTree::Unserialize(const AXTreeUpdate& update) { |
changes.push_back( |
AXTreeDelegate::Change(node, AXTreeDelegate::SUBTREE_CREATED)); |
} else { |
- changes.push_back( |
- AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED)); |
+ // Node creation based on |new_nodes| is sometimes unreliable. Define |
+ // creation based on this tree. |
+ if (node_created_ids.find(node->data().id) != |
+ node_created_ids.end()) { |
+ changes.push_back( |
+ AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CREATED)); |
+ } |
} |
} else { |
- changes.push_back( |
- AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED)); |
+ if (text_changed_ids.find(node->data().id) == text_changed_ids.end()) { |
+ changes.push_back( |
+ AXTreeDelegate::Change(node, AXTreeDelegate::NODE_CHANGED)); |
+ } else { |
+ changes.push_back( |
+ AXTreeDelegate::Change(node, AXTreeDelegate::TEXT_CHANGED)); |
+ } |
} |
} |
delegate_->OnAtomicUpdateFinished( |