1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_a11y_RemoteAccessible_h
8 #define mozilla_a11y_RemoteAccessible_h
10 #include "mozilla/a11y/Accessible.h"
11 #include "mozilla/a11y/CacheConstants.h"
12 #include "mozilla/a11y/HyperTextAccessibleBase.h"
13 #include "mozilla/a11y/Role.h"
14 #include "AccAttributes.h"
15 #include "nsIAccessibleText.h"
16 #include "nsIAccessibleTypes.h"
19 #include "LocalAccessible.h"
25 class DocAccessibleParent
;
26 class RemoteAccessible
;
27 enum class RelationType
;
30 * The class for an accessibility tree node that originated in the parent
33 class RemoteAccessible
: public Accessible
, public HyperTextAccessibleBase
{
35 virtual ~RemoteAccessible() {
36 MOZ_ASSERT(!mWrapper
);
37 MOZ_COUNT_DTOR(RemoteAccessible
);
40 virtual bool IsRemote() const override
{ return true; }
42 void AddChildAt(uint32_t aIdx
, RemoteAccessible
* aChild
) {
43 mChildren
.InsertElementAt(aIdx
, aChild
);
45 InvalidateCachedHyperTextOffsets();
49 virtual uint32_t ChildCount() const override
{ return mChildren
.Length(); }
50 RemoteAccessible
* RemoteChildAt(uint32_t aIdx
) const {
51 return mChildren
.SafeElementAt(aIdx
);
53 RemoteAccessible
* RemoteFirstChild() const {
54 return mChildren
.Length() ? mChildren
[0] : nullptr;
56 RemoteAccessible
* RemoteLastChild() const {
57 return mChildren
.Length() ? mChildren
[mChildren
.Length() - 1] : nullptr;
59 RemoteAccessible
* RemotePrevSibling() const {
61 // The normal code path doesn't work for documents because the parent
62 // might be a local OuterDoc, but IndexInParent() will return 1.
63 // A document is always a single child of an OuterDoc anyway.
66 int32_t idx
= IndexInParent();
68 return nullptr; // No parent.
70 return idx
> 0 ? RemoteParent()->mChildren
[idx
- 1] : nullptr;
72 RemoteAccessible
* RemoteNextSibling() const {
74 // The normal code path doesn't work for documents because the parent
75 // might be a local OuterDoc, but IndexInParent() will return 1.
76 // A document is always a single child of an OuterDoc anyway.
79 int32_t idx
= IndexInParent();
81 return nullptr; // No parent.
84 size_t newIdx
= idx
+ 1;
85 return newIdx
< RemoteParent()->mChildren
.Length()
86 ? RemoteParent()->mChildren
[newIdx
]
90 // Accessible hierarchy method overrides
92 virtual Accessible
* Parent() const override
{ return RemoteParent(); }
94 virtual Accessible
* ChildAt(uint32_t aIndex
) const override
{
95 return RemoteChildAt(aIndex
);
98 virtual Accessible
* NextSibling() const override
{
99 return RemoteNextSibling();
102 virtual Accessible
* PrevSibling() const override
{
103 return RemotePrevSibling();
106 // XXX evaluate if this is fast enough.
107 virtual int32_t IndexInParent() const override
{
108 RemoteAccessible
* parent
= RemoteParent();
112 return parent
->mChildren
.IndexOf(
113 static_cast<const RemoteAccessible
*>(this));
115 virtual uint32_t EmbeddedChildCount() override
;
116 virtual int32_t IndexOfEmbeddedChild(Accessible
* aChild
) override
;
117 virtual Accessible
* EmbeddedChildAt(uint32_t aChildIdx
) override
;
121 void SetChildDoc(DocAccessibleParent
* aChildDoc
);
122 void ClearChildDoc(DocAccessibleParent
* aChildDoc
);
125 * Remove The given child.
127 void RemoveChild(RemoteAccessible
* aChild
) {
128 mChildren
.RemoveElement(aChild
);
130 InvalidateCachedHyperTextOffsets();
135 * Return the proxy for the parent of the wrapped accessible.
137 RemoteAccessible
* RemoteParent() const;
139 LocalAccessible
* OuterDocOfRemoteBrowser() const;
142 * Get the role of the accessible we're proxying.
144 virtual role
Role() const override
{ return mRole
; }
147 * Return true if this is an embedded object.
149 bool IsEmbeddedObject() const { return !IsText(); }
151 virtual bool IsLink() const override
{
153 // XXX: HTML links always return true for IsLink.
161 if (Accessible
* parent
= Parent()) {
162 return parent
->IsHyperText();
168 virtual bool HasNumericValue() const override
{
169 // XXX: We combine the aria and native "has numeric value" field
170 // when we serialize the local accessible into eNumericValue.
171 return HasGenericType(eNumericValue
);
174 // Methods that potentially access a cache.
176 virtual ENameValueFlag
Name(nsString
& aName
) const override
;
177 virtual void Description(nsString
& aDescription
) const override
;
178 virtual void Value(nsString
& aValue
) const override
;
180 virtual double CurValue() const override
;
181 virtual double MinValue() const override
;
182 virtual double MaxValue() const override
;
183 virtual double Step() const override
;
184 virtual bool SetCurValue(double aValue
) override
;
186 virtual Accessible
* ChildAtPoint(
187 int32_t aX
, int32_t aY
,
188 LocalAccessible::EWhichChildAtPoint aWhichChild
) override
;
190 virtual LayoutDeviceIntRect
Bounds() const override
;
192 virtual nsRect
BoundsInAppUnits() const override
;
194 virtual Relation
RelationByType(RelationType aType
) const override
;
196 virtual uint64_t State() override
;
198 virtual already_AddRefed
<AccAttributes
> Attributes() override
;
200 virtual nsAtom
* TagName() const override
;
202 virtual already_AddRefed
<nsAtom
> InputType() const override
;
204 virtual already_AddRefed
<nsAtom
> DisplayStyle() const override
;
206 virtual float Opacity() const override
;
208 virtual void LiveRegionAttributes(nsAString
* aLive
, nsAString
* aRelevant
,
209 Maybe
<bool>* aAtomic
,
210 nsAString
* aBusy
) const override
;
212 virtual Maybe
<bool> ARIASelected() const override
;
214 virtual uint8_t ActionCount() const override
;
216 virtual void ActionNameAt(uint8_t aIndex
, nsAString
& aName
) override
;
218 virtual bool DoAction(uint8_t aIndex
) const override
;
220 virtual KeyBinding
AccessKey() const override
;
222 virtual void SelectionRanges(nsTArray
<TextRange
>* aRanges
) const override
;
224 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual bool RemoveFromSelection(
225 int32_t aSelectionNum
) override
;
227 virtual Maybe
<int32_t> GetIntARIAAttr(nsAtom
* aAttrName
) const override
;
229 virtual void Language(nsAString
& aLocale
) override
;
231 //////////////////////////////////////////////////////////////////////////////
232 // EditableTextAccessible
234 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void ReplaceText(
235 const nsAString
& aText
) override
;
236 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void InsertText(
237 const nsAString
& aText
, int32_t aPosition
) override
;
238 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void CopyText(int32_t aStartPos
,
239 int32_t aEndPos
) override
;
240 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void CutText(int32_t aStartPos
,
241 int32_t aEndPos
) override
;
242 MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void DeleteText(int32_t aStartPos
,
243 int32_t aEndPos
) override
;
244 MOZ_CAN_RUN_SCRIPT
virtual void PasteText(int32_t aPosition
) override
;
246 //////////////////////////////////////////////////////////////////////////////
249 virtual void SelectedItems(nsTArray
<Accessible
*>* aItems
) override
;
251 virtual uint32_t SelectedItemCount() override
;
253 virtual Accessible
* GetSelectedItem(uint32_t aIndex
) override
;
255 virtual bool IsItemSelected(uint32_t aIndex
) override
;
257 virtual bool AddItemToSelection(uint32_t aIndex
) override
;
259 virtual bool RemoveItemFromSelection(uint32_t aIndex
) override
;
261 virtual bool SelectAll() override
;
263 virtual bool UnselectAll() override
;
265 virtual void TakeSelection() override
;
267 virtual void SetSelected(bool aSelect
) override
;
269 // Methods that interact with content.
271 virtual void TakeFocus() const override
;
272 virtual void ScrollTo(uint32_t aHow
) const override
;
273 virtual void SetCaretOffset(int32_t aOffset
) override
;
276 * Allow the platform to store a pointers worth of data on us.
278 uintptr_t GetWrapper() const { return mWrapper
; }
279 void SetWrapper(uintptr_t aWrapper
) { mWrapper
= aWrapper
; }
281 virtual uint64_t ID() const override
{ return mID
; }
284 * Return the document containing this proxy, or the proxy itself if it is a
287 DocAccessibleParent
* Document() const { return mDoc
; }
289 DocAccessibleParent
* AsDoc() const { return IsDoc() ? mDoc
: nullptr; }
291 void ApplyCache(CacheUpdateType aUpdateType
, AccAttributes
* aFields
);
293 void UpdateStateCache(uint64_t aState
, bool aEnabled
) {
294 if (aState
& kRemoteCalculatedStates
) {
300 mCachedFields
->GetAttribute
<uint64_t>(CacheKey::State
)) {
304 mCachedFields
= new AccAttributes();
311 mCachedFields
->SetAttribute(CacheKey::State
, state
);
314 void InvalidateGroupInfo();
316 virtual void AppendTextTo(nsAString
& aText
, uint32_t aStartOffset
= 0,
317 uint32_t aLength
= UINT32_MAX
) override
;
319 virtual bool TableIsProbablyForLayout();
322 * Iterates through each atom in kRelationTypeAtoms, checking to see
323 * if it is present in aFields. If it is present (or if aFields contains
324 * a DeleteEntry() for this atom) and mCachedFields is initialized,
325 * fetches the old rel targets and removes their existing reverse relations
326 * stored in mReverseRelations.
327 * Returns an array of bools where the ith array entry corresponds
328 * to whether or not the rel at the ith entry of kRelationTypeAtoms
329 * requires a post-processing update.
331 nsTArray
<bool> PreProcessRelations(AccAttributes
* aFields
);
334 * Takes in the array returned from PreProcessRelations.
335 * For each entry requiring an update, fetches the new relation
336 * targets stored in mCachedFields and appropriately
337 * updates their reverse relations in mReverseRelations.
339 void PostProcessRelations(const nsTArray
<bool>& aToUpdate
);
342 * This method is called during shutdown, before we clear our
343 * reverse rel map from the document's mReverseRelations cache.
344 * Here, we traverse our reverse relations, removing our ID from
345 * the corresponding forward relation's target list. This ensures
346 * the stored forward relations do not reference defunct accessibles.
348 void PruneRelationsOnShutdown();
350 uint32_t GetCachedTextLength();
351 Maybe
<const nsTArray
<int32_t>&> GetCachedTextLines();
352 nsRect
GetCachedCharRect(int32_t aOffset
);
353 RefPtr
<const AccAttributes
> GetCachedTextAttributes();
354 RefPtr
<const AccAttributes
> GetCachedARIAAttributes() const;
356 nsString
GetCachedHTMLNameAttribute() const;
358 virtual HyperTextAccessibleBase
* AsHyperTextBase() override
{
359 return IsHyperText() ? static_cast<HyperTextAccessibleBase
*>(this)
363 virtual TableAccessible
* AsTable() override
;
364 virtual TableCellAccessible
* AsTableCell() override
;
366 virtual void DOMNodeID(nsString
& aID
) const override
;
368 virtual void ScrollToPoint(uint32_t aScrollType
, int32_t aX
,
369 int32_t aY
) override
;
372 void Announce(const nsString
& aAnnouncement
, uint16_t aPriority
);
373 #endif // !defined(XP_WIN)
375 // HyperTextAccessibleBase
376 virtual already_AddRefed
<AccAttributes
> DefaultTextAttributes() override
;
378 virtual void ScrollSubstringToPoint(int32_t aStartOffset
, int32_t aEndOffset
,
379 uint32_t aCoordinateType
, int32_t aX
,
380 int32_t aY
) override
;
383 * Invalidate cached HyperText offsets. This should be called whenever a
384 * child is added or removed or the text of a text leaf child is changed.
385 * Although GetChildOffset can either fully or partially invalidate the
386 * offsets cache, calculating which offset to invalidate is not worthwhile
387 * because a client might not even query offsets. This is in contrast to
388 * LocalAccessible, where the offsets are always needed to fire text change
389 * events. For RemoteAccessible, it's cheaper overall to just rebuild the
390 * offsets cache when a client next needs it.
392 void InvalidateCachedHyperTextOffsets() {
394 mCachedFields
->Remove(CacheKey::HyperTextOffsets
);
398 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
);
399 virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
);
402 RemoteAccessible(uint64_t aID
, DocAccessibleParent
* aDoc
, role aRole
,
403 AccType aType
, AccGenericType aGenericTypes
,
404 uint8_t aRoleMapEntryIndex
)
405 : Accessible(aType
, aGenericTypes
, aRoleMapEntryIndex
),
410 mCachedFields(nullptr),
412 MOZ_COUNT_CTOR(RemoteAccessible
);
415 explicit RemoteAccessible(DocAccessibleParent
* aThisAsDoc
)
421 mCachedFields(nullptr),
422 mRole(roles::DOCUMENT
) {
423 mGenericTypes
= eDocument
| eHyperText
;
424 MOZ_COUNT_CTOR(RemoteAccessible
);
428 void SetParent(RemoteAccessible
* aParent
);
429 Maybe
<nsRect
> RetrieveCachedBounds() const;
430 bool ApplyTransform(nsRect
& aCumulativeBounds
) const;
431 bool ApplyScrollOffset(nsRect
& aBounds
) const;
432 void ApplyCrossDocOffset(nsRect
& aBounds
) const;
433 LayoutDeviceIntRect
BoundsWithOffset(
434 Maybe
<nsRect
> aOffset
, bool aBoundsAreForHittesting
= false) const;
435 bool IsFixedPos() const;
436 bool IsOverflowHidden() const;
439 * Returns true if an accessible's frame has no scrollable overflow, and
441 * Does not return true for partially clipped accessibles.
443 bool IsClipped() const;
446 * Checks if our hittesting match has any clipped children and, if so
447 * descends it and subsequent TEXT_CONTAINERs in search of a text leaf.
448 * We do this because some sites use clipping to hide text that is only
449 * visible to a11y, while displaying a visual version of the same text on
450 * the web page. We want a hittest of the visible text to resolve to the
451 * hidden, a11y-only text node.
453 RemoteAccessible
* DoFuzzyHittesting();
455 // This function is used exclusively for hit testing.
456 bool ContainsPoint(int32_t aX
, int32_t aY
);
458 virtual void ARIAGroupPosition(int32_t* aLevel
, int32_t* aSetSize
,
459 int32_t* aPosInSet
) const override
;
461 virtual AccGroupInfo
* GetGroupInfo() const override
;
463 virtual AccGroupInfo
* GetOrCreateGroupInfo() override
;
465 virtual void GetPositionAndSetSize(int32_t* aPosInSet
,
466 int32_t* aSetSize
) override
;
468 virtual bool HasPrimaryAction() const override
;
470 nsAtom
* GetPrimaryAction() const;
472 virtual nsTArray
<int32_t>& GetCachedHyperTextOffsets() override
;
476 static const uintptr_t kNoParent
= UINTPTR_MAX
;
478 friend DocAccessibleParent
;
479 friend TextLeafPoint
;
480 friend HyperTextAccessibleBase
;
481 friend class xpcAccessible
;
482 friend class CachedTableCellAccessible
;
484 friend class sdnAccessible
;
487 nsTArray
<RemoteAccessible
*> mChildren
;
488 DocAccessibleParent
* mDoc
;
493 virtual const Accessible
* Acc() const override
{ return this; }
495 RefPtr
<AccAttributes
> mCachedFields
;
497 // XXX DocAccessibleParent gets to change this to change the role of
502 ////////////////////////////////////////////////////////////////////////////////
503 // RemoteAccessible downcasting method
505 inline RemoteAccessible
* Accessible::AsRemote() {
506 return IsRemote() ? static_cast<RemoteAccessible
*>(this) : nullptr;
510 } // namespace mozilla