2 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "AXIsolatedTree.h"
29 #include "AXTextStateChangeIntent.h"
30 #include "AccessibilityObject.h"
31 #include "SimpleRange.h"
33 #include "VisibleUnits.h"
35 #include <wtf/HashMap.h>
36 #include <wtf/HashSet.h>
37 #include <wtf/ListHashSet.h>
38 #include <wtf/WeakHashSet.h>
47 class HTMLAreaElement
;
48 class HTMLTextFormControlElement
;
55 class VisiblePosition
;
58 struct TextMarkerData
{
61 Node
* node
{ nullptr };
62 unsigned offset
{ 0 };
63 Position::AnchorType anchorType
{ Position::PositionIsOffsetInAnchor
};
64 Affinity affinity
{ Affinity::Downstream
};
66 int characterStartIndex
{ 0 };
67 int characterOffset
{ 0 };
68 bool ignored
{ false };
71 struct CharacterOffset
{
77 CharacterOffset(Node
* n
= nullptr, int startIndex
= 0, int offset
= 0, int remaining
= 0)
79 , startIndex(startIndex
)
81 , remainingOffset(remaining
)
84 int remaining() const { return remainingOffset
; }
85 bool isNull() const { return !node
; }
86 bool isEqual(const CharacterOffset
& other
) const
88 if (isNull() || other
.isNull())
90 return node
== other
.node
&& startIndex
== other
.startIndex
&& offset
== other
.offset
;
94 class AXComputedObjectAttributeCache
{
95 WTF_MAKE_FAST_ALLOCATED
;
97 AccessibilityObjectInclusion
getIgnored(AXID
) const;
98 void setIgnored(AXID
, AccessibilityObjectInclusion
);
101 struct CachedAXObjectAttributes
{
102 CachedAXObjectAttributes()
103 : ignored(AccessibilityObjectInclusion::DefaultBehavior
)
106 AccessibilityObjectInclusion ignored
;
109 HashMap
<AXID
, CachedAXObjectAttributes
> m_idMapping
;
112 struct VisiblePositionIndex
{
114 RefPtr
<ContainerNode
> scope
;
117 struct VisiblePositionIndexRange
{
118 VisiblePositionIndex startIndex
;
119 VisiblePositionIndex endIndex
;
120 bool isNull() const { return startIndex
.value
== -1 || endIndex
.value
== -1; }
128 class AccessibilityReplacedText
{
130 AccessibilityReplacedText() = default;
131 AccessibilityReplacedText(const VisibleSelection
&);
132 void postTextStateChangeNotification(AXObjectCache
*, AXTextEditType
, const String
&, const VisibleSelection
&);
133 const VisiblePositionIndexRange
& replacedRange() { return m_replacedRange
; }
135 String m_replacedText
;
136 VisiblePositionIndexRange m_replacedRange
;
140 enum AXTextChange
{ AXTextInserted
, AXTextDeleted
, AXTextAttributesChanged
};
143 enum class PostTarget
{ Element
, ObservableParent
};
145 class AXObjectCache
{
146 WTF_MAKE_NONCOPYABLE(AXObjectCache
); WTF_MAKE_FAST_ALLOCATED
;
147 friend class AXIsolatedTree
;
148 friend WTF::TextStream
& operator<<(WTF::TextStream
&, AXObjectCache
&);
150 explicit AXObjectCache(Document
&);
153 // Returns the root object for the entire document.
154 WEBCORE_EXPORT AXCoreObject
* rootObject();
155 // Returns the root object for a specific frame.
156 WEBCORE_EXPORT AccessibilityObject
* rootObjectForFrame(Frame
*);
158 // For AX objects with elements that back them.
159 AccessibilityObject
* getOrCreate(RenderObject
*);
160 AccessibilityObject
* getOrCreate(Widget
*);
161 WEBCORE_EXPORT AccessibilityObject
* getOrCreate(Node
*);
163 // used for objects without backing elements
164 AccessibilityObject
* create(AccessibilityRole
);
166 // will only return the AccessibilityObject if it already exists
167 AccessibilityObject
* get(RenderObject
*);
168 AccessibilityObject
* get(Widget
*);
169 AccessibilityObject
* get(Node
*);
171 void remove(RenderObject
*);
173 void remove(Widget
*);
176 #if !PLATFORM(COCOA) && !USE(ATSPI)
177 void detachWrapper(AXCoreObject
*, AccessibilityDetachmentType
);
180 using DOMObjectVariant
= std::variant
<std::nullptr_t
, RenderObject
*, Node
*, Widget
*>;
181 void cacheAndInitializeWrapper(AccessibilityObject
*, DOMObjectVariant
= nullptr);
182 void attachWrapper(AXCoreObject
*);
185 void childrenChanged(Node
*, Node
* newChild
= nullptr);
186 void childrenChanged(RenderObject
*, RenderObject
* newChild
= nullptr);
187 void childrenChanged(AccessibilityObject
*);
188 void checkedStateChanged(Node
*);
189 void handleRoleChange(AccessibilityObject
*);
190 // Called when a node has just been attached, so we can make sure we have the right subclass of AccessibilityObject.
191 void updateCacheAfterNodeIsAttached(Node
*);
192 void updateLoadingProgress(double);
193 void loadingFinished() { updateLoadingProgress(1); }
194 double loadingProgress() const { return m_loadingProgress
; }
196 void deferFocusedUIElementChangeIfNeeded(Node
* oldFocusedNode
, Node
* newFocusedNode
);
197 void deferModalChange(Element
*);
198 void deferMenuListValueChange(Element
*);
199 void deferNodeAddedOrRemoved(Node
*);
200 void handleScrolledToAnchor(const Node
* anchorNode
);
201 void handleScrollbarUpdate(ScrollView
*);
203 bool isRetrievingCurrentModalNode() { return m_isRetrievingCurrentModalNode
; }
206 void deferAttributeChangeIfNeeded(const QualifiedName
&, Element
*);
207 void recomputeIsIgnored(RenderObject
*);
208 void recomputeIsIgnored(Node
*);
210 WEBCORE_EXPORT
static void enableAccessibility();
211 WEBCORE_EXPORT
static void disableAccessibility();
213 WEBCORE_EXPORT AccessibilityObject
* focusedObjectForPage(const Page
*);
215 // Enhanced user interface accessibility can be toggled by the assistive technology.
216 WEBCORE_EXPORT
static void setEnhancedUserInterfaceAccessibility(bool flag
);
218 // Note: these may be called from a non-main thread concurrently as other readers.
219 static bool accessibilityEnabled() { return gAccessibilityEnabled
; }
220 static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled
; }
222 const Element
* rootAXEditableElement(const Node
*);
223 bool nodeIsTextControl(const Node
*);
225 AXID
platformGenerateAXID() const;
226 AccessibilityObject
* objectFromAXID(AXID id
) const { return m_objects
.get(id
); }
227 Vector
<RefPtr
<AXCoreObject
>> objectsForIDs(const Vector
<AXID
>&) const;
229 // Text marker utilities.
230 std::optional
<TextMarkerData
> textMarkerDataForVisiblePosition(const VisiblePosition
&);
231 std::optional
<TextMarkerData
> textMarkerDataForFirstPositionInTextControl(HTMLTextFormControlElement
&);
232 void textMarkerDataForCharacterOffset(TextMarkerData
&, const CharacterOffset
&);
233 void textMarkerDataForNextCharacterOffset(TextMarkerData
&, const CharacterOffset
&);
234 void textMarkerDataForPreviousCharacterOffset(TextMarkerData
&, const CharacterOffset
&);
235 VisiblePosition
visiblePositionForTextMarkerData(TextMarkerData
&);
236 CharacterOffset
characterOffsetForTextMarkerData(TextMarkerData
&);
237 // Use ignoreNextNodeStart/ignorePreviousNodeEnd to determine the behavior when we are at node boundary.
238 CharacterOffset
nextCharacterOffset(const CharacterOffset
&, bool ignoreNextNodeStart
= true);
239 CharacterOffset
previousCharacterOffset(const CharacterOffset
&, bool ignorePreviousNodeEnd
= true);
240 void startOrEndTextMarkerDataForRange(TextMarkerData
&, const SimpleRange
&, bool);
241 CharacterOffset
startOrEndCharacterOffsetForRange(const SimpleRange
&, bool, bool enterTextControls
= false);
242 AccessibilityObject
* accessibilityObjectForTextMarkerData(TextMarkerData
&);
243 std::optional
<SimpleRange
> rangeForUnorderedCharacterOffsets(const CharacterOffset
&, const CharacterOffset
&);
244 static SimpleRange
rangeForNodeContents(Node
&);
245 static int lengthForRange(const std::optional
<SimpleRange
>&);
248 CharacterOffset
nextWordEndCharacterOffset(const CharacterOffset
&);
249 CharacterOffset
previousWordStartCharacterOffset(const CharacterOffset
&);
250 std::optional
<SimpleRange
> leftWordRange(const CharacterOffset
&);
251 std::optional
<SimpleRange
> rightWordRange(const CharacterOffset
&);
254 std::optional
<SimpleRange
> paragraphForCharacterOffset(const CharacterOffset
&);
255 CharacterOffset
nextParagraphEndCharacterOffset(const CharacterOffset
&);
256 CharacterOffset
previousParagraphStartCharacterOffset(const CharacterOffset
&);
259 std::optional
<SimpleRange
> sentenceForCharacterOffset(const CharacterOffset
&);
260 CharacterOffset
nextSentenceEndCharacterOffset(const CharacterOffset
&);
261 CharacterOffset
previousSentenceStartCharacterOffset(const CharacterOffset
&);
264 CharacterOffset
characterOffsetForPoint(const IntPoint
&, AXCoreObject
*);
265 IntRect
absoluteCaretBoundsForCharacterOffset(const CharacterOffset
&);
266 CharacterOffset
characterOffsetForBounds(const IntRect
&, bool);
269 CharacterOffset
endCharacterOffsetOfLine(const CharacterOffset
&);
270 CharacterOffset
startCharacterOffsetOfLine(const CharacterOffset
&);
273 CharacterOffset
characterOffsetForIndex(int, const AXCoreObject
*);
274 int indexForCharacterOffset(const CharacterOffset
&, AccessibilityObject
*);
276 enum AXNotification
{
277 AXActiveDescendantChanged
,
279 AXAutocorrectionOccured
,
280 AXCheckedStateChanged
,
282 AXCurrentStateChanged
,
283 AXDescribedByChanged
,
284 AXDisabledStateChanged
,
285 AXFocusedUIElementChanged
,
287 AXGrabbedStateChanged
,
289 AXIdAttributeChanged
,
290 AXImageOverlayChanged
,
294 AXNewDocumentLoadComplete
,
296 AXPositionInSetChanged
,
297 AXSelectedChildrenChanged
,
298 AXSelectedStateChanged
,
299 AXSelectedTextChanged
,
304 AXMenuListItemSelected
,
305 AXMenuListValueChanged
,
312 AXInvalidStatusChanged
,
315 AXPressedStateChanged
,
316 AXReadOnlyStatusChanged
,
317 AXRequiredStatusChanged
,
318 AXSortDirectionChanged
,
320 AXElementBusyChanged
,
323 AXDraggingEnteredDropZone
,
325 AXDraggingExitedDropZone
328 void postNotification(RenderObject
*, AXNotification
, PostTarget
= PostTarget::Element
);
329 void postNotification(Node
*, AXNotification
, PostTarget
= PostTarget::Element
);
330 void postNotification(AXCoreObject
*, Document
*, AXNotification
, PostTarget
= PostTarget::Element
);
333 void showIntent(const AXTextStateChangeIntent
&);
336 void setTextSelectionIntent(const AXTextStateChangeIntent
&);
337 void setIsSynchronizingSelection(bool);
339 void postTextStateChangeNotification(Node
*, AXTextEditType
, const String
&, const VisiblePosition
&);
340 void postTextReplacementNotification(Node
*, AXTextEditType deletionType
, const String
& deletedText
, AXTextEditType insertionType
, const String
& insertedText
, const VisiblePosition
&);
341 void postTextReplacementNotificationForTextControl(HTMLTextFormControlElement
&, const String
& deletedText
, const String
& insertedText
);
342 void postTextStateChangeNotification(Node
*, const AXTextStateChangeIntent
&, const VisibleSelection
&);
343 void postTextStateChangeNotification(const Position
&, const AXTextStateChangeIntent
&, const VisibleSelection
&);
344 void postLiveRegionChangeNotification(AccessibilityObject
*);
345 void focusModalNode();
347 enum AXLoadingEvent
{
354 void frameLoadingEventNotification(Frame
*, AXLoadingEvent
);
356 void prepareForDocumentDestruction(const Document
&);
358 void startCachingComputedObjectAttributesUntilTreeMutates();
359 void stopCachingComputedObjectAttributes();
361 AXComputedObjectAttributeCache
* computedObjectAttributeCache() { return m_computedObjectAttributeCache
.get(); }
363 Document
& document() const { return m_document
; }
364 std::optional
<PageIdentifier
> pageID() const { return m_pageID
; }
367 static void setShouldRepostNotificationsForTests(bool value
);
369 void deferRecomputeIsIgnoredIfNeeded(Element
*);
370 void deferRecomputeIsIgnored(Element
*);
371 void deferTextChangedIfNeeded(Node
*);
372 void deferSelectedChildrenChangedIfNeeded(Element
&);
373 void performDeferredCacheUpdate();
374 void deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement
&, const String
& previousValue
);
376 std::optional
<SimpleRange
> rangeMatchesTextNearRange(const SimpleRange
&, const String
&);
378 static ASCIILiteral
notificationPlatformName(AXNotification
);
380 AXTreeData
treeData();
382 // Returns the IDs of the objects that relate to the given object with the specified relationship.
383 std::optional
<Vector
<AXID
>> relatedObjectsFor(const AXCoreObject
&, AXRelationType
);
385 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
386 WEBCORE_EXPORT
static bool isIsolatedTreeEnabled();
387 WEBCORE_EXPORT
static bool usedOnAXThread();
389 static bool clientSupportsIsolatedTree();
390 AXCoreObject
* isolatedTreeRootObject();
391 void setIsolatedTreeFocusedObject(Node
*);
392 RefPtr
<AXIsolatedTree
> getOrCreateIsolatedTree() const;
393 void updateIsolatedTree(AXCoreObject
&, AXNotification
);
394 void updateIsolatedTree(AXCoreObject
*, AXNotification
);
395 void updateIsolatedTree(const Vector
<std::pair
<RefPtr
<AXCoreObject
>, AXNotification
>>&);
396 static void initializeSecondaryAXThread();
400 void postPlatformNotification(AXCoreObject
*, AXNotification
);
401 void platformHandleFocusedUIElementChanged(Node
* oldFocusedNode
, Node
* newFocusedNode
);
403 void platformPerformDeferredCacheUpdate();
405 #if PLATFORM(COCOA) || USE(ATSPI)
406 void postTextStateChangePlatformNotification(AXCoreObject
*, const AXTextStateChangeIntent
&, const VisibleSelection
&);
407 void postTextStateChangePlatformNotification(AccessibilityObject
*, AXTextEditType
, const String
&, const VisiblePosition
&);
408 void postTextReplacementPlatformNotificationForTextControl(AXCoreObject
*, const String
& deletedText
, const String
& insertedText
, HTMLTextFormControlElement
&);
409 void postTextReplacementPlatformNotification(AXCoreObject
*, AXTextEditType
, const String
&, AXTextEditType
, const String
&, const VisiblePosition
&);
411 static AXTextChange
textChangeForEditType(AXTextEditType
);
412 void nodeTextChangePlatformNotification(AccessibilityObject
*, AXTextChange
, unsigned, const String
&);
415 void frameLoadingEventPlatformNotification(AccessibilityObject
*, AXLoadingEvent
);
416 void textChanged(AccessibilityObject
*);
417 void labelChanged(Element
*);
419 // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
420 void setNodeInUse(Node
* n
) { m_textMarkerNodes
.add(n
); }
421 void removeNodeForUse(Node
& n
) { m_textMarkerNodes
.remove(&n
); }
422 bool isNodeInUse(Node
* n
) { return m_textMarkerNodes
.contains(n
); }
424 // CharacterOffset functions.
425 enum TraverseOption
{ TraverseOptionDefault
= 1 << 0, TraverseOptionToNodeEnd
= 1 << 1, TraverseOptionIncludeStart
= 1 << 2, TraverseOptionValidateOffset
= 1 << 3, TraverseOptionDoNotEnterTextControls
= 1 << 4 };
426 Node
* nextNode(Node
*) const;
427 Node
* previousNode(Node
*) const;
428 CharacterOffset
traverseToOffsetInRange(const SimpleRange
&, int, TraverseOption
= TraverseOptionDefault
, bool stayWithinRange
= false);
429 VisiblePosition
visiblePositionFromCharacterOffset(const CharacterOffset
&);
430 CharacterOffset
characterOffsetFromVisiblePosition(const VisiblePosition
&);
431 void setTextMarkerDataWithCharacterOffset(TextMarkerData
&, const CharacterOffset
&);
432 UChar32
characterAfter(const CharacterOffset
&);
433 UChar32
characterBefore(const CharacterOffset
&);
434 CharacterOffset
characterOffsetForNodeAndOffset(Node
&, int, TraverseOption
= TraverseOptionDefault
);
436 enum class NeedsContextAtParagraphStart
{ Yes
, No
};
437 CharacterOffset
previousBoundary(const CharacterOffset
&, BoundarySearchFunction
, NeedsContextAtParagraphStart
= NeedsContextAtParagraphStart::No
);
438 CharacterOffset
nextBoundary(const CharacterOffset
&, BoundarySearchFunction
);
439 CharacterOffset
startCharacterOffsetOfWord(const CharacterOffset
&, EWordSide
= RightWordIfOnBoundary
);
440 CharacterOffset
endCharacterOffsetOfWord(const CharacterOffset
&, EWordSide
= RightWordIfOnBoundary
);
441 CharacterOffset
startCharacterOffsetOfParagraph(const CharacterOffset
&, EditingBoundaryCrossingRule
= CannotCrossEditingBoundary
);
442 CharacterOffset
endCharacterOffsetOfParagraph(const CharacterOffset
&, EditingBoundaryCrossingRule
= CannotCrossEditingBoundary
);
443 CharacterOffset
startCharacterOffsetOfSentence(const CharacterOffset
&);
444 CharacterOffset
endCharacterOffsetOfSentence(const CharacterOffset
&);
445 CharacterOffset
characterOffsetForPoint(const IntPoint
&);
446 LayoutRect
localCaretRectForCharacterOffset(RenderObject
*&, const CharacterOffset
&);
447 bool shouldSkipBoundary(const CharacterOffset
&, const CharacterOffset
&);
449 AccessibilityObject
* rootWebArea();
450 static AccessibilityObject
* focusedImageMapUIElement(HTMLAreaElement
*);
452 AXID
getAXID(AccessibilityObject
*);
454 void notificationPostTimerFired();
456 void liveRegionChangedNotificationPostTimerFired();
458 void focusModalNodeTimerFired();
460 void performCacheUpdateTimerFired();
462 void postTextStateChangeNotification(AccessibilityObject
*, const AXTextStateChangeIntent
&, const VisibleSelection
&);
464 bool enqueuePasswordValueChangeNotification(AccessibilityObject
*);
465 void passwordNotificationPostTimerFired();
467 void processDeferredChildrenChangedList();
468 void handleChildrenChanged(AccessibilityObject
&);
469 void handleMenuOpened(Node
*);
470 void handleLiveRegionCreated(Node
*);
471 void handleMenuItemSelected(Node
*);
472 void handleRowCountChanged(AXCoreObject
*, Document
*);
473 void handleAttributeChange(const QualifiedName
&, Element
*);
474 bool shouldProcessAttributeChange(const QualifiedName
&, Element
*);
475 void selectedChildrenChanged(Node
*);
476 void selectedChildrenChanged(RenderObject
*);
477 void selectedStateChanged(Node
*);
478 // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
479 void textChanged(Node
*);
481 void handleActiveDescendantChanged(Element
&);
483 void handleAriaExpandedChange(Node
*);
484 void handleFocusedUIElementChanged(Node
* oldFocusedNode
, Node
* newFocusedNode
);
485 void handleMenuListValueChanged(Element
&);
487 // aria-modal or modal <dialog> related
488 bool isModalElement(Element
&) const;
489 void findModalNodes();
490 Element
* currentModalNode();
491 bool isNodeVisible(Node
*) const;
492 void handleModalChange(Element
&);
493 bool modalElementHasAccessibleContent(Element
&);
495 // Relationships between objects.
496 static Vector
<QualifiedName
>& relationAttributes();
497 static AXRelationType
attributeToRelationType(const QualifiedName
&);
498 enum class AddingSymmetricRelation
: bool { No
, Yes
};
499 static AXRelationType
symmetricRelation(AXRelationType
);
500 void addRelation(Element
*, Element
*, AXRelationType
);
501 void addRelation(AccessibilityObject
*, AccessibilityObject
*, AXRelationType
, AddingSymmetricRelation
= AddingSymmetricRelation::No
);
502 void updateRelationsIfNeeded();
503 void relationsNeedUpdate(bool needUpdate
) { m_relationsNeedUpdate
= needUpdate
; }
505 Document
& m_document
;
506 const std::optional
<PageIdentifier
> m_pageID
; // constant for object's lifetime.
507 HashMap
<AXID
, RefPtr
<AccessibilityObject
>> m_objects
;
508 HashMap
<RenderObject
*, AXID
> m_renderObjectMapping
;
509 HashMap
<Widget
*, AXID
> m_widgetObjectMapping
;
510 HashMap
<Node
*, AXID
> m_nodeObjectMapping
;
511 ListHashSet
<Node
*> m_textMarkerNodes
;
512 std::unique_ptr
<AXComputedObjectAttributeCache
> m_computedObjectAttributeCache
;
514 #if ENABLE(ACCESSIBILITY)
515 WEBCORE_EXPORT
static bool gAccessibilityEnabled
;
516 WEBCORE_EXPORT
static bool gAccessibilityEnhancedUserInterfaceEnabled
;
518 static constexpr bool gAccessibilityEnabled
= false;
519 static constexpr bool gAccessibilityEnhancedUserInterfaceEnabled
= false;
522 HashSet
<AXID
> m_idsInUse
;
524 Timer m_notificationPostTimer
;
525 Vector
<std::pair
<RefPtr
<AXCoreObject
>, AXNotification
>> m_notificationsToPost
;
527 Timer m_passwordNotificationPostTimer
;
529 ListHashSet
<RefPtr
<AccessibilityObject
>> m_passwordNotificationsToPost
;
531 Timer m_liveRegionChangedPostTimer
;
532 ListHashSet
<RefPtr
<AccessibilityObject
>> m_liveRegionObjectsSet
;
534 Timer m_focusModalNodeTimer
;
535 WeakPtr
<Element
> m_currentModalElement
;
536 // Multiple aria-modals behavior is undefined by spec. We keep them sorted based on DOM order here.
537 // If that changes to require only one aria-modal we could change this to a WeakHashSet, or discard the set completely.
538 ListHashSet
<Element
*> m_modalElementsSet
;
539 bool m_modalNodesInitialized
{ false };
540 bool m_isRetrievingCurrentModalNode
{ false };
542 Timer m_performCacheUpdateTimer
;
544 AXTextStateChangeIntent m_textSelectionIntent
;
545 WeakHashSet
<Element
> m_deferredRecomputeIsIgnoredList
;
546 WeakHashSet
<HTMLTableElement
> m_deferredRecomputeTableIsExposedList
;
547 ListHashSet
<Node
*> m_deferredTextChangedList
;
548 WeakHashSet
<Element
> m_deferredSelectedChildredChangedList
;
549 ListHashSet
<RefPtr
<AccessibilityObject
>> m_deferredChildrenChangedList
;
550 ListHashSet
<Node
*> m_deferredNodeAddedOrRemovedList
;
551 WeakHashSet
<Element
> m_deferredModalChangedList
;
552 WeakHashSet
<Element
> m_deferredMenuListChange
;
553 HashMap
<Element
*, String
> m_deferredTextFormControlValue
;
554 HashMap
<Element
*, QualifiedName
> m_deferredAttributeChange
;
555 Vector
<std::pair
<Node
*, Node
*>> m_deferredFocusedNodeChange
;
556 bool m_isSynchronizingSelection
{ false };
557 bool m_performingDeferredCacheUpdate
{ false };
558 double m_loadingProgress
{ 0 };
560 // Relationships between objects.
561 using Relations
= HashMap
<AXRelationType
, Vector
<AXID
>, DefaultHash
<uint8_t>, WTF::UnsignedWithZeroKeyHashTraits
<uint8_t>>;
562 HashMap
<AXID
, Relations
> m_relations
;
563 bool m_relationsNeedUpdate
{ true };
566 ListHashSet
<RefPtr
<AXCoreObject
>> m_deferredParentChangedList
;
570 class AXAttributeCacheEnabler
573 explicit AXAttributeCacheEnabler(AXObjectCache
*cache
);
574 ~AXAttributeCacheEnabler();
576 #if ENABLE(ACCESSIBILITY)
578 AXObjectCache
* m_cache
;
582 bool nodeHasRole(Node
*, StringView role
);
583 // This will let you know if aria-hidden was explicitly set to false.
584 bool isNodeAriaVisible(Node
*);
586 #if !ENABLE(ACCESSIBILITY)
587 inline AccessibilityObjectInclusion
AXComputedObjectAttributeCache::getIgnored(AXID
) const { return AccessibilityObjectInclusion::DefaultBehavior
; }
588 inline AccessibilityReplacedText::AccessibilityReplacedText(const VisibleSelection
&) { }
589 inline void AccessibilityReplacedText::postTextStateChangeNotification(AXObjectCache
*, AXTextEditType
, const String
&, const VisibleSelection
&) { }
590 inline void AXComputedObjectAttributeCache::setIgnored(AXID
, AccessibilityObjectInclusion
) { }
591 inline AXObjectCache::AXObjectCache(Document
& document
) : m_document(document
), m_notificationPostTimer(*this, &AXObjectCache::notificationPostTimerFired
), m_passwordNotificationPostTimer(*this, &AXObjectCache::passwordNotificationPostTimerFired
), m_liveRegionChangedPostTimer(*this, &AXObjectCache::liveRegionChangedNotificationPostTimerFired
), m_focusModalNodeTimer(*this, &AXObjectCache::focusModalNodeTimerFired
), m_performCacheUpdateTimer(*this, &AXObjectCache::performCacheUpdateTimerFired
) { }
592 inline AXObjectCache::~AXObjectCache() { }
593 inline AccessibilityObject
* AXObjectCache::get(RenderObject
*) { return nullptr; }
594 inline AccessibilityObject
* AXObjectCache::get(Node
*) { return nullptr; }
595 inline AccessibilityObject
* AXObjectCache::get(Widget
*) { return nullptr; }
596 inline AccessibilityObject
* AXObjectCache::getOrCreate(RenderObject
*) { return nullptr; }
597 inline AccessibilityObject
* AXObjectCache::create(AccessibilityRole
) { return nullptr; }
598 inline AccessibilityObject
* AXObjectCache::getOrCreate(Node
*) { return nullptr; }
599 inline AccessibilityObject
* AXObjectCache::getOrCreate(Widget
*) { return nullptr; }
600 inline AXCoreObject
* AXObjectCache::rootObject() { return nullptr; }
601 inline AccessibilityObject
* AXObjectCache::rootObjectForFrame(Frame
*) { return nullptr; }
602 inline AccessibilityObject
* AXObjectCache::focusedObjectForPage(const Page
*) { return nullptr; }
603 inline void AXObjectCache::enableAccessibility() { }
604 inline void AXObjectCache::disableAccessibility() { }
605 inline void AXObjectCache::setEnhancedUserInterfaceAccessibility(bool) { }
606 inline bool nodeHasRole(Node
*, StringView
) { return false; }
607 inline void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates() { }
608 inline void AXObjectCache::stopCachingComputedObjectAttributes() { }
609 inline bool isNodeAriaVisible(Node
*) { return true; }
610 inline const Element
* AXObjectCache::rootAXEditableElement(const Node
*) { return nullptr; }
611 inline Node
* AXObjectCache::modalNode() { return nullptr; }
612 inline void AXObjectCache::attachWrapper(AXCoreObject
*) { }
613 inline void AXObjectCache::checkedStateChanged(Node
*) { }
614 inline void AXObjectCache::childrenChanged(Node
*, Node
*) { }
615 inline void AXObjectCache::childrenChanged(RenderObject
*, RenderObject
*) { }
616 inline void AXObjectCache::childrenChanged(AccessibilityObject
*) { }
617 inline void AXObjectCache::deferFocusedUIElementChangeIfNeeded(Node
*, Node
*) { }
618 inline void AXObjectCache::deferRecomputeIsIgnoredIfNeeded(Element
*) { }
619 inline void AXObjectCache::deferRecomputeIsIgnored(Element
*) { }
620 inline void AXObjectCache::deferTextChangedIfNeeded(Node
*) { }
621 inline void AXObjectCache::deferSelectedChildrenChangedIfNeeded(Element
&) { }
622 inline void AXObjectCache::deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement
&, const String
&) { }
623 #if !PLATFORM(COCOA) && !USE(ATSPI)
624 inline void AXObjectCache::detachWrapper(AXCoreObject
*, AccessibilityDetachmentType
) { }
626 inline void AXObjectCache::focusModalNodeTimerFired() { }
627 inline void AXObjectCache::performCacheUpdateTimerFired() { }
628 inline void AXObjectCache::frameLoadingEventNotification(Frame
*, AXLoadingEvent
) { }
629 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject
*, AXLoadingEvent
) { }
630 inline void AXObjectCache::handleActiveDescendantChanged(Element
&) { }
631 inline void AXObjectCache::handleAriaExpandedChange(Node
*) { }
632 inline void AXObjectCache::handleModalChange(Element
&) { }
633 inline void AXObjectCache::deferModalChange(Element
*) { }
634 inline void AXObjectCache::handleRoleChange(AccessibilityObject
*) { }
635 inline void AXObjectCache::deferAttributeChangeIfNeeded(const QualifiedName
&, Element
*) { }
636 inline void AXObjectCache::handleAttributeChange(const QualifiedName
&, Element
*) { }
637 inline bool AXObjectCache::shouldProcessAttributeChange(const QualifiedName
&, Element
*) { return false; }
638 inline void AXObjectCache::handleFocusedUIElementChanged(Node
*, Node
*) { }
639 inline void AXObjectCache::handleScrollbarUpdate(ScrollView
*) { }
640 inline void AXObjectCache::handleScrolledToAnchor(const Node
*) { }
641 inline void AXObjectCache::liveRegionChangedNotificationPostTimerFired() { }
642 inline void AXObjectCache::notificationPostTimerFired() { }
643 inline Vector
<RefPtr
<AXCoreObject
>> AXObjectCache::objectsForIDs(const Vector
<AXID
>&) const { return { }; }
644 inline void AXObjectCache::passwordNotificationPostTimerFired() { }
645 inline void AXObjectCache::performDeferredCacheUpdate() { }
646 inline void AXObjectCache::postLiveRegionChangeNotification(AccessibilityObject
*) { }
647 inline void AXObjectCache::postNotification(AXCoreObject
*, Document
*, AXNotification
, PostTarget
) { }
648 inline void AXObjectCache::postNotification(Node
*, AXNotification
, PostTarget
) { }
649 inline void AXObjectCache::postNotification(RenderObject
*, AXNotification
, PostTarget
) { }
650 inline void AXObjectCache::postPlatformNotification(AXCoreObject
*, AXNotification
) { }
651 inline void AXObjectCache::postTextReplacementNotification(Node
*, AXTextEditType
, const String
&, AXTextEditType
, const String
&, const VisiblePosition
&) { }
652 inline void AXObjectCache::postTextReplacementNotificationForTextControl(HTMLTextFormControlElement
&, const String
&, const String
&) { }
653 inline void AXObjectCache::postTextStateChangeNotification(Node
*, AXTextEditType
, const String
&, const VisiblePosition
&) { }
654 inline void AXObjectCache::postTextStateChangeNotification(Node
*, const AXTextStateChangeIntent
&, const VisibleSelection
&) { }
655 inline void AXObjectCache::recomputeIsIgnored(RenderObject
*) { }
656 inline void AXObjectCache::textChanged(AccessibilityObject
*) { }
657 inline void AXObjectCache::textChanged(Node
*) { }
658 inline void AXObjectCache::updateCacheAfterNodeIsAttached(Node
*) { }
659 inline void AXObjectCache::updateLoadingProgress(double) { }
660 inline SimpleRange
AXObjectCache::rangeForNodeContents(Node
& node
) { return makeRangeSelectingNodeContents(node
); }
661 inline std::optional
<Vector
<AXID
>> AXObjectCache::relatedObjectsFor(const AXCoreObject
&, AXRelationType
) { return std::nullopt
; }
662 inline void AXObjectCache::remove(AXID
) { }
663 inline void AXObjectCache::remove(RenderObject
*) { }
664 inline void AXObjectCache::remove(Node
&) { }
665 inline void AXObjectCache::remove(Widget
*) { }
666 inline void AXObjectCache::selectedChildrenChanged(RenderObject
*) { }
667 inline void AXObjectCache::selectedChildrenChanged(Node
*) { }
668 inline void AXObjectCache::setIsSynchronizingSelection(bool) { }
669 inline void AXObjectCache::setTextSelectionIntent(const AXTextStateChangeIntent
&) { }
670 inline std::optional
<SimpleRange
> AXObjectCache::rangeForUnorderedCharacterOffsets(const CharacterOffset
&, const CharacterOffset
&) { return std::nullopt
; }
671 inline IntRect
AXObjectCache::absoluteCaretBoundsForCharacterOffset(const CharacterOffset
&) { return IntRect(); }
672 inline CharacterOffset
AXObjectCache::characterOffsetForIndex(int, const AXCoreObject
*) { return CharacterOffset(); }
673 inline CharacterOffset
AXObjectCache::startOrEndCharacterOffsetForRange(const SimpleRange
&, bool, bool) { return CharacterOffset(); }
674 inline CharacterOffset
AXObjectCache::endCharacterOffsetOfLine(const CharacterOffset
&) { return CharacterOffset(); }
675 inline CharacterOffset
AXObjectCache::nextCharacterOffset(const CharacterOffset
&, bool) { return CharacterOffset(); }
676 inline CharacterOffset
AXObjectCache::previousCharacterOffset(const CharacterOffset
&, bool) { return CharacterOffset(); }
678 inline void AXObjectCache::postTextStateChangePlatformNotification(AccessibilityObject
*, const AXTextStateChangeIntent
&, const VisibleSelection
&) { }
679 inline void AXObjectCache::postTextStateChangePlatformNotification(AccessibilityObject
*, AXTextEditType
, const String
&, const VisiblePosition
&) { }
680 inline void AXObjectCache::postTextReplacementPlatformNotification(AccessibilityObject
*, AXTextEditType
, const String
&, AXTextEditType
, const String
&, const VisiblePosition
&) { }
682 inline AXTextChange
AXObjectCache::textChangeForEditType(AXTextEditType
) { return AXTextInserted
; }
683 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject
*, AXTextChange
, unsigned, const String
&) { }
685 inline AXTreeData
AXObjectCache::treeData() { return { }; }
687 inline AXAttributeCacheEnabler::AXAttributeCacheEnabler(AXObjectCache
*) { }
688 inline AXAttributeCacheEnabler::~AXAttributeCacheEnabler() { }
689 #endif // !ENABLE(ACCESSIBILITY)
691 WTF::TextStream
& operator<<(WTF::TextStream
&, AXObjectCache::AXNotification
);
693 } // namespace WebCore