blob: b943ca3131aec6fb1b8c2e4025f9ca20f66aadd6 [file] [log] [blame]
Abigail Klein508432f2022-12-15 17:23:211// Copyright 2022 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/accessibility/ax_tree_update_util.h"
6
7#include "ui/accessibility/ax_tree_update.h"
8
9namespace ui {
10
11// Two tree updates can be merged into one if the second one
12// doesn't clear a subtree, doesn't have new tree data, and
13// doesn't have a new root id - in other words the second tree
14// update consists of only changes to nodes.
15bool AXTreeUpdatesCanBeMerged(const AXTreeUpdate& u1, const AXTreeUpdate& u2) {
16 if (u2.node_id_to_clear)
17 return false;
18
19 if (u2.has_tree_data && u2.tree_data != u1.tree_data)
20 return false;
21
22 if (u2.root_id != u1.root_id)
23 return false;
24
25 return true;
26}
27
28bool MergeAXTreeUpdates(const std::vector<AXTreeUpdate>& src,
29 std::vector<AXTreeUpdate>* dst) {
30 size_t merge_count = 0;
31 for (size_t i = 1; i < src.size(); i++) {
32 if (AXTreeUpdatesCanBeMerged(src[i - 1], src[i]))
33 merge_count++;
34 }
35
36 // Doing a single merge isn't necessarily worth it because
37 // copying the tree updates takes time too so the total
38 // savings is less. But two more more merges is probably
39 // worth the overhead of copying.
40 if (merge_count < 2)
41 return false;
42
43 dst->resize(src.size() - merge_count);
44 (*dst)[0] = src[0];
45 size_t dst_index = 0;
46 for (size_t i = 1; i < src.size(); i++) {
47 if (AXTreeUpdatesCanBeMerged(src[i - 1], src[i])) {
48 std::vector<AXNodeData>& dst_nodes = (*dst)[dst_index].nodes;
49 const std::vector<AXNodeData>& src_nodes = src[i].nodes;
50 dst_nodes.insert(dst_nodes.end(), src_nodes.begin(), src_nodes.end());
51 } else {
52 dst_index++;
53 (*dst)[dst_index] = src[i];
54 }
55 }
56
57 return true;
58}
59
60} // namespace ui