| Index: ui/accessibility/tree_generator.cc
|
| diff --git a/ui/accessibility/tree_generator.cc b/ui/accessibility/tree_generator.cc
|
| index 8eb45028ed4d45cd5994b1b2c58bc7e7135ac4c1..144b8029f445bc30692b56bb70426c27bded6a1f 100644
|
| --- a/ui/accessibility/tree_generator.cc
|
| +++ b/ui/accessibility/tree_generator.cc
|
| @@ -9,50 +9,95 @@
|
|
|
| namespace ui {
|
|
|
| -TreeGenerator::TreeGenerator(int node_count)
|
| - : node_count_(node_count), unique_tree_count_(1) {
|
| +static int UniqueTreeCountForNodeCount(int node_count,
|
| + bool permutations) {
|
| + int unique_tree_count = 1;
|
| +
|
| // (n-1)! for the possible trees.
|
| - for (int i = 2; i < node_count_; i++)
|
| - unique_tree_count_ *= i;
|
| + for (int i = 2; i < node_count; ++i)
|
| + unique_tree_count *= i;
|
| +
|
| // n! for the permutations of ids.
|
| - for (int i = 2; i <= node_count_; i++)
|
| - unique_tree_count_ *= i;
|
| -};
|
| + if (permutations)
|
| + unique_tree_count = unique_tree_count * unique_tree_count * node_count;
|
| +
|
| + return unique_tree_count;
|
| +}
|
| +
|
| +TreeGenerator::TreeGenerator(int max_node_count, bool permutations)
|
| + : max_node_count_(max_node_count),
|
| + permutations_(permutations),
|
| + total_unique_tree_count_(0) {
|
| + unique_tree_count_by_size_.push_back(0);
|
| + for (int i = 1; i <= max_node_count; ++i) {
|
| + int unique_tree_count = UniqueTreeCountForNodeCount(i, permutations);
|
| + unique_tree_count_by_size_.push_back(unique_tree_count);
|
| + total_unique_tree_count_ += unique_tree_count;
|
| + }
|
| +}
|
| +
|
| +TreeGenerator::~TreeGenerator() {
|
| +}
|
|
|
| int TreeGenerator::UniqueTreeCount() const {
|
| - return unique_tree_count_;
|
| -};
|
| + return total_unique_tree_count_;
|
| +}
|
|
|
| void TreeGenerator::BuildUniqueTree(int tree_index, AXTree* out_tree) const {
|
| + CHECK_LT(tree_index, total_unique_tree_count_);
|
| +
|
| + int unique_tree_count_so_far = 0;
|
| + for (int node_count = 1; node_count <= max_node_count_; ++node_count) {
|
| + int unique_tree_count = unique_tree_count_by_size_[node_count];
|
| + if (tree_index - unique_tree_count_so_far < unique_tree_count) {
|
| + BuildUniqueTreeWithSize(node_count,
|
| + tree_index - unique_tree_count_so_far,
|
| + out_tree);
|
| + return;
|
| + }
|
| + unique_tree_count_so_far += unique_tree_count;
|
| + }
|
| +}
|
| +
|
| +void TreeGenerator::BuildUniqueTreeWithSize(
|
| + int node_count, int tree_index, AXTree* out_tree) const {
|
| std::vector<int> indices;
|
| std::vector<int> permuted;
|
| - CHECK(tree_index <= unique_tree_count_);
|
| -
|
| - // Use the first few bits of |tree_index| to permute the indices.
|
| - for (int i = 0; i < node_count_; i++)
|
| - indices.push_back(i + 1);
|
| - for (int i = 0; i < node_count_; i++) {
|
| - int p = (node_count_ - i);
|
| - int index = tree_index % p;
|
| - tree_index /= p;
|
| - permuted.push_back(indices[index]);
|
| - indices.erase(indices.begin() + index);
|
| + int unique_tree_count = unique_tree_count_by_size_[node_count];
|
| + CHECK_LT(tree_index, unique_tree_count);
|
| +
|
| + if (permutations_) {
|
| + // Use the first few bits of |tree_index| to permute the indices.
|
| + for (int i = 0; i < node_count; ++i)
|
| + indices.push_back(i + 1);
|
| + for (int i = 0; i < node_count; ++i) {
|
| + int p = (node_count - i);
|
| + int index = tree_index % p;
|
| + tree_index /= p;
|
| + permuted.push_back(indices[index]);
|
| + indices.erase(indices.begin() + index);
|
| + }
|
| + } else {
|
| + for (int i = 0; i < node_count; ++i)
|
| + permuted.push_back(i + 1);
|
| }
|
|
|
| // Build an AXTreeUpdate. The first two nodes of the tree always
|
| // go in the same place.
|
| AXTreeUpdate update;
|
| - update.nodes.resize(node_count_);
|
| + update.nodes.resize(node_count);
|
| update.nodes[0].id = permuted[0];
|
| update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
|
| update.nodes[0].state = AX_STATE_NONE;
|
| - update.nodes[0].child_ids.push_back(permuted[1]);
|
| - update.nodes[1].id = permuted[1];
|
| - update.nodes[1].state = AX_STATE_NONE;
|
| + if (node_count > 1) {
|
| + update.nodes[0].child_ids.push_back(permuted[1]);
|
| + update.nodes[1].id = permuted[1];
|
| + update.nodes[1].state = AX_STATE_NONE;
|
| + }
|
|
|
| // The remaining nodes are assigned based on their parent
|
| // selected from the next bits from |tree_index|.
|
| - for (int i = 2; i < node_count_; i++) {
|
| + for (int i = 2; i < node_count; ++i) {
|
| update.nodes[i].id = permuted[i];
|
| update.nodes[i].state = AX_STATE_NONE;
|
| int parent_index = (tree_index % i);
|
|
|