#pragma once
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
#include "AccessibilityObjectInterface.h"
#include "PageIdentifier.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSafeRefCounted.h>
namespace WTF {
class TextStream;
}
namespace WebCore {
class AXIsolatedObject;
class AXObjectCache;
class Page;
using AXIsolatedTreeID = unsigned;
enum class AXPropertyName : uint16_t {
ARIAControlsElements,
ARIADetailsElements,
DropEffects,
ARIAErrorMessageElements,
ARIAIsMultiline,
ARIAFlowToElements,
ARIALandmarkRoleDescription,
ARIATreeItemContent,
ARIATreeRows,
ARIARoleAttribute,
ARIAOwnsElements,
AXColumnCount,
AXColumnIndex,
AXRowCount,
AXRowIndex,
AccessKey,
AccessibilityButtonState,
AccessibilityDescription,
AccessibilityText,
ActionVerb,
AutoCompleteValue,
BlockquoteLevel,
BoundingBoxRect,
BrailleLabel,
BrailleRoleDescription,
CanHaveSelectedChildren,
CanSetExpandedAttribute,
CanSetFocusAttribute,
CanSetNumericValue,
CanSetSelectedAttribute,
CanSetSelectedChildren,
CanSetTextRangeAttributes,
CanSetValueAttribute,
CanvasHasFallbackContent,
#if PLATFORM(MAC)
CaretBrowsingEnabled,
#endif
Cells,
ClassList,
ClickPoint,
ColorValue,
Columns,
ColumnCount,
ColumnHeader,
ColumnHeaders,
ColumnIndex,
ColumnIndexRange,
ComputedLabel,
ComputedRoleString,
CurrentState,
CurrentValue,
DatetimeAttributeValue,
DecrementButton,
Description,
DisclosedByRow,
DisclosedRows,
DocumentEncoding,
DocumentLinks,
DocumentURI,
EditableAncestor,
ElementRect,
EstimatedLoadingProgress,
ExpandedTextValue,
ExposesTitleUIElement,
FileUploadButtonReturnsValueInTitle,
FocusableAncestor,
HasARIAValueNow,
HasApplePDFAnnotationAttribute,
HasBoldFont,
HasChildren,
HasHighlighting,
HasItalicFont,
HasPlainText,
HasPopup,
HasUnderline,
HeaderContainer,
HeadingLevel,
HelpText,
HierarchicalLevel,
HighestEditableAncestor,
HorizontalScrollBar,
IdentifierAttribute,
IncrementButton,
InnerHTML,
InvalidStatus,
IsAccessibilityIgnored,
IsActiveDescendantOfFocusedContainer,
IsAnonymousMathOperator,
IsGrabbed,
IsARIATreeGridRow,
IsAttachment,
IsButton,
IsBusy,
IsChecked,
IsCollapsed,
IsColumnHeaderCell,
IsControl,
IsDataTable,
IsDescriptionList,
IsEnabled,
IsExpanded,
IsExposable,
IsFieldset,
IsFileUploadButton,
IsFocused,
IsGroup,
IsImageMapLink,
IsIncrementor,
IsIndeterminate,
IsInlineText,
IsInputImage,
IsInsideLiveRegion,
IsHeading,
IsHovered,
IsKeyboardFocusable,
IsLandmark,
IsLink,
IsLinked,
IsList,
IsListBox,
IsLoaded,
IsMathElement,
IsMathFraction,
IsMathFenced,
IsMathSubscriptSuperscript,
IsMathRow,
IsMathUnderOver,
IsMathRoot,
IsMathSquareRoot,
IsMathText,
IsMathNumber,
IsMathOperator,
IsMathFenceOperator,
IsMathSeparatorOperator,
IsMathIdentifier,
IsMathTable,
IsMathTableRow,
IsMathTableCell,
IsMathMultiscript,
IsMathToken,
IsMathScriptObject,
IsMediaTimeline,
IsMenu,
IsMenuBar,
IsMenuButton,
IsMenuItem,
IsMenuList,
IsMenuListOption,
IsMenuListPopup,
IsMenuRelated,
IsMeter,
IsMultiSelectable,
IsOrderedList,
IsOutput,
IsPasswordField,
IsPressed,
IsProgressIndicator,
IsRangeControl,
IsRequired,
IsRowHeaderCell,
IsScrollbar,
IsSearchField,
IsSelected,
IsSelectedOptionActive,
IsShowingValidationMessage,
IsSlider,
IsStyleFormatGroup,
IsTable,
IsTableCell,
IsTableColumn,
IsTableRow,
IsTextControl,
IsTree,
IsTreeItem,
IsUnorderedList,
IsUnvisited,
IsValueAutofilled,
IsValueAutofillAvailable,
IsVisible,
IsVisited,
KeyShortcutsValue,
Language,
LayoutCount,
LinkRelValue,
LinkedUIElements,
LiveRegionAtomic,
LiveRegionRelevant,
LiveRegionStatus,
MathFencedOpenString,
MathFencedCloseString,
MathLineThickness,
MathPrescripts,
MathPostscripts,
MathRadicandObject,
MathRootIndexObject,
MathUnderObject,
MathOverObject,
MathNumeratorObject,
MathDenominatorObject,
MathBaseObject,
MathSubscriptObject,
MathSuperscriptObject,
MaxValueForRange,
MinValueForRange,
NextSibling,
Orientation,
OuterHTML,
Path,
PlaceholderValue,
PressedIsPresent,
PreviousSibling,
PopupValue,
PosInSet,
PreventKeyboardDOMEventDispatch,
ReadOnlyValue,
RoleValue,
RolePlatformString,
RoleDescription,
Rows,
RowCount,
RowHeaders,
RowIndex,
RowIndexRange,
SelectedChildren,
SelectedRadioButton,
SelectedTabItem,
SessionID,
SetSize,
SortDirection,
SpeakAs,
SpeechHint,
StringValue,
SupportsRowCountChange,
SupportsDragging,
SupportsDropping,
SupportsARIAOwns,
SupportsCheckedState,
SupportsCurrent,
SupportsDatetimeAttribute,
SupportsExpanded,
SupportsExpandedTextValue,
SupportsLiveRegion,
SupportsPath,
SupportsPosInSet,
SupportsPressAction,
SupportsRangeValue,
SupportsRequiredAttribute,
SupportsSelectedRows,
SupportsSetSize,
TabChildren,
TableLevel,
TagName,
TextLength,
Title,
TitleAttributeValue,
TitleUIElement,
URL,
ValueAutofillButtonType,
ValueDescription,
ValueForRange,
ValidationMessage,
VerticalScrollBar,
VisibleChildren,
VisibleRows,
WebArea,
};
using AXPropertyValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double, float, uint64_t, Color, URL, LayoutRect, FloatRect, AXID, IntPoint, OptionSet<SpeakAs>, std::pair<unsigned, unsigned>, Vector<AccessibilityText>, Vector<AXID>, Vector<std::pair<AXID, AXID>>, Vector<String>, Path>;
using AXPropertyMap = HashMap<AXPropertyName, AXPropertyValueVariant, WTF::IntHash<AXPropertyName>, WTF::StrongEnumHashTraits<AXPropertyName>>;
struct AXPropertyChange {
AXID axID { InvalidAXID }; AXPropertyMap properties; };
class AXIsolatedTree : public ThreadSafeRefCounted<AXIsolatedTree> {
WTF_MAKE_NONCOPYABLE(AXIsolatedTree); WTF_MAKE_FAST_ALLOCATED;
friend WTF::TextStream& operator<<(WTF::TextStream&, AXIsolatedTree&);
public:
static Ref<AXIsolatedTree> create(AXObjectCache*);
virtual ~AXIsolatedTree();
static void removeTreeForPageID(PageIdentifier);
static RefPtr<AXIsolatedTree> treeForPageID(PageIdentifier);
static RefPtr<AXIsolatedTree> treeForID(AXIsolatedTreeID);
AXObjectCache* axObjectCache() const;
RefPtr<AXIsolatedObject> rootNode();
RefPtr<AXIsolatedObject> focusedNode();
RefPtr<AXIsolatedObject> nodeForID(AXID) const;
Vector<RefPtr<AXCoreObject>> objectsForIDs(const Vector<AXID>&) const;
Vector<AXID> idsForObjects(const Vector<RefPtr<AXCoreObject>>&) const;
struct NodeChange {
Ref<AXIsolatedObject> isolatedObject;
RetainPtr<AccessibilityObjectWrapper> wrapper;
};
void generateSubtree(AXCoreObject&, AXCoreObject*, bool attachWrapper);
void updateNode(AXCoreObject&);
void updateNodeProperty(const AXCoreObject&, AXPropertyName);
void updateSubtree(AXCoreObject&);
void updateChildren(AXCoreObject&);
void removeNode(AXID);
void removeSubtree(AXID);
void setRootNode(AXIsolatedObject*);
void setFocusedNodeID(AXID);
void applyPendingChanges();
AXIsolatedTreeID treeID() const { return m_treeID; }
private:
AXIsolatedTree(AXObjectCache*);
void clear();
static HashMap<AXIsolatedTreeID, Ref<AXIsolatedTree>>& treeIDCache();
static HashMap<PageIdentifier, Ref<AXIsolatedTree>>& treePageCache();
Ref<AXIsolatedObject> createSubtree(AXCoreObject&, AXID parentID, bool attachWrapper);
void updateChildrenIDs(AXID parentID, Vector<AXID>&& childrenIDs);
AXIsolatedTreeID m_treeID;
AXObjectCache* m_axObjectCache { nullptr };
bool m_usedOnAXThread { true };
HashMap<AXID, Vector<AXID>> m_nodeMap;
HashMap<AXID, Ref<AXIsolatedObject>> m_readerThreadNodeMap;
RefPtr<AXIsolatedObject> m_rootNode;
Vector<NodeChange> m_pendingAppends; Vector<AXPropertyChange> m_pendingPropertyChanges;
Vector<AXID> m_pendingNodeRemovals; Vector<AXID> m_pendingSubtreeRemovals; Vector<std::pair<AXID, Vector<AXID>>> m_pendingChildrenUpdates;
AXID m_pendingFocusedNodeID { InvalidAXID };
AXID m_focusedNodeID { InvalidAXID };
Lock m_changeLogLock;
};
inline AXObjectCache* AXIsolatedTree::axObjectCache() const
{
ASSERT(isMainThread());
return m_axObjectCache;
}
}
#endif