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

Unified Diff: ui/accessibility/ax_tree_serializer.h

Issue 966833002: Fix a case where AXTreeSerializer didn't handle reparenting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address feedback Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/accessibility/ax_tree_serializer.h
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
index f1cbfcea1053760d218d8686fe310273c6a0f7e5..53e515aaa484a99ed9b2d6cdc28bcb166c07f80b 100644
--- a/ui/accessibility/ax_tree_serializer.h
+++ b/ui/accessibility/ax_tree_serializer.h
@@ -292,36 +292,39 @@ void AXTreeSerializer<AXSourceNode>::SerializeChanges(
// with the LCA.
AXSourceNode lca = LeastCommonAncestor(node);
- if (client_root_) {
- bool need_delete = false;
- if (tree_->IsValid(lca)) {
- // Check for any reparenting within this subtree - if there is
- // any, we need to delete and reserialize the whole subtree
- // that contains the old and new parents of the reparented node.
- if (AnyDescendantWasReparented(lca, &lca))
- need_delete = true;
- }
+ // This loop computes the least common ancestor that includes the old
+ // and new parents of any nodes that have been reparented, and clears the
+ // whole client subtree of that LCA if necessary. If we do end up clearing
+ // any client nodes, keep looping because we have to search for more
+ // nodes that may have been reparented from this new LCA.
+ bool need_delete;
+ do {
+ need_delete = false;
+ if (client_root_) {
+ if (tree_->IsValid(lca)) {
+ // Check for any reparenting within this subtree - if there is
+ // any, we need to delete and reserialize the whole subtree
+ // that contains the old and new parents of the reparented node.
+ if (AnyDescendantWasReparented(lca, &lca))
+ need_delete = true;
+ }
- if (!tree_->IsValid(lca)) {
- // If there's no LCA, just tell the client to destroy the whole
- // tree and then we'll serialize everything from the new root.
- out_update->node_id_to_clear = client_root_->id;
- Reset();
- } else if (need_delete) {
- // Otherwise, if we need to reserialize a subtree, first we need
- // to delete those nodes in our client tree so that
- // SerializeChangedNodes() will be sure to send them again.
- out_update->node_id_to_clear = tree_->GetId(lca);
- ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca));
- CHECK(client_lca);
- for (size_t i = 0; i < client_lca->children.size(); ++i) {
- client_id_map_.erase(client_lca->children[i]->id);
- DeleteClientSubtree(client_lca->children[i]);
- delete client_lca->children[i];
+ if (!tree_->IsValid(lca)) {
+ // If there's no LCA, just tell the client to destroy the whole
+ // tree and then we'll serialize everything from the new root.
+ out_update->node_id_to_clear = client_root_->id;
+ Reset();
+ } else if (need_delete) {
+ // Otherwise, if we need to reserialize a subtree, first we need
+ // to delete those nodes in our client tree so that
+ // SerializeChangedNodes() will be sure to send them again.
+ out_update->node_id_to_clear = tree_->GetId(lca);
+ ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca));
+ CHECK(client_lca);
+ DeleteClientSubtree(client_lca);
}
- client_lca->children.clear();
}
- }
+ } while (need_delete);
// Serialize from the LCA, or from the root if there isn't one.
if (!tree_->IsValid(lca))
« 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