1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/generic/Accessible.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1093 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef _Accessible_H_ 1.10 +#define _Accessible_H_ 1.11 + 1.12 +#include "mozilla/a11y/AccTypes.h" 1.13 +#include "mozilla/a11y/RelationType.h" 1.14 +#include "mozilla/a11y/Role.h" 1.15 +#include "mozilla/a11y/States.h" 1.16 + 1.17 +#include "nsIAccessible.h" 1.18 +#include "nsIAccessibleHyperLink.h" 1.19 +#include "nsIAccessibleStates.h" 1.20 +#include "xpcAccessibleSelectable.h" 1.21 +#include "xpcAccessibleValue.h" 1.22 + 1.23 +#include "nsIContent.h" 1.24 +#include "nsString.h" 1.25 +#include "nsTArray.h" 1.26 +#include "nsRefPtrHashtable.h" 1.27 + 1.28 +struct nsRoleMapEntry; 1.29 + 1.30 +struct nsRect; 1.31 +class nsIFrame; 1.32 +class nsIAtom; 1.33 +class nsView; 1.34 + 1.35 +namespace mozilla { 1.36 +namespace a11y { 1.37 + 1.38 +class Accessible; 1.39 +class AccEvent; 1.40 +class AccGroupInfo; 1.41 +class DocAccessible; 1.42 +class EmbeddedObjCollector; 1.43 +class HTMLImageMapAccessible; 1.44 +class HTMLLIAccessible; 1.45 +class HyperTextAccessible; 1.46 +class ImageAccessible; 1.47 +class KeyBinding; 1.48 +class Relation; 1.49 +class RootAccessible; 1.50 +class TableAccessible; 1.51 +class TableCellAccessible; 1.52 +class TextLeafAccessible; 1.53 +class XULLabelAccessible; 1.54 +class XULTreeAccessible; 1.55 + 1.56 +/** 1.57 + * Name type flags. 1.58 + */ 1.59 +enum ENameValueFlag { 1.60 + /** 1.61 + * Name either 1.62 + * a) present (not empty): !name.IsEmpty() 1.63 + * b) no name (was missed): name.IsVoid() 1.64 + */ 1.65 + eNameOK, 1.66 + 1.67 + /** 1.68 + * Name was left empty by the author on purpose: 1.69 + * name.IsEmpty() && !name.IsVoid(). 1.70 + */ 1.71 + eNoNameOnPurpose, 1.72 + 1.73 + /** 1.74 + * Name was computed from the subtree. 1.75 + */ 1.76 + eNameFromSubtree, 1.77 + 1.78 + /** 1.79 + * Tooltip was used as a name. 1.80 + */ 1.81 + eNameFromTooltip 1.82 +}; 1.83 + 1.84 +/** 1.85 + * Group position (level, position in set and set size). 1.86 + */ 1.87 +struct GroupPos 1.88 +{ 1.89 + GroupPos() : level(0), posInSet(0), setSize(0) { } 1.90 + 1.91 + int32_t level; 1.92 + int32_t posInSet; 1.93 + int32_t setSize; 1.94 +}; 1.95 + 1.96 +typedef nsRefPtrHashtable<nsPtrHashKey<const void>, Accessible> 1.97 + AccessibleHashtable; 1.98 + 1.99 + 1.100 +#define NS_ACCESSIBLE_IMPL_IID \ 1.101 +{ /* 133c8bf4-4913-4355-bd50-426bd1d6e1ad */ \ 1.102 + 0x133c8bf4, \ 1.103 + 0x4913, \ 1.104 + 0x4355, \ 1.105 + { 0xbd, 0x50, 0x42, 0x6b, 0xd1, 0xd6, 0xe1, 0xad } \ 1.106 +} 1.107 + 1.108 +class Accessible : public nsIAccessible, 1.109 + public nsIAccessibleHyperLink, 1.110 + public xpcAccessibleSelectable, 1.111 + public xpcAccessibleValue 1.112 +{ 1.113 +public: 1.114 + Accessible(nsIContent* aContent, DocAccessible* aDoc); 1.115 + virtual ~Accessible(); 1.116 + 1.117 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.118 + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(Accessible, nsIAccessible) 1.119 + 1.120 + NS_DECL_NSIACCESSIBLE 1.121 + NS_DECL_NSIACCESSIBLEHYPERLINK 1.122 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLE_IMPL_IID) 1.123 + 1.124 + ////////////////////////////////////////////////////////////////////////////// 1.125 + // Public methods 1.126 + 1.127 + /** 1.128 + * Return the document accessible for this accessible. 1.129 + */ 1.130 + DocAccessible* Document() const { return mDoc; } 1.131 + 1.132 + /** 1.133 + * Return the root document accessible for this accessible. 1.134 + */ 1.135 + a11y::RootAccessible* RootAccessible() const; 1.136 + 1.137 + /** 1.138 + * Return frame for this accessible. 1.139 + */ 1.140 + virtual nsIFrame* GetFrame() const; 1.141 + 1.142 + /** 1.143 + * Return DOM node associated with the accessible. 1.144 + */ 1.145 + virtual nsINode* GetNode() const; 1.146 + inline already_AddRefed<nsIDOMNode> DOMNode() const 1.147 + { 1.148 + nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(GetNode()); 1.149 + return DOMNode.forget(); 1.150 + } 1.151 + nsIContent* GetContent() const { return mContent; } 1.152 + 1.153 + /** 1.154 + * Return node type information of DOM node associated with the accessible. 1.155 + */ 1.156 + bool IsContent() const 1.157 + { return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT); } 1.158 + 1.159 + /** 1.160 + * Return the unique identifier of the accessible. 1.161 + */ 1.162 + void* UniqueID() { return static_cast<void*>(this); } 1.163 + 1.164 + /** 1.165 + * Return language associated with the accessible. 1.166 + */ 1.167 + void Language(nsAString& aLocale); 1.168 + 1.169 + /** 1.170 + * Get the description of this accessible. 1.171 + */ 1.172 + virtual void Description(nsString& aDescription); 1.173 + 1.174 + /** 1.175 + * Get the value of this accessible. 1.176 + */ 1.177 + virtual void Value(nsString& aValue); 1.178 + 1.179 + /** 1.180 + * Get the name of this accessible. 1.181 + * 1.182 + * Note: aName.IsVoid() when name was left empty by the author on purpose. 1.183 + * aName.IsEmpty() when the author missed name, AT can try to repair a name. 1.184 + */ 1.185 + virtual ENameValueFlag Name(nsString& aName); 1.186 + 1.187 + /** 1.188 + * Maps ARIA state attributes to state of accessible. Note the given state 1.189 + * argument should hold states for accessible before you pass it into this 1.190 + * method. 1.191 + * 1.192 + * @param [in/out] where to fill the states into. 1.193 + */ 1.194 + virtual void ApplyARIAState(uint64_t* aState) const; 1.195 + 1.196 + /** 1.197 + * Return enumerated accessible role (see constants in Role.h). 1.198 + */ 1.199 + mozilla::a11y::role Role(); 1.200 + 1.201 + /** 1.202 + * Return true if ARIA role is specified on the element. 1.203 + */ 1.204 + bool HasARIARole() const { return mRoleMapEntry; } 1.205 + bool IsARIARole(nsIAtom* aARIARole) const; 1.206 + 1.207 + /** 1.208 + * Retrun ARIA role map if any. 1.209 + */ 1.210 + nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; } 1.211 + 1.212 + /** 1.213 + * Return accessible role specified by ARIA (see constants in 1.214 + * roles). 1.215 + */ 1.216 + mozilla::a11y::role ARIARole(); 1.217 + 1.218 + /** 1.219 + * Returns enumerated accessible role from native markup (see constants in 1.220 + * Role.h). Doesn't take into account ARIA roles. 1.221 + */ 1.222 + virtual mozilla::a11y::role NativeRole(); 1.223 + 1.224 + /** 1.225 + * Return all states of accessible (including ARIA states). 1.226 + */ 1.227 + virtual uint64_t State(); 1.228 + 1.229 + /** 1.230 + * Return interactive states present on the accessible 1.231 + * (@see NativeInteractiveState). 1.232 + */ 1.233 + uint64_t InteractiveState() const 1.234 + { 1.235 + uint64_t state = NativeInteractiveState(); 1.236 + ApplyARIAState(&state); 1.237 + return state; 1.238 + } 1.239 + 1.240 + /** 1.241 + * Return link states present on the accessible. 1.242 + */ 1.243 + uint64_t LinkState() const 1.244 + { 1.245 + uint64_t state = NativeLinkState(); 1.246 + ApplyARIAState(&state); 1.247 + return state; 1.248 + } 1.249 + 1.250 + /** 1.251 + * Return if accessible is unavailable. 1.252 + */ 1.253 + bool Unavailable() const 1.254 + { 1.255 + uint64_t state = NativelyUnavailable() ? states::UNAVAILABLE : 0; 1.256 + ApplyARIAState(&state); 1.257 + return state & states::UNAVAILABLE; 1.258 + } 1.259 + 1.260 + /** 1.261 + * Return the states of accessible, not taking into account ARIA states. 1.262 + * Use State() to get complete set of states. 1.263 + */ 1.264 + virtual uint64_t NativeState(); 1.265 + 1.266 + /** 1.267 + * Return native interactice state (unavailable, focusable or selectable). 1.268 + */ 1.269 + virtual uint64_t NativeInteractiveState() const; 1.270 + 1.271 + /** 1.272 + * Return native link states present on the accessible. 1.273 + */ 1.274 + virtual uint64_t NativeLinkState() const; 1.275 + 1.276 + /** 1.277 + * Return bit set of invisible and offscreen states. 1.278 + */ 1.279 + uint64_t VisibilityState(); 1.280 + 1.281 + /** 1.282 + * Return true if native unavailable state present. 1.283 + */ 1.284 + virtual bool NativelyUnavailable() const; 1.285 + 1.286 + /** 1.287 + * Return object attributes for the accessible. 1.288 + */ 1.289 + virtual already_AddRefed<nsIPersistentProperties> Attributes(); 1.290 + 1.291 + /** 1.292 + * Return group position (level, position in set and set size). 1.293 + */ 1.294 + virtual mozilla::a11y::GroupPos GroupPosition(); 1.295 + 1.296 + /** 1.297 + * Used by ChildAtPoint() method to get direct or deepest child at point. 1.298 + */ 1.299 + enum EWhichChildAtPoint { 1.300 + eDirectChild, 1.301 + eDeepestChild 1.302 + }; 1.303 + 1.304 + /** 1.305 + * Return direct or deepest child at the given point. 1.306 + * 1.307 + * @param aX [in] x coordinate relative screen 1.308 + * @param aY [in] y coordinate relative screen 1.309 + * @param aWhichChild [in] flag points if deepest or direct child 1.310 + * should be returned 1.311 + */ 1.312 + virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY, 1.313 + EWhichChildAtPoint aWhichChild); 1.314 + 1.315 + /** 1.316 + * Return the focused child if any. 1.317 + */ 1.318 + virtual Accessible* FocusedChild(); 1.319 + 1.320 + /** 1.321 + * Return calculated group level based on accessible hierarchy. 1.322 + */ 1.323 + virtual int32_t GetLevelInternal(); 1.324 + 1.325 + /** 1.326 + * Calculate position in group and group size ('posinset' and 'setsize') based 1.327 + * on accessible hierarchy. 1.328 + * 1.329 + * @param aPosInSet [out] accessible position in the group 1.330 + * @param aSetSize [out] the group size 1.331 + */ 1.332 + virtual void GetPositionAndSizeInternal(int32_t *aPosInSet, 1.333 + int32_t *aSetSize); 1.334 + 1.335 + /** 1.336 + * Get the relation of the given type. 1.337 + */ 1.338 + virtual Relation RelationByType(RelationType aType); 1.339 + 1.340 + ////////////////////////////////////////////////////////////////////////////// 1.341 + // Initializing methods 1.342 + 1.343 + /** 1.344 + * Shutdown this accessible object. 1.345 + */ 1.346 + virtual void Shutdown(); 1.347 + 1.348 + /** 1.349 + * Set the ARIA role map entry for a new accessible. 1.350 + */ 1.351 + void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry) 1.352 + { mRoleMapEntry = aRoleMapEntry; } 1.353 + 1.354 + /** 1.355 + * Update the children cache. 1.356 + */ 1.357 + inline bool UpdateChildren() 1.358 + { 1.359 + InvalidateChildren(); 1.360 + return EnsureChildren(); 1.361 + } 1.362 + 1.363 + /** 1.364 + * Cache children if necessary. Return true if the accessible is defunct. 1.365 + */ 1.366 + bool EnsureChildren(); 1.367 + 1.368 + /** 1.369 + * Set the child count to -1 (unknown) and null out cached child pointers. 1.370 + * Should be called when accessible tree is changed because document has 1.371 + * transformed. Note, if accessible cares about its parent relation chain 1.372 + * itself should override this method to do nothing. 1.373 + */ 1.374 + virtual void InvalidateChildren(); 1.375 + 1.376 + /** 1.377 + * Append/insert/remove a child. Return true if operation was successful. 1.378 + */ 1.379 + bool AppendChild(Accessible* aChild) 1.380 + { return InsertChildAt(mChildren.Length(), aChild); } 1.381 + virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild); 1.382 + virtual bool RemoveChild(Accessible* aChild); 1.383 + 1.384 + ////////////////////////////////////////////////////////////////////////////// 1.385 + // Accessible tree traverse methods 1.386 + 1.387 + /** 1.388 + * Return parent accessible. 1.389 + */ 1.390 + Accessible* Parent() const { return mParent; } 1.391 + 1.392 + /** 1.393 + * Return child accessible at the given index. 1.394 + */ 1.395 + virtual Accessible* GetChildAt(uint32_t aIndex) const; 1.396 + 1.397 + /** 1.398 + * Return child accessible count. 1.399 + */ 1.400 + virtual uint32_t ChildCount() const; 1.401 + 1.402 + /** 1.403 + * Return index of the given child accessible. 1.404 + */ 1.405 + int32_t GetIndexOf(const Accessible* aChild) const 1.406 + { return (aChild->mParent != this) ? -1 : aChild->IndexInParent(); } 1.407 + 1.408 + /** 1.409 + * Return index in parent accessible. 1.410 + */ 1.411 + virtual int32_t IndexInParent() const; 1.412 + 1.413 + /** 1.414 + * Return true if accessible has children; 1.415 + */ 1.416 + bool HasChildren() { return !!GetChildAt(0); } 1.417 + 1.418 + /** 1.419 + * Return first/last/next/previous sibling of the accessible. 1.420 + */ 1.421 + inline Accessible* NextSibling() const 1.422 + { return GetSiblingAtOffset(1); } 1.423 + inline Accessible* PrevSibling() const 1.424 + { return GetSiblingAtOffset(-1); } 1.425 + inline Accessible* FirstChild() 1.426 + { return GetChildAt(0); } 1.427 + inline Accessible* LastChild() 1.428 + { 1.429 + uint32_t childCount = ChildCount(); 1.430 + return childCount != 0 ? GetChildAt(childCount - 1) : nullptr; 1.431 + } 1.432 + 1.433 + /** 1.434 + * Return embedded accessible children count. 1.435 + */ 1.436 + uint32_t EmbeddedChildCount(); 1.437 + 1.438 + /** 1.439 + * Return embedded accessible child at the given index. 1.440 + */ 1.441 + Accessible* GetEmbeddedChildAt(uint32_t aIndex); 1.442 + 1.443 + /** 1.444 + * Return index of the given embedded accessible child. 1.445 + */ 1.446 + int32_t GetIndexOfEmbeddedChild(Accessible* aChild); 1.447 + 1.448 + /** 1.449 + * Return number of content children/content child at index. The content 1.450 + * child is created from markup in contrast to it's never constructed by its 1.451 + * parent accessible (like treeitem accessibles for XUL trees). 1.452 + */ 1.453 + uint32_t ContentChildCount() const { return mChildren.Length(); } 1.454 + Accessible* ContentChildAt(uint32_t aIndex) const 1.455 + { return mChildren.ElementAt(aIndex); } 1.456 + 1.457 + /** 1.458 + * Return true if children were initialized. 1.459 + */ 1.460 + inline bool AreChildrenCached() const 1.461 + { return !IsChildrenFlag(eChildrenUninitialized); } 1.462 + 1.463 + /** 1.464 + * Return true if the accessible is attached to tree. 1.465 + */ 1.466 + bool IsBoundToParent() const { return !!mParent; } 1.467 + 1.468 + ////////////////////////////////////////////////////////////////////////////// 1.469 + // Miscellaneous methods 1.470 + 1.471 + /** 1.472 + * Handle accessible event, i.e. process it, notifies observers and fires 1.473 + * platform specific event. 1.474 + */ 1.475 + virtual nsresult HandleAccEvent(AccEvent* aAccEvent); 1.476 + 1.477 + /** 1.478 + * Return true if this accessible allows accessible children from anonymous subtree. 1.479 + */ 1.480 + virtual bool CanHaveAnonChildren(); 1.481 + 1.482 + /** 1.483 + * Return true if the accessible is an acceptable child. 1.484 + */ 1.485 + virtual bool IsAcceptableChild(Accessible* aPossibleChild) const { return true; } 1.486 + 1.487 + /** 1.488 + * Returns text of accessible if accessible has text role otherwise empty 1.489 + * string. 1.490 + * 1.491 + * @param aText [in] returned text of the accessible 1.492 + * @param aStartOffset [in, optional] start offset inside of the accessible, 1.493 + * if missed entire text is appended 1.494 + * @param aLength [in, optional] required length of text, if missed 1.495 + * then text form start offset till the end is appended 1.496 + */ 1.497 + virtual void AppendTextTo(nsAString& aText, uint32_t aStartOffset = 0, 1.498 + uint32_t aLength = UINT32_MAX); 1.499 + 1.500 + /** 1.501 + * Assert if child not in parent's cache if the cache was initialized at this 1.502 + * point. 1.503 + */ 1.504 + void TestChildCache(Accessible* aCachedChild) const; 1.505 + 1.506 + /** 1.507 + * Return boundaries rect relative the bounding frame. 1.508 + */ 1.509 + virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); 1.510 + 1.511 + ////////////////////////////////////////////////////////////////////////////// 1.512 + // Downcasting and types 1.513 + 1.514 + inline bool IsAbbreviation() const 1.515 + { 1.516 + return mContent->IsHTML() && 1.517 + (mContent->Tag() == nsGkAtoms::abbr || mContent->Tag() == nsGkAtoms::acronym); 1.518 + } 1.519 + 1.520 + bool IsApplication() const { return mType == eApplicationType; } 1.521 + 1.522 + bool IsAutoComplete() const { return HasGenericType(eAutoComplete); } 1.523 + 1.524 + bool IsAutoCompletePopup() const 1.525 + { return HasGenericType(eAutoCompletePopup); } 1.526 + 1.527 + bool IsButton() const { return HasGenericType(eButton); } 1.528 + 1.529 + bool IsCombobox() const { return HasGenericType(eCombobox); } 1.530 + 1.531 + bool IsDoc() const { return HasGenericType(eDocument); } 1.532 + DocAccessible* AsDoc(); 1.533 + 1.534 + bool IsHyperText() const { return HasGenericType(eHyperText); } 1.535 + HyperTextAccessible* AsHyperText(); 1.536 + 1.537 + bool IsHTMLBr() const { return mType == eHTMLBRType; } 1.538 + bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; } 1.539 + 1.540 + bool IsHTMLListItem() const { return mType == eHTMLLiType; } 1.541 + HTMLLIAccessible* AsHTMLListItem(); 1.542 + 1.543 + bool IsHTMLOptGroup() const { return mType == eHTMLOptGroupType; } 1.544 + 1.545 + bool IsHTMLTable() const { return mType == eHTMLTableType; } 1.546 + bool IsHTMLTableRow() const { return mType == eHTMLTableRowType; } 1.547 + 1.548 + bool IsImage() const { return mType == eImageType; } 1.549 + ImageAccessible* AsImage(); 1.550 + 1.551 + bool IsImageMap() const { return mType == eImageMapType; } 1.552 + HTMLImageMapAccessible* AsImageMap(); 1.553 + 1.554 + bool IsList() const { return HasGenericType(eList); } 1.555 + 1.556 + bool IsListControl() const { return HasGenericType(eListControl); } 1.557 + 1.558 + bool IsMenuButton() const { return HasGenericType(eMenuButton); } 1.559 + 1.560 + bool IsMenuPopup() const { return mType == eMenuPopupType; } 1.561 + 1.562 + bool IsProgress() const { return mType == eProgressType; } 1.563 + 1.564 + bool IsRoot() const { return mType == eRootType; } 1.565 + a11y::RootAccessible* AsRoot(); 1.566 + 1.567 + bool IsSelect() const { return HasGenericType(eSelect); } 1.568 + 1.569 + bool IsTable() const { return HasGenericType(eTable); } 1.570 + virtual TableAccessible* AsTable() { return nullptr; } 1.571 + 1.572 + bool IsTableCell() const { return HasGenericType(eTableCell); } 1.573 + virtual TableCellAccessible* AsTableCell() { return nullptr; } 1.574 + const TableCellAccessible* AsTableCell() const 1.575 + { return const_cast<Accessible*>(this)->AsTableCell(); } 1.576 + 1.577 + bool IsTableRow() const { return HasGenericType(eTableRow); } 1.578 + 1.579 + bool IsTextField() const { return mType == eHTMLTextFieldType; } 1.580 + 1.581 + bool IsTextLeaf() const { return mType == eTextLeafType; } 1.582 + TextLeafAccessible* AsTextLeaf(); 1.583 + 1.584 + bool IsXULLabel() const { return mType == eXULLabelType; } 1.585 + XULLabelAccessible* AsXULLabel(); 1.586 + 1.587 + bool IsXULListItem() const { return mType == eXULListItemType; } 1.588 + 1.589 + bool IsXULTabpanels() const { return mType == eXULTabpanelsType; } 1.590 + 1.591 + bool IsXULTree() const { return mType == eXULTreeType; } 1.592 + XULTreeAccessible* AsXULTree(); 1.593 + 1.594 + /** 1.595 + * Return true if the accessible belongs to the given accessible type. 1.596 + */ 1.597 + bool HasGenericType(AccGenericType aType) const; 1.598 + 1.599 + ////////////////////////////////////////////////////////////////////////////// 1.600 + // ActionAccessible 1.601 + 1.602 + /** 1.603 + * Return the number of actions that can be performed on this accessible. 1.604 + */ 1.605 + virtual uint8_t ActionCount(); 1.606 + 1.607 + /** 1.608 + * Return access key, such as Alt+D. 1.609 + */ 1.610 + virtual KeyBinding AccessKey() const; 1.611 + 1.612 + /** 1.613 + * Return global keyboard shortcut for default action, such as Ctrl+O for 1.614 + * Open file menuitem. 1.615 + */ 1.616 + virtual KeyBinding KeyboardShortcut() const; 1.617 + 1.618 + ////////////////////////////////////////////////////////////////////////////// 1.619 + // HyperLinkAccessible 1.620 + 1.621 + /** 1.622 + * Return true if the accessible is hyper link accessible. 1.623 + */ 1.624 + virtual bool IsLink(); 1.625 + 1.626 + /** 1.627 + * Return the start offset of the link within the parent accessible. 1.628 + */ 1.629 + virtual uint32_t StartOffset(); 1.630 + 1.631 + /** 1.632 + * Return the end offset of the link within the parent accessible. 1.633 + */ 1.634 + virtual uint32_t EndOffset(); 1.635 + 1.636 + /** 1.637 + * Return true if the link is valid (e. g. points to a valid URL). 1.638 + */ 1.639 + inline bool IsLinkValid() 1.640 + { 1.641 + NS_PRECONDITION(IsLink(), "IsLinkValid is called on not hyper link!"); 1.642 + 1.643 + // XXX In order to implement this we would need to follow every link 1.644 + // Perhaps we can get information about invalid links from the cache 1.645 + // In the mean time authors can use role="link" aria-invalid="true" 1.646 + // to force it for links they internally know to be invalid 1.647 + return (0 == (State() & mozilla::a11y::states::INVALID)); 1.648 + } 1.649 + 1.650 + /** 1.651 + * Return the number of anchors within the link. 1.652 + */ 1.653 + virtual uint32_t AnchorCount(); 1.654 + 1.655 + /** 1.656 + * Returns an anchor accessible at the given index. 1.657 + */ 1.658 + virtual Accessible* AnchorAt(uint32_t aAnchorIndex); 1.659 + 1.660 + /** 1.661 + * Returns an anchor URI at the given index. 1.662 + */ 1.663 + virtual already_AddRefed<nsIURI> AnchorURIAt(uint32_t aAnchorIndex); 1.664 + 1.665 + ////////////////////////////////////////////////////////////////////////////// 1.666 + // SelectAccessible 1.667 + 1.668 + /** 1.669 + * Return an array of selected items. 1.670 + */ 1.671 + virtual already_AddRefed<nsIArray> SelectedItems(); 1.672 + 1.673 + /** 1.674 + * Return the number of selected items. 1.675 + */ 1.676 + virtual uint32_t SelectedItemCount(); 1.677 + 1.678 + /** 1.679 + * Return selected item at the given index. 1.680 + */ 1.681 + virtual Accessible* GetSelectedItem(uint32_t aIndex); 1.682 + 1.683 + /** 1.684 + * Determine if item at the given index is selected. 1.685 + */ 1.686 + virtual bool IsItemSelected(uint32_t aIndex); 1.687 + 1.688 + /** 1.689 + * Add item at the given index the selection. Return true if success. 1.690 + */ 1.691 + virtual bool AddItemToSelection(uint32_t aIndex); 1.692 + 1.693 + /** 1.694 + * Remove item at the given index from the selection. Return if success. 1.695 + */ 1.696 + virtual bool RemoveItemFromSelection(uint32_t aIndex); 1.697 + 1.698 + /** 1.699 + * Select all items. Return true if success. 1.700 + */ 1.701 + virtual bool SelectAll(); 1.702 + 1.703 + /** 1.704 + * Unselect all items. Return true if success. 1.705 + */ 1.706 + virtual bool UnselectAll(); 1.707 + 1.708 + ////////////////////////////////////////////////////////////////////////////// 1.709 + // Value (numeric value interface) 1.710 + 1.711 + virtual double MaxValue() const; 1.712 + virtual double MinValue() const; 1.713 + virtual double CurValue() const; 1.714 + virtual double Step() const; 1.715 + virtual bool SetCurValue(double aValue); 1.716 + 1.717 + ////////////////////////////////////////////////////////////////////////////// 1.718 + // Widgets 1.719 + 1.720 + /** 1.721 + * Return true if accessible is a widget, i.e. control or accessible that 1.722 + * manages its items. Note, being a widget the accessible may be a part of 1.723 + * composite widget. 1.724 + */ 1.725 + virtual bool IsWidget() const; 1.726 + 1.727 + /** 1.728 + * Return true if the widget is active, i.e. has a focus within it. 1.729 + */ 1.730 + virtual bool IsActiveWidget() const; 1.731 + 1.732 + /** 1.733 + * Return true if the widget has items and items are operable by user and 1.734 + * can be activated. 1.735 + */ 1.736 + virtual bool AreItemsOperable() const; 1.737 + 1.738 + /** 1.739 + * Return the current item of the widget, i.e. an item that has or will have 1.740 + * keyboard focus when widget gets active. 1.741 + */ 1.742 + virtual Accessible* CurrentItem(); 1.743 + 1.744 + /** 1.745 + * Set the current item of the widget. 1.746 + */ 1.747 + virtual void SetCurrentItem(Accessible* aItem); 1.748 + 1.749 + /** 1.750 + * Return container widget this accessible belongs to. 1.751 + */ 1.752 + virtual Accessible* ContainerWidget() const; 1.753 + 1.754 + /** 1.755 + * Return the localized string for the given key. 1.756 + */ 1.757 + static void TranslateString(const nsString& aKey, nsAString& aStringOut); 1.758 + 1.759 + /** 1.760 + * Return true if the accessible is defunct. 1.761 + */ 1.762 + bool IsDefunct() const { return mStateFlags & eIsDefunct; } 1.763 + 1.764 + /** 1.765 + * Return true if the accessible is no longer in the document. 1.766 + */ 1.767 + bool IsInDocument() const { return !(mStateFlags & eIsNotInDocument); } 1.768 + 1.769 + /** 1.770 + * Return true if the accessible should be contained by document node map. 1.771 + */ 1.772 + bool IsNodeMapEntry() const 1.773 + { return HasOwnContent() && !(mStateFlags & eNotNodeMapEntry); } 1.774 + 1.775 + /** 1.776 + * Return true if the accessible's group info needs to be updated. 1.777 + */ 1.778 + inline bool HasDirtyGroupInfo() const { return mStateFlags & eGroupInfoDirty; } 1.779 + 1.780 + /** 1.781 + * Return true if the accessible has associated DOM content. 1.782 + */ 1.783 + bool HasOwnContent() const 1.784 + { return mContent && !(mStateFlags & eSharedNode); } 1.785 + 1.786 + /** 1.787 + * Return true if the accessible has a numeric value. 1.788 + */ 1.789 + bool HasNumericValue() const; 1.790 + 1.791 + /** 1.792 + * Return true if the accessible state change is processed by handling proper 1.793 + * DOM UI event, if otherwise then false. For example, HTMLCheckboxAccessible 1.794 + * process nsIDocumentObserver::ContentStateChanged instead 1.795 + * 'CheckboxStateChange' event. 1.796 + */ 1.797 + bool NeedsDOMUIEvent() const 1.798 + { return !(mStateFlags & eIgnoreDOMUIEvent); } 1.799 + 1.800 + /** 1.801 + * Return true if this accessible has a parent whose name depends on this 1.802 + * accessible. 1.803 + */ 1.804 + bool HasNameDependentParent() const 1.805 + { return mContextFlags & eHasNameDependentParent; } 1.806 + 1.807 +protected: 1.808 + 1.809 + /** 1.810 + * Return the accessible name provided by native markup. It doesn't take 1.811 + * into account ARIA markup used to specify the name. 1.812 + */ 1.813 + virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName); 1.814 + 1.815 + /** 1.816 + * Return object attributes provided by native markup. It doesn't take into 1.817 + * account ARIA. 1.818 + */ 1.819 + virtual already_AddRefed<nsIPersistentProperties> NativeAttributes(); 1.820 + 1.821 + ////////////////////////////////////////////////////////////////////////////// 1.822 + // Initializing, cache and tree traverse methods 1.823 + 1.824 + /** 1.825 + * Destroy the object. 1.826 + */ 1.827 + void LastRelease(); 1.828 + 1.829 + /** 1.830 + * Cache accessible children. 1.831 + */ 1.832 + virtual void CacheChildren(); 1.833 + 1.834 + /** 1.835 + * Set accessible parent and index in parent. 1.836 + */ 1.837 + virtual void BindToParent(Accessible* aParent, uint32_t aIndexInParent); 1.838 + virtual void UnbindFromParent(); 1.839 + 1.840 + /** 1.841 + * Return sibling accessible at the given offset. 1.842 + */ 1.843 + virtual Accessible* GetSiblingAtOffset(int32_t aOffset, 1.844 + nsresult *aError = nullptr) const; 1.845 + 1.846 + /** 1.847 + * Flags used to describe the state and type of children. 1.848 + */ 1.849 + enum ChildrenFlags { 1.850 + eChildrenUninitialized = 0, // children aren't initialized 1.851 + eMixedChildren = 1 << 0, // text leaf children are presented 1.852 + eEmbeddedChildren = 1 << 1, // all children are embedded objects 1.853 + 1.854 + eLastChildrenFlag = eEmbeddedChildren 1.855 + }; 1.856 + 1.857 + /** 1.858 + * Return true if the children flag is set. 1.859 + */ 1.860 + bool IsChildrenFlag(ChildrenFlags aFlag) const 1.861 + { return static_cast<ChildrenFlags>(mChildrenFlags) == aFlag; } 1.862 + 1.863 + /** 1.864 + * Set children flag. 1.865 + */ 1.866 + void SetChildrenFlag(ChildrenFlags aFlag) { mChildrenFlags = aFlag; } 1.867 + 1.868 + /** 1.869 + * Flags used to describe the state of this accessible. 1.870 + * @note keep these flags in sync with ChildrenFlags 1.871 + */ 1.872 + enum StateFlags { 1.873 + eIsDefunct = 1 << 0, // accessible is defunct 1.874 + eIsNotInDocument = 1 << 1, // accessible is not in document 1.875 + eSharedNode = 1 << 2, // accessible shares DOM node from another accessible 1.876 + eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map 1.877 + eHasNumericValue = 1 << 4, // accessible has a numeric value 1.878 + eGroupInfoDirty = 1 << 5, // accessible needs to update group info 1.879 + eIgnoreDOMUIEvent = 1 << 6, // don't process DOM UI events for a11y events 1.880 + 1.881 + eLastStateFlag = eIgnoreDOMUIEvent 1.882 + }; 1.883 + 1.884 + /** 1.885 + * Flags used for contextual information about the accessible. 1.886 + */ 1.887 + enum ContextFlags { 1.888 + eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible. 1.889 + 1.890 + eLastContextFlag = eHasNameDependentParent 1.891 + }; 1.892 + 1.893 +protected: 1.894 + 1.895 + ////////////////////////////////////////////////////////////////////////////// 1.896 + // Miscellaneous helpers 1.897 + 1.898 + /** 1.899 + * Return ARIA role (helper method). 1.900 + */ 1.901 + mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole); 1.902 + 1.903 + ////////////////////////////////////////////////////////////////////////////// 1.904 + // Name helpers 1.905 + 1.906 + /** 1.907 + * Returns the accessible name specified by ARIA. 1.908 + */ 1.909 + void ARIAName(nsString& aName); 1.910 + 1.911 + /** 1.912 + * Return the name for XUL element. 1.913 + */ 1.914 + static void XULElmName(DocAccessible* aDocument, 1.915 + nsIContent* aElm, nsString& aName); 1.916 + 1.917 + // helper method to verify frames 1.918 + static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut); 1.919 + 1.920 + ////////////////////////////////////////////////////////////////////////////// 1.921 + // Action helpers 1.922 + 1.923 + /** 1.924 + * Prepares click action that will be invoked in timeout. 1.925 + * 1.926 + * @note DoCommand() prepares an action in timeout because when action 1.927 + * command opens a modal dialog/window, it won't return until the 1.928 + * dialog/window is closed. If executing action command directly in 1.929 + * nsIAccessible::DoAction() method, it will block AT tools (e.g. GOK) that 1.930 + * invoke action of mozilla accessibles direclty (see bug 277888 for details). 1.931 + * 1.932 + * @param aContent [in, optional] element to click 1.933 + * @param aActionIndex [in, optional] index of accessible action 1.934 + */ 1.935 + void DoCommand(nsIContent *aContent = nullptr, uint32_t aActionIndex = 0); 1.936 + 1.937 + /** 1.938 + * Dispatch click event. 1.939 + */ 1.940 + virtual void DispatchClickEvent(nsIContent *aContent, uint32_t aActionIndex); 1.941 + 1.942 + ////////////////////////////////////////////////////////////////////////////// 1.943 + // Helpers 1.944 + 1.945 + /** 1.946 + * Get the container node for an atomic region, defined by aria-atomic="true" 1.947 + * @return the container node 1.948 + */ 1.949 + nsIContent* GetAtomicRegion() const; 1.950 + 1.951 + /** 1.952 + * Return numeric value of the given ARIA attribute, NaN if not applicable. 1.953 + * 1.954 + * @param aARIAProperty [in] the ARIA property we're using 1.955 + * @return a numeric value 1.956 + */ 1.957 + double AttrNumericValue(nsIAtom* aARIAAttr) const; 1.958 + 1.959 + /** 1.960 + * Return the action rule based on ARIA enum constants EActionRule 1.961 + * (see ARIAMap.h). Used by ActionCount() and GetActionName(). 1.962 + */ 1.963 + uint32_t GetActionRule(); 1.964 + 1.965 + /** 1.966 + * Return group info. 1.967 + */ 1.968 + AccGroupInfo* GetGroupInfo(); 1.969 + 1.970 + /** 1.971 + * Set dirty state of the accessible's group info. 1.972 + */ 1.973 + inline void SetDirtyGroupInfo(bool aIsDirty) 1.974 + { 1.975 + if (aIsDirty) 1.976 + mStateFlags |= eGroupInfoDirty; 1.977 + else 1.978 + mStateFlags &= ~eGroupInfoDirty; 1.979 + } 1.980 + 1.981 + /** 1.982 + * Flag all children group info as needing to be updated. 1.983 + */ 1.984 + void InvalidateChildrenGroupInfo(); 1.985 + 1.986 + // Data Members 1.987 + nsCOMPtr<nsIContent> mContent; 1.988 + DocAccessible* mDoc; 1.989 + 1.990 + nsRefPtr<Accessible> mParent; 1.991 + nsTArray<nsRefPtr<Accessible> > mChildren; 1.992 + int32_t mIndexInParent; 1.993 + 1.994 + static const uint8_t kChildrenFlagsBits = 2; 1.995 + static const uint8_t kStateFlagsBits = 7; 1.996 + static const uint8_t kContextFlagsBits = 1; 1.997 + static const uint8_t kTypeBits = 6; 1.998 + static const uint8_t kGenericTypesBits = 13; 1.999 + 1.1000 + /** 1.1001 + * Keep in sync with ChildrenFlags, StateFlags, ContextFlags, and AccTypes. 1.1002 + */ 1.1003 + uint32_t mChildrenFlags : kChildrenFlagsBits; 1.1004 + uint32_t mStateFlags : kStateFlagsBits; 1.1005 + uint32_t mContextFlags : kContextFlagsBits; 1.1006 + uint32_t mType : kTypeBits; 1.1007 + uint32_t mGenericTypes : kGenericTypesBits; 1.1008 + 1.1009 + void StaticAsserts() const; 1.1010 + 1.1011 + friend class DocAccessible; 1.1012 + 1.1013 + nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector; 1.1014 + int32_t mIndexOfEmbeddedChild; 1.1015 + friend class EmbeddedObjCollector; 1.1016 + 1.1017 + nsAutoPtr<AccGroupInfo> mGroupInfo; 1.1018 + friend class AccGroupInfo; 1.1019 + 1.1020 + /** 1.1021 + * Non-null indicates author-supplied role; possibly state & value as well 1.1022 + */ 1.1023 + nsRoleMapEntry* mRoleMapEntry; 1.1024 + 1.1025 +private: 1.1026 + Accessible() MOZ_DELETE; 1.1027 + Accessible(const Accessible&) MOZ_DELETE; 1.1028 + Accessible& operator =(const Accessible&) MOZ_DELETE; 1.1029 + 1.1030 +}; 1.1031 + 1.1032 +NS_DEFINE_STATIC_IID_ACCESSOR(Accessible, 1.1033 + NS_ACCESSIBLE_IMPL_IID) 1.1034 + 1.1035 + 1.1036 +/** 1.1037 + * Represent key binding associated with accessible (such as access key and 1.1038 + * global keyboard shortcuts). 1.1039 + */ 1.1040 +class KeyBinding 1.1041 +{ 1.1042 +public: 1.1043 + /** 1.1044 + * Modifier mask values. 1.1045 + */ 1.1046 + static const uint32_t kShift = 1; 1.1047 + static const uint32_t kControl = 2; 1.1048 + static const uint32_t kAlt = 4; 1.1049 + static const uint32_t kMeta = 8; 1.1050 + static const uint32_t kOS = 16; 1.1051 + 1.1052 + KeyBinding() : mKey(0), mModifierMask(0) {} 1.1053 + KeyBinding(uint32_t aKey, uint32_t aModifierMask) : 1.1054 + mKey(aKey), mModifierMask(aModifierMask) {} 1.1055 + 1.1056 + inline bool IsEmpty() const { return !mKey; } 1.1057 + inline uint32_t Key() const { return mKey; } 1.1058 + inline uint32_t ModifierMask() const { return mModifierMask; } 1.1059 + 1.1060 + enum Format { 1.1061 + ePlatformFormat, 1.1062 + eAtkFormat 1.1063 + }; 1.1064 + 1.1065 + /** 1.1066 + * Return formatted string for this key binding depending on the given format. 1.1067 + */ 1.1068 + inline void ToString(nsAString& aValue, 1.1069 + Format aFormat = ePlatformFormat) const 1.1070 + { 1.1071 + aValue.Truncate(); 1.1072 + AppendToString(aValue, aFormat); 1.1073 + } 1.1074 + inline void AppendToString(nsAString& aValue, 1.1075 + Format aFormat = ePlatformFormat) const 1.1076 + { 1.1077 + if (mKey) { 1.1078 + if (aFormat == ePlatformFormat) 1.1079 + ToPlatformFormat(aValue); 1.1080 + else 1.1081 + ToAtkFormat(aValue); 1.1082 + } 1.1083 + } 1.1084 + 1.1085 +private: 1.1086 + void ToPlatformFormat(nsAString& aValue) const; 1.1087 + void ToAtkFormat(nsAString& aValue) const; 1.1088 + 1.1089 + uint32_t mKey; 1.1090 + uint32_t mModifierMask; 1.1091 +}; 1.1092 + 1.1093 +} // namespace a11y 1.1094 +} // namespace mozilla 1.1095 + 1.1096 +#endif