| 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))
|
|
|