Bug 1891340 - Part 1: Add parameters to customize the before and after icon tints...
[gecko.git] / accessible / generic / DocAccessible.h
blob791d09661e45e851d11a6ccdcc5f9624de89da3e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_a11y_DocAccessible_h__
7 #define mozilla_a11y_DocAccessible_h__
9 #include "HyperTextAccessible.h"
10 #include "AccEvent.h"
12 #include "nsClassHashtable.h"
13 #include "nsTHashMap.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsIDocumentObserver.h"
16 #include "nsITimer.h"
17 #include "nsTHashSet.h"
18 #include "nsWeakReference.h"
20 const uint32_t kDefaultCacheLength = 128;
22 namespace mozilla {
24 class EditorBase;
25 class PresShell;
27 namespace dom {
28 class Document;
31 namespace a11y {
33 class DocManager;
34 class NotificationController;
35 class DocAccessibleChild;
36 class RelatedAccIterator;
37 template <class Class, class... Args>
38 class TNotification;
40 /**
41 * An accessibility tree node that originated in a content process and
42 * represents a document. Tabs, in-process iframes, and out-of-process iframes
43 * all use this class to represent the doc they contain.
45 class DocAccessible : public HyperTextAccessible,
46 public nsIDocumentObserver,
47 public nsSupportsWeakReference {
48 NS_DECL_ISUPPORTS_INHERITED
49 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocAccessible, LocalAccessible)
51 protected:
52 typedef mozilla::dom::Document Document;
54 public:
55 DocAccessible(Document* aDocument, PresShell* aPresShell);
57 // nsIDocumentObserver
58 NS_DECL_NSIDOCUMENTOBSERVER
60 // LocalAccessible
61 virtual void Init();
62 virtual void Shutdown() override;
63 virtual nsIFrame* GetFrame() const override;
64 virtual nsINode* GetNode() const override;
65 Document* DocumentNode() const { return mDocumentNode; }
67 virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) const override;
68 virtual void Description(nsString& aDescription) const override;
69 virtual Accessible* FocusedChild() override;
70 virtual mozilla::a11y::role NativeRole() const override;
71 virtual uint64_t NativeState() const override;
72 virtual uint64_t NativeInteractiveState() const override;
73 virtual bool NativelyUnavailable() const override;
74 virtual void ApplyARIAState(uint64_t* aState) const override;
76 virtual void TakeFocus() const override;
78 #ifdef A11Y_LOG
79 virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
80 #endif
82 virtual nsRect RelativeBounds(nsIFrame** aRelativeFrame) const override;
84 // ActionAccessible
85 virtual bool HasPrimaryAction() const override;
86 virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
88 // HyperTextAccessible
89 virtual already_AddRefed<EditorBase> GetEditor() const override;
91 // DocAccessible
93 /**
94 * Return document URL.
96 void URL(nsAString& aURL) const;
98 /**
99 * Return DOM document title.
101 void Title(nsString& aTitle) const;
104 * Return DOM document mime type.
106 void MimeType(nsAString& aType) const;
108 * Return DOM document type.
110 void DocType(nsAString& aType) const;
113 * Adds an entry to queued cache updates indicating aAcc requires
114 * a cache update on domain aNewDomain. If we've already queued an update
115 * for aAcc, aNewDomain is or'd with the existing domain(s)
116 * and the map is updated. Otherwise, the entry is simply inserted.
117 * This function also schedules processing on the controller.
118 * Note that this CANNOT be used for anything which fires events, since events
119 * must be fired after their associated cache update.
121 void QueueCacheUpdate(LocalAccessible* aAcc, uint64_t aNewDomain);
124 * Walks the dependent ids and elements maps for the given accessible and
125 * queues a CacheDomain::Relations cache update fore each related acc.
126 * We call this when we observe an ID mutation or when an acc is bound
127 * to its document.
129 void QueueCacheUpdateForDependentRelations(LocalAccessible* aAcc);
132 * Returns true if the instance has shutdown.
134 bool HasShutdown() const { return !mPresShell; }
137 * Return presentation shell for this document accessible.
139 PresShell* PresShellPtr() const {
140 MOZ_DIAGNOSTIC_ASSERT(!HasShutdown());
141 return mPresShell;
145 * Return the presentation shell's context.
147 nsPresContext* PresContext() const;
150 * Return true if associated DOM document was loaded and isn't unloading.
152 bool IsContentLoaded() const;
154 bool IsHidden() const;
156 void SetViewportCacheDirty(bool aDirty) { mViewportCacheDirty = aDirty; }
159 * Document load states.
161 enum LoadState {
162 // initial tree construction is pending
163 eTreeConstructionPending = 0,
164 // initial tree construction done
165 eTreeConstructed = 1,
166 // DOM document is loaded.
167 eDOMLoaded = 1 << 1,
168 // document is ready
169 eReady = eTreeConstructed | eDOMLoaded,
170 // document and all its subdocuments are ready
171 eCompletelyLoaded = eReady | 1 << 2
175 * Return true if the document has given document state.
177 bool HasLoadState(LoadState aState) const {
178 return (mLoadState & static_cast<uint32_t>(aState)) ==
179 static_cast<uint32_t>(aState);
183 * Return a native window handler or pointer depending on platform.
185 virtual void* GetNativeWindow() const;
188 * Return the parent document.
190 DocAccessible* ParentDocument() const {
191 return mParent ? mParent->Document() : nullptr;
195 * Return the child document count.
197 uint32_t ChildDocumentCount() const { return mChildDocuments.Length(); }
200 * Return the child document at the given index.
202 DocAccessible* GetChildDocumentAt(uint32_t aIndex) const {
203 return mChildDocuments.SafeElementAt(aIndex, nullptr);
207 * Fire accessible event asynchronously.
209 void FireDelayedEvent(AccEvent* aEvent);
210 void FireDelayedEvent(uint32_t aEventType, LocalAccessible* aTarget);
211 void FireEventsOnInsertion(LocalAccessible* aContainer);
214 * Fire value change event on the given accessible if applicable.
216 void MaybeNotifyOfValueChange(LocalAccessible* aAccessible);
219 * Get/set the anchor jump.
221 LocalAccessible* AnchorJump() {
222 return GetAccessibleOrContainer(mAnchorJumpElm);
225 void SetAnchorJump(nsIContent* aTargetNode) { mAnchorJumpElm = aTargetNode; }
228 * Bind the child document to the tree.
230 void BindChildDocument(DocAccessible* aDocument);
233 * Process the generic notification.
235 * @note The caller must guarantee that the given instance still exists when
236 * notification is processed.
237 * @see NotificationController::HandleNotification
239 template <class Class, class... Args>
240 void HandleNotification(
241 Class* aInstance,
242 typename TNotification<Class, Args...>::Callback aMethod, Args*... aArgs);
245 * Return the cached accessible by the given DOM node if it's in subtree of
246 * this document accessible or the document accessible itself, otherwise null.
248 * @return the accessible object
250 LocalAccessible* GetAccessible(nsINode* aNode) const;
253 * Return an accessible for the given node even if the node is not in
254 * document's node map cache (like HTML area element).
256 * XXX: it should be really merged with GetAccessible().
258 LocalAccessible* GetAccessibleEvenIfNotInMap(nsINode* aNode) const;
259 LocalAccessible* GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const;
262 * Return whether the given DOM node has an accessible or not.
264 bool HasAccessible(nsINode* aNode) const { return GetAccessible(aNode); }
267 * Return the cached accessible by the given unique ID within this document.
269 * @note the unique ID matches with the uniqueID() of Accessible
271 * @param aUniqueID [in] the unique ID used to cache the node.
273 LocalAccessible* GetAccessibleByUniqueID(void* aUniqueID) {
274 return UniqueID() == aUniqueID ? this : mAccessibleCache.GetWeak(aUniqueID);
278 * Return the cached accessible by the given unique ID looking through
279 * this and nested documents.
281 LocalAccessible* GetAccessibleByUniqueIDInSubtree(void* aUniqueID);
284 * Return an accessible for the given DOM node or container accessible if
285 * the node is not accessible. If aNoContainerIfPruned is true it will return
286 * null if the node is in a pruned subtree (eg. aria-hidden or unselected deck
287 * panel)
289 LocalAccessible* GetAccessibleOrContainer(
290 nsINode* aNode, bool aNoContainerIfPruned = false) const;
293 * Return a container accessible for the given DOM node.
295 LocalAccessible* GetContainerAccessible(nsINode* aNode) const;
298 * Return an accessible for the given node if any, or an immediate accessible
299 * container for it.
301 LocalAccessible* AccessibleOrTrueContainer(
302 nsINode* aNode, bool aNoContainerIfPruned = false) const;
305 * Return an accessible for the given node or its first accessible descendant.
307 LocalAccessible* GetAccessibleOrDescendant(nsINode* aNode) const;
310 * Returns aria-owns seized child at the given index.
312 LocalAccessible* ARIAOwnedAt(LocalAccessible* aParent,
313 uint32_t aIndex) const {
314 nsTArray<RefPtr<LocalAccessible>>* children = mARIAOwnsHash.Get(aParent);
315 if (children) {
316 return children->SafeElementAt(aIndex);
318 return nullptr;
320 uint32_t ARIAOwnedCount(LocalAccessible* aParent) const {
321 nsTArray<RefPtr<LocalAccessible>>* children = mARIAOwnsHash.Get(aParent);
322 return children ? children->Length() : 0;
326 * Return true if the given ID is referred by relation attribute.
328 bool IsDependentID(dom::Element* aElement, const nsAString& aID) const {
329 return GetRelProviders(aElement, aID);
333 * Initialize the newly created accessible and put it into document caches.
335 * @param aAccessible [in] created accessible
336 * @param aRoleMapEntry [in] the role map entry role the ARIA role or
337 * nullptr if none
339 void BindToDocument(LocalAccessible* aAccessible,
340 const nsRoleMapEntry* aRoleMapEntry);
343 * Remove from document and shutdown the given accessible.
345 void UnbindFromDocument(LocalAccessible* aAccessible);
348 * Notify the document accessible that content was inserted.
350 void ContentInserted(nsIContent* aStartChildNode, nsIContent* aEndChildNode);
353 * @see nsAccessibilityService::ScheduleAccessibilitySubtreeUpdate
355 void ScheduleTreeUpdate(nsIContent* aContent);
358 * Update the tree on content removal.
360 void ContentRemoved(LocalAccessible* aAccessible);
361 void ContentRemoved(nsIContent* aContentNode);
364 * Updates accessible tree when rendered text is changed.
366 void UpdateText(nsIContent* aTextNode);
369 * Recreate an accessible, results in hide/show events pair.
371 void RecreateAccessible(nsIContent* aContent);
374 * Schedule ARIA owned element relocation if needed. Return true if relocation
375 * was scheduled.
377 bool RelocateARIAOwnedIfNeeded(nsIContent* aEl);
380 * Return a notification controller associated with the document.
382 NotificationController* Controller() const { return mNotificationController; }
385 * If this document is in a content process return the object responsible for
386 * communicating with the main process for it.
388 DocAccessibleChild* IPCDoc() const { return mIPCDoc; }
391 * Notify the document that a DOM node has been scrolled. document will
392 * dispatch throttled accessibility events for scrolling, and a scroll-end
393 * event. This function also queues a cache update for ScrollPosition.
395 void HandleScroll(nsINode* aTarget);
398 * Retrieves the scroll frame (if it exists) for the given accessible
399 * and returns its scroll position and scroll range. If the given
400 * accessible is `this`, return the scroll position and range of
401 * the root scroll frame. Return values have been scaled by the
402 * PresShell's resolution.
404 std::pair<nsPoint, nsRect> ComputeScrollData(LocalAccessible* aAcc);
407 * Only works in content process documents.
409 bool IsAccessibleBeingMoved(LocalAccessible* aAcc) {
410 return mMovedAccessibles.Contains(aAcc);
413 void AttrElementWillChange(dom::Element* aElement, nsAtom* aAttr);
414 void AttrElementChanged(dom::Element* aElement, nsAtom* aAttr);
416 protected:
417 virtual ~DocAccessible();
419 void LastRelease();
421 // DocAccessible
422 virtual nsresult AddEventListeners();
423 virtual nsresult RemoveEventListeners();
426 * Marks this document as loaded or loading.
428 void NotifyOfLoad(uint32_t aLoadEventType);
429 void NotifyOfLoading(bool aIsReloading);
431 friend class DocManager;
434 * Perform initial update (create accessible tree).
435 * Can be overridden by wrappers to prepare initialization work.
437 virtual void DoInitialUpdate();
440 * Updates root element and picks up ARIA role on it if any.
442 void UpdateRootElIfNeeded();
445 * Process document load notification, fire document load and state busy
446 * events if applicable.
448 void ProcessLoad();
451 * Append the given document accessible to this document's child document
452 * accessibles.
454 bool AppendChildDocument(DocAccessible* aChildDocument) {
455 // XXX(Bug 1631371) Check if this should use a fallible operation as it
456 // pretended earlier, or change the return type to void.
457 mChildDocuments.AppendElement(aChildDocument);
458 return true;
462 * Remove the given document accessible from this document's child document
463 * accessibles.
465 void RemoveChildDocument(DocAccessible* aChildDocument) {
466 mChildDocuments.RemoveElement(aChildDocument);
470 * Add dependent IDs pointed by accessible element by relation attribute to
471 * cache. If the relation attribute is missed then all relation attributes
472 * are checked.
474 * @param aRelProvider [in] accessible that element has relation attribute
475 * @param aRelAttr [in, optional] relation attribute
477 void AddDependentIDsFor(LocalAccessible* aRelProvider,
478 nsAtom* aRelAttr = nullptr);
481 * Remove dependent IDs pointed by accessible element by relation attribute
482 * from cache. If the relation attribute is absent then all relation
483 * attributes are checked.
485 * @param aRelProvider [in] accessible that element has relation attribute
486 * @param aRelAttr [in, optional] relation attribute
488 void RemoveDependentIDsFor(LocalAccessible* aRelProvider,
489 nsAtom* aRelAttr = nullptr);
492 * Add dependent elements targeted by a relation attribute on an accessible
493 * element to the dependent elements cache. This is used for reflected IDL
494 * attributes which return DOM elements and reflect a content attribute, where
495 * the IDL attribute has been set to an element. For example, if the
496 * .popoverTargetElement IDL attribute is set to an element using JS, the
497 * target element will be added to the dependent elements cache. If the
498 * relation attribute is not specified, then all relation attributes are
499 * checked.
501 * @param aRelProvider [in] the accessible with the relation IDL attribute.
502 * @param aRelAttr [in, optional] the name of the reflected content attribute.
503 * For example, for the popoverTargetElement IDL attribute, this would be
504 * "popovertarget".
506 void AddDependentElementsFor(LocalAccessible* aRelProvider,
507 nsAtom* aRelAttr = nullptr);
510 * Remove dependent elements targeted by a relation attribute on an accessible
511 * element from the dependent elements cache. If the relation attribute is
512 * not specified, then all relation attributes are checked.
514 * @param aRelProvider [in] the accessible with the relation IDL attribute.
515 * @param aRelAttr [in, optional] the name of the reflected content attribute.
517 void RemoveDependentElementsFor(LocalAccessible* aRelProvider,
518 nsAtom* aRelAttr = nullptr);
521 * Update or recreate an accessible depending on a changed attribute.
523 * @param aElement [in] the element the attribute was changed on
524 * @param aAttribute [in] the changed attribute
525 * @return true if an action was taken on the attribute change
527 bool UpdateAccessibleOnAttrChange(mozilla::dom::Element* aElement,
528 nsAtom* aAttribute);
531 * Process ARIA active-descendant attribute change.
533 void ARIAActiveDescendantChanged(LocalAccessible* aAccessible);
536 * Update the accessible tree for inserted content.
538 void ProcessContentInserted(
539 LocalAccessible* aContainer,
540 const nsTArray<nsCOMPtr<nsIContent>>* aInsertedContent);
541 void ProcessContentInserted(LocalAccessible* aContainer,
542 nsIContent* aInsertedContent);
545 * Used to notify the document to make it process the invalidation list.
547 * While children are cached we may encounter the case there's no accessible
548 * for referred content by related accessible. Store these related nodes to
549 * invalidate their containers later.
551 void ProcessInvalidationList();
554 * Process mPendingUpdates
556 void ProcessPendingUpdates();
559 * Called from NotificationController to process this doc's
560 * queued cache updates. For each acc in the map, this function
561 * sends a cache update with its corresponding CacheDomain.
563 void ProcessQueuedCacheUpdates();
566 * Called from NotificationController before mutation events are processed to
567 * notify the parent process which Accessibles are being moved (if any).
569 void SendAccessiblesWillMove();
572 * Called from NotificationController after all mutation events have been
573 * processed to clear our data about mutations during this tick.
575 void ClearMutationData() {
576 mMovedAccessibles.Clear();
577 mInsertedAccessibles.Clear();
578 mRemovedNodes.Clear();
582 * Steals or puts back accessible subtrees.
584 void DoARIAOwnsRelocation(LocalAccessible* aOwner);
587 * Moves children back under their original parents.
589 void PutChildrenBack(nsTArray<RefPtr<LocalAccessible>>* aChildren,
590 uint32_t aStartIdx);
592 bool MoveChild(LocalAccessible* aChild, LocalAccessible* aNewParent,
593 int32_t aIdxInParent);
596 * Create accessible tree.
598 * @param aRoot [in] a root of subtree to create
599 * @param aFocusedAcc [in, optional] a focused accessible under created
600 * subtree if any
602 void CacheChildrenInSubtree(LocalAccessible* aRoot,
603 LocalAccessible** aFocusedAcc = nullptr);
604 void CreateSubtree(LocalAccessible* aRoot);
607 * Remove accessibles in subtree from node to accessible map.
609 void UncacheChildrenInSubtree(LocalAccessible* aRoot);
612 * Shutdown any cached accessible in the subtree.
614 * @param aAccessible [in] the root of the subrtee to invalidate accessible
615 * child/parent refs in
617 void ShutdownChildrenInSubtree(LocalAccessible* aAccessible);
620 * Return true if the document is a target of document loading events
621 * (for example, state busy change or document reload events).
623 * Rules: The root chrome document accessible is never an event target
624 * (for example, Firefox UI window). If the sub document is loaded within its
625 * parent document then the parent document is a target only (aka events
626 * coalescence).
628 bool IsLoadEventTarget() const;
631 * Set the object responsible for communicating with the main process on
632 * behalf of this document.
634 void SetIPCDoc(DocAccessibleChild* aIPCDoc);
636 friend class DocAccessibleChild;
639 * Used to fire scrolling end event after page scroll.
641 * @param aTimer [in] the timer object
642 * @param aClosure [in] the document accessible where scrolling happens
644 static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure);
646 void DispatchScrollingEvent(nsINode* aTarget, uint32_t aEventType);
649 * Check if an id attribute change affects aria-activedescendant and handle
650 * the aria-activedescendant change if appropriate.
651 * If the currently focused element has aria-activedescendant and an
652 * element's id changes to match this, the id was probably moved from the
653 * previous active descendant, thus making this element the new active
654 * descendant. In that case, accessible focus must be changed accordingly.
656 void ARIAActiveDescendantIDMaybeMoved(LocalAccessible* aAccessible);
659 * Traverse content subtree and for each node do one of 3 things:
660 * 1. Check if content node has an accessible that should be removed and
661 * remove it.
662 * 2. Check if content node has an accessible that needs to be recreated.
663 * Remove it and schedule it for reinsertion.
664 * 3. Check if content node has no accessible but needs one. Schedule one for
665 * insertion.
667 * Returns true if the root node should be reinserted.
669 bool PruneOrInsertSubtree(nsIContent* aRoot);
671 protected:
673 * State and property flags, kept by mDocFlags.
675 enum {
676 // Whether the document is a top level content document in this process.
677 eTopLevelContentDocInProcess = 1 << 0
681 * Cache of accessibles within this document accessible.
683 AccessibleHashtable mAccessibleCache;
684 nsTHashMap<nsPtrHashKey<const nsINode>, LocalAccessible*>
685 mNodeToAccessibleMap;
687 Document* mDocumentNode;
688 nsCOMPtr<nsITimer> mScrollWatchTimer;
689 nsTHashMap<nsPtrHashKey<nsINode>, TimeStamp> mLastScrollingDispatch;
692 * Bit mask of document load states (@see LoadState).
694 uint32_t mLoadState : 3;
697 * Bit mask of other states and props.
699 uint32_t mDocFlags : 27;
702 * Tracks whether we have seen changes to this document's content that
703 * indicate we should re-send the viewport cache we use for hittesting.
704 * This value is set in `BundleFieldsForCache` and processed in
705 * `ProcessQueuedCacheUpdates`.
707 bool mViewportCacheDirty : 1;
710 * Type of document load event fired after the document is loaded completely.
712 uint32_t mLoadEventType;
715 * Reference to anchor jump element.
717 nsCOMPtr<nsIContent> mAnchorJumpElm;
720 * A generic state (see items below) before the attribute value was changed.
721 * @see AttributeWillChange and AttributeChanged notifications.
724 // Previous state bits before attribute change
725 uint64_t mPrevStateBits;
727 nsTArray<RefPtr<DocAccessible>> mChildDocuments;
730 * A storage class for pairing content with one of its relation attributes.
732 class AttrRelProvider {
733 public:
734 AttrRelProvider(nsAtom* aRelAttr, nsIContent* aContent)
735 : mRelAttr(aRelAttr), mContent(aContent) {}
737 nsAtom* mRelAttr;
738 nsCOMPtr<nsIContent> mContent;
740 private:
741 AttrRelProvider();
742 AttrRelProvider(const AttrRelProvider&);
743 AttrRelProvider& operator=(const AttrRelProvider&);
746 typedef nsTArray<mozilla::UniquePtr<AttrRelProvider>> AttrRelProviders;
747 typedef nsClassHashtable<nsStringHashKey, AttrRelProviders>
748 DependentIDsHashtable;
751 * Returns/creates/removes attribute relation providers associated with
752 * a DOM document if the element is in uncomposed document or associated
753 * with shadow DOM the element is in.
755 AttrRelProviders* GetRelProviders(dom::Element* aElement,
756 const nsAString& aID) const;
757 AttrRelProviders* GetOrCreateRelProviders(dom::Element* aElement,
758 const nsAString& aID);
759 void RemoveRelProvidersIfEmpty(dom::Element* aElement, const nsAString& aID);
762 * A map used to look up the target node for an implicit reverse relation
763 * where the target of the explicit relation is specified as an id.
764 * For example:
765 * <div id="label">Name:</div><input aria-labelledby="label">
766 * The div should get a LABEL_FOR relation targeting the input. To facilitate
767 * that, mDependentIDsHashes maps from "label" to an AttrRelProvider
768 * specifying aria-labelledby and the input. Because ids are scoped to the
769 * nearest ancestor document or shadow root, mDependentIDsHashes maps from the
770 * DocumentOrShadowRoot first.
772 nsClassHashtable<nsPtrHashKey<dom::DocumentOrShadowRoot>,
773 DependentIDsHashtable>
774 mDependentIDsHashes;
777 * A map used to look up the target element for an implicit reverse relation
778 * where the target of the explicit relation is also specified as an element.
779 * This is similar to mDependentIDsHashes, except that this is used when a
780 * DOM property is used to set the relation target element directly, rather
781 * than using an id. For example:
782 * <button>More info</button><div popover>Some info</div>
783 * The button's .popoverTargetElement property is set to the div so that the
784 * button invokes the popover.
785 * To facilitate finding the invoker given the popover, mDependentElementsMap
786 * maps from the div to an AttrRelProvider specifying popovertarget and the
787 * button.
789 nsTHashMap<nsIContent*, AttrRelProviders> mDependentElementsMap;
791 friend class RelatedAccIterator;
794 * Used for our caching algorithm. We store the list of nodes that should be
795 * invalidated.
797 * @see ProcessInvalidationList
799 nsTArray<RefPtr<nsIContent>> mInvalidationList;
802 * Holds a list of aria-owns relocations.
804 nsClassHashtable<nsPtrHashKey<LocalAccessible>,
805 nsTArray<RefPtr<LocalAccessible>>>
806 mARIAOwnsHash;
809 * Keeps a list of pending subtrees to update post-refresh.
811 nsTArray<RefPtr<nsIContent>> mPendingUpdates;
814 * Used to process notification from core and accessible events.
816 RefPtr<NotificationController> mNotificationController;
817 friend class EventTree;
818 friend class NotificationController;
820 private:
821 void SetRoleMapEntryForDoc(dom::Element* aElement);
824 * This must be called whenever an Accessible is moved in a content process.
825 * It keeps track of Accessibles moved during this tick.
827 void TrackMovedAccessible(LocalAccessible* aAcc);
830 * For hidden subtrees, fire a name/description change event if the subtree
831 * is a target of aria-labelledby/describedby.
832 * This does nothing if it is called on a node which is not part of a hidden
833 * aria-labelledby/describedby target.
835 void MaybeHandleChangeToHiddenNameOrDescription(nsIContent* aChild);
837 void MaybeFireEventsForChangedPopover(LocalAccessible* aAcc);
839 PresShell* mPresShell;
841 // Exclusively owned by IPDL so don't manually delete it!
842 // Cleared in ActorDestroy
843 DocAccessibleChild* mIPCDoc;
845 // These data structures map between LocalAccessibles and CacheDomains,
846 // tracking cache updates that have been queued during the current tick but
847 // not yet sent. If there are a lot of nearby text cache updates (e.g. during
848 // a reflow), it is much more performant to process them in order because we
849 // then benefit from the layout line cursor. However, we still only want to
850 // process each LocalAccessible only once. Therefore, we use an array for
851 // ordering and a hash map to avoid duplicates, since Gecko has no ordered
852 // set data structure. The array contains pairs of LocalAccessible and cache
853 // domain. The hash map maps from LocalAccessible to the corresponding index
854 // in the array. These data structures must be kept in sync. It is possible
855 // for these to contain a reference to the document they live on. We clear
856 // them in Shutdown() to avoid cyclical references.
857 nsTArray<std::pair<RefPtr<LocalAccessible>, uint64_t>>
858 mQueuedCacheUpdatesArray;
859 nsTHashMap<LocalAccessible*, size_t> mQueuedCacheUpdatesHash;
861 // A set of Accessibles moved during this tick. Only used in content
862 // processes.
863 nsTHashSet<RefPtr<LocalAccessible>> mMovedAccessibles;
864 // A set of Accessibles inserted during this tick. Only used in content
865 // processes. This is needed to prevent insertions + moves of the same
866 // Accessible in the same tick from being tracked as moves.
867 nsTHashSet<RefPtr<LocalAccessible>> mInsertedAccessibles;
868 // A set of DOM nodes removed during this tick. This avoids a lot of pointless
869 // recursive DOM traversals.
870 nsTHashSet<nsIContent*> mRemovedNodes;
873 inline DocAccessible* LocalAccessible::AsDoc() {
874 return IsDoc() ? static_cast<DocAccessible*>(this) : nullptr;
877 } // namespace a11y
878 } // namespace mozilla
880 #endif