summaryrefslogtreecommitdiffstats
path: root/accessible/base/Pivot.h
blob: c00f1613a25d8bc2d293c9c2851836ce033a0a28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_a11y_Pivot_h_
#define mozilla_a11y_Pivot_h_

#include <stdint.h>
#include "Role.h"
#include "mozilla/dom/ChildIterator.h"

namespace mozilla {
namespace a11y {

class DocAccessible;
class Accessible;

class PivotRule {
 public:
  // A filtering function that returns a bitmask from
  // nsIAccessibleTraversalRule: FILTER_IGNORE (0x0): Don't match this
  // accessible. FILTER_MATCH (0x1): Match this accessible FILTER_IGNORE_SUBTREE
  // (0x2): Ignore accessible's subtree.
  virtual uint16_t Match(Accessible* aAcc) = 0;
};

// The Pivot class is used for searching for accessible nodes in a given subtree
// with a given criteria. Since it only holds a weak reference to the root,
// this class is meant to be used primarily on the stack.
class Pivot final {
 public:
  explicit Pivot(Accessible* aRoot);
  Pivot() = delete;
  Pivot(const Pivot&) = delete;
  Pivot& operator=(const Pivot&) = delete;

  ~Pivot();

  // Return the next accessible after aAnchor in pre-order that matches the
  // given rule. If aIncludeStart, return aAnchor if it matches the rule.
  Accessible* Next(Accessible* aAnchor, PivotRule& aRule,
                   bool aIncludeStart = false);

  // Return the previous accessible before aAnchor in pre-order that matches the
  // given rule. If aIncludeStart, return aAnchor if it matches the rule.
  Accessible* Prev(Accessible* aAnchor, PivotRule& aRule,
                   bool aIncludeStart = false);

  // Return the first accessible within the root that matches the pivot rule.
  Accessible* First(PivotRule& aRule);

  // Return the last accessible within the root that matches the pivot rule.
  Accessible* Last(PivotRule& aRule);

  // Return the next range of text according to the boundary type.
  Accessible* NextText(Accessible* aAnchor, int32_t* aStartOffset,
                       int32_t* aEndOffset, int32_t aBoundaryType);

  // Return the previous range of text according to the boundary type.
  Accessible* PrevText(Accessible* aAnchor, int32_t* aStartOffset,
                       int32_t* aEndOffset, int32_t aBoundaryType);

  // Return the accessible at the given screen coordinate if it matches the
  // pivot rule.
  Accessible* AtPoint(int32_t aX, int32_t aY, PivotRule& aRule);

 private:
  Accessible* AdjustStartPosition(Accessible* aAnchor, PivotRule& aRule,
                                  uint16_t* aFilterResult);

  // Search in preorder for the first accessible to match the rule.
  Accessible* SearchForward(Accessible* aAnchor, PivotRule& aRule,
                            bool aSearchCurrent);

  // Reverse search in preorder for the first accessible to match the rule.
  Accessible* SearchBackward(Accessible* aAnchor, PivotRule& aRule,
                             bool aSearchCurrent);

  // Search in preorder for the first text accessible.
  Accessible* SearchForText(Accessible* aAnchor, bool aBackward);

  Accessible* mRoot;
};

/**
 * This rule matches accessibles on a given role, filtering out non-direct
 * descendants if necessary.
 */
class PivotRoleRule : public PivotRule {
 public:
  explicit PivotRoleRule(role aRole);
  explicit PivotRoleRule(role aRole, Accessible* aDirectDescendantsFrom);

  virtual uint16_t Match(Accessible* aAcc) override;

 protected:
  role mRole;
  Accessible* mDirectDescendantsFrom;
};

/**
 * This rule matches accessibles with a given state.
 */
class PivotStateRule : public PivotRule {
 public:
  explicit PivotStateRule(uint64_t aState);

  virtual uint16_t Match(Accessible* aAcc) override;

 protected:
  uint64_t mState;
};

/**
 * This rule matches any local LocalAccessible (i.e. not RemoteAccessible) in
 * the same document as the anchor. That is, it includes any descendant
 * OuterDocAccessible, but not its descendants.
 */
class LocalAccInSameDocRule : public PivotRule {
 public:
  virtual uint16_t Match(Accessible* aAcc) override;
};

/**
 * This rule matches remote radio button accessibles with the given name
 * attribute. It assumes the cache is enabled.
 */
class PivotRadioNameRule : public PivotRule {
 public:
  explicit PivotRadioNameRule(const nsString& aName);

  virtual uint16_t Match(Accessible* aAcc) override;

 protected:
  const nsString& mName;
};

/**
 * This rule doesn't search iframes. Subtrees that should be
 * pruned by way of nsAccUtils::MustPrune are also not searched.
 */

class MustPruneSameDocRule : public PivotRule {
 public:
  virtual uint16_t Match(Accessible* aAcc) override;
};

}  // namespace a11y
}  // namespace mozilla

#endif  // mozilla_a11y_Pivot_h_