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