Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
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/. */
6 #ifndef _Accessible_H_
7 #define _Accessible_H_
9 #include "mozilla/a11y/AccTypes.h"
10 #include "mozilla/a11y/RelationType.h"
11 #include "mozilla/a11y/Role.h"
12 #include "mozilla/a11y/States.h"
14 #include "nsIAccessible.h"
15 #include "nsIAccessibleHyperLink.h"
16 #include "nsIAccessibleStates.h"
17 #include "xpcAccessibleSelectable.h"
18 #include "xpcAccessibleValue.h"
20 #include "nsIContent.h"
21 #include "nsString.h"
22 #include "nsTArray.h"
23 #include "nsRefPtrHashtable.h"
25 struct nsRoleMapEntry;
27 struct nsRect;
28 class nsIFrame;
29 class nsIAtom;
30 class nsView;
32 namespace mozilla {
33 namespace a11y {
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;
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,
64 /**
65 * Name was left empty by the author on purpose:
66 * name.IsEmpty() && !name.IsVoid().
67 */
68 eNoNameOnPurpose,
70 /**
71 * Name was computed from the subtree.
72 */
73 eNameFromSubtree,
75 /**
76 * Tooltip was used as a name.
77 */
78 eNameFromTooltip
79 };
81 /**
82 * Group position (level, position in set and set size).
83 */
84 struct GroupPos
85 {
86 GroupPos() : level(0), posInSet(0), setSize(0) { }
88 int32_t level;
89 int32_t posInSet;
90 int32_t setSize;
91 };
93 typedef nsRefPtrHashtable<nsPtrHashKey<const void>, Accessible>
94 AccessibleHashtable;
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 }
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();
114 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
115 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(Accessible, nsIAccessible)
117 NS_DECL_NSIACCESSIBLE
118 NS_DECL_NSIACCESSIBLEHYPERLINK
119 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLE_IMPL_IID)
121 //////////////////////////////////////////////////////////////////////////////
122 // Public methods
124 /**
125 * Return the document accessible for this accessible.
126 */
127 DocAccessible* Document() const { return mDoc; }
129 /**
130 * Return the root document accessible for this accessible.
131 */
132 a11y::RootAccessible* RootAccessible() const;
134 /**
135 * Return frame for this accessible.
136 */
137 virtual nsIFrame* GetFrame() const;
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; }
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); }
156 /**
157 * Return the unique identifier of the accessible.
158 */
159 void* UniqueID() { return static_cast<void*>(this); }
161 /**
162 * Return language associated with the accessible.
163 */
164 void Language(nsAString& aLocale);
166 /**
167 * Get the description of this accessible.
168 */
169 virtual void Description(nsString& aDescription);
171 /**
172 * Get the value of this accessible.
173 */
174 virtual void Value(nsString& aValue);
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);
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;
193 /**
194 * Return enumerated accessible role (see constants in Role.h).
195 */
196 mozilla::a11y::role Role();
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;
204 /**
205 * Retrun ARIA role map if any.
206 */
207 nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; }
209 /**
210 * Return accessible role specified by ARIA (see constants in
211 * roles).
212 */
213 mozilla::a11y::role ARIARole();
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();
221 /**
222 * Return all states of accessible (including ARIA states).
223 */
224 virtual uint64_t State();
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 }
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 }
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 }
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();
263 /**
264 * Return native interactice state (unavailable, focusable or selectable).
265 */
266 virtual uint64_t NativeInteractiveState() const;
268 /**
269 * Return native link states present on the accessible.
270 */
271 virtual uint64_t NativeLinkState() const;
273 /**
274 * Return bit set of invisible and offscreen states.
275 */
276 uint64_t VisibilityState();
278 /**
279 * Return true if native unavailable state present.
280 */
281 virtual bool NativelyUnavailable() const;
283 /**
284 * Return object attributes for the accessible.
285 */
286 virtual already_AddRefed<nsIPersistentProperties> Attributes();
288 /**
289 * Return group position (level, position in set and set size).
290 */
291 virtual mozilla::a11y::GroupPos GroupPosition();
293 /**
294 * Used by ChildAtPoint() method to get direct or deepest child at point.
295 */
296 enum EWhichChildAtPoint {
297 eDirectChild,
298 eDeepestChild
299 };
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);
312 /**
313 * Return the focused child if any.
314 */
315 virtual Accessible* FocusedChild();
317 /**
318 * Return calculated group level based on accessible hierarchy.
319 */
320 virtual int32_t GetLevelInternal();
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);
332 /**
333 * Get the relation of the given type.
334 */
335 virtual Relation RelationByType(RelationType aType);
337 //////////////////////////////////////////////////////////////////////////////
338 // Initializing methods
340 /**
341 * Shutdown this accessible object.
342 */
343 virtual void Shutdown();
345 /**
346 * Set the ARIA role map entry for a new accessible.
347 */
348 void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
349 { mRoleMapEntry = aRoleMapEntry; }
351 /**
352 * Update the children cache.
353 */
354 inline bool UpdateChildren()
355 {
356 InvalidateChildren();
357 return EnsureChildren();
358 }
360 /**
361 * Cache children if necessary. Return true if the accessible is defunct.
362 */
363 bool EnsureChildren();
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();
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);
381 //////////////////////////////////////////////////////////////////////////////
382 // Accessible tree traverse methods
384 /**
385 * Return parent accessible.
386 */
387 Accessible* Parent() const { return mParent; }
389 /**
390 * Return child accessible at the given index.
391 */
392 virtual Accessible* GetChildAt(uint32_t aIndex) const;
394 /**
395 * Return child accessible count.
396 */
397 virtual uint32_t ChildCount() const;
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(); }
405 /**
406 * Return index in parent accessible.
407 */
408 virtual int32_t IndexInParent() const;
410 /**
411 * Return true if accessible has children;
412 */
413 bool HasChildren() { return !!GetChildAt(0); }
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 }
430 /**
431 * Return embedded accessible children count.
432 */
433 uint32_t EmbeddedChildCount();
435 /**
436 * Return embedded accessible child at the given index.
437 */
438 Accessible* GetEmbeddedChildAt(uint32_t aIndex);
440 /**
441 * Return index of the given embedded accessible child.
442 */
443 int32_t GetIndexOfEmbeddedChild(Accessible* aChild);
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); }
454 /**
455 * Return true if children were initialized.
456 */
457 inline bool AreChildrenCached() const
458 { return !IsChildrenFlag(eChildrenUninitialized); }
460 /**
461 * Return true if the accessible is attached to tree.
462 */
463 bool IsBoundToParent() const { return !!mParent; }
465 //////////////////////////////////////////////////////////////////////////////
466 // Miscellaneous methods
468 /**
469 * Handle accessible event, i.e. process it, notifies observers and fires
470 * platform specific event.
471 */
472 virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
474 /**
475 * Return true if this accessible allows accessible children from anonymous subtree.
476 */
477 virtual bool CanHaveAnonChildren();
479 /**
480 * Return true if the accessible is an acceptable child.
481 */
482 virtual bool IsAcceptableChild(Accessible* aPossibleChild) const { return true; }
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);
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;
503 /**
504 * Return boundaries rect relative the bounding frame.
505 */
506 virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
508 //////////////////////////////////////////////////////////////////////////////
509 // Downcasting and types
511 inline bool IsAbbreviation() const
512 {
513 return mContent->IsHTML() &&
514 (mContent->Tag() == nsGkAtoms::abbr || mContent->Tag() == nsGkAtoms::acronym);
515 }
517 bool IsApplication() const { return mType == eApplicationType; }
519 bool IsAutoComplete() const { return HasGenericType(eAutoComplete); }
521 bool IsAutoCompletePopup() const
522 { return HasGenericType(eAutoCompletePopup); }
524 bool IsButton() const { return HasGenericType(eButton); }
526 bool IsCombobox() const { return HasGenericType(eCombobox); }
528 bool IsDoc() const { return HasGenericType(eDocument); }
529 DocAccessible* AsDoc();
531 bool IsHyperText() const { return HasGenericType(eHyperText); }
532 HyperTextAccessible* AsHyperText();
534 bool IsHTMLBr() const { return mType == eHTMLBRType; }
535 bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; }
537 bool IsHTMLListItem() const { return mType == eHTMLLiType; }
538 HTMLLIAccessible* AsHTMLListItem();
540 bool IsHTMLOptGroup() const { return mType == eHTMLOptGroupType; }
542 bool IsHTMLTable() const { return mType == eHTMLTableType; }
543 bool IsHTMLTableRow() const { return mType == eHTMLTableRowType; }
545 bool IsImage() const { return mType == eImageType; }
546 ImageAccessible* AsImage();
548 bool IsImageMap() const { return mType == eImageMapType; }
549 HTMLImageMapAccessible* AsImageMap();
551 bool IsList() const { return HasGenericType(eList); }
553 bool IsListControl() const { return HasGenericType(eListControl); }
555 bool IsMenuButton() const { return HasGenericType(eMenuButton); }
557 bool IsMenuPopup() const { return mType == eMenuPopupType; }
559 bool IsProgress() const { return mType == eProgressType; }
561 bool IsRoot() const { return mType == eRootType; }
562 a11y::RootAccessible* AsRoot();
564 bool IsSelect() const { return HasGenericType(eSelect); }
566 bool IsTable() const { return HasGenericType(eTable); }
567 virtual TableAccessible* AsTable() { return nullptr; }
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(); }
574 bool IsTableRow() const { return HasGenericType(eTableRow); }
576 bool IsTextField() const { return mType == eHTMLTextFieldType; }
578 bool IsTextLeaf() const { return mType == eTextLeafType; }
579 TextLeafAccessible* AsTextLeaf();
581 bool IsXULLabel() const { return mType == eXULLabelType; }
582 XULLabelAccessible* AsXULLabel();
584 bool IsXULListItem() const { return mType == eXULListItemType; }
586 bool IsXULTabpanels() const { return mType == eXULTabpanelsType; }
588 bool IsXULTree() const { return mType == eXULTreeType; }
589 XULTreeAccessible* AsXULTree();
591 /**
592 * Return true if the accessible belongs to the given accessible type.
593 */
594 bool HasGenericType(AccGenericType aType) const;
596 //////////////////////////////////////////////////////////////////////////////
597 // ActionAccessible
599 /**
600 * Return the number of actions that can be performed on this accessible.
601 */
602 virtual uint8_t ActionCount();
604 /**
605 * Return access key, such as Alt+D.
606 */
607 virtual KeyBinding AccessKey() const;
609 /**
610 * Return global keyboard shortcut for default action, such as Ctrl+O for
611 * Open file menuitem.
612 */
613 virtual KeyBinding KeyboardShortcut() const;
615 //////////////////////////////////////////////////////////////////////////////
616 // HyperLinkAccessible
618 /**
619 * Return true if the accessible is hyper link accessible.
620 */
621 virtual bool IsLink();
623 /**
624 * Return the start offset of the link within the parent accessible.
625 */
626 virtual uint32_t StartOffset();
628 /**
629 * Return the end offset of the link within the parent accessible.
630 */
631 virtual uint32_t EndOffset();
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!");
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 }
647 /**
648 * Return the number of anchors within the link.
649 */
650 virtual uint32_t AnchorCount();
652 /**
653 * Returns an anchor accessible at the given index.
654 */
655 virtual Accessible* AnchorAt(uint32_t aAnchorIndex);
657 /**
658 * Returns an anchor URI at the given index.
659 */
660 virtual already_AddRefed<nsIURI> AnchorURIAt(uint32_t aAnchorIndex);
662 //////////////////////////////////////////////////////////////////////////////
663 // SelectAccessible
665 /**
666 * Return an array of selected items.
667 */
668 virtual already_AddRefed<nsIArray> SelectedItems();
670 /**
671 * Return the number of selected items.
672 */
673 virtual uint32_t SelectedItemCount();
675 /**
676 * Return selected item at the given index.
677 */
678 virtual Accessible* GetSelectedItem(uint32_t aIndex);
680 /**
681 * Determine if item at the given index is selected.
682 */
683 virtual bool IsItemSelected(uint32_t aIndex);
685 /**
686 * Add item at the given index the selection. Return true if success.
687 */
688 virtual bool AddItemToSelection(uint32_t aIndex);
690 /**
691 * Remove item at the given index from the selection. Return if success.
692 */
693 virtual bool RemoveItemFromSelection(uint32_t aIndex);
695 /**
696 * Select all items. Return true if success.
697 */
698 virtual bool SelectAll();
700 /**
701 * Unselect all items. Return true if success.
702 */
703 virtual bool UnselectAll();
705 //////////////////////////////////////////////////////////////////////////////
706 // Value (numeric value interface)
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);
714 //////////////////////////////////////////////////////////////////////////////
715 // Widgets
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;
724 /**
725 * Return true if the widget is active, i.e. has a focus within it.
726 */
727 virtual bool IsActiveWidget() const;
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;
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();
741 /**
742 * Set the current item of the widget.
743 */
744 virtual void SetCurrentItem(Accessible* aItem);
746 /**
747 * Return container widget this accessible belongs to.
748 */
749 virtual Accessible* ContainerWidget() const;
751 /**
752 * Return the localized string for the given key.
753 */
754 static void TranslateString(const nsString& aKey, nsAString& aStringOut);
756 /**
757 * Return true if the accessible is defunct.
758 */
759 bool IsDefunct() const { return mStateFlags & eIsDefunct; }
761 /**
762 * Return true if the accessible is no longer in the document.
763 */
764 bool IsInDocument() const { return !(mStateFlags & eIsNotInDocument); }
766 /**
767 * Return true if the accessible should be contained by document node map.
768 */
769 bool IsNodeMapEntry() const
770 { return HasOwnContent() && !(mStateFlags & eNotNodeMapEntry); }
772 /**
773 * Return true if the accessible's group info needs to be updated.
774 */
775 inline bool HasDirtyGroupInfo() const { return mStateFlags & eGroupInfoDirty; }
777 /**
778 * Return true if the accessible has associated DOM content.
779 */
780 bool HasOwnContent() const
781 { return mContent && !(mStateFlags & eSharedNode); }
783 /**
784 * Return true if the accessible has a numeric value.
785 */
786 bool HasNumericValue() const;
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); }
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; }
804 protected:
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);
812 /**
813 * Return object attributes provided by native markup. It doesn't take into
814 * account ARIA.
815 */
816 virtual already_AddRefed<nsIPersistentProperties> NativeAttributes();
818 //////////////////////////////////////////////////////////////////////////////
819 // Initializing, cache and tree traverse methods
821 /**
822 * Destroy the object.
823 */
824 void LastRelease();
826 /**
827 * Cache accessible children.
828 */
829 virtual void CacheChildren();
831 /**
832 * Set accessible parent and index in parent.
833 */
834 virtual void BindToParent(Accessible* aParent, uint32_t aIndexInParent);
835 virtual void UnbindFromParent();
837 /**
838 * Return sibling accessible at the given offset.
839 */
840 virtual Accessible* GetSiblingAtOffset(int32_t aOffset,
841 nsresult *aError = nullptr) const;
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
851 eLastChildrenFlag = eEmbeddedChildren
852 };
854 /**
855 * Return true if the children flag is set.
856 */
857 bool IsChildrenFlag(ChildrenFlags aFlag) const
858 { return static_cast<ChildrenFlags>(mChildrenFlags) == aFlag; }
860 /**
861 * Set children flag.
862 */
863 void SetChildrenFlag(ChildrenFlags aFlag) { mChildrenFlags = aFlag; }
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
878 eLastStateFlag = eIgnoreDOMUIEvent
879 };
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.
887 eLastContextFlag = eHasNameDependentParent
888 };
890 protected:
892 //////////////////////////////////////////////////////////////////////////////
893 // Miscellaneous helpers
895 /**
896 * Return ARIA role (helper method).
897 */
898 mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole);
900 //////////////////////////////////////////////////////////////////////////////
901 // Name helpers
903 /**
904 * Returns the accessible name specified by ARIA.
905 */
906 void ARIAName(nsString& aName);
908 /**
909 * Return the name for XUL element.
910 */
911 static void XULElmName(DocAccessible* aDocument,
912 nsIContent* aElm, nsString& aName);
914 // helper method to verify frames
915 static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
917 //////////////////////////////////////////////////////////////////////////////
918 // Action helpers
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);
934 /**
935 * Dispatch click event.
936 */
937 virtual void DispatchClickEvent(nsIContent *aContent, uint32_t aActionIndex);
939 //////////////////////////////////////////////////////////////////////////////
940 // Helpers
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;
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;
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();
962 /**
963 * Return group info.
964 */
965 AccGroupInfo* GetGroupInfo();
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 }
978 /**
979 * Flag all children group info as needing to be updated.
980 */
981 void InvalidateChildrenGroupInfo();
983 // Data Members
984 nsCOMPtr<nsIContent> mContent;
985 DocAccessible* mDoc;
987 nsRefPtr<Accessible> mParent;
988 nsTArray<nsRefPtr<Accessible> > mChildren;
989 int32_t mIndexInParent;
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;
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;
1006 void StaticAsserts() const;
1008 friend class DocAccessible;
1010 nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
1011 int32_t mIndexOfEmbeddedChild;
1012 friend class EmbeddedObjCollector;
1014 nsAutoPtr<AccGroupInfo> mGroupInfo;
1015 friend class AccGroupInfo;
1017 /**
1018 * Non-null indicates author-supplied role; possibly state & value as well
1019 */
1020 nsRoleMapEntry* mRoleMapEntry;
1022 private:
1023 Accessible() MOZ_DELETE;
1024 Accessible(const Accessible&) MOZ_DELETE;
1025 Accessible& operator =(const Accessible&) MOZ_DELETE;
1027 };
1029 NS_DEFINE_STATIC_IID_ACCESSOR(Accessible,
1030 NS_ACCESSIBLE_IMPL_IID)
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;
1049 KeyBinding() : mKey(0), mModifierMask(0) {}
1050 KeyBinding(uint32_t aKey, uint32_t aModifierMask) :
1051 mKey(aKey), mModifierMask(aModifierMask) {}
1053 inline bool IsEmpty() const { return !mKey; }
1054 inline uint32_t Key() const { return mKey; }
1055 inline uint32_t ModifierMask() const { return mModifierMask; }
1057 enum Format {
1058 ePlatformFormat,
1059 eAtkFormat
1060 };
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 }
1082 private:
1083 void ToPlatformFormat(nsAString& aValue) const;
1084 void ToAtkFormat(nsAString& aValue) const;
1086 uint32_t mKey;
1087 uint32_t mModifierMask;
1088 };
1090 } // namespace a11y
1091 } // namespace mozilla
1093 #endif