|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef _Accessible_H_ |
|
7 #define _Accessible_H_ |
|
8 |
|
9 #include "mozilla/a11y/AccTypes.h" |
|
10 #include "mozilla/a11y/RelationType.h" |
|
11 #include "mozilla/a11y/Role.h" |
|
12 #include "mozilla/a11y/States.h" |
|
13 |
|
14 #include "nsIAccessible.h" |
|
15 #include "nsIAccessibleHyperLink.h" |
|
16 #include "nsIAccessibleStates.h" |
|
17 #include "xpcAccessibleSelectable.h" |
|
18 #include "xpcAccessibleValue.h" |
|
19 |
|
20 #include "nsIContent.h" |
|
21 #include "nsString.h" |
|
22 #include "nsTArray.h" |
|
23 #include "nsRefPtrHashtable.h" |
|
24 |
|
25 struct nsRoleMapEntry; |
|
26 |
|
27 struct nsRect; |
|
28 class nsIFrame; |
|
29 class nsIAtom; |
|
30 class nsView; |
|
31 |
|
32 namespace mozilla { |
|
33 namespace a11y { |
|
34 |
|
35 class Accessible; |
|
36 class AccEvent; |
|
37 class AccGroupInfo; |
|
38 class DocAccessible; |
|
39 class EmbeddedObjCollector; |
|
40 class HTMLImageMapAccessible; |
|
41 class HTMLLIAccessible; |
|
42 class HyperTextAccessible; |
|
43 class ImageAccessible; |
|
44 class KeyBinding; |
|
45 class Relation; |
|
46 class RootAccessible; |
|
47 class TableAccessible; |
|
48 class TableCellAccessible; |
|
49 class TextLeafAccessible; |
|
50 class XULLabelAccessible; |
|
51 class XULTreeAccessible; |
|
52 |
|
53 /** |
|
54 * Name type flags. |
|
55 */ |
|
56 enum ENameValueFlag { |
|
57 /** |
|
58 * Name either |
|
59 * a) present (not empty): !name.IsEmpty() |
|
60 * b) no name (was missed): name.IsVoid() |
|
61 */ |
|
62 eNameOK, |
|
63 |
|
64 /** |
|
65 * Name was left empty by the author on purpose: |
|
66 * name.IsEmpty() && !name.IsVoid(). |
|
67 */ |
|
68 eNoNameOnPurpose, |
|
69 |
|
70 /** |
|
71 * Name was computed from the subtree. |
|
72 */ |
|
73 eNameFromSubtree, |
|
74 |
|
75 /** |
|
76 * Tooltip was used as a name. |
|
77 */ |
|
78 eNameFromTooltip |
|
79 }; |
|
80 |
|
81 /** |
|
82 * Group position (level, position in set and set size). |
|
83 */ |
|
84 struct GroupPos |
|
85 { |
|
86 GroupPos() : level(0), posInSet(0), setSize(0) { } |
|
87 |
|
88 int32_t level; |
|
89 int32_t posInSet; |
|
90 int32_t setSize; |
|
91 }; |
|
92 |
|
93 typedef nsRefPtrHashtable<nsPtrHashKey<const void>, Accessible> |
|
94 AccessibleHashtable; |
|
95 |
|
96 |
|
97 #define NS_ACCESSIBLE_IMPL_IID \ |
|
98 { /* 133c8bf4-4913-4355-bd50-426bd1d6e1ad */ \ |
|
99 0x133c8bf4, \ |
|
100 0x4913, \ |
|
101 0x4355, \ |
|
102 { 0xbd, 0x50, 0x42, 0x6b, 0xd1, 0xd6, 0xe1, 0xad } \ |
|
103 } |
|
104 |
|
105 class Accessible : public nsIAccessible, |
|
106 public nsIAccessibleHyperLink, |
|
107 public xpcAccessibleSelectable, |
|
108 public xpcAccessibleValue |
|
109 { |
|
110 public: |
|
111 Accessible(nsIContent* aContent, DocAccessible* aDoc); |
|
112 virtual ~Accessible(); |
|
113 |
|
114 NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
|
115 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(Accessible, nsIAccessible) |
|
116 |
|
117 NS_DECL_NSIACCESSIBLE |
|
118 NS_DECL_NSIACCESSIBLEHYPERLINK |
|
119 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLE_IMPL_IID) |
|
120 |
|
121 ////////////////////////////////////////////////////////////////////////////// |
|
122 // Public methods |
|
123 |
|
124 /** |
|
125 * Return the document accessible for this accessible. |
|
126 */ |
|
127 DocAccessible* Document() const { return mDoc; } |
|
128 |
|
129 /** |
|
130 * Return the root document accessible for this accessible. |
|
131 */ |
|
132 a11y::RootAccessible* RootAccessible() const; |
|
133 |
|
134 /** |
|
135 * Return frame for this accessible. |
|
136 */ |
|
137 virtual nsIFrame* GetFrame() const; |
|
138 |
|
139 /** |
|
140 * Return DOM node associated with the accessible. |
|
141 */ |
|
142 virtual nsINode* GetNode() const; |
|
143 inline already_AddRefed<nsIDOMNode> DOMNode() const |
|
144 { |
|
145 nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(GetNode()); |
|
146 return DOMNode.forget(); |
|
147 } |
|
148 nsIContent* GetContent() const { return mContent; } |
|
149 |
|
150 /** |
|
151 * Return node type information of DOM node associated with the accessible. |
|
152 */ |
|
153 bool IsContent() const |
|
154 { return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT); } |
|
155 |
|
156 /** |
|
157 * Return the unique identifier of the accessible. |
|
158 */ |
|
159 void* UniqueID() { return static_cast<void*>(this); } |
|
160 |
|
161 /** |
|
162 * Return language associated with the accessible. |
|
163 */ |
|
164 void Language(nsAString& aLocale); |
|
165 |
|
166 /** |
|
167 * Get the description of this accessible. |
|
168 */ |
|
169 virtual void Description(nsString& aDescription); |
|
170 |
|
171 /** |
|
172 * Get the value of this accessible. |
|
173 */ |
|
174 virtual void Value(nsString& aValue); |
|
175 |
|
176 /** |
|
177 * Get the name of this accessible. |
|
178 * |
|
179 * Note: aName.IsVoid() when name was left empty by the author on purpose. |
|
180 * aName.IsEmpty() when the author missed name, AT can try to repair a name. |
|
181 */ |
|
182 virtual ENameValueFlag Name(nsString& aName); |
|
183 |
|
184 /** |
|
185 * Maps ARIA state attributes to state of accessible. Note the given state |
|
186 * argument should hold states for accessible before you pass it into this |
|
187 * method. |
|
188 * |
|
189 * @param [in/out] where to fill the states into. |
|
190 */ |
|
191 virtual void ApplyARIAState(uint64_t* aState) const; |
|
192 |
|
193 /** |
|
194 * Return enumerated accessible role (see constants in Role.h). |
|
195 */ |
|
196 mozilla::a11y::role Role(); |
|
197 |
|
198 /** |
|
199 * Return true if ARIA role is specified on the element. |
|
200 */ |
|
201 bool HasARIARole() const { return mRoleMapEntry; } |
|
202 bool IsARIARole(nsIAtom* aARIARole) const; |
|
203 |
|
204 /** |
|
205 * Retrun ARIA role map if any. |
|
206 */ |
|
207 nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; } |
|
208 |
|
209 /** |
|
210 * Return accessible role specified by ARIA (see constants in |
|
211 * roles). |
|
212 */ |
|
213 mozilla::a11y::role ARIARole(); |
|
214 |
|
215 /** |
|
216 * Returns enumerated accessible role from native markup (see constants in |
|
217 * Role.h). Doesn't take into account ARIA roles. |
|
218 */ |
|
219 virtual mozilla::a11y::role NativeRole(); |
|
220 |
|
221 /** |
|
222 * Return all states of accessible (including ARIA states). |
|
223 */ |
|
224 virtual uint64_t State(); |
|
225 |
|
226 /** |
|
227 * Return interactive states present on the accessible |
|
228 * (@see NativeInteractiveState). |
|
229 */ |
|
230 uint64_t InteractiveState() const |
|
231 { |
|
232 uint64_t state = NativeInteractiveState(); |
|
233 ApplyARIAState(&state); |
|
234 return state; |
|
235 } |
|
236 |
|
237 /** |
|
238 * Return link states present on the accessible. |
|
239 */ |
|
240 uint64_t LinkState() const |
|
241 { |
|
242 uint64_t state = NativeLinkState(); |
|
243 ApplyARIAState(&state); |
|
244 return state; |
|
245 } |
|
246 |
|
247 /** |
|
248 * Return if accessible is unavailable. |
|
249 */ |
|
250 bool Unavailable() const |
|
251 { |
|
252 uint64_t state = NativelyUnavailable() ? states::UNAVAILABLE : 0; |
|
253 ApplyARIAState(&state); |
|
254 return state & states::UNAVAILABLE; |
|
255 } |
|
256 |
|
257 /** |
|
258 * Return the states of accessible, not taking into account ARIA states. |
|
259 * Use State() to get complete set of states. |
|
260 */ |
|
261 virtual uint64_t NativeState(); |
|
262 |
|
263 /** |
|
264 * Return native interactice state (unavailable, focusable or selectable). |
|
265 */ |
|
266 virtual uint64_t NativeInteractiveState() const; |
|
267 |
|
268 /** |
|
269 * Return native link states present on the accessible. |
|
270 */ |
|
271 virtual uint64_t NativeLinkState() const; |
|
272 |
|
273 /** |
|
274 * Return bit set of invisible and offscreen states. |
|
275 */ |
|
276 uint64_t VisibilityState(); |
|
277 |
|
278 /** |
|
279 * Return true if native unavailable state present. |
|
280 */ |
|
281 virtual bool NativelyUnavailable() const; |
|
282 |
|
283 /** |
|
284 * Return object attributes for the accessible. |
|
285 */ |
|
286 virtual already_AddRefed<nsIPersistentProperties> Attributes(); |
|
287 |
|
288 /** |
|
289 * Return group position (level, position in set and set size). |
|
290 */ |
|
291 virtual mozilla::a11y::GroupPos GroupPosition(); |
|
292 |
|
293 /** |
|
294 * Used by ChildAtPoint() method to get direct or deepest child at point. |
|
295 */ |
|
296 enum EWhichChildAtPoint { |
|
297 eDirectChild, |
|
298 eDeepestChild |
|
299 }; |
|
300 |
|
301 /** |
|
302 * Return direct or deepest child at the given point. |
|
303 * |
|
304 * @param aX [in] x coordinate relative screen |
|
305 * @param aY [in] y coordinate relative screen |
|
306 * @param aWhichChild [in] flag points if deepest or direct child |
|
307 * should be returned |
|
308 */ |
|
309 virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY, |
|
310 EWhichChildAtPoint aWhichChild); |
|
311 |
|
312 /** |
|
313 * Return the focused child if any. |
|
314 */ |
|
315 virtual Accessible* FocusedChild(); |
|
316 |
|
317 /** |
|
318 * Return calculated group level based on accessible hierarchy. |
|
319 */ |
|
320 virtual int32_t GetLevelInternal(); |
|
321 |
|
322 /** |
|
323 * Calculate position in group and group size ('posinset' and 'setsize') based |
|
324 * on accessible hierarchy. |
|
325 * |
|
326 * @param aPosInSet [out] accessible position in the group |
|
327 * @param aSetSize [out] the group size |
|
328 */ |
|
329 virtual void GetPositionAndSizeInternal(int32_t *aPosInSet, |
|
330 int32_t *aSetSize); |
|
331 |
|
332 /** |
|
333 * Get the relation of the given type. |
|
334 */ |
|
335 virtual Relation RelationByType(RelationType aType); |
|
336 |
|
337 ////////////////////////////////////////////////////////////////////////////// |
|
338 // Initializing methods |
|
339 |
|
340 /** |
|
341 * Shutdown this accessible object. |
|
342 */ |
|
343 virtual void Shutdown(); |
|
344 |
|
345 /** |
|
346 * Set the ARIA role map entry for a new accessible. |
|
347 */ |
|
348 void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry) |
|
349 { mRoleMapEntry = aRoleMapEntry; } |
|
350 |
|
351 /** |
|
352 * Update the children cache. |
|
353 */ |
|
354 inline bool UpdateChildren() |
|
355 { |
|
356 InvalidateChildren(); |
|
357 return EnsureChildren(); |
|
358 } |
|
359 |
|
360 /** |
|
361 * Cache children if necessary. Return true if the accessible is defunct. |
|
362 */ |
|
363 bool EnsureChildren(); |
|
364 |
|
365 /** |
|
366 * Set the child count to -1 (unknown) and null out cached child pointers. |
|
367 * Should be called when accessible tree is changed because document has |
|
368 * transformed. Note, if accessible cares about its parent relation chain |
|
369 * itself should override this method to do nothing. |
|
370 */ |
|
371 virtual void InvalidateChildren(); |
|
372 |
|
373 /** |
|
374 * Append/insert/remove a child. Return true if operation was successful. |
|
375 */ |
|
376 bool AppendChild(Accessible* aChild) |
|
377 { return InsertChildAt(mChildren.Length(), aChild); } |
|
378 virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild); |
|
379 virtual bool RemoveChild(Accessible* aChild); |
|
380 |
|
381 ////////////////////////////////////////////////////////////////////////////// |
|
382 // Accessible tree traverse methods |
|
383 |
|
384 /** |
|
385 * Return parent accessible. |
|
386 */ |
|
387 Accessible* Parent() const { return mParent; } |
|
388 |
|
389 /** |
|
390 * Return child accessible at the given index. |
|
391 */ |
|
392 virtual Accessible* GetChildAt(uint32_t aIndex) const; |
|
393 |
|
394 /** |
|
395 * Return child accessible count. |
|
396 */ |
|
397 virtual uint32_t ChildCount() const; |
|
398 |
|
399 /** |
|
400 * Return index of the given child accessible. |
|
401 */ |
|
402 int32_t GetIndexOf(const Accessible* aChild) const |
|
403 { return (aChild->mParent != this) ? -1 : aChild->IndexInParent(); } |
|
404 |
|
405 /** |
|
406 * Return index in parent accessible. |
|
407 */ |
|
408 virtual int32_t IndexInParent() const; |
|
409 |
|
410 /** |
|
411 * Return true if accessible has children; |
|
412 */ |
|
413 bool HasChildren() { return !!GetChildAt(0); } |
|
414 |
|
415 /** |
|
416 * Return first/last/next/previous sibling of the accessible. |
|
417 */ |
|
418 inline Accessible* NextSibling() const |
|
419 { return GetSiblingAtOffset(1); } |
|
420 inline Accessible* PrevSibling() const |
|
421 { return GetSiblingAtOffset(-1); } |
|
422 inline Accessible* FirstChild() |
|
423 { return GetChildAt(0); } |
|
424 inline Accessible* LastChild() |
|
425 { |
|
426 uint32_t childCount = ChildCount(); |
|
427 return childCount != 0 ? GetChildAt(childCount - 1) : nullptr; |
|
428 } |
|
429 |
|
430 /** |
|
431 * Return embedded accessible children count. |
|
432 */ |
|
433 uint32_t EmbeddedChildCount(); |
|
434 |
|
435 /** |
|
436 * Return embedded accessible child at the given index. |
|
437 */ |
|
438 Accessible* GetEmbeddedChildAt(uint32_t aIndex); |
|
439 |
|
440 /** |
|
441 * Return index of the given embedded accessible child. |
|
442 */ |
|
443 int32_t GetIndexOfEmbeddedChild(Accessible* aChild); |
|
444 |
|
445 /** |
|
446 * Return number of content children/content child at index. The content |
|
447 * child is created from markup in contrast to it's never constructed by its |
|
448 * parent accessible (like treeitem accessibles for XUL trees). |
|
449 */ |
|
450 uint32_t ContentChildCount() const { return mChildren.Length(); } |
|
451 Accessible* ContentChildAt(uint32_t aIndex) const |
|
452 { return mChildren.ElementAt(aIndex); } |
|
453 |
|
454 /** |
|
455 * Return true if children were initialized. |
|
456 */ |
|
457 inline bool AreChildrenCached() const |
|
458 { return !IsChildrenFlag(eChildrenUninitialized); } |
|
459 |
|
460 /** |
|
461 * Return true if the accessible is attached to tree. |
|
462 */ |
|
463 bool IsBoundToParent() const { return !!mParent; } |
|
464 |
|
465 ////////////////////////////////////////////////////////////////////////////// |
|
466 // Miscellaneous methods |
|
467 |
|
468 /** |
|
469 * Handle accessible event, i.e. process it, notifies observers and fires |
|
470 * platform specific event. |
|
471 */ |
|
472 virtual nsresult HandleAccEvent(AccEvent* aAccEvent); |
|
473 |
|
474 /** |
|
475 * Return true if this accessible allows accessible children from anonymous subtree. |
|
476 */ |
|
477 virtual bool CanHaveAnonChildren(); |
|
478 |
|
479 /** |
|
480 * Return true if the accessible is an acceptable child. |
|
481 */ |
|
482 virtual bool IsAcceptableChild(Accessible* aPossibleChild) const { return true; } |
|
483 |
|
484 /** |
|
485 * Returns text of accessible if accessible has text role otherwise empty |
|
486 * string. |
|
487 * |
|
488 * @param aText [in] returned text of the accessible |
|
489 * @param aStartOffset [in, optional] start offset inside of the accessible, |
|
490 * if missed entire text is appended |
|
491 * @param aLength [in, optional] required length of text, if missed |
|
492 * then text form start offset till the end is appended |
|
493 */ |
|
494 virtual void AppendTextTo(nsAString& aText, uint32_t aStartOffset = 0, |
|
495 uint32_t aLength = UINT32_MAX); |
|
496 |
|
497 /** |
|
498 * Assert if child not in parent's cache if the cache was initialized at this |
|
499 * point. |
|
500 */ |
|
501 void TestChildCache(Accessible* aCachedChild) const; |
|
502 |
|
503 /** |
|
504 * Return boundaries rect relative the bounding frame. |
|
505 */ |
|
506 virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); |
|
507 |
|
508 ////////////////////////////////////////////////////////////////////////////// |
|
509 // Downcasting and types |
|
510 |
|
511 inline bool IsAbbreviation() const |
|
512 { |
|
513 return mContent->IsHTML() && |
|
514 (mContent->Tag() == nsGkAtoms::abbr || mContent->Tag() == nsGkAtoms::acronym); |
|
515 } |
|
516 |
|
517 bool IsApplication() const { return mType == eApplicationType; } |
|
518 |
|
519 bool IsAutoComplete() const { return HasGenericType(eAutoComplete); } |
|
520 |
|
521 bool IsAutoCompletePopup() const |
|
522 { return HasGenericType(eAutoCompletePopup); } |
|
523 |
|
524 bool IsButton() const { return HasGenericType(eButton); } |
|
525 |
|
526 bool IsCombobox() const { return HasGenericType(eCombobox); } |
|
527 |
|
528 bool IsDoc() const { return HasGenericType(eDocument); } |
|
529 DocAccessible* AsDoc(); |
|
530 |
|
531 bool IsHyperText() const { return HasGenericType(eHyperText); } |
|
532 HyperTextAccessible* AsHyperText(); |
|
533 |
|
534 bool IsHTMLBr() const { return mType == eHTMLBRType; } |
|
535 bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; } |
|
536 |
|
537 bool IsHTMLListItem() const { return mType == eHTMLLiType; } |
|
538 HTMLLIAccessible* AsHTMLListItem(); |
|
539 |
|
540 bool IsHTMLOptGroup() const { return mType == eHTMLOptGroupType; } |
|
541 |
|
542 bool IsHTMLTable() const { return mType == eHTMLTableType; } |
|
543 bool IsHTMLTableRow() const { return mType == eHTMLTableRowType; } |
|
544 |
|
545 bool IsImage() const { return mType == eImageType; } |
|
546 ImageAccessible* AsImage(); |
|
547 |
|
548 bool IsImageMap() const { return mType == eImageMapType; } |
|
549 HTMLImageMapAccessible* AsImageMap(); |
|
550 |
|
551 bool IsList() const { return HasGenericType(eList); } |
|
552 |
|
553 bool IsListControl() const { return HasGenericType(eListControl); } |
|
554 |
|
555 bool IsMenuButton() const { return HasGenericType(eMenuButton); } |
|
556 |
|
557 bool IsMenuPopup() const { return mType == eMenuPopupType; } |
|
558 |
|
559 bool IsProgress() const { return mType == eProgressType; } |
|
560 |
|
561 bool IsRoot() const { return mType == eRootType; } |
|
562 a11y::RootAccessible* AsRoot(); |
|
563 |
|
564 bool IsSelect() const { return HasGenericType(eSelect); } |
|
565 |
|
566 bool IsTable() const { return HasGenericType(eTable); } |
|
567 virtual TableAccessible* AsTable() { return nullptr; } |
|
568 |
|
569 bool IsTableCell() const { return HasGenericType(eTableCell); } |
|
570 virtual TableCellAccessible* AsTableCell() { return nullptr; } |
|
571 const TableCellAccessible* AsTableCell() const |
|
572 { return const_cast<Accessible*>(this)->AsTableCell(); } |
|
573 |
|
574 bool IsTableRow() const { return HasGenericType(eTableRow); } |
|
575 |
|
576 bool IsTextField() const { return mType == eHTMLTextFieldType; } |
|
577 |
|
578 bool IsTextLeaf() const { return mType == eTextLeafType; } |
|
579 TextLeafAccessible* AsTextLeaf(); |
|
580 |
|
581 bool IsXULLabel() const { return mType == eXULLabelType; } |
|
582 XULLabelAccessible* AsXULLabel(); |
|
583 |
|
584 bool IsXULListItem() const { return mType == eXULListItemType; } |
|
585 |
|
586 bool IsXULTabpanels() const { return mType == eXULTabpanelsType; } |
|
587 |
|
588 bool IsXULTree() const { return mType == eXULTreeType; } |
|
589 XULTreeAccessible* AsXULTree(); |
|
590 |
|
591 /** |
|
592 * Return true if the accessible belongs to the given accessible type. |
|
593 */ |
|
594 bool HasGenericType(AccGenericType aType) const; |
|
595 |
|
596 ////////////////////////////////////////////////////////////////////////////// |
|
597 // ActionAccessible |
|
598 |
|
599 /** |
|
600 * Return the number of actions that can be performed on this accessible. |
|
601 */ |
|
602 virtual uint8_t ActionCount(); |
|
603 |
|
604 /** |
|
605 * Return access key, such as Alt+D. |
|
606 */ |
|
607 virtual KeyBinding AccessKey() const; |
|
608 |
|
609 /** |
|
610 * Return global keyboard shortcut for default action, such as Ctrl+O for |
|
611 * Open file menuitem. |
|
612 */ |
|
613 virtual KeyBinding KeyboardShortcut() const; |
|
614 |
|
615 ////////////////////////////////////////////////////////////////////////////// |
|
616 // HyperLinkAccessible |
|
617 |
|
618 /** |
|
619 * Return true if the accessible is hyper link accessible. |
|
620 */ |
|
621 virtual bool IsLink(); |
|
622 |
|
623 /** |
|
624 * Return the start offset of the link within the parent accessible. |
|
625 */ |
|
626 virtual uint32_t StartOffset(); |
|
627 |
|
628 /** |
|
629 * Return the end offset of the link within the parent accessible. |
|
630 */ |
|
631 virtual uint32_t EndOffset(); |
|
632 |
|
633 /** |
|
634 * Return true if the link is valid (e. g. points to a valid URL). |
|
635 */ |
|
636 inline bool IsLinkValid() |
|
637 { |
|
638 NS_PRECONDITION(IsLink(), "IsLinkValid is called on not hyper link!"); |
|
639 |
|
640 // XXX In order to implement this we would need to follow every link |
|
641 // Perhaps we can get information about invalid links from the cache |
|
642 // In the mean time authors can use role="link" aria-invalid="true" |
|
643 // to force it for links they internally know to be invalid |
|
644 return (0 == (State() & mozilla::a11y::states::INVALID)); |
|
645 } |
|
646 |
|
647 /** |
|
648 * Return the number of anchors within the link. |
|
649 */ |
|
650 virtual uint32_t AnchorCount(); |
|
651 |
|
652 /** |
|
653 * Returns an anchor accessible at the given index. |
|
654 */ |
|
655 virtual Accessible* AnchorAt(uint32_t aAnchorIndex); |
|
656 |
|
657 /** |
|
658 * Returns an anchor URI at the given index. |
|
659 */ |
|
660 virtual already_AddRefed<nsIURI> AnchorURIAt(uint32_t aAnchorIndex); |
|
661 |
|
662 ////////////////////////////////////////////////////////////////////////////// |
|
663 // SelectAccessible |
|
664 |
|
665 /** |
|
666 * Return an array of selected items. |
|
667 */ |
|
668 virtual already_AddRefed<nsIArray> SelectedItems(); |
|
669 |
|
670 /** |
|
671 * Return the number of selected items. |
|
672 */ |
|
673 virtual uint32_t SelectedItemCount(); |
|
674 |
|
675 /** |
|
676 * Return selected item at the given index. |
|
677 */ |
|
678 virtual Accessible* GetSelectedItem(uint32_t aIndex); |
|
679 |
|
680 /** |
|
681 * Determine if item at the given index is selected. |
|
682 */ |
|
683 virtual bool IsItemSelected(uint32_t aIndex); |
|
684 |
|
685 /** |
|
686 * Add item at the given index the selection. Return true if success. |
|
687 */ |
|
688 virtual bool AddItemToSelection(uint32_t aIndex); |
|
689 |
|
690 /** |
|
691 * Remove item at the given index from the selection. Return if success. |
|
692 */ |
|
693 virtual bool RemoveItemFromSelection(uint32_t aIndex); |
|
694 |
|
695 /** |
|
696 * Select all items. Return true if success. |
|
697 */ |
|
698 virtual bool SelectAll(); |
|
699 |
|
700 /** |
|
701 * Unselect all items. Return true if success. |
|
702 */ |
|
703 virtual bool UnselectAll(); |
|
704 |
|
705 ////////////////////////////////////////////////////////////////////////////// |
|
706 // Value (numeric value interface) |
|
707 |
|
708 virtual double MaxValue() const; |
|
709 virtual double MinValue() const; |
|
710 virtual double CurValue() const; |
|
711 virtual double Step() const; |
|
712 virtual bool SetCurValue(double aValue); |
|
713 |
|
714 ////////////////////////////////////////////////////////////////////////////// |
|
715 // Widgets |
|
716 |
|
717 /** |
|
718 * Return true if accessible is a widget, i.e. control or accessible that |
|
719 * manages its items. Note, being a widget the accessible may be a part of |
|
720 * composite widget. |
|
721 */ |
|
722 virtual bool IsWidget() const; |
|
723 |
|
724 /** |
|
725 * Return true if the widget is active, i.e. has a focus within it. |
|
726 */ |
|
727 virtual bool IsActiveWidget() const; |
|
728 |
|
729 /** |
|
730 * Return true if the widget has items and items are operable by user and |
|
731 * can be activated. |
|
732 */ |
|
733 virtual bool AreItemsOperable() const; |
|
734 |
|
735 /** |
|
736 * Return the current item of the widget, i.e. an item that has or will have |
|
737 * keyboard focus when widget gets active. |
|
738 */ |
|
739 virtual Accessible* CurrentItem(); |
|
740 |
|
741 /** |
|
742 * Set the current item of the widget. |
|
743 */ |
|
744 virtual void SetCurrentItem(Accessible* aItem); |
|
745 |
|
746 /** |
|
747 * Return container widget this accessible belongs to. |
|
748 */ |
|
749 virtual Accessible* ContainerWidget() const; |
|
750 |
|
751 /** |
|
752 * Return the localized string for the given key. |
|
753 */ |
|
754 static void TranslateString(const nsString& aKey, nsAString& aStringOut); |
|
755 |
|
756 /** |
|
757 * Return true if the accessible is defunct. |
|
758 */ |
|
759 bool IsDefunct() const { return mStateFlags & eIsDefunct; } |
|
760 |
|
761 /** |
|
762 * Return true if the accessible is no longer in the document. |
|
763 */ |
|
764 bool IsInDocument() const { return !(mStateFlags & eIsNotInDocument); } |
|
765 |
|
766 /** |
|
767 * Return true if the accessible should be contained by document node map. |
|
768 */ |
|
769 bool IsNodeMapEntry() const |
|
770 { return HasOwnContent() && !(mStateFlags & eNotNodeMapEntry); } |
|
771 |
|
772 /** |
|
773 * Return true if the accessible's group info needs to be updated. |
|
774 */ |
|
775 inline bool HasDirtyGroupInfo() const { return mStateFlags & eGroupInfoDirty; } |
|
776 |
|
777 /** |
|
778 * Return true if the accessible has associated DOM content. |
|
779 */ |
|
780 bool HasOwnContent() const |
|
781 { return mContent && !(mStateFlags & eSharedNode); } |
|
782 |
|
783 /** |
|
784 * Return true if the accessible has a numeric value. |
|
785 */ |
|
786 bool HasNumericValue() const; |
|
787 |
|
788 /** |
|
789 * Return true if the accessible state change is processed by handling proper |
|
790 * DOM UI event, if otherwise then false. For example, HTMLCheckboxAccessible |
|
791 * process nsIDocumentObserver::ContentStateChanged instead |
|
792 * 'CheckboxStateChange' event. |
|
793 */ |
|
794 bool NeedsDOMUIEvent() const |
|
795 { return !(mStateFlags & eIgnoreDOMUIEvent); } |
|
796 |
|
797 /** |
|
798 * Return true if this accessible has a parent whose name depends on this |
|
799 * accessible. |
|
800 */ |
|
801 bool HasNameDependentParent() const |
|
802 { return mContextFlags & eHasNameDependentParent; } |
|
803 |
|
804 protected: |
|
805 |
|
806 /** |
|
807 * Return the accessible name provided by native markup. It doesn't take |
|
808 * into account ARIA markup used to specify the name. |
|
809 */ |
|
810 virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName); |
|
811 |
|
812 /** |
|
813 * Return object attributes provided by native markup. It doesn't take into |
|
814 * account ARIA. |
|
815 */ |
|
816 virtual already_AddRefed<nsIPersistentProperties> NativeAttributes(); |
|
817 |
|
818 ////////////////////////////////////////////////////////////////////////////// |
|
819 // Initializing, cache and tree traverse methods |
|
820 |
|
821 /** |
|
822 * Destroy the object. |
|
823 */ |
|
824 void LastRelease(); |
|
825 |
|
826 /** |
|
827 * Cache accessible children. |
|
828 */ |
|
829 virtual void CacheChildren(); |
|
830 |
|
831 /** |
|
832 * Set accessible parent and index in parent. |
|
833 */ |
|
834 virtual void BindToParent(Accessible* aParent, uint32_t aIndexInParent); |
|
835 virtual void UnbindFromParent(); |
|
836 |
|
837 /** |
|
838 * Return sibling accessible at the given offset. |
|
839 */ |
|
840 virtual Accessible* GetSiblingAtOffset(int32_t aOffset, |
|
841 nsresult *aError = nullptr) const; |
|
842 |
|
843 /** |
|
844 * Flags used to describe the state and type of children. |
|
845 */ |
|
846 enum ChildrenFlags { |
|
847 eChildrenUninitialized = 0, // children aren't initialized |
|
848 eMixedChildren = 1 << 0, // text leaf children are presented |
|
849 eEmbeddedChildren = 1 << 1, // all children are embedded objects |
|
850 |
|
851 eLastChildrenFlag = eEmbeddedChildren |
|
852 }; |
|
853 |
|
854 /** |
|
855 * Return true if the children flag is set. |
|
856 */ |
|
857 bool IsChildrenFlag(ChildrenFlags aFlag) const |
|
858 { return static_cast<ChildrenFlags>(mChildrenFlags) == aFlag; } |
|
859 |
|
860 /** |
|
861 * Set children flag. |
|
862 */ |
|
863 void SetChildrenFlag(ChildrenFlags aFlag) { mChildrenFlags = aFlag; } |
|
864 |
|
865 /** |
|
866 * Flags used to describe the state of this accessible. |
|
867 * @note keep these flags in sync with ChildrenFlags |
|
868 */ |
|
869 enum StateFlags { |
|
870 eIsDefunct = 1 << 0, // accessible is defunct |
|
871 eIsNotInDocument = 1 << 1, // accessible is not in document |
|
872 eSharedNode = 1 << 2, // accessible shares DOM node from another accessible |
|
873 eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map |
|
874 eHasNumericValue = 1 << 4, // accessible has a numeric value |
|
875 eGroupInfoDirty = 1 << 5, // accessible needs to update group info |
|
876 eIgnoreDOMUIEvent = 1 << 6, // don't process DOM UI events for a11y events |
|
877 |
|
878 eLastStateFlag = eIgnoreDOMUIEvent |
|
879 }; |
|
880 |
|
881 /** |
|
882 * Flags used for contextual information about the accessible. |
|
883 */ |
|
884 enum ContextFlags { |
|
885 eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible. |
|
886 |
|
887 eLastContextFlag = eHasNameDependentParent |
|
888 }; |
|
889 |
|
890 protected: |
|
891 |
|
892 ////////////////////////////////////////////////////////////////////////////// |
|
893 // Miscellaneous helpers |
|
894 |
|
895 /** |
|
896 * Return ARIA role (helper method). |
|
897 */ |
|
898 mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole); |
|
899 |
|
900 ////////////////////////////////////////////////////////////////////////////// |
|
901 // Name helpers |
|
902 |
|
903 /** |
|
904 * Returns the accessible name specified by ARIA. |
|
905 */ |
|
906 void ARIAName(nsString& aName); |
|
907 |
|
908 /** |
|
909 * Return the name for XUL element. |
|
910 */ |
|
911 static void XULElmName(DocAccessible* aDocument, |
|
912 nsIContent* aElm, nsString& aName); |
|
913 |
|
914 // helper method to verify frames |
|
915 static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut); |
|
916 |
|
917 ////////////////////////////////////////////////////////////////////////////// |
|
918 // Action helpers |
|
919 |
|
920 /** |
|
921 * Prepares click action that will be invoked in timeout. |
|
922 * |
|
923 * @note DoCommand() prepares an action in timeout because when action |
|
924 * command opens a modal dialog/window, it won't return until the |
|
925 * dialog/window is closed. If executing action command directly in |
|
926 * nsIAccessible::DoAction() method, it will block AT tools (e.g. GOK) that |
|
927 * invoke action of mozilla accessibles direclty (see bug 277888 for details). |
|
928 * |
|
929 * @param aContent [in, optional] element to click |
|
930 * @param aActionIndex [in, optional] index of accessible action |
|
931 */ |
|
932 void DoCommand(nsIContent *aContent = nullptr, uint32_t aActionIndex = 0); |
|
933 |
|
934 /** |
|
935 * Dispatch click event. |
|
936 */ |
|
937 virtual void DispatchClickEvent(nsIContent *aContent, uint32_t aActionIndex); |
|
938 |
|
939 ////////////////////////////////////////////////////////////////////////////// |
|
940 // Helpers |
|
941 |
|
942 /** |
|
943 * Get the container node for an atomic region, defined by aria-atomic="true" |
|
944 * @return the container node |
|
945 */ |
|
946 nsIContent* GetAtomicRegion() const; |
|
947 |
|
948 /** |
|
949 * Return numeric value of the given ARIA attribute, NaN if not applicable. |
|
950 * |
|
951 * @param aARIAProperty [in] the ARIA property we're using |
|
952 * @return a numeric value |
|
953 */ |
|
954 double AttrNumericValue(nsIAtom* aARIAAttr) const; |
|
955 |
|
956 /** |
|
957 * Return the action rule based on ARIA enum constants EActionRule |
|
958 * (see ARIAMap.h). Used by ActionCount() and GetActionName(). |
|
959 */ |
|
960 uint32_t GetActionRule(); |
|
961 |
|
962 /** |
|
963 * Return group info. |
|
964 */ |
|
965 AccGroupInfo* GetGroupInfo(); |
|
966 |
|
967 /** |
|
968 * Set dirty state of the accessible's group info. |
|
969 */ |
|
970 inline void SetDirtyGroupInfo(bool aIsDirty) |
|
971 { |
|
972 if (aIsDirty) |
|
973 mStateFlags |= eGroupInfoDirty; |
|
974 else |
|
975 mStateFlags &= ~eGroupInfoDirty; |
|
976 } |
|
977 |
|
978 /** |
|
979 * Flag all children group info as needing to be updated. |
|
980 */ |
|
981 void InvalidateChildrenGroupInfo(); |
|
982 |
|
983 // Data Members |
|
984 nsCOMPtr<nsIContent> mContent; |
|
985 DocAccessible* mDoc; |
|
986 |
|
987 nsRefPtr<Accessible> mParent; |
|
988 nsTArray<nsRefPtr<Accessible> > mChildren; |
|
989 int32_t mIndexInParent; |
|
990 |
|
991 static const uint8_t kChildrenFlagsBits = 2; |
|
992 static const uint8_t kStateFlagsBits = 7; |
|
993 static const uint8_t kContextFlagsBits = 1; |
|
994 static const uint8_t kTypeBits = 6; |
|
995 static const uint8_t kGenericTypesBits = 13; |
|
996 |
|
997 /** |
|
998 * Keep in sync with ChildrenFlags, StateFlags, ContextFlags, and AccTypes. |
|
999 */ |
|
1000 uint32_t mChildrenFlags : kChildrenFlagsBits; |
|
1001 uint32_t mStateFlags : kStateFlagsBits; |
|
1002 uint32_t mContextFlags : kContextFlagsBits; |
|
1003 uint32_t mType : kTypeBits; |
|
1004 uint32_t mGenericTypes : kGenericTypesBits; |
|
1005 |
|
1006 void StaticAsserts() const; |
|
1007 |
|
1008 friend class DocAccessible; |
|
1009 |
|
1010 nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector; |
|
1011 int32_t mIndexOfEmbeddedChild; |
|
1012 friend class EmbeddedObjCollector; |
|
1013 |
|
1014 nsAutoPtr<AccGroupInfo> mGroupInfo; |
|
1015 friend class AccGroupInfo; |
|
1016 |
|
1017 /** |
|
1018 * Non-null indicates author-supplied role; possibly state & value as well |
|
1019 */ |
|
1020 nsRoleMapEntry* mRoleMapEntry; |
|
1021 |
|
1022 private: |
|
1023 Accessible() MOZ_DELETE; |
|
1024 Accessible(const Accessible&) MOZ_DELETE; |
|
1025 Accessible& operator =(const Accessible&) MOZ_DELETE; |
|
1026 |
|
1027 }; |
|
1028 |
|
1029 NS_DEFINE_STATIC_IID_ACCESSOR(Accessible, |
|
1030 NS_ACCESSIBLE_IMPL_IID) |
|
1031 |
|
1032 |
|
1033 /** |
|
1034 * Represent key binding associated with accessible (such as access key and |
|
1035 * global keyboard shortcuts). |
|
1036 */ |
|
1037 class KeyBinding |
|
1038 { |
|
1039 public: |
|
1040 /** |
|
1041 * Modifier mask values. |
|
1042 */ |
|
1043 static const uint32_t kShift = 1; |
|
1044 static const uint32_t kControl = 2; |
|
1045 static const uint32_t kAlt = 4; |
|
1046 static const uint32_t kMeta = 8; |
|
1047 static const uint32_t kOS = 16; |
|
1048 |
|
1049 KeyBinding() : mKey(0), mModifierMask(0) {} |
|
1050 KeyBinding(uint32_t aKey, uint32_t aModifierMask) : |
|
1051 mKey(aKey), mModifierMask(aModifierMask) {} |
|
1052 |
|
1053 inline bool IsEmpty() const { return !mKey; } |
|
1054 inline uint32_t Key() const { return mKey; } |
|
1055 inline uint32_t ModifierMask() const { return mModifierMask; } |
|
1056 |
|
1057 enum Format { |
|
1058 ePlatformFormat, |
|
1059 eAtkFormat |
|
1060 }; |
|
1061 |
|
1062 /** |
|
1063 * Return formatted string for this key binding depending on the given format. |
|
1064 */ |
|
1065 inline void ToString(nsAString& aValue, |
|
1066 Format aFormat = ePlatformFormat) const |
|
1067 { |
|
1068 aValue.Truncate(); |
|
1069 AppendToString(aValue, aFormat); |
|
1070 } |
|
1071 inline void AppendToString(nsAString& aValue, |
|
1072 Format aFormat = ePlatformFormat) const |
|
1073 { |
|
1074 if (mKey) { |
|
1075 if (aFormat == ePlatformFormat) |
|
1076 ToPlatformFormat(aValue); |
|
1077 else |
|
1078 ToAtkFormat(aValue); |
|
1079 } |
|
1080 } |
|
1081 |
|
1082 private: |
|
1083 void ToPlatformFormat(nsAString& aValue) const; |
|
1084 void ToAtkFormat(nsAString& aValue) const; |
|
1085 |
|
1086 uint32_t mKey; |
|
1087 uint32_t mModifierMask; |
|
1088 }; |
|
1089 |
|
1090 } // namespace a11y |
|
1091 } // namespace mozilla |
|
1092 |
|
1093 #endif |