accessible/src/generic/Accessible.h

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial