1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Alexander Surkov <surkov.alexander@gmail.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsAccUtils_h_
40 : #define nsAccUtils_h_
41 :
42 : #include "nsIAccessible.h"
43 : #include "nsIAccessibleRole.h"
44 : #include "nsIAccessibleText.h"
45 : #include "nsIAccessibleTable.h"
46 :
47 : #include "nsARIAMap.h"
48 : #include "nsAccessibilityService.h"
49 : #include "nsCoreUtils.h"
50 :
51 : #include "mozilla/dom/Element.h"
52 : #include "nsIDocShell.h"
53 : #include "nsIDOMNode.h"
54 : #include "nsIPersistentProperties2.h"
55 : #include "nsIPresShell.h"
56 : #include "nsPoint.h"
57 :
58 : class nsAccessNode;
59 : class nsAccessible;
60 : class nsHyperTextAccessible;
61 : class nsHTMLTableAccessible;
62 : class nsDocAccessible;
63 : #ifdef MOZ_XUL
64 : class nsXULTreeAccessible;
65 : #endif
66 :
67 : class nsAccUtils
68 : {
69 : public:
70 : /**
71 : * Returns value of attribute from the given attributes container.
72 : *
73 : * @param aAttributes - attributes container
74 : * @param aAttrName - the name of requested attribute
75 : * @param aAttrValue - value of attribute
76 : */
77 : static void GetAccAttr(nsIPersistentProperties *aAttributes,
78 : nsIAtom *aAttrName,
79 : nsAString& aAttrValue);
80 :
81 : /**
82 : * Set value of attribute for the given attributes container.
83 : *
84 : * @param aAttributes - attributes container
85 : * @param aAttrName - the name of requested attribute
86 : * @param aAttrValue - new value of attribute
87 : */
88 : static void SetAccAttr(nsIPersistentProperties *aAttributes,
89 : nsIAtom *aAttrName,
90 : const nsAString& aAttrValue);
91 :
92 : /**
93 : * Set group attributes ('level', 'setsize', 'posinset').
94 : */
95 : static void SetAccGroupAttrs(nsIPersistentProperties *aAttributes,
96 : PRInt32 aLevel, PRInt32 aSetSize,
97 : PRInt32 aPosInSet);
98 :
99 : /**
100 : * Get default value of the level for the given accessible.
101 : */
102 : static PRInt32 GetDefaultLevel(nsAccessible *aAcc);
103 :
104 : /**
105 : * Return ARIA level value or the default one if ARIA is missed for the
106 : * given accessible.
107 : */
108 : static PRInt32 GetARIAOrDefaultLevel(nsAccessible *aAccessible);
109 :
110 : /**
111 : * Compute position in group (posinset) and group size (setsize) for
112 : * nsIDOMXULSelectControlItemElement node.
113 : */
114 : static void GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
115 : PRInt32 *aPosInSet,
116 : PRInt32 *aSetSize);
117 :
118 : /**
119 : * Compute group level for nsIDOMXULContainerItemElement node.
120 : */
121 : static PRInt32 GetLevelForXULContainerItem(nsIContent *aContent);
122 :
123 : /**
124 : * Set container-foo live region attributes for the given node.
125 : *
126 : * @param aAttributes where to store the attributes
127 : * @param aStartContent node to start from
128 : * @param aTopContent node to end at
129 : */
130 : static void SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
131 : nsIContent *aStartContent,
132 : nsIContent *aTopContent);
133 :
134 : /**
135 : * Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA
136 : * property is not present, or is "" or "undefined". Do not call
137 : * this method for properties of type string, decimal, IDREF or IDREFS.
138 : *
139 : * Return true if the ARIA property is defined, otherwise false
140 : */
141 : static bool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
142 :
143 : /**
144 : * Return atomic value of ARIA attribute of boolean or NMTOKEN type.
145 : */
146 : static nsIAtom* GetARIAToken(mozilla::dom::Element* aElement, nsIAtom* aAttr);
147 :
148 : /**
149 : * Return document accessible for the given presshell.
150 : */
151 0 : static nsDocAccessible* GetDocAccessibleFor(const nsIPresShell* aPresShell)
152 : {
153 : return aPresShell ?
154 0 : GetAccService()->GetDocAccessible(aPresShell->GetDocument()) : nsnull;
155 : }
156 :
157 : /**
158 : * Return document accessible for the given DOM node.
159 : */
160 0 : static nsDocAccessible *GetDocAccessibleFor(nsINode *aNode)
161 : {
162 0 : nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
163 : return presShell ?
164 0 : GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
165 : }
166 :
167 : /**
168 : * Return document accessible for the given docshell.
169 : */
170 0 : static nsDocAccessible *GetDocAccessibleFor(nsIDocShellTreeItem *aContainer)
171 : {
172 0 : nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
173 0 : nsCOMPtr<nsIPresShell> presShell;
174 0 : docShell->GetPresShell(getter_AddRefs(presShell));
175 : return presShell ?
176 0 : GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
177 : }
178 :
179 : /**
180 : * Return ancestor in this document with the given role if it exists.
181 : *
182 : * @param aDescendant [in] descendant to start search with
183 : * @param aRole [in] role to find matching ancestor for
184 : * @return the ancestor accessible with the given role, or
185 : * nsnull if no match is found
186 : */
187 : static nsAccessible * GetAncestorWithRole(nsAccessible *aDescendant,
188 : PRUint32 aRole);
189 :
190 : /**
191 : * Return single or multi selectable container for the given item.
192 : *
193 : * @param aAccessible [in] the item accessible
194 : * @param aState [in] the state of the item accessible
195 : */
196 : static nsAccessible* GetSelectableContainer(nsAccessible* aAccessible,
197 : PRUint64 aState);
198 :
199 : /**
200 : * Return multi selectable container for the given item.
201 : */
202 : static nsAccessible *GetMultiSelectableContainer(nsINode *aNode);
203 :
204 : /**
205 : * Return true if the DOM node of given accessible has aria-selected="true"
206 : * attribute.
207 : */
208 : static bool IsARIASelected(nsAccessible *aAccessible);
209 :
210 : /**
211 : * Return text accessible containing focus point of the given selection.
212 : * Used for normal and misspelling selection changes processing.
213 : *
214 : * @param aSelection [in] the given selection
215 : * @return text accessible
216 : */
217 : static nsHyperTextAccessible*
218 : GetTextAccessibleFromSelection(nsISelection* aSelection);
219 :
220 : /**
221 : * Converts the given coordinates to coordinates relative screen.
222 : *
223 : * @param aX [in] the given x coord
224 : * @param aY [in] the given y coord
225 : * @param aCoordinateType [in] specifies coordinates origin (refer to
226 : * nsIAccessibleCoordinateType)
227 : * @param aAccessNode [in] the accessible if coordinates are given
228 : * relative it.
229 : * @param aCoords [out] converted coordinates
230 : */
231 : static nsresult ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
232 : PRUint32 aCoordinateType,
233 : nsAccessNode *aAccessNode,
234 : nsIntPoint *aCoords);
235 :
236 : /**
237 : * Converts the given coordinates relative screen to another coordinate
238 : * system.
239 : *
240 : * @param aX [in, out] the given x coord
241 : * @param aY [in, out] the given y coord
242 : * @param aCoordinateType [in] specifies coordinates origin (refer to
243 : * nsIAccessibleCoordinateType)
244 : * @param aAccessNode [in] the accessible if coordinates are given
245 : * relative it
246 : */
247 : static nsresult ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
248 : PRUint32 aCoordinateType,
249 : nsAccessNode *aAccessNode);
250 :
251 : /**
252 : * Returns coordinates relative screen for the top level window.
253 : *
254 : * @param aAccessNode the accessible hosted in the window
255 : */
256 : static nsIntPoint GetScreenCoordsForWindow(nsAccessNode *aAccessNode);
257 :
258 : /**
259 : * Returns coordinates relative screen for the parent of the given accessible.
260 : *
261 : * @param aAccessNode the accessible
262 : */
263 : static nsIntPoint GetScreenCoordsForParent(nsAccessNode *aAccessNode);
264 :
265 : /**
266 : * Get the role map entry for a given DOM node. This will use the first
267 : * ARIA role if the role attribute provides a space delimited list of roles.
268 : *
269 : * @param aNode [in] the DOM node to get the role map entry for
270 : * @return a pointer to the role map entry for the ARIA role, or nsnull
271 : * if none
272 : */
273 : static nsRoleMapEntry *GetRoleMapEntry(nsINode *aNode);
274 :
275 : /**
276 : * Return the role of the given accessible.
277 : */
278 0 : static PRUint32 Role(nsIAccessible *aAcc)
279 : {
280 0 : PRUint32 role = nsIAccessibleRole::ROLE_NOTHING;
281 0 : if (aAcc)
282 0 : aAcc->GetRole(&role);
283 :
284 0 : return role;
285 : }
286 :
287 : /**
288 : * Get the ARIA attribute characteristics for a given ARIA attribute.
289 : *
290 : * @param aAtom ARIA attribute
291 : * @return A bitflag representing the attribute characteristics
292 : * (see nsARIAMap.h for possible bit masks, prefixed "ARIA_")
293 : */
294 : static PRUint8 GetAttributeCharacteristics(nsIAtom* aAtom);
295 :
296 : /**
297 : * Get the 'live' or 'container-live' object attribute value from the given
298 : * ELiveAttrRule constant.
299 : *
300 : * @param aRule [in] rule constant (see ELiveAttrRule in nsAccMap.h)
301 : * @param aValue [out] object attribute value
302 : *
303 : * @return true if object attribute should be exposed
304 : */
305 : static bool GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
306 :
307 : #ifdef DEBUG_A11Y
308 : /**
309 : * Detect whether the given accessible object implements nsIAccessibleText,
310 : * when it is text or has text child node.
311 : */
312 : static bool IsTextInterfaceSupportCorrect(nsAccessible *aAccessible);
313 : #endif
314 :
315 : /**
316 : * Return true if the given accessible has text role.
317 : */
318 0 : static bool IsText(nsIAccessible *aAcc)
319 : {
320 0 : PRUint32 role = Role(aAcc);
321 : return role == nsIAccessibleRole::ROLE_TEXT_LEAF ||
322 0 : role == nsIAccessibleRole::ROLE_STATICTEXT;
323 : }
324 :
325 : /**
326 : * Return text length of the given accessible, return 0 on failure.
327 : */
328 : static PRUint32 TextLength(nsAccessible *aAccessible);
329 :
330 : /**
331 : * Return true if the given accessible is embedded object.
332 : */
333 0 : static bool IsEmbeddedObject(nsIAccessible *aAcc)
334 : {
335 0 : PRUint32 role = Role(aAcc);
336 : return role != nsIAccessibleRole::ROLE_TEXT_LEAF &&
337 : role != nsIAccessibleRole::ROLE_WHITESPACE &&
338 0 : role != nsIAccessibleRole::ROLE_STATICTEXT;
339 : }
340 :
341 : /**
342 : * Transform nsIAccessibleStates constants to internal state constant.
343 : */
344 0 : static inline PRUint64 To64State(PRUint32 aState1, PRUint32 aState2)
345 : {
346 : return static_cast<PRUint64>(aState1) +
347 0 : (static_cast<PRUint64>(aState2) << 31);
348 : }
349 :
350 : /**
351 : * Transform internal state constant to nsIAccessibleStates constants.
352 : */
353 0 : static inline void To32States(PRUint64 aState64,
354 : PRUint32* aState1, PRUint32* aState2)
355 : {
356 0 : *aState1 = aState64 & 0x7fffffff;
357 0 : if (aState2)
358 0 : *aState2 = static_cast<PRUint32>(aState64 >> 31);
359 0 : }
360 :
361 : /**
362 : * Return true if the given accessible can't have children. Used when exposing
363 : * to platform accessibility APIs, should the children be pruned off?
364 : */
365 : static bool MustPrune(nsIAccessible *aAccessible);
366 :
367 : /**
368 : * Search hint enum constants. Used by GetHeaderCellsFor() method.
369 : */
370 : enum {
371 : // search for row header cells, left direction
372 : eRowHeaderCells,
373 : // search for column header cells, top direction
374 : eColumnHeaderCells
375 : };
376 :
377 : /**
378 : * Return an array of row or column header cells for the given cell.
379 : *
380 : * @param aTable [in] table accessible
381 : * @param aCell [in] cell accessible within the given table to
382 : * get header cells
383 : * @param aRowOrColHeaderCells [in] specifies whether column or row header
384 : * cells are returned (see enum constants
385 : * above)
386 : * @param aCells [out] array of header cell accessibles
387 : */
388 : static nsresult GetHeaderCellsFor(nsIAccessibleTable *aTable,
389 : nsIAccessibleTableCell *aCell,
390 : PRInt32 aRowOrColHeaderCells,
391 : nsIArray **aCells);
392 : };
393 :
394 : #endif
|