| 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 #ifndef UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ | 5 #ifndef UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ |
| 6 #define UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ | 6 #define UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "ui/accessibility/ax_node_data.h" | 12 #include "ui/accessibility/ax_node_data.h" |
| 13 #include "ui/accessibility/ax_tree_data.h" |
| 13 | 14 |
| 14 namespace ui { | 15 namespace ui { |
| 15 | 16 |
| 16 // An AXTreeUpdate is a serialized representation of an atomic change | 17 // An AXTreeUpdate is a serialized representation of an atomic change |
| 17 // to an AXTree. The sender and receiver must be in sync; the update | 18 // to an AXTree. The sender and receiver must be in sync; the update |
| 18 // is only meant to bring the tree from a specific previous state into | 19 // is only meant to bring the tree from a specific previous state into |
| 19 // its next state. Trying to apply it to the wrong tree should immediately | 20 // its next state. Trying to apply it to the wrong tree should immediately |
| 20 // die with a fatal assertion. | 21 // die with a fatal assertion. |
| 21 // | 22 // |
| 22 // An AXTreeUpdate consists of an optional node id to clear (meaning | 23 // An AXTreeUpdate consists of an optional node id to clear (meaning |
| 23 // that all of that node's children and their descendants are deleted), | 24 // that all of that node's children and their descendants are deleted), |
| 24 // followed by an ordered vector of AXNodeData structures to be applied | 25 // followed by an ordered vector of zero or more AXNodeData structures to |
| 25 // to the tree in order. | 26 // be applied to the tree in order. An update may also include an optional |
| 27 // update to the AXTreeData structure that applies to the tree as a whole. |
| 26 // | 28 // |
| 27 // Suppose that the next AXNodeData to be applied is |node|. The following | 29 // Suppose that the next AXNodeData to be applied is |node|. The following |
| 28 // invariants must hold: | 30 // invariants must hold: |
| 29 // 1. Either |node.id| is already in the tree, or else the tree is empty, | 31 // 1. Either |node.id| is already in the tree, or else the tree is empty, |
| 30 // |node| is the new root of the tree, and | 32 // |node| is the new root of the tree, and |
| 31 // |node.role| == WebAXRoleRootWebArea. | 33 // |node.role| == WebAXRoleRootWebArea. |
| 32 // 2. Every child id in |node.child_ids| must either be already a child | 34 // 2. Every child id in |node.child_ids| must either be already a child |
| 33 // of this node, or a new id not previously in the tree. It is not | 35 // of this node, or a new id not previously in the tree. It is not |
| 34 // allowed to "reparent" a child to this node without first removing | 36 // allowed to "reparent" a child to this node without first removing |
| 35 // that child from its previous parent. | 37 // that child from its previous parent. |
| 36 // 3. When a new id appears in |node.child_ids|, the tree should create a | 38 // 3. When a new id appears in |node.child_ids|, the tree should create a |
| 37 // new uninitialized placeholder node for it immediately. That | 39 // new uninitialized placeholder node for it immediately. That |
| 38 // placeholder must be updated within the same AXTreeUpdate, otherwise | 40 // placeholder must be updated within the same AXTreeUpdate, otherwise |
| 39 // it's a fatal error. This guarantees the tree is always complete | 41 // it's a fatal error. This guarantees the tree is always complete |
| 40 // before or after an AXTreeUpdate. | 42 // before or after an AXTreeUpdate. |
| 41 template<typename AXNodeData> struct AXTreeUpdate { | 43 template<typename AXNodeData, typename AXTreeData> struct AXTreeUpdateBase { |
| 42 AXTreeUpdate(); | 44 AXTreeUpdateBase(); |
| 43 ~AXTreeUpdate(); | 45 ~AXTreeUpdateBase(); |
| 46 |
| 47 // If |has_tree_data| is true, the value of |tree_data| should be used |
| 48 // to update the tree data, otherwise it should be ignored. |
| 49 bool has_tree_data; |
| 50 AXTreeData tree_data; |
| 44 | 51 |
| 45 // The id of a node to clear, before applying any updates, | 52 // The id of a node to clear, before applying any updates, |
| 46 // or 0 if no nodes should be cleared. Clearing a node means deleting | 53 // or 0 if no nodes should be cleared. Clearing a node means deleting |
| 47 // all of its children and their descendants, but leaving that node in | 54 // all of its children and their descendants, but leaving that node in |
| 48 // the tree. It's an error to clear a node but not subsequently update it | 55 // the tree. It's an error to clear a node but not subsequently update it |
| 49 // as part of the tree update. | 56 // as part of the tree update. |
| 50 int node_id_to_clear; | 57 int node_id_to_clear; |
| 51 | 58 |
| 52 // A vector of nodes to update, according to the rules above. | 59 // A vector of nodes to update, according to the rules above. |
| 53 std::vector<AXNodeData> nodes; | 60 std::vector<AXNodeData> nodes; |
| 54 | 61 |
| 55 // Return a multi-line indented string representation, for logging. | 62 // Return a multi-line indented string representation, for logging. |
| 56 std::string ToString() const; | 63 std::string ToString() const; |
| 57 | 64 |
| 58 // TODO(dmazzoni): location changes | 65 // TODO(dmazzoni): location changes |
| 59 }; | 66 }; |
| 60 | 67 |
| 61 template<typename AXNodeData> | 68 typedef AXTreeUpdateBase<AXNodeData, AXTreeData> AXTreeUpdate; |
| 62 AXTreeUpdate<AXNodeData>::AXTreeUpdate() : node_id_to_clear(0) { | 69 |
| 70 template<typename AXNodeData, typename AXTreeData> |
| 71 AXTreeUpdateBase<AXNodeData, AXTreeData>::AXTreeUpdateBase() |
| 72 : has_tree_data(false), |
| 73 node_id_to_clear(0) { |
| 63 } | 74 } |
| 64 | 75 |
| 65 template<typename AXNodeData> | 76 template<typename AXNodeData, typename AXTreeData> |
| 66 AXTreeUpdate<AXNodeData>::~AXTreeUpdate() { | 77 AXTreeUpdateBase<AXNodeData, AXTreeData>::~AXTreeUpdateBase() { |
| 67 } | 78 } |
| 68 | 79 |
| 69 template<typename AXNodeData> | 80 template<typename AXNodeData, typename AXTreeData> |
| 70 std::string AXTreeUpdate<AXNodeData>::ToString() const { | 81 std::string AXTreeUpdateBase<AXNodeData, AXTreeData>::ToString() const { |
| 71 std::string result; | 82 std::string result; |
| 83 |
| 84 if (has_tree_data) { |
| 85 result += "AXTreeUpdate tree data:" + tree_data.ToString(); |
| 86 } |
| 87 |
| 72 if (node_id_to_clear != 0) { | 88 if (node_id_to_clear != 0) { |
| 73 result += "AXTreeUpdate: clear node " + | 89 result += "AXTreeUpdate: clear node " + |
| 74 base::IntToString(node_id_to_clear) + "\n"; | 90 base::IntToString(node_id_to_clear) + "\n"; |
| 75 } | 91 } |
| 76 | 92 |
| 77 // The challenge here is that we want to indent the nodes being updated | 93 // The challenge here is that we want to indent the nodes being updated |
| 78 // so that parent/child relationships are clear, but we don't have access | 94 // so that parent/child relationships are clear, but we don't have access |
| 79 // to the rest of the tree for context, so we have to try to show the | 95 // to the rest of the tree for context, so we have to try to show the |
| 80 // relative indentation of child nodes in this update relative to their | 96 // relative indentation of child nodes in this update relative to their |
| 81 // parents. | 97 // parents. |
| 82 base::hash_map<int32, int> id_to_indentation; | 98 base::hash_map<int32, int> id_to_indentation; |
| 83 for (size_t i = 0; i < nodes.size(); ++i) { | 99 for (size_t i = 0; i < nodes.size(); ++i) { |
| 84 int indent = id_to_indentation[nodes[i].id]; | 100 int indent = id_to_indentation[nodes[i].id]; |
| 85 result += std::string(2 * indent, ' '); | 101 result += std::string(2 * indent, ' '); |
| 86 result += nodes[i].ToString() + "\n"; | 102 result += nodes[i].ToString() + "\n"; |
| 87 for (size_t j = 0; j < nodes[i].child_ids.size(); ++j) | 103 for (size_t j = 0; j < nodes[i].child_ids.size(); ++j) |
| 88 id_to_indentation[nodes[i].child_ids[j]] = indent + 1; | 104 id_to_indentation[nodes[i].child_ids[j]] = indent + 1; |
| 89 } | 105 } |
| 90 | 106 |
| 91 return result; | 107 return result; |
| 92 } | 108 } |
| 93 | 109 |
| 94 } // namespace ui | 110 } // namespace ui |
| 95 | 111 |
| 96 #endif // UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ | 112 #endif // UI_ACCESSIBILITY_AX_TREE_UPDATE_H_ |
| OLD | NEW |