summaryrefslogtreecommitdiffstats
path: root/accessible/base/nsAccUtils.h
blob: ed51eef7094e48a08e7e2795ea408324a1e37681 (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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/* -*- 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 nsAccUtils_h_
#define nsAccUtils_h_

#include "mozilla/a11y/LocalAccessible.h"
#include "mozilla/a11y/DocManager.h"

#include "nsAccessibilityService.h"
#include "nsCoreUtils.h"

#include "nsIDocShell.h"
#include "nsPoint.h"

namespace mozilla {

class PresShell;

namespace dom {
class Element;
}

namespace a11y {

class HyperTextAccessible;
class DocAccessible;
class Attribute;

class nsAccUtils {
 public:
  /**
   * Set group attributes ('level', 'setsize', 'posinset').
   */
  static void SetAccGroupAttrs(AccAttributes* aAttributes, int32_t aLevel,
                               int32_t aSetSize, int32_t aPosInSet);

  /**
   * Compute group level for nsIDOMXULContainerItemElement node.
   */
  static int32_t GetLevelForXULContainerItem(nsIContent* aContent);

  /**
   * Set container-foo live region attributes for the given node.
   *
   * @param aAttributes    where to store the attributes
   * @param aStartAcc  Accessible to start from
   */
  static void SetLiveContainerAttributes(AccAttributes* aAttributes,
                                         Accessible* aStartAcc);

  /**
   * Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA
   * property is not present, or is "" or "undefined". Do not call
   * this method for properties of type string, decimal, IDREF or IDREFS.
   *
   * Return true if the ARIA property is defined, otherwise false
   */
  static bool HasDefinedARIAToken(nsIContent* aContent, nsAtom* aAtom);
  static bool HasDefinedARIAToken(const AttrArray* aAttrs, nsAtom* aAtom);

  /**
   * If the given ARIA attribute has a specific known token value, return it.
   * If the specification demands for a fallback value for unknown attribute
   * values, return that. For all others, return a nullptr.
   */
  static nsStaticAtom* NormalizeARIAToken(const AttrArray* aAttrs,
                                          nsAtom* aAttr);
  static nsStaticAtom* NormalizeARIAToken(mozilla::dom::Element* aElement,
                                          nsAtom* aAttr);

  /**
   * Return document accessible for the given DOM node.
   */
  static DocAccessible* GetDocAccessibleFor(nsINode* aNode) {
    return GetAccService()->GetDocAccessible(
        nsCoreUtils::GetPresShellFor(aNode));
  }

  /**
   * Return document accessible for the given docshell.
   */
  static DocAccessible* GetDocAccessibleFor(nsIDocShellTreeItem* aContainer) {
    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
    return GetAccService()->GetDocAccessible(docShell->GetPresShell());
  }

  /**
   * Return single or multi selectable container for the given item.
   *
   * @param  aAccessible  [in] the item accessible
   * @param  aState       [in] the state of the item accessible
   */
  static Accessible* GetSelectableContainer(const Accessible* aAccessible,
                                            uint64_t aState);
  static LocalAccessible* GetSelectableContainer(LocalAccessible* aAccessible,
                                                 uint64_t aState);

  /**
   * Return a text container accessible for the given node.
   */
  static HyperTextAccessible* GetTextContainer(nsINode* aNode);

  static Accessible* TableFor(Accessible* aRow);
  static LocalAccessible* TableFor(LocalAccessible* aRow);

  static const LocalAccessible* TableFor(const LocalAccessible* aAcc) {
    return TableFor(const_cast<LocalAccessible*>(aAcc));
  }

  /**
   * Return true if the DOM node of a given accessible has a given attribute
   * with a value of "true".
   */
  static bool IsDOMAttrTrue(const LocalAccessible* aAccessible, nsAtom* aAttr);

  /**
   * Return true if the DOM node of given accessible has aria-selected="true"
   * attribute.
   */
  static inline bool IsARIASelected(const LocalAccessible* aAccessible) {
    return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_selected);
  }

  /**
   * Return true if the DOM node of given accessible has
   * aria-multiselectable="true" attribute.
   */
  static inline bool IsARIAMultiSelectable(const LocalAccessible* aAccessible) {
    return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_multiselectable);
  }

  /**
   * Converts the given coordinates to coordinates relative screen.
   *
   * @param aX               [in] the given x coord in dev pixels
   * @param aY               [in] the given y coord in dev pixels
   * @param aCoordinateType  [in] specifies coordinates origin (refer to
   *                         nsIAccessibleCoordinateType)
   * @param aAccessible      [in] the accessible if coordinates are given
   *                         relative it.
   * @return converted coordinates
   */
  static LayoutDeviceIntPoint ConvertToScreenCoords(int32_t aX, int32_t aY,
                                                    uint32_t aCoordinateType,
                                                    Accessible* aAccessible);

  /**
   * Converts the given coordinates relative screen to another coordinate
   * system.
   *
   * @param aX               [in, out] the given x coord in dev pixels
   * @param aY               [in, out] the given y coord in dev pixels
   * @param aCoordinateType  [in] specifies coordinates origin (refer to
   *                         nsIAccessibleCoordinateType)
   * @param aAccessible      [in] the accessible if coordinates are given
   *                         relative it
   */
  static void ConvertScreenCoordsTo(int32_t* aX, int32_t* aY,
                                    uint32_t aCoordinateType,
                                    Accessible* aAccessible);

  /**
   * Returns screen-relative coordinates (in dev pixels) for the parent of the
   * given accessible.
   *
   * @param [in] aAccessible  the accessible
   */
  static LayoutDeviceIntPoint GetScreenCoordsForParent(Accessible* aAccessible);

  /**
   * Returns coordinates in device pixels relative screen for the top level
   * window.
   *
   * @param aAccessible the acc hosted in the window.
   */
  static mozilla::LayoutDeviceIntPoint GetScreenCoordsForWindow(
      mozilla::a11y::Accessible* aAccessible);

  /**
   * Get the 'live' or 'container-live' object attribute value from the given
   * ELiveAttrRule constant.
   *
   * @param  aRule   [in] rule constant (see ELiveAttrRule in nsAccMap.h)
   * @param  aValue  [out] object attribute value
   *
   * @return         true if object attribute should be exposed
   */
  static bool GetLiveAttrValue(uint32_t aRule, nsAString& aValue);

#ifdef DEBUG
  /**
   * Detect whether the given accessible object implements nsIAccessibleText,
   * when it is text or has text child node.
   */
  static bool IsTextInterfaceSupportCorrect(LocalAccessible* aAccessible);
#endif

  /**
   * Return text length of the given accessible, return 0 on failure.
   */
  static uint32_t TextLength(Accessible* aAccessible);

  /**
   * Transform nsIAccessibleStates constants to internal state constant.
   */
  static inline uint64_t To64State(uint32_t aState1, uint32_t aState2) {
    return static_cast<uint64_t>(aState1) +
           (static_cast<uint64_t>(aState2) << 31);
  }

  /**
   * Transform internal state constant to nsIAccessibleStates constants.
   */
  static inline void To32States(uint64_t aState64, uint32_t* aState1,
                                uint32_t* aState2) {
    *aState1 = aState64 & 0x7fffffff;
    if (aState2) *aState2 = static_cast<uint32_t>(aState64 >> 31);
  }

  static uint32_t To32States(uint64_t aState, bool* aIsExtra) {
    uint32_t extraState = aState >> 31;
    *aIsExtra = !!extraState;
    return extraState ? extraState : aState;
  }

  /**
   * Return true if the given accessible can't have children. Used when exposing
   * to platform accessibility APIs, should the children be pruned off?
   */
  static bool MustPrune(Accessible* aAccessible);

  /**
   * Return true if the given accessible is within an ARIA live region; i.e.
   * the container-live attribute would be something other than "off" or empty.
   */
  static bool IsARIALive(const LocalAccessible* aAccessible);

  /**
   * Get the document Accessible which owns a given Accessible.
   * This function is needed because there is no unified base class for local
   * and remote documents.
   * If aAcc is null, null will be returned.
   */
  static Accessible* DocumentFor(Accessible* aAcc);

  /**
   * Get an Accessible in a given document by its unique id.
   * An Accessible's id can be obtained using Accessible::ID.
   * This function is needed because there is no unified base class for local
   * and remote documents.
   * If aDoc is nul, null will be returned.
   */
  static Accessible* GetAccessibleByID(Accessible* aDoc, uint64_t aID);

  /**
   * Get the URL for a given document.
   * This function is needed because there is no unified base class for local
   * and remote documents.
   */
  static void DocumentURL(Accessible* aDoc, nsAString& aURL);

  /**
   * Get the mime type for a given document.
   * This function is needed because there is no unified base class for local
   * and remote documents.
   */
  static void DocumentMimeType(Accessible* aDoc, nsAString& aMimeType);

  /**
   * Accessors for element attributes that are aware of CustomElement ARIA
   * accessibility defaults. If the element does not have the provided
   * attribute defined directly on it, we will then attempt to fetch the
   * default instead.
   */
  static const AttrArray* GetARIADefaults(dom::Element* aElement);
  static bool HasARIAAttr(dom::Element* aElement, const nsAtom* aName);
  static bool GetARIAAttr(dom::Element* aElement, const nsAtom* aName,
                          nsAString& aResult);
  static const nsAttrValue* GetARIAAttr(dom::Element* aElement,
                                        const nsAtom* aName);
  static bool ARIAAttrValueIs(dom::Element* aElement, const nsAtom* aName,
                              const nsAString& aValue,
                              nsCaseTreatment aCaseSensitive);
  static bool ARIAAttrValueIs(dom::Element* aElement, const nsAtom* aName,
                              const nsAtom* aValue,
                              nsCaseTreatment aCaseSensitive);
  static int32_t FindARIAAttrValueIn(dom::Element* aElement,
                                     const nsAtom* aName,
                                     AttrArray::AttrValuesArray* aValues,
                                     nsCaseTreatment aCaseSensitive);
};

}  // namespace a11y
}  // namespace mozilla

#endif