/*
 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "WebAccessibilityObjectWrapperMac.h"

#if ENABLE(ACCESSIBILITY) && PLATFORM(MAC)

#import "AXLogger.h"
#import "AXObjectCache.h"
#import "AccessibilityARIAGridRow.h"
#import "AccessibilityLabel.h"
#import "AccessibilityList.h"
#import "AccessibilityListBox.h"
#import "AccessibilityProgressIndicator.h"
#import "AccessibilityRenderObject.h"
#import "AccessibilityScrollView.h"
#import "AccessibilitySpinButton.h"
#import "AccessibilityTable.h"
#import "AccessibilityTableCell.h"
#import "AccessibilityTableColumn.h"
#import "AccessibilityTableRow.h"
#import "Chrome.h"
#import "ChromeClient.h"
#import "ColorMac.h"
#import "ContextMenuController.h"
#import "Editing.h"
#import "Editor.h"
#import "Font.h"
#import "FontCascade.h"
#import "Frame.h"
#import "FrameLoaderClient.h"
#import "FrameSelection.h"
#import "HTMLAnchorElement.h"
#import "HTMLAreaElement.h"
#import "HTMLFrameOwnerElement.h"
#import "HTMLImageElement.h"
#import "HTMLInputElement.h"
#import "HTMLNames.h"
#import "LocalizedStrings.h"
#import "Page.h"
#import "PluginDocument.h"
#import "PluginViewBase.h"
#import "Range.h"
#import "RenderInline.h"
#import "RenderTextControl.h"
#import "RenderView.h"
#import "RenderWidget.h"
#import "ScrollView.h"
#import "TextCheckerClient.h"
#import "TextCheckingHelper.h"
#import "TextDecorationPainter.h"
#import "TextIterator.h"
#import "VisibleUnits.h"
#import "WebCoreFrameView.h"
#import <pal/spi/cocoa/NSAccessibilitySPI.h>
#import <wtf/cocoa/TypeCastsCocoa.h>
#import <wtf/cocoa/VectorCocoa.h>

using namespace WebCore;

// Cell Tables
#ifndef NSAccessibilitySelectedCellsAttribute
#define NSAccessibilitySelectedCellsAttribute @"AXSelectedCells"
#endif

#ifndef NSAccessibilityVisibleCellsAttribute
#define NSAccessibilityVisibleCellsAttribute @"AXVisibleCells"
#endif

#ifndef NSAccessibilityRowIndexRangeAttribute
#define NSAccessibilityRowIndexRangeAttribute @"AXRowIndexRange"
#endif

#ifndef NSAccessibilityColumnIndexRangeAttribute
#define NSAccessibilityColumnIndexRangeAttribute @"AXColumnIndexRange"
#endif

#ifndef NSAccessibilityCellForColumnAndRowParameterizedAttribute
#define NSAccessibilityCellForColumnAndRowParameterizedAttribute @"AXCellForColumnAndRow"
#endif

#ifndef NSAccessibilityCellRole
#define NSAccessibilityCellRole @"AXCell"
#endif

// Lists
#ifndef NSAccessibilityContentListSubrole
#define NSAccessibilityContentListSubrole @"AXContentList"
#endif

#ifndef NSAccessibilityDefinitionListSubrole
#define NSAccessibilityDefinitionListSubrole @"AXDefinitionList"
#endif

#ifndef NSAccessibilityDescriptionListSubrole
#define NSAccessibilityDescriptionListSubrole @"AXDescriptionList"
#endif

#ifndef NSAccessibilityContentSeparatorSubrole
#define NSAccessibilityContentSeparatorSubrole @"AXContentSeparator"
#endif

#ifndef NSAccessibilityRubyBaseSubRole
#define NSAccessibilityRubyBaseSubrole @"AXRubyBase"
#endif

#ifndef NSAccessibilityRubyBlockSubrole
#define NSAccessibilityRubyBlockSubrole @"AXRubyBlock"
#endif

#ifndef NSAccessibilityRubyInlineSubrole
#define NSAccessibilityRubyInlineSubrole @"AXRubyInline"
#endif

#ifndef NSAccessibilityRubyRunSubrole
#define NSAccessibilityRubyRunSubrole @"AXRubyRun"
#endif

#ifndef NSAccessibilityRubyTextSubrole
#define NSAccessibilityRubyTextSubrole @"AXRubyText"
#endif

// Miscellaneous
#ifndef NSAccessibilityBlockQuoteLevelAttribute
#define NSAccessibilityBlockQuoteLevelAttribute @"AXBlockQuoteLevel"
#endif

#ifndef NSAccessibilityChildrenInNavigationOrderAttribute
#define NSAccessibilityChildrenInNavigationOrderAttribute @"AXChildrenInNavigationOrder"
#endif

#ifndef NSAccessibilityAccessKeyAttribute
#define NSAccessibilityAccessKeyAttribute @"AXAccessKey"
#endif

#ifndef NSAccessibilityValueAutofilledAttribute
#define NSAccessibilityValueAutofilledAttribute @"AXValueAutofilled"
#endif

#ifndef NSAccessibilityValueAutofillAvailableAttribute
#define NSAccessibilityValueAutofillAvailableAttribute @"AXValueAutofillAvailable"
#endif

#ifndef NSAccessibilityValueAutofillTypeAttribute
#define NSAccessibilityValueAutofillTypeAttribute @"AXValueAutofillType"
#endif

#ifndef NSAccessibilityLanguageAttribute
#define NSAccessibilityLanguageAttribute @"AXLanguage"
#endif

#ifndef NSAccessibilityRequiredAttribute
#define NSAccessibilityRequiredAttribute @"AXRequired"
#endif

#ifndef NSAccessibilityInvalidAttribute
#define NSAccessibilityInvalidAttribute @"AXInvalid"
#endif

#ifndef NSAccessibilityOwnsAttribute
#define NSAccessibilityOwnsAttribute @"AXOwns"
#endif

#ifndef NSAccessibilityGrabbedAttribute
#define NSAccessibilityGrabbedAttribute @"AXGrabbed"
#endif

#ifndef NSAccessibilityDatetimeValueAttribute
#define NSAccessibilityDatetimeValueAttribute @"AXDateTimeValue"
#endif

#ifndef NSAccessibilityInlineTextAttribute
#define NSAccessibilityInlineTextAttribute @"AXInlineText"
#endif

#ifndef NSAccessibilityDropEffectsAttribute
#define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
#endif

#ifndef NSAccessibilityARIALiveAttribute
#define NSAccessibilityARIALiveAttribute @"AXARIALive"
#endif

#ifndef NSAccessibilityARIAAtomicAttribute
#define NSAccessibilityARIAAtomicAttribute @"AXARIAAtomic"
#endif

#ifndef NSAccessibilityARIARelevantAttribute
#define NSAccessibilityARIARelevantAttribute @"AXARIARelevant"
#endif

#ifndef NSAccessibilityElementBusyAttribute
#define NSAccessibilityElementBusyAttribute @"AXElementBusy"
#endif

#ifndef NSAccessibilityARIAPosInSetAttribute
#define NSAccessibilityARIAPosInSetAttribute @"AXARIAPosInSet"
#endif

#ifndef NSAccessibilityARIASetSizeAttribute
#define NSAccessibilityARIASetSizeAttribute @"AXARIASetSize"
#endif

#ifndef NSAccessibilityLoadingProgressAttribute
#define NSAccessibilityLoadingProgressAttribute @"AXLoadingProgress"
#endif

#ifndef NSAccessibilityHasPopupAttribute
#define NSAccessibilityHasPopupAttribute @"AXHasPopup"
#endif

#ifndef NSAccessibilityPopupValueAttribute
#define NSAccessibilityPopupValueAttribute @"AXPopupValue"
#endif

#ifndef NSAccessibilityPlaceholderValueAttribute
#define NSAccessibilityPlaceholderValueAttribute @"AXPlaceholderValue"
#endif

#define NSAccessibilityTextMarkerIsValidParameterizedAttribute @"AXTextMarkerIsValid"
#define NSAccessibilityIndexForTextMarkerParameterizedAttribute @"AXIndexForTextMarker"
#define NSAccessibilityTextMarkerForIndexParameterizedAttribute @"AXTextMarkerForIndex"

#ifndef NSAccessibilityScrollToVisibleAction
#define NSAccessibilityScrollToVisibleAction @"AXScrollToVisible"
#endif

#ifndef NSAccessibilityPathAttribute
#define NSAccessibilityPathAttribute @"AXPath"
#endif

#ifndef NSAccessibilityExpandedTextValueAttribute
#define NSAccessibilityExpandedTextValueAttribute @"AXExpandedTextValue"
#endif

#ifndef NSAccessibilityIsMultiSelectableAttribute
#define NSAccessibilityIsMultiSelectableAttribute @"AXIsMultiSelectable"
#endif

#ifndef NSAccessibilityDocumentURIAttribute
#define NSAccessibilityDocumentURIAttribute @"AXDocumentURI"
#endif

#ifndef NSAccessibilityDocumentEncodingAttribute
#define NSAccessibilityDocumentEncodingAttribute @"AXDocumentEncoding"
#endif

#ifndef NSAccessibilityAriaControlsAttribute
#define NSAccessibilityAriaControlsAttribute @"AXARIAControls"
#endif

#define NSAccessibilityDOMIdentifierAttribute @"AXDOMIdentifier"
#define NSAccessibilityDOMClassListAttribute @"AXDOMClassList"

#ifndef NSAccessibilityARIACurrentAttribute
#define NSAccessibilityARIACurrentAttribute @"AXARIACurrent"
#endif

// Table/grid attributes
#ifndef NSAccessibilityARIAColumnIndexAttribute
#define NSAccessibilityARIAColumnIndexAttribute @"AXARIAColumnIndex"
#endif

#ifndef NSAccessibilityARIARowIndexAttribute
#define NSAccessibilityARIARowIndexAttribute @"AXARIARowIndex"
#endif

#ifndef NSAccessibilityARIAColumnCountAttribute
#define NSAccessibilityARIAColumnCountAttribute @"AXARIAColumnCount"
#endif

#ifndef NSAccessibilityARIARowCountAttribute
#define NSAccessibilityARIARowCountAttribute @"AXARIARowCount"
#endif


#ifndef NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute
#define NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute @"AXUIElementCountForSearchPredicate"
#endif

#ifndef NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute
#define NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute @"AXUIElementsForSearchPredicate"
#endif

// Text markers
#ifndef NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute
#define NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute @"AXEndTextMarkerForBounds"
#endif

#ifndef NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute
#define NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute @"AXStartTextMarkerForBounds"
#endif

#ifndef NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute
#define NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute @"AXLineTextMarkerRangeForTextMarker"
#endif

#ifndef NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute
#define NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute @"AXMisspellingTextMarkerRange"
#endif

// Text selection
#ifndef NSAccessibilitySelectTextActivity
#define NSAccessibilitySelectTextActivity @"AXSelectTextActivity"
#endif

#ifndef NSAccessibilitySelectTextActivityFindAndReplace
#define NSAccessibilitySelectTextActivityFindAndReplace @"AXSelectTextActivityFindAndReplace"
#endif

#ifndef NSAccessibilitySelectTextActivityFindAndSelect
#define NSAccessibilitySelectTextActivityFindAndSelect @"AXSelectTextActivityFindAndSelect"
#endif

#ifndef kAXSelectTextActivityFindAndCapitalize
#define kAXSelectTextActivityFindAndCapitalize @"AXSelectTextActivityFindAndCapitalize"
#endif

#ifndef kAXSelectTextActivityFindAndLowercase
#define kAXSelectTextActivityFindAndLowercase @"AXSelectTextActivityFindAndLowercase"
#endif

#ifndef kAXSelectTextActivityFindAndUppercase
#define kAXSelectTextActivityFindAndUppercase @"AXSelectTextActivityFindAndUppercase"
#endif

#ifndef NSAccessibilitySelectTextAmbiguityResolution
#define NSAccessibilitySelectTextAmbiguityResolution @"AXSelectTextAmbiguityResolution"
#endif

#ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection
#define NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection @"AXSelectTextAmbiguityResolutionClosestAfterSelection"
#endif

#ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection
#define NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection @"AXSelectTextAmbiguityResolutionClosestBeforeSelection"
#endif

#ifndef NSAccessibilitySelectTextAmbiguityResolutionClosestToSelection
#define NSAccessibilitySelectTextAmbiguityResolutionClosestToSelection @"AXSelectTextAmbiguityResolutionClosestToSelection"
#endif

#ifndef NSAccessibilitySelectTextReplacementString
#define NSAccessibilitySelectTextReplacementString @"AXSelectTextReplacementString"
#endif

#ifndef NSAccessibilitySelectTextSearchStrings
#define NSAccessibilitySelectTextSearchStrings @"AXSelectTextSearchStrings"
#endif

#ifndef NSAccessibilitySelectTextWithCriteriaParameterizedAttribute
#define NSAccessibilitySelectTextWithCriteriaParameterizedAttribute @"AXSelectTextWithCriteria"
#endif

// Text search

#ifndef NSAccessibilitySearchTextWithCriteriaParameterizedAttribute
/* Performs a text search with the given parameters.
 Returns an NSArray of text marker ranges of the search hits.
 */
#define NSAccessibilitySearchTextWithCriteriaParameterizedAttribute @"AXSearchTextWithCriteria"
#endif

#ifndef NSAccessibilitySearchTextSearchStrings
// NSArray of strings to search for.
#define NSAccessibilitySearchTextSearchStrings @"AXSearchTextSearchStrings"
#endif

#ifndef NSAccessibilitySearchTextStartFrom
// NSString specifying the start point of the search: selection, begin or end.
#define NSAccessibilitySearchTextStartFrom @"AXSearchTextStartFrom"
#endif

#ifndef NSAccessibilitySearchTextStartFromBegin
// Value for SearchTextStartFrom.
#define NSAccessibilitySearchTextStartFromBegin @"AXSearchTextStartFromBegin"
#endif

#ifndef NSAccessibilitySearchTextStartFromSelection
// Value for SearchTextStartFrom.
#define NSAccessibilitySearchTextStartFromSelection @"AXSearchTextStartFromSelection"
#endif

#ifndef NSAccessibilitySearchTextStartFromEnd
// Value for SearchTextStartFrom.
#define NSAccessibilitySearchTextStartFromEnd @"AXSearchTextStartFromEnd"
#endif

#ifndef NSAccessibilitySearchTextDirection
// NSString specifying the direction of the search: forward, backward, closest, all.
#define NSAccessibilitySearchTextDirection @"AXSearchTextDirection"
#endif

#ifndef NSAccessibilitySearchTextDirectionForward
// Value for SearchTextDirection.
#define NSAccessibilitySearchTextDirectionForward @"AXSearchTextDirectionForward"
#endif

#ifndef NSAccessibilitySearchTextDirectionBackward
// Value for SearchTextDirection.
#define NSAccessibilitySearchTextDirectionBackward @"AXSearchTextDirectionBackward"
#endif

#ifndef NSAccessibilitySearchTextDirectionClosest
// Value for SearchTextDirection.
#define NSAccessibilitySearchTextDirectionClosest @"AXSearchTextDirectionClosest"
#endif

#ifndef NSAccessibilitySearchTextDirectionAll
// Value for SearchTextDirection.
#define NSAccessibilitySearchTextDirectionAll @"AXSearchTextDirectionAll"
#endif

// Text operations

#ifndef NSAccessibilityTextOperationParameterizedAttribute
// Performs an operation on the given text.
#define NSAccessibilityTextOperationParameterizedAttribute @"AXTextOperation"
#endif

#ifndef NSAccessibilityTextOperationMarkerRanges
// Text on which to perform operation.
#define NSAccessibilityTextOperationMarkerRanges @"AXTextOperationMarkerRanges"
#endif

#ifndef NSAccessibilityTextOperationType
// The type of operation to be performed: select, replace, capitalize....
#define NSAccessibilityTextOperationType @"AXTextOperationType"
#endif

#ifndef NSAccessibilityTextOperationSelect
// Value for TextOperationType.
#define NSAccessibilityTextOperationSelect @"TextOperationSelect"
#endif

#ifndef NSAccessibilityTextOperationReplace
// Value for TextOperationType.
#define NSAccessibilityTextOperationReplace @"TextOperationReplace"
#endif

#ifndef NSAccessibilityTextOperationCapitalize
// Value for TextOperationType.
#define NSAccessibilityTextOperationCapitalize @"Capitalize"
#endif

#ifndef NSAccessibilityTextOperationLowercase
// Value for TextOperationType.
#define NSAccessibilityTextOperationLowercase @"Lowercase"
#endif

#ifndef NSAccessibilityTextOperationUppercase
// Value for TextOperationType.
#define NSAccessibilityTextOperationUppercase @"Uppercase"
#endif

#ifndef NSAccessibilityTextOperationReplacementString
// Replacement text for operation replace.
#define NSAccessibilityTextOperationReplacementString @"AXTextOperationReplacementString"
#endif

// Math attributes
#define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand"
#define NSAccessibilityMathRootIndexAttribute @"AXMathRootIndex"
#define NSAccessibilityMathFractionDenominatorAttribute @"AXMathFractionDenominator"
#define NSAccessibilityMathFractionNumeratorAttribute @"AXMathFractionNumerator"
#define NSAccessibilityMathBaseAttribute @"AXMathBase"
#define NSAccessibilityMathSubscriptAttribute @"AXMathSubscript"
#define NSAccessibilityMathSuperscriptAttribute @"AXMathSuperscript"
#define NSAccessibilityMathUnderAttribute @"AXMathUnder"
#define NSAccessibilityMathOverAttribute @"AXMathOver"
#define NSAccessibilityMathFencedOpenAttribute @"AXMathFencedOpen"
#define NSAccessibilityMathFencedCloseAttribute @"AXMathFencedClose"
#define NSAccessibilityMathLineThicknessAttribute @"AXMathLineThickness"
#define NSAccessibilityMathPrescriptsAttribute @"AXMathPrescripts"
#define NSAccessibilityMathPostscriptsAttribute @"AXMathPostscripts"

#ifndef NSAccessibilityPreventKeyboardDOMEventDispatchAttribute
#define NSAccessibilityPreventKeyboardDOMEventDispatchAttribute @"AXPreventKeyboardDOMEventDispatch"
#endif

#ifndef NSAccessibilityCaretBrowsingEnabledAttribute
#define NSAccessibilityCaretBrowsingEnabledAttribute @"AXCaretBrowsingEnabled"
#endif

#ifndef NSAccessibilityWebSessionIDAttribute
#define NSAccessibilityWebSessionIDAttribute @"AXWebSessionID"
#endif

#ifndef NSAccessibilitFocusableAncestorAttribute
#define NSAccessibilityFocusableAncestorAttribute @"AXFocusableAncestor"
#endif

#ifndef NSAccessibilityEditableAncestorAttribute
#define NSAccessibilityEditableAncestorAttribute @"AXEditableAncestor"
#endif

#ifndef NSAccessibilityHighestEditableAncestorAttribute
#define NSAccessibilityHighestEditableAncestorAttribute @"AXHighestEditableAncestor"
#endif

#ifndef NSAccessibilityLinkRelationshipTypeAttribute
#define NSAccessibilityLinkRelationshipTypeAttribute @"AXLinkRelationshipType"
#endif

#ifndef NSAccessibilityRelativeFrameAttribute
#define NSAccessibilityRelativeFrameAttribute @"AXRelativeFrame"
#endif

#ifndef NSAccessibilityBrailleLabelAttribute
#define NSAccessibilityBrailleLabelAttribute @"AXBrailleLabel"
#endif

#ifndef NSAccessibilityBrailleRoleDescriptionAttribute
#define NSAccessibilityBrailleRoleDescriptionAttribute @"AXBrailleRoleDescription"
#endif

#ifndef NSAccessibilityEmbeddedImageDescriptionAttribute
#define NSAccessibilityEmbeddedImageDescriptionAttribute @"AXEmbeddedImageDescription"
#endif

#ifndef NSAccessibilityImageOverlayElementsAttribute
#define NSAccessibilityImageOverlayElementsAttribute @"AXImageOverlayElements"
#endif

extern "C" AXUIElementRef NSAccessibilityCreateAXUIElementRef(id element);

@implementation WebAccessibilityObjectWrapper

- (void)unregisterUniqueIdForUIElement
{
    ASSERT(isMainThread());
    NSAccessibilityUnregisterUniqueIdForUIElement(self);
}

- (void)detach
{
    // Send unregisterUniqueIdForUIElement unconditionally because if it is
    // ever accidentally not done (via other bugs in our AX implementation) you
    // end up with a crash like <rdar://problem/4273149>.  It is safe and not
    // expensive to send even if the object is not registered.
    [self unregisterUniqueIdForUIElement];
    [super detach];
}

- (id)attachmentView
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto* widget = backingObject->widgetForAttachmentView();
        return widget ? NSAccessibilityUnignoredDescendant(widget->platformWidget()) : nil;
    });
}

#pragma mark SystemInterface wrappers

static inline BOOL AXObjectIsTextMarker(id object)
{
    return object && CFGetTypeID((__bridge CFTypeRef)object) == AXTextMarkerGetTypeID();
}

static inline BOOL AXObjectIsTextMarkerRange(id object)
{
    return object && CFGetTypeID((__bridge CFTypeRef)object) == AXTextMarkerRangeGetTypeID();
}

#pragma mark Other helpers

- (IntRect)screenToContents:(const IntRect&)rect
{
    ASSERT(isMainThread());

    Document* document = self.axBackingObject->document();
    if (!document)
        return IntRect();
    
    FrameView* frameView = document->view();
    if (!frameView)
        return IntRect();
    
    IntPoint startPoint = frameView->screenToContents(rect.minXMaxYCorner());
    IntPoint endPoint = frameView->screenToContents(rect.maxXMinYCorner());
    return IntRect(startPoint.x(), startPoint.y(), endPoint.x() - startPoint.x(), endPoint.y() - startPoint.y());
}

#pragma mark Select text helpers

// To be deprecated.
static std::pair<AccessibilitySearchTextCriteria, AccessibilityTextOperation> accessibilityTextCriteriaForParameterizedAttribute(const NSDictionary *parameterizedAttribute)
{
    AccessibilitySearchTextCriteria criteria;
    AccessibilityTextOperation operation;

    NSString *activityParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextActivity];
    NSString *ambiguityResolutionParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextAmbiguityResolution];
    NSString *replacementStringParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextReplacementString];
    NSArray *searchStringsParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextSearchStrings];

    if ([activityParameter isKindOfClass:[NSString class]]) {
        if ([activityParameter isEqualToString:NSAccessibilitySelectTextActivityFindAndReplace])
            operation.type = AccessibilityTextOperationType::Replace;
        else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndCapitalize])
            operation.type = AccessibilityTextOperationType::Capitalize;
        else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndLowercase])
            operation.type = AccessibilityTextOperationType::Lowercase;
        else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndUppercase])
            operation.type = AccessibilityTextOperationType::Uppercase;
    }

    criteria.direction = AccessibilitySearchTextDirection::Closest;
    if ([ambiguityResolutionParameter isKindOfClass:[NSString class]]) {
        if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection])
            criteria.direction = AccessibilitySearchTextDirection::Forward;
        else if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection])
            criteria.direction = AccessibilitySearchTextDirection::Backward;
    }

    if ([replacementStringParameter isKindOfClass:[NSString class]])
        operation.replacementText = replacementStringParameter;

    if ([searchStringsParameter isKindOfClass:[NSArray class]])
        criteria.searchStrings = makeVector<String>(searchStringsParameter);

    return std::make_pair(criteria, operation);
}

static AccessibilitySearchTextCriteria accessibilitySearchTextCriteriaForParameterizedAttribute(const NSDictionary *params)
{
    AccessibilitySearchTextCriteria criteria;

    NSArray *searchStrings = [params objectForKey:NSAccessibilitySearchTextSearchStrings];
    NSString *start = [params objectForKey:NSAccessibilitySearchTextStartFrom];
    NSString *direction = [params objectForKey:NSAccessibilitySearchTextDirection];

    if ([searchStrings isKindOfClass:[NSArray class]])
        criteria.searchStrings = makeVector<String>(searchStrings);

    if ([start isKindOfClass:[NSString class]]) {
        if ([start isEqualToString:NSAccessibilitySearchTextStartFromBegin])
            criteria.start = AccessibilitySearchTextStartFrom::Begin;
        else if ([start isEqualToString:NSAccessibilitySearchTextStartFromEnd])
            criteria.start = AccessibilitySearchTextStartFrom::End;
    }

    if ([direction isKindOfClass:[NSString class]]) {
        if ([direction isEqualToString:NSAccessibilitySearchTextDirectionBackward])
            criteria.direction = AccessibilitySearchTextDirection::Backward;
        else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionClosest])
            criteria.direction = AccessibilitySearchTextDirection::Closest;
        else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionAll])
            criteria.direction = AccessibilitySearchTextDirection::All;
    }

    return criteria;
}

static AccessibilityTextOperation accessibilityTextOperationForParameterizedAttribute(AXObjectCache* axObjectCache, const NSDictionary *parameterizedAttribute)
{
    AccessibilityTextOperation operation;

    NSArray *markerRanges = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationMarkerRanges];
    NSString *operationType = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationType];
    NSString *replacementString = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationReplacementString];

    if ([markerRanges isKindOfClass:[NSArray class]]) {
        operation.textRanges = makeVector(markerRanges, [&axObjectCache] (id markerRange) {
            ASSERT(AXObjectIsTextMarkerRange(markerRange));
            return rangeForTextMarkerRange(axObjectCache, (AXTextMarkerRangeRef)markerRange);
        });
    }

    if ([operationType isKindOfClass:[NSString class]]) {
        if ([operationType isEqualToString:NSAccessibilityTextOperationReplace])
            operation.type = AccessibilityTextOperationType::Replace;
        else if ([operationType isEqualToString:NSAccessibilityTextOperationCapitalize])
            operation.type = AccessibilityTextOperationType::Capitalize;
        else if ([operationType isEqualToString:NSAccessibilityTextOperationLowercase])
            operation.type = AccessibilityTextOperationType::Lowercase;
        else if ([operationType isEqualToString:NSAccessibilityTextOperationUppercase])
            operation.type = AccessibilityTextOperationType::Uppercase;
    }

    if ([replacementString isKindOfClass:[NSString class]])
        operation.replacementText = replacementString;

    return operation;
}

static std::pair<std::optional<SimpleRange>, AccessibilitySearchDirection> accessibilityMisspellingSearchCriteriaForParameterizedAttribute(AXObjectCache* axObjectCache, const NSDictionary *params)
{
    ASSERT(isMainThread());

    std::pair<std::optional<SimpleRange>, AccessibilitySearchDirection> criteria;

    ASSERT(AXObjectIsTextMarkerRange([params objectForKey:@"AXStartTextMarkerRange"]));
    criteria.first = rangeForTextMarkerRange(axObjectCache, (AXTextMarkerRangeRef)[params objectForKey:@"AXStartTextMarkerRange"]);

    NSNumber *forward = [params objectForKey:NSAccessibilitySearchTextDirection];
    if ([forward isKindOfClass:[NSNumber class]])
        criteria.second = [forward boolValue] ? AccessibilitySearchDirection::Next : AccessibilitySearchDirection::Previous;
    else
        criteria.second = AccessibilitySearchDirection::Next;

    return criteria;
}

#pragma mark Text Marker helpers

static RetainPtr<AXTextMarkerRef> nextTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
{
    if (!cache)
        return nil;
    
    TextMarkerData textMarkerData;
    cache->textMarkerDataForNextCharacterOffset(textMarkerData, characterOffset);
    if (!textMarkerData.axID)
        return nil;
    return adoptCF(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
}

static RetainPtr<AXTextMarkerRef> previousTextMarkerForCharacterOffset(AXObjectCache* cache, CharacterOffset& characterOffset)
{
    if (!cache)
        return nil;
    
    TextMarkerData textMarkerData;
    cache->textMarkerDataForPreviousCharacterOffset(textMarkerData, characterOffset);
    if (!textMarkerData.axID)
        return nil;
    return adoptCF(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData, sizeof(textMarkerData)));
}

- (RetainPtr<AXTextMarkerRef>)nextTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
    return nextTextMarkerForCharacterOffset(self.axBackingObject->axObjectCache(), characterOffset);
}

- (RetainPtr<AXTextMarkerRef>)previousTextMarkerForCharacterOffset:(CharacterOffset&)characterOffset
{
    return previousTextMarkerForCharacterOffset(self.axBackingObject->axObjectCache(), characterOffset);
}

// FIXME: Remove this method since clients should not need to call this method and should not be exposed in the public interface.
// Inside WebCore, use WebCore::textMarkerFromVisiblePosition instead.
- (id)textMarkerForVisiblePosition:(const VisiblePosition&)position
{
    ASSERT(isMainThread());
    auto *backingObject = self.axBackingObject;
    return backingObject ? (id)textMarkerForVisiblePosition(backingObject->axObjectCache(), position) : nil;
}

- (RetainPtr<AXTextMarkerRef>)textMarkerForFirstPositionInTextControl:(HTMLTextFormControlElement &)textControl
{
    ASSERT(isMainThread());

    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    auto* cache = backingObject->axObjectCache();
    if (!cache)
        return nil;

    auto textMarkerData = cache->textMarkerDataForFirstPositionInTextControl(textControl);
    if (!textMarkerData)
        return nil;

    return adoptCF(AXTextMarkerCreate(kCFAllocatorDefault, (const UInt8*)&textMarkerData.value(), sizeof(textMarkerData.value())));
}

// When modifying attributed strings, the range can come from a source which may provide faulty information (e.g. the spell checker).
// To protect against such cases the range should be validated before adding or removing attributes.
static BOOL AXAttributedStringRangeIsValid(NSAttributedString *attrString, NSRange range)
{
    return (range.location < [attrString length] && NSMaxRange(range) <= [attrString length]);
}

static void AXAttributeStringSetFont(NSMutableAttributedString *attrString, NSString *attribute, CTFontRef font, NSRange range)
{
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;

    if (font) {
        NSDictionary *dictionary = @{
            NSAccessibilityFontNameKey: (__bridge NSString *)adoptCF(CTFontCopyPostScriptName(font)).get(),
            NSAccessibilityFontFamilyKey: (__bridge NSString *)adoptCF(CTFontCopyFamilyName(font)).get(),
            NSAccessibilityVisibleNameKey: (__bridge NSString *)adoptCF(CTFontCopyDisplayName(font)).get(),
            NSAccessibilityFontSizeKey: @(CTFontGetSize(font)),
        };
        [attrString addAttribute:attribute value:dictionary range:range];
    } else
        [attrString removeAttribute:attribute range:range];
    
}

static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range)
{
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;

    if (color) {
        CGColorRef cgColor = color.CGColor;
        id existingColor = [attrString attribute:attribute atIndex:range.location effectiveRange:nil];
        if (!existingColor || !CGColorEqualToColor((__bridge CGColorRef)existingColor, cgColor))
            [attrString addAttribute:attribute value:(__bridge id)cgColor range:range];
    } else
        [attrString removeAttribute:attribute range:range];
}

static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range)
{
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;
    
    if (number)
        [attrString addAttribute:attribute value:number range:range];
    else
        [attrString removeAttribute:attribute range:range];
}

static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
{
    const RenderStyle& style = renderer->style();
    
    // set basic font info
    AXAttributeStringSetFont(attrString, NSAccessibilityFontTextAttribute, style.fontCascade().primaryFont().getCTFont(), range);
    
    // set basic colors
    AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style.visitedDependentColor(CSSPropertyColor)), range);
    AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style.visitedDependentColor(CSSPropertyBackgroundColor)), range);
    
    // set super/sub scripting
    VerticalAlign alignment = style.verticalAlign();
    if (alignment == VerticalAlign::Sub)
        AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, @(-1), range);
    else if (alignment == VerticalAlign::Super)
        AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, @(1), range);
    else
        [attrString removeAttribute:NSAccessibilitySuperscriptTextAttribute range:range];
    
    // set shadow
    if (style.textShadow())
        AXAttributeStringSetNumber(attrString, NSAccessibilityShadowTextAttribute, @YES, range);
    else
        [attrString removeAttribute:NSAccessibilityShadowTextAttribute range:range];
    
    // set underline and strikethrough
    auto decor = style.textDecorationsInEffect();
    if (!(decor & TextDecoration::Underline)) {
        [attrString removeAttribute:NSAccessibilityUnderlineTextAttribute range:range];
        [attrString removeAttribute:NSAccessibilityUnderlineColorTextAttribute range:range];
    }
    
    if (!(decor & TextDecoration::LineThrough)) {
        [attrString removeAttribute:NSAccessibilityStrikethroughTextAttribute range:range];
        [attrString removeAttribute:NSAccessibilityStrikethroughColorTextAttribute range:range];
    }

    if (decor & TextDecoration::Underline || decor & TextDecoration::LineThrough) {
        // FIXME: Should the underline style be reported here?
        auto decorationStyles = TextDecorationPainter::stylesForRenderer(*renderer, decor);

        if (decor & TextDecoration::Underline) {
            AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, @YES, range);
            AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(decorationStyles.underlineColor), range);
        }
        
        if (decor & TextDecoration::LineThrough) {
            AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, @YES, range);
            AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(decorationStyles.linethroughColor), range);
        }
    }
    
    // Indicate background highlighting.
    for (Node* node = renderer->node(); node; node = node->parentNode()) {
        if (node->hasTagName(HTMLNames::markTag))
            AXAttributeStringSetNumber(attrString, @"AXHighlight", @YES, range);
    }
}

static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
{
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;
    
    AccessibilityObject* obj = renderer->document().axObjectCache()->getOrCreate(renderer);
    int quoteLevel = obj->blockquoteLevel();
    
    if (quoteLevel)
        [attrString addAttribute:NSAccessibilityBlockQuoteLevelAttribute value:@(quoteLevel) range:range];
    else
        [attrString removeAttribute:NSAccessibilityBlockQuoteLevelAttribute range:range];
}

static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, StringView text, NSRange range)
{
    ASSERT(node);
    
    // If this node is not inside editable content, do not run the spell checker on the text.
    if (!node->document().axObjectCache()->rootAXEditableElement(node))
        return;

    if (unifiedTextCheckerEnabled(node->document().frame())) {
        // Check the spelling directly since document->markersForNode() does not store the misspelled marking when the cursor is in a word.
        TextCheckerClient* checker = node->document().editor().textChecker();
        
        // checkTextOfParagraph is the only spelling/grammar checker implemented in WK1 and WK2
        Vector<TextCheckingResult> results;
        checkTextOfParagraph(*checker, text, TextCheckingType::Spelling, results, node->document().frame()->selection().selection());
        
        size_t size = results.size();
        for (unsigned i = 0; i < size; i++) {
            const TextCheckingResult& result = results[i];
            AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, @YES, NSMakeRange(result.range.location + range.location, result.range.length));
#if PLATFORM(MAC)
            AXAttributeStringSetNumber(attrString, NSAccessibilityMarkedMisspelledTextAttribute, @YES, NSMakeRange(result.range.location + range.location, result.range.length));
#endif
        }
        return;
    }

    for (unsigned currentPosition = 0; currentPosition < text.length(); ) {
        int misspellingLocation = -1;
        int misspellingLength = 0;
        node->document().editor().textChecker()->checkSpellingOfString(text.substring(currentPosition), &misspellingLocation, &misspellingLength);
        if (misspellingLocation == -1 || !misspellingLength)
            break;
        
        NSRange spellRange = NSMakeRange(range.location + currentPosition + misspellingLocation, misspellingLength);
        AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, @YES, spellRange);
#if PLATFORM(MAC)
        AXAttributeStringSetNumber(attrString, NSAccessibilityMarkedMisspelledTextAttribute, @YES, spellRange);
#endif

        currentPosition += misspellingLocation + misspellingLength;
    }
}

static void AXAttributeStringSetExpandedTextValue(NSMutableAttributedString *attrString, RenderObject* renderer, NSRange range)
{
    if (!renderer || !AXAttributedStringRangeIsValid(attrString, range))
        return;
    AccessibilityObject* axObject = renderer->document().axObjectCache()->getOrCreate(renderer);
    if (axObject->supportsExpandedTextValue())
        [attrString addAttribute:NSAccessibilityExpandedTextValueAttribute value:axObject->expandedTextValue() range:range];
    else
        [attrString removeAttribute:NSAccessibilityExpandedTextValueAttribute range:range];
}

static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
{
    if (!renderer)
        return;
    
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;
    
    // Sometimes there are objects between the text and the heading.
    // In those cases the parent hierarchy should be queried to see if there is a heading level.
    int parentHeadingLevel = 0;
    AccessibilityObject* parentObject = renderer->document().axObjectCache()->getOrCreate(renderer->parent());
    for (; parentObject; parentObject = parentObject->parentObject()) {
        parentHeadingLevel = parentObject->headingLevel();
        if (parentHeadingLevel)
            break;
    }
    
    if (parentHeadingLevel)
        [attrString addAttribute:@"AXHeadingLevel" value:@(parentHeadingLevel) range:range];
    else
        [attrString removeAttribute:@"AXHeadingLevel" range:range];
}

static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, AccessibilityObject* object, NSRange range)
{
    if (!AXAttributedStringRangeIsValid(attrString, range))
        return;
    
    if (is<AccessibilityRenderObject>(object)) {
        // make a serializable AX object
        
        RenderObject* renderer = downcast<AccessibilityRenderObject>(*object).renderer();
        if (!renderer)
            return;
        
        AXObjectCache* cache = renderer->document().axObjectCache();
        if (!cache)
            return;
        
        id objectWrapper = object->wrapper();
        if ([attribute isEqualToString:NSAccessibilityAttachmentTextAttribute] && object->isAttachment() && [objectWrapper attachmentView])
            objectWrapper = [objectWrapper attachmentView];
        
        if (auto axElement = adoptCF(NSAccessibilityCreateAXUIElementRef(objectWrapper)))
            [attrString addAttribute:attribute value:(__bridge id)axElement.get() range:range];
    } else
        [attrString removeAttribute:attribute range:range];
}

static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, StringView text, bool spellCheck)
{
    // skip invisible text
    RenderObject* renderer = node->renderer();
    if (!renderer || !text.length())
        return;
    
    // easier to calculate the range before appending the string
    NSRange attrStringRange = NSMakeRange([attrString length], text.length());
    
    // append the string from this node
    [[attrString mutableString] appendString:text.createNSStringWithoutCopying().get()];
    
    // add new attributes and remove irrelevant inherited ones
    // NOTE: color attributes are handled specially because -[NSMutableAttributedString addAttribute: value: range:] does not merge
    // identical colors.  Workaround is to not replace an existing color attribute if it matches what we are adding.  This also means
    // we cannot just pre-remove all inherited attributes on the appended string, so we have to remove the irrelevant ones individually.
    
    // remove inherited attachment from prior AXAttributedStringAppendReplaced
    [attrString removeAttribute:NSAccessibilityAttachmentTextAttribute range:attrStringRange];
    if (spellCheck) {
#if PLATFORM(MAC)
        [attrString removeAttribute:NSAccessibilityMarkedMisspelledTextAttribute range:attrStringRange];
#endif
        [attrString removeAttribute:NSAccessibilityMisspelledTextAttribute range:attrStringRange];
    }
    
    // set new attributes
    AXAttributeStringSetStyle(attrString, renderer, attrStringRange);
    AXAttributeStringSetHeadingLevel(attrString, renderer, attrStringRange);
    AXAttributeStringSetBlockquoteLevel(attrString, renderer, attrStringRange);
    AXAttributeStringSetExpandedTextValue(attrString, renderer, attrStringRange);
    AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AccessibilityObject::anchorElementForNode(node), attrStringRange);
    
    // do spelling last because it tends to break up the range
    if (spellCheck)
        AXAttributeStringSetSpelling(attrString, node, text, attrStringRange);
}

static NSString* nsStringForReplacedNode(Node* replacedNode)
{
    // we should always be given a rendered node and a replaced node, but be safe
    // replaced nodes are either attachments (widgets) or images
    if (!replacedNode || !isRendererReplacedElement(replacedNode->renderer()) || replacedNode->isTextNode()) {
        ASSERT_NOT_REACHED();
        return nil;
    }
    
    // create an AX object, but skip it if it is not supposed to be seen
    RefPtr<AccessibilityObject> obj = replacedNode->renderer()->document().axObjectCache()->getOrCreate(replacedNode->renderer());
    if (obj->accessibilityIsIgnored())
        return nil;
    
    // use the attachmentCharacter to represent the replaced node
    const UniChar attachmentChar = NSAttachmentCharacter;
    return [NSString stringWithCharacters:&attachmentChar length:1];
}

- (NSAttributedString *)doAXAttributedStringForTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange spellCheck:(BOOL)spellCheck
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<NSAttributedString *>([&textMarkerRange, &spellCheck, protectedSelf = retainPtr(self)] () -> RetainPtr<NSAttributedString> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
        if (!range)
            return nil;
        auto attrString = adoptNS([[NSMutableAttributedString alloc] init]);
        TextIterator it(*range);
        while (!it.atEnd()) {
            Node& node = it.range().start.container;

            // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX)
            if (it.text().length()) {
                // Add the text of the list marker item if necessary.
                String listMarkerText = AccessibilityObject::listMarkerTextForNodeAndPosition(&node, makeContainerOffsetPosition(it.range().start));
                if (!listMarkerText.isEmpty())
                    AXAttributedStringAppendText(attrString.get(), &node, listMarkerText, spellCheck);
                AXAttributedStringAppendText(attrString.get(), &node, it.text(), spellCheck);
            } else {
                Node* replacedNode = it.node();
                NSString *attachmentString = nsStringForReplacedNode(replacedNode);
                if (attachmentString) {
                    NSRange attrStringRange = NSMakeRange([attrString length], [attachmentString length]);

                    // append the placeholder string
                    [[attrString mutableString] appendString:attachmentString];

                    // remove all inherited attributes
                    [attrString setAttributes:nil range:attrStringRange];

                    // add the attachment attribute
                    AccessibilityObject* obj = replacedNode->renderer()->document().axObjectCache()->getOrCreate(replacedNode->renderer());
                    AXAttributeStringSetElement(attrString.get(), NSAccessibilityAttachmentTextAttribute, obj, attrStringRange);
                }
            }
            it.advance();
        }

        return attrString;
    });
}

// FIXME: Remove this method since clients should not need to call this method and should not be exposed in the public interface.
// Inside WebCore, use WebCore::textMarkerRangeFromVisiblePositions instead.
- (id)textMarkerRangeFromVisiblePositions:(const VisiblePosition&)startPosition endPosition:(const VisiblePosition&)endPosition
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&startPosition, &endPosition, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        return (id)textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), startPosition, endPosition);
    });
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSArray*)accessibilityActionNames
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    // All elements should get ShowMenu and ScrollToVisible.
    // But certain earlier VoiceOver versions do not support scroll to visible, and it confuses them to see it in the list.
    static NeverDestroyed<RetainPtr<NSArray>> defaultElementActions = @[NSAccessibilityShowMenuAction, NSAccessibilityScrollToVisibleAction];

    // Action elements allow Press.
    // The order is important to VoiceOver, which expects the 'default' action to be the first action. In this case the default action should be press.
    static NeverDestroyed<RetainPtr<NSArray>> actionElementActions = @[NSAccessibilityPressAction, NSAccessibilityShowMenuAction, NSAccessibilityScrollToVisibleAction];

    // Menu elements allow Press and Cancel.
    static NeverDestroyed<RetainPtr<NSArray>> menuElementActions = [actionElementActions.get() arrayByAddingObject:NSAccessibilityCancelAction];

    // Slider elements allow Increment/Decrement.
    static NeverDestroyed<RetainPtr<NSArray>> sliderActions = [defaultElementActions.get() arrayByAddingObjectsFromArray:@[NSAccessibilityIncrementAction, NSAccessibilityDecrementAction]];

    NSArray *actions;
    if (backingObject->supportsPressAction())
        actions = actionElementActions.get().get();
    else if (backingObject->isMenuRelated())
        actions = menuElementActions.get().get();
    else if (backingObject->isSlider())
        actions = sliderActions.get().get();
    else if (backingObject->isAttachment())
        actions = [[self attachmentView] accessibilityActionNames];
    else
        actions = defaultElementActions.get().get();

    return actions;
}

- (NSArray*)additionalAccessibilityAttributeNames
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    NSMutableArray *additional = [NSMutableArray array];
    if (backingObject->supportsARIAOwns())
        [additional addObject:NSAccessibilityOwnsAttribute];

    if (backingObject->isToggleButton())
        [additional addObject:NSAccessibilityValueAttribute];

    if (backingObject->supportsExpanded() || backingObject->isSummary())
        [additional addObject:NSAccessibilityExpandedAttribute];

    if (backingObject->isScrollbar()
        || backingObject->isRadioGroup()
        || backingObject->isSplitter()
        || backingObject->isToolbar())
        [additional addObject:NSAccessibilityOrientationAttribute];

    if (backingObject->supportsDragging())
        [additional addObject:NSAccessibilityGrabbedAttribute];

    if (backingObject->supportsDropping())
        [additional addObject:NSAccessibilityDropEffectsAttribute];

    if (backingObject->isTable() && backingObject->isExposable() && backingObject->supportsSelectedRows())
        [additional addObject:NSAccessibilitySelectedRowsAttribute];

    if (backingObject->supportsLiveRegion()) {
        [additional addObject:NSAccessibilityARIALiveAttribute];
        [additional addObject:NSAccessibilityARIARelevantAttribute];
    }

    if (backingObject->supportsSetSize())
        [additional addObject:NSAccessibilityARIASetSizeAttribute];

    if (backingObject->supportsPosInSet())
        [additional addObject:NSAccessibilityARIAPosInSetAttribute];

    AccessibilitySortDirection sortDirection = backingObject->sortDirection();
    if (sortDirection != AccessibilitySortDirection::None && sortDirection != AccessibilitySortDirection::Invalid)
        [additional addObject:NSAccessibilitySortDirectionAttribute];

    // If an object is a child of a live region, then add these
    if (backingObject->isInsideLiveRegion())
        [additional addObject:NSAccessibilityARIAAtomicAttribute];

    // All objects should expose the ARIA busy attribute (ARIA 1.1 with ISSUE-538).
    [additional addObject:NSAccessibilityElementBusyAttribute];

    // Popup buttons on the Mac expose the value attribute.
    if (backingObject->isPopUpButton())
        [additional addObject:NSAccessibilityValueAttribute];

    if (backingObject->supportsDatetimeAttribute())
        [additional addObject:NSAccessibilityDatetimeValueAttribute];

    if (backingObject->supportsRequiredAttribute())
        [additional addObject:NSAccessibilityRequiredAttribute];

    if (backingObject->hasPopup())
        [additional addObject:NSAccessibilityHasPopupAttribute];

    if (backingObject->isMathRoot()) {
        // The index of a square root is always known, so there's no object associated with it.
        if (!backingObject->isMathSquareRoot())
            [additional addObject:NSAccessibilityMathRootIndexAttribute];
        [additional addObject:NSAccessibilityMathRootRadicandAttribute];
    } else if (backingObject->isMathFraction()) {
        [additional addObject:NSAccessibilityMathFractionNumeratorAttribute];
        [additional addObject:NSAccessibilityMathFractionDenominatorAttribute];
        [additional addObject:NSAccessibilityMathLineThicknessAttribute];
    } else if (backingObject->isMathSubscriptSuperscript()) {
        [additional addObject:NSAccessibilityMathBaseAttribute];
        [additional addObject:NSAccessibilityMathSubscriptAttribute];
        [additional addObject:NSAccessibilityMathSuperscriptAttribute];
    } else if (backingObject->isMathUnderOver()) {
        [additional addObject:NSAccessibilityMathBaseAttribute];
        [additional addObject:NSAccessibilityMathUnderAttribute];
        [additional addObject:NSAccessibilityMathOverAttribute];
    } else if (backingObject->isMathFenced()) {
        [additional addObject:NSAccessibilityMathFencedOpenAttribute];
        [additional addObject:NSAccessibilityMathFencedCloseAttribute];
    } else if (backingObject->isMathMultiscript()) {
        [additional addObject:NSAccessibilityMathBaseAttribute];
        [additional addObject:NSAccessibilityMathPrescriptsAttribute];
        [additional addObject:NSAccessibilityMathPostscriptsAttribute];
    }

    if (backingObject->supportsPath())
        [additional addObject:NSAccessibilityPathAttribute];

    if (backingObject->supportsExpandedTextValue())
        [additional addObject:NSAccessibilityExpandedTextValueAttribute];

#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    if (AXObjectCache::isIsolatedTreeEnabled())
        [additional addObject:NSAccessibilityRelativeFrameAttribute];
#endif
    
    return additional;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSArray*)accessibilityAttributeNames
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    if (backingObject->isAttachment())
        return [[self attachmentView] accessibilityAttributeNames];

    static NeverDestroyed<RetainPtr<NSArray>> attributes = @[
        NSAccessibilityRoleAttribute,
        NSAccessibilitySubroleAttribute,
        NSAccessibilityRoleDescriptionAttribute,
        NSAccessibilityChildrenAttribute,
        NSAccessibilityHelpAttribute,
        NSAccessibilityParentAttribute,
        NSAccessibilityPositionAttribute,
        NSAccessibilitySizeAttribute,
        NSAccessibilityTitleAttribute,
        NSAccessibilityDescriptionAttribute,
        NSAccessibilityValueAttribute,
        NSAccessibilityFocusedAttribute,
        NSAccessibilityEnabledAttribute,
        NSAccessibilityWindowAttribute,
        @"AXSelectedTextMarkerRange",
        @"AXStartTextMarker",
        @"AXEndTextMarker",
        @"AXVisited",
        NSAccessibilityLinkedUIElementsAttribute,
        NSAccessibilitySelectedAttribute,
        NSAccessibilityBlockQuoteLevelAttribute,
        NSAccessibilityTopLevelUIElementAttribute,
        NSAccessibilityLanguageAttribute,
        NSAccessibilityDOMIdentifierAttribute,
        NSAccessibilityDOMClassListAttribute,
        NSAccessibilityFocusableAncestorAttribute,
        NSAccessibilityEditableAncestorAttribute,
        NSAccessibilityHighestEditableAncestorAttribute,
    ];
    static auto incrementorAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityIncrementButtonAttribute];
        [tempArray addObject:NSAccessibilityDecrementButtonAttribute];
        [tempArray addObject:NSAccessibilityValueDescriptionAttribute];
        [tempArray addObject:NSAccessibilityMinValueAttribute];
        [tempArray addObject:NSAccessibilityMaxValueAttribute];
        return tempArray;
    }());
    static auto anchorAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityURLAttribute];
        [tempArray addObject:NSAccessibilityAccessKeyAttribute];
        [tempArray addObject:NSAccessibilityLinkRelationshipTypeAttribute];
        return tempArray;
    }());
    static NeverDestroyed<RetainPtr<NSArray>> commonMenuAttrs = @[
        NSAccessibilityRoleAttribute,
        NSAccessibilityRoleDescriptionAttribute,
        NSAccessibilityChildrenAttribute,
        NSAccessibilityParentAttribute,
        NSAccessibilityEnabledAttribute,
        NSAccessibilityPositionAttribute,
        NSAccessibilitySizeAttribute,
    ];
    static auto webAreaAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        // WebAreas should not expose AXSubrole.
        [tempArray removeObject:NSAccessibilitySubroleAttribute];
        // WebAreas should not expose ancestor attributes
        [tempArray removeObject:NSAccessibilityFocusableAncestorAttribute];
        [tempArray removeObject:NSAccessibilityEditableAncestorAttribute];
        [tempArray removeObject:NSAccessibilityHighestEditableAncestorAttribute];
        [tempArray addObject:@"AXLinkUIElements"];
        [tempArray addObject:@"AXLoaded"];
        [tempArray addObject:@"AXLayoutCount"];
        [tempArray addObject:NSAccessibilityLoadingProgressAttribute];
        [tempArray addObject:NSAccessibilityURLAttribute];
        [tempArray addObject:NSAccessibilityCaretBrowsingEnabledAttribute];
        [tempArray addObject:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute];
        [tempArray addObject:NSAccessibilityWebSessionIDAttribute];
        return tempArray;
    }());
    static auto textAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityNumberOfCharactersAttribute];
        [tempArray addObject:NSAccessibilitySelectedTextAttribute];
        [tempArray addObject:NSAccessibilitySelectedTextRangeAttribute];
        [tempArray addObject:NSAccessibilityVisibleCharacterRangeAttribute];
        [tempArray addObject:NSAccessibilityInsertionPointLineNumberAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityAccessKeyAttribute];
        [tempArray addObject:NSAccessibilityRequiredAttribute];
        [tempArray addObject:NSAccessibilityInvalidAttribute];
        [tempArray addObject:NSAccessibilityPlaceholderValueAttribute];
        [tempArray addObject:NSAccessibilityValueAutofilledAttribute];
        return tempArray;
    }());
    static auto listAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
        [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        return tempArray;
    }());
    static auto listBoxAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:listAttrs.get().get()]);
        [tempArray addObject:NSAccessibilityAccessKeyAttribute];
        [tempArray addObject:NSAccessibilityRequiredAttribute];
        [tempArray addObject:NSAccessibilityInvalidAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto rangeAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityMinValueAttribute];
        [tempArray addObject:NSAccessibilityMaxValueAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        [tempArray addObject:NSAccessibilityValueDescriptionAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        return tempArray;
    }());
    static auto menuBarAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:commonMenuAttrs.get().get()]);
        [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
        [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto menuAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:commonMenuAttrs.get().get()]);
        [tempArray addObject:NSAccessibilitySelectedChildrenAttribute];
        [tempArray addObject:NSAccessibilityVisibleChildrenAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto menuItemAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:commonMenuAttrs.get().get()]);
        [tempArray addObject:NSAccessibilityTitleAttribute];
        [tempArray addObject:NSAccessibilityDescriptionAttribute];
        [tempArray addObject:NSAccessibilityHelpAttribute];
        [tempArray addObject:NSAccessibilitySelectedAttribute];
        [tempArray addObject:NSAccessibilityValueAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemCmdCharAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemCmdVirtualKeyAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemCmdGlyphAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemCmdModifiersAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemMarkCharAttribute];
        [tempArray addObject:(NSString*)kAXMenuItemPrimaryUIElementAttribute];
        [tempArray addObject:NSAccessibilityServesAsTitleForUIElementsAttribute];
        [tempArray addObject:NSAccessibilityFocusedAttribute];
        return tempArray;
    }());
    static NeverDestroyed<RetainPtr<NSArray>> menuButtonAttrs = @[
        NSAccessibilityRoleAttribute,
        NSAccessibilityRoleDescriptionAttribute,
        NSAccessibilityParentAttribute,
        NSAccessibilityPositionAttribute,
        NSAccessibilitySizeAttribute,
        NSAccessibilityWindowAttribute,
        NSAccessibilityEnabledAttribute,
        NSAccessibilityFocusedAttribute,
        NSAccessibilityTitleAttribute,
        NSAccessibilityChildrenAttribute,
    ];
    static auto controlAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityAccessKeyAttribute];
        [tempArray addObject:NSAccessibilityRequiredAttribute];
        [tempArray addObject:NSAccessibilityInvalidAttribute];
        return tempArray;
    }());
    static auto buttonAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        // Buttons should not expose AXValue.
        [tempArray removeObject:NSAccessibilityValueAttribute];
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityAccessKeyAttribute];
        return tempArray;
    }());
    static auto comboBoxAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:controlAttrs.get().get()]);
        [tempArray addObject:NSAccessibilityExpandedAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto tableAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityRowsAttribute];
        [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
        [tempArray addObject:NSAccessibilityColumnsAttribute];
        [tempArray addObject:NSAccessibilityVisibleColumnsAttribute];
        [tempArray addObject:NSAccessibilityVisibleCellsAttribute];
        [tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
        [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
        [tempArray addObject:NSAccessibilityHeaderAttribute];
        [tempArray addObject:NSAccessibilityColumnCountAttribute];
        [tempArray addObject:NSAccessibilityRowCountAttribute];
        [tempArray addObject:NSAccessibilityARIAColumnCountAttribute];
        [tempArray addObject:NSAccessibilityARIARowCountAttribute];
        return tempArray;
    }());
    static auto tableRowAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityIndexAttribute];
        return tempArray;
    }());
    static auto tableColAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityIndexAttribute];
        [tempArray addObject:NSAccessibilityHeaderAttribute];
        [tempArray addObject:NSAccessibilityRowsAttribute];
        [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
        return tempArray;
    }());
    static auto tableCellAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
        [tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
        [tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
        [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
        [tempArray addObject:NSAccessibilityARIAColumnIndexAttribute];
        [tempArray addObject:NSAccessibilityARIARowIndexAttribute];
        return tempArray;
    }());
    static auto groupAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        return tempArray;
    }());
    static auto inputImageAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:buttonAttrs.get().get()]);
        [tempArray addObject:NSAccessibilityURLAttribute];
        return tempArray;
    }());
    static auto passwordFieldAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityTitleUIElementAttribute];
        [tempArray addObject:NSAccessibilityRequiredAttribute];
        [tempArray addObject:NSAccessibilityInvalidAttribute];
        [tempArray addObject:NSAccessibilityPlaceholderValueAttribute];
        [tempArray addObject:NSAccessibilityValueAutofilledAttribute];
        return tempArray;
    }());
    static auto tabListAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityTabsAttribute];
        [tempArray addObject:NSAccessibilityContentsAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto outlineAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilitySelectedRowsAttribute];
        [tempArray addObject:NSAccessibilityRowsAttribute];
        [tempArray addObject:NSAccessibilityColumnsAttribute];
        [tempArray addObject:NSAccessibilityOrientationAttribute];
        return tempArray;
    }());
    static auto outlineRowAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:tableRowAttrs.get().get()]);
        [tempArray addObject:NSAccessibilityDisclosingAttribute];
        [tempArray addObject:NSAccessibilityDisclosedByRowAttribute];
        [tempArray addObject:NSAccessibilityDisclosureLevelAttribute];
        [tempArray addObject:NSAccessibilityDisclosedRowsAttribute];
        [tempArray removeObject:NSAccessibilityValueAttribute];
        return tempArray;
    }());
    static auto scrollViewAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityContentsAttribute];
        [tempArray addObject:NSAccessibilityHorizontalScrollBarAttribute];
        [tempArray addObject:NSAccessibilityVerticalScrollBarAttribute];
        return tempArray;
    }());
    static auto imageAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        [tempArray addObject:NSAccessibilityImageOverlayElementsAttribute];
        [tempArray addObject:NSAccessibilityEmbeddedImageDescriptionAttribute];
        [tempArray addObject:NSAccessibilityURLAttribute];
        return tempArray;
    }());
    static auto videoAttrs = makeNeverDestroyed([] {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:attributes.get().get()]);
        // This should represent the URL of the video content, not the poster.
        [tempArray addObject:NSAccessibilityURLAttribute];
        return tempArray;
    }());

    NSArray *objectAttributes = attributes.get().get();

    if (backingObject->isPasswordField())
        objectAttributes = passwordFieldAttrs.get().get();
    else if (backingObject->isWebArea())
        objectAttributes = webAreaAttrs.get().get();
    else if (backingObject->isTextControl())
        objectAttributes = textAttrs.get().get();
    else if (backingObject->isLink())
        objectAttributes = anchorAttrs.get().get();
    else if (backingObject->isImage())
        objectAttributes = imageAttrs.get().get();
    else if (backingObject->isTable() && backingObject->isExposable())
        objectAttributes = tableAttrs.get().get();
    else if (backingObject->isTableColumn())
        objectAttributes = tableColAttrs.get().get();
    else if (backingObject->isTableCell())
        objectAttributes = tableCellAttrs.get().get();
    else if (backingObject->isTableRow()) {
        // An ARIA table row can be collapsed and expanded, so it needs the extra attributes.
        if (backingObject->isARIATreeGridRow())
            objectAttributes = outlineRowAttrs.get().get();
        else
            objectAttributes = tableRowAttrs.get().get();
    } else if (backingObject->isTree())
        objectAttributes = outlineAttrs.get().get();
    else if (backingObject->isTreeItem()) {
        if (backingObject->supportsCheckedState())
            objectAttributes = [outlineRowAttrs.get() arrayByAddingObject:NSAccessibilityValueAttribute];
        else
            objectAttributes = outlineRowAttrs.get().get();
    }
    else if (backingObject->isListBox())
        objectAttributes = listBoxAttrs.get().get();
    else if (backingObject->isList())
        objectAttributes = listAttrs.get().get();
    else if (backingObject->isComboBox())
        objectAttributes = comboBoxAttrs.get().get();
    else if (backingObject->isProgressIndicator() || backingObject->isSlider())
        objectAttributes = rangeAttrs.get().get();
    // These are processed in order because an input image is a button, and a button is a control.
    else if (backingObject->isInputImage())
        objectAttributes = inputImageAttrs.get().get();
    else if (backingObject->isButton())
        objectAttributes = buttonAttrs.get().get();
    else if (backingObject->isControl())
        objectAttributes = controlAttrs.get().get();

    else if (backingObject->isGroup() || backingObject->isListItem())
        objectAttributes = groupAttrs.get().get();
    else if (backingObject->isTabList())
        objectAttributes = tabListAttrs.get().get();
    else if (backingObject->isScrollView())
        objectAttributes = scrollViewAttrs.get().get();
    else if (backingObject->isSpinButton())
        objectAttributes = incrementorAttrs.get().get();
    else if (backingObject->isMenu())
        objectAttributes = menuAttrs.get().get();
    else if (backingObject->isMenuBar())
        objectAttributes = menuBarAttrs.get().get();
    else if (backingObject->isMenuButton())
        objectAttributes = menuButtonAttrs.get().get();
    else if (backingObject->isMenuItem())
        objectAttributes = menuItemAttrs.get().get();
    else if (backingObject->isVideo())
        objectAttributes = videoAttrs.get().get();

    NSArray *additionalAttributes = [self additionalAccessibilityAttributeNames];
    if ([additionalAttributes count])
        objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:additionalAttributes];

    // Only expose AXARIACurrent attribute when the element is set to be current item.
    if (backingObject->currentState() != AccessibilityCurrentState::False)
        objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityARIACurrentAttribute ]];

    // AppKit needs to know the screen height in order to do the coordinate conversion.
    objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityPrimaryScreenHeightAttribute ]];

    return objectAttributes;
}

- (NSArray*)renderWidgetChildren
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    auto* widget = backingObject->widget();
    if (widget && widget->accessibilityObject())
        return @[widget->accessibilityObject()];

    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    return [backingObject->platformWidget() accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
    ALLOW_DEPRECATED_DECLARATIONS_END
}

- (id)remoteAccessibilityParentObject
{
    auto* backingObject = self.axBackingObject;
    return backingObject ? backingObject->remoteParentObject() : nil;
}

static void convertToVector(NSArray* array, AccessibilityObject::AccessibilityChildrenVector& vector)
{
    unsigned length = [array count];
    vector.reserveInitialCapacity(length);
    for (unsigned i = 0; i < length; ++i) {
        AXCoreObject* obj = [[array objectAtIndex:i] axBackingObject];
        if (obj)
            vector.append(obj);
    }
}

- (AXTextMarkerRangeRef)selectedTextMarkerRange
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRangeRef>([protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRangeRef> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto selectedVisiblePositionRange = backingObject->selectedVisiblePositionRange();
        if (selectedVisiblePositionRange.isNull())
            return nil;
        return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), selectedVisiblePositionRange.start, selectedVisiblePositionRange.end);
    });
}

- (id)associatedPluginParent
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject || !backingObject->hasApplePDFAnnotationAttribute())
            return nil;

        if (!backingObject->document()->isPluginDocument())
            return nil;

        Widget* pluginWidget = static_cast<PluginDocument*>(backingObject->document())->pluginWidget();
        if (!pluginWidget || !pluginWidget->isPluginViewBase())
            return nil;

        return static_cast<PluginViewBase*>(pluginWidget)->accessibilityAssociatedPluginParentForElement(backingObject->element());
    });
}

static void WebTransformCGPathToNSBezierPath(void* info, const CGPathElement *element)
{
    NSBezierPath *bezierPath = (__bridge NSBezierPath *)info;
    switch (element->type) {
    case kCGPathElementMoveToPoint:
        [bezierPath moveToPoint:NSPointFromCGPoint(element->points[0])];
        break;
    case kCGPathElementAddLineToPoint:
        [bezierPath lineToPoint:NSPointFromCGPoint(element->points[0])];
        break;
    case kCGPathElementAddCurveToPoint:
        [bezierPath curveToPoint:NSPointFromCGPoint(element->points[0]) controlPoint1:NSPointFromCGPoint(element->points[1]) controlPoint2:NSPointFromCGPoint(element->points[2])];
        break;
    case kCGPathElementCloseSubpath:
        [bezierPath closePath];
        break;
    default:
        break;
    }
}

- (NSBezierPath *)bezierPathFromPath:(CGPathRef)path
{
    NSBezierPath *bezierPath = [NSBezierPath bezierPath];
    CGPathApply(path, (__bridge void*)bezierPath, WebTransformCGPathToNSBezierPath);
    return bezierPath;
}

- (NSBezierPath *)path
{
    Path path = self.axBackingObject->elementPath();
    if (path.isEmpty())
        return NULL;
    
    CGPathRef transformedPath = [self convertPathToScreenSpace:path];
    return [self bezierPathFromPath:transformedPath];
}

- (NSNumber *)primaryScreenHeight
{
    // The rect for primary screen should not change in normal use. So cache it
    // here to avoid hitting the main thread repeatedly.
    static FloatRect screenRect = Accessibility::retrieveValueFromMainThread<FloatRect>([] () -> FloatRect {
        return screenRectForPrimaryScreen();
    });
    return [NSNumber numberWithFloat:screenRect.height()];
}

- (size_t)childrenVectorSize
{
    return self.axBackingObject->children().size();
}

- (NSArray<WebAccessibilityObjectWrapper *> *)childrenVectorArray
{
    return convertToNSArray(self.axBackingObject->children());
}

- (NSValue *)position
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    auto rect = snappedIntRect(backingObject->elementRect());

    // The Cocoa accessibility API wants the lower-left corner.
    FloatPoint floatPoint(rect.x(), rect.maxY());

    // FIXME: add a function to convert a point, no need to convert a rect when you only need a point.
    FloatRect floatRect(floatPoint, FloatSize());
    CGRect cgRect(backingObject->convertRectToPlatformSpace(floatRect, AccessibilityConversionSpace::Screen));
    return @(cgRect.origin);
}

- (NSString*)role
{
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if (self.axBackingObject->isAttachment())
        return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleAttribute];
    ALLOW_DEPRECATED_DECLARATIONS_END

    NSString *string = self.axBackingObject->rolePlatformString();
    if (string.length)
        return string;
    return NSAccessibilityUnknownRole;
}

ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- (NSString*)subrole
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    // FIXME: create AXCoreObject::subrolePlatformString to replace the following linear search and heuristics, similar to rolePlatformString.
    if (backingObject->isPasswordField())
        return NSAccessibilitySecureTextFieldSubrole;
    if (backingObject->isSearchField())
        return NSAccessibilitySearchFieldSubrole;

    if (backingObject->isAttachment()) {
        NSView* attachView = [self attachmentView];
        if ([[attachView accessibilityAttributeNames] containsObject:NSAccessibilitySubroleAttribute])
            return [attachView accessibilityAttributeValue:NSAccessibilitySubroleAttribute];
    }

    if (backingObject->isMeter())
        return @"AXMeter";

    AccessibilityRole role = backingObject->roleValue();
    if (role == AccessibilityRole::HorizontalRule)
        return NSAccessibilityContentSeparatorSubrole;
    if (role == AccessibilityRole::ToggleButton)
        return NSAccessibilityToggleSubrole;
    if (role == AccessibilityRole::Footer)
        return @"AXFooter";
    if (role == AccessibilityRole::SpinButtonPart) {
        if (backingObject->isIncrementor())
            return NSAccessibilityIncrementArrowSubrole;
        return NSAccessibilityDecrementArrowSubrole;
    }

    if (backingObject->isFileUploadButton())
        return @"AXFileUploadButton";

    if (backingObject->isTreeItem())
        return NSAccessibilityOutlineRowSubrole;

    if (backingObject->isFieldset())
        return @"AXFieldset";

    if (backingObject->isList()) {
        if (backingObject->isUnorderedList() || backingObject->isOrderedList())
            return NSAccessibilityContentListSubrole;
        if (backingObject->isDescriptionList()) {
            return NSAccessibilityDescriptionListSubrole;
        }
    }

    // ARIA content subroles.
    switch (role) {
    case AccessibilityRole::LandmarkBanner:
        return @"AXLandmarkBanner";
    case AccessibilityRole::LandmarkComplementary:
        return @"AXLandmarkComplementary";
    case AccessibilityRole::LandmarkContentInfo:
        return @"AXLandmarkContentInfo";
    case AccessibilityRole::LandmarkMain:
        return @"AXLandmarkMain";
    case AccessibilityRole::LandmarkNavigation:
        return @"AXLandmarkNavigation";
    case AccessibilityRole::LandmarkDocRegion:
    case AccessibilityRole::LandmarkRegion:
        return @"AXLandmarkRegion";
    case AccessibilityRole::LandmarkSearch:
        return @"AXLandmarkSearch";
    case AccessibilityRole::ApplicationAlert:
        return @"AXApplicationAlert";
    case AccessibilityRole::ApplicationAlertDialog:
        return @"AXApplicationAlertDialog";
    case AccessibilityRole::ApplicationDialog:
        return @"AXApplicationDialog";
    case AccessibilityRole::ApplicationGroup:
    case AccessibilityRole::ApplicationTextGroup:
    case AccessibilityRole::Feed:
    case AccessibilityRole::Footnote:
        return @"AXApplicationGroup";
    case AccessibilityRole::ApplicationLog:
        return @"AXApplicationLog";
    case AccessibilityRole::ApplicationMarquee:
        return @"AXApplicationMarquee";
    case AccessibilityRole::ApplicationStatus:
        return @"AXApplicationStatus";
    case AccessibilityRole::ApplicationTimer:
        return @"AXApplicationTimer";
    case AccessibilityRole::Document:
    case AccessibilityRole::GraphicsDocument:
        return @"AXDocument";
    case AccessibilityRole::DocumentArticle:
        return @"AXDocumentArticle";
    case AccessibilityRole::DocumentMath:
        return @"AXDocumentMath";
    case AccessibilityRole::DocumentNote:
        return @"AXDocumentNote";
    case AccessibilityRole::UserInterfaceTooltip:
        return @"AXUserInterfaceTooltip";
    case AccessibilityRole::TabPanel:
        return @"AXTabPanel";
    case AccessibilityRole::Definition:
        return @"AXDefinition";
    case AccessibilityRole::DescriptionListTerm:
    case AccessibilityRole::Term:
        return @"AXTerm";
    case AccessibilityRole::DescriptionListDetail:
        return @"AXDescription";
    case AccessibilityRole::WebApplication:
        return @"AXWebApplication";
        // Default doesn't return anything, so roles defined below can be chosen.
    default:
        break;
    }

    if (role == AccessibilityRole::MathElement) {
        if (backingObject->isMathFraction())
            return @"AXMathFraction";
        if (backingObject->isMathFenced())
            return @"AXMathFenced";
        if (backingObject->isMathSubscriptSuperscript())
            return @"AXMathSubscriptSuperscript";
        if (backingObject->isMathRow())
            return @"AXMathRow";
        if (backingObject->isMathUnderOver())
            return @"AXMathUnderOver";
        if (backingObject->isMathSquareRoot())
            return @"AXMathSquareRoot";
        if (backingObject->isMathRoot())
            return @"AXMathRoot";
        if (backingObject->isMathText())
            return @"AXMathText";
        if (backingObject->isMathNumber())
            return @"AXMathNumber";
        if (backingObject->isMathIdentifier())
            return @"AXMathIdentifier";
        if (backingObject->isMathTable())
            return @"AXMathTable";
        if (backingObject->isMathTableRow())
            return @"AXMathTableRow";
        if (backingObject->isMathTableCell())
            return @"AXMathTableCell";
        if (backingObject->isMathFenceOperator())
            return @"AXMathFenceOperator";
        if (backingObject->isMathSeparatorOperator())
            return @"AXMathSeparatorOperator";
        if (backingObject->isMathOperator())
            return @"AXMathOperator";
        if (backingObject->isMathMultiscript())
            return @"AXMathMultiscript";
    }

    if (role == AccessibilityRole::Video)
        return @"AXVideo";
    if (role == AccessibilityRole::Audio)
        return @"AXAudio";
    if (role == AccessibilityRole::Details)
        return @"AXDetails";
    if (role == AccessibilityRole::Summary)
        return @"AXSummary";
    if (role == AccessibilityRole::Time)
        return @"AXTimeGroup";

    if (backingObject->isMediaTimeline())
        return NSAccessibilityTimelineSubrole;

    if (backingObject->isSwitch())
        return NSAccessibilitySwitchSubrole;

    if (role == AccessibilityRole::Insertion)
        return @"AXInsertStyleGroup";
    if (role == AccessibilityRole::Deletion)
        return @"AXDeleteStyleGroup";
    if (role == AccessibilityRole::Superscript)
        return @"AXSuperscriptStyleGroup";
    if (role == AccessibilityRole::Subscript)
        return @"AXSubscriptStyleGroup";

    if (backingObject->isStyleFormatGroup()) {
        using namespace HTMLNames;
        auto tagName = backingObject->tagName();
        if (tagName == kbdTag)
            return @"AXKeyboardInputStyleGroup";
        if (tagName == codeTag)
            return @"AXCodeStyleGroup";
        if (tagName == preTag)
            return @"AXPreformattedStyleGroup";
        if (tagName == sampTag)
            return @"AXSampleStyleGroup";
        if (tagName == varTag)
            return @"AXVariableStyleGroup";
        if (tagName == citeTag)
            return @"AXCiteStyleGroup";
        ASSERT_NOT_REACHED();
    }

    // Ruby subroles
    switch (role) {
    case AccessibilityRole::RubyBase:
        return NSAccessibilityRubyBaseSubrole;
    case AccessibilityRole::RubyBlock:
        return NSAccessibilityRubyBlockSubrole;
    case AccessibilityRole::RubyInline:
        return NSAccessibilityRubyInlineSubrole;
    case AccessibilityRole::RubyRun:
        return NSAccessibilityRubyRunSubrole;
    case AccessibilityRole::RubyText:
        return NSAccessibilityRubyTextSubrole;
    default:
        break;
    }

    return nil;
}
ALLOW_DEPRECATED_DECLARATIONS_END

- (NSString*)roleDescription
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return nil;

    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    // attachments have the AXImage role, but a different subrole
    if (backingObject->isAttachment())
        return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute];
    ALLOW_DEPRECATED_DECLARATIONS_END

    String roleDescription = backingObject->roleDescription();
    if (!roleDescription.isEmpty())
        return roleDescription;

    NSString *axRole = backingObject->rolePlatformString();
    NSString *subrole = self.subrole;
    // Fallback to the system default role description.
    // If we get the same string back, then as a last resort, return unknown.
    NSString *defaultRoleDescription = NSAccessibilityRoleDescription(axRole, subrole);

    // On earlier Mac versions (Lion), using a non-standard subrole would result in a role description
    // being returned that looked like AXRole:AXSubrole. To make all platforms have the same role descriptions
    // we should fallback on a role description ignoring the subrole in these cases.
    if ([defaultRoleDescription isEqualToString:[NSString stringWithFormat:@"%@:%@", axRole, subrole]])
        defaultRoleDescription = NSAccessibilityRoleDescription(axRole, nil);

    if (![defaultRoleDescription isEqualToString:axRole])
        return defaultRoleDescription;

    return NSAccessibilityRoleDescription(NSAccessibilityUnknownRole, nil);
}

- (NSString *)computedRoleString
{
    if (!self.axBackingObject)
        return nil;
    return self.axBackingObject->computedRoleString();
}

- (id)scrollViewParent
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject || !backingObject->isScrollView())
        return nil;

    // If this scroll view provides it's parent object (because it's a sub-frame), then
    // we should not find the remoteAccessibilityParent.
    if (backingObject->parentObject())
        return nil;

    if (auto platformWidget = backingObject->platformWidget())
        return NSAccessibilityUnignoredAncestor(platformWidget);

    return backingObject->remoteParentObject();
}

- (id)windowElement:(NSString*)attributeName
{
    if (id remoteParent = self.remoteAccessibilityParentObject) {
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        return [remoteParent accessibilityAttributeValue:attributeName];
        ALLOW_DEPRECATED_DECLARATIONS_END
    }

    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        if (auto* fv = backingObject->documentFrameView())
            return [fv->platformWidget() window];

        return nil;
    });
}

// FIXME: split up this function in a better way.
// suggestions: Use a hash table that maps attribute names to function calls,
// or maybe pointers to member functions
ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (id)accessibilityAttributeValue:(NSString*)attributeName
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    AXTRACE(makeString("WebAccessibilityObjectWrapper accessibilityAttributeValue:", String(attributeName)));

    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject) {
        AXLOG("No backingObject!!!");
        return nil;
    }

    if (backingObject->isDetachedFromParent()) {
        AXLOG("backingObject is detached from parent!!!");
        return nil;
    }

    if ([attributeName isEqualToString: NSAccessibilityRoleAttribute])
        return [self role];

    if ([attributeName isEqualToString: NSAccessibilitySubroleAttribute])
        return [self subrole];

    if ([attributeName isEqualToString: NSAccessibilityRoleDescriptionAttribute])
        return [self roleDescription];

    // AXARIARole is only used by DumpRenderTree (so far).
    if ([attributeName isEqualToString:@"AXARIARole"])
        return [self computedRoleString];

    if ([attributeName isEqualToString: NSAccessibilityParentAttribute]) {

        // This will return the parent of the AXWebArea, if this is a web area.
        id scrollViewParent = [self scrollViewParent];
        if (scrollViewParent)
            return scrollViewParent;

        // Tree item (changed to AXRows) can only report the tree (AXOutline) as its parent.
        if (backingObject->isTreeItem()) {
            auto parent = backingObject->parentObjectUnignored();
            while (parent) {
                if (parent->isTree())
                    return parent->wrapper();
                parent = parent->parentObjectUnignored();
            }
        }

        auto parent = backingObject->parentObjectUnignored();
        if (!parent)
            return nil;

        // In WebKit1, the scroll view is provided by the system (the attachment view), so the parent
        // should be reported directly as such.
        if (backingObject->isWebArea() && parent->isAttachment())
            return [parent->wrapper() attachmentView];

        return parent->wrapper();
    }

    if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute] || [attributeName isEqualToString: NSAccessibilityChildrenInNavigationOrderAttribute]) {
        if (!self.childrenVectorSize) {
            NSArray* children = [self renderWidgetChildren];
            if (children != nil)
                return children;
        }

        // The tree's (AXOutline) children are supposed to be its rows and columns.
        // The ARIA spec doesn't have columns, so we just need rows.
        if (backingObject->isTree())
            return [self accessibilityAttributeValue:NSAccessibilityRowsAttribute];

        // A tree item should only expose its content as its children (not its rows)
        if (backingObject->isTreeItem()) {
            AccessibilityObject::AccessibilityChildrenVector contentCopy;
            backingObject->ariaTreeItemContent(contentCopy);
            return convertToNSArray(contentCopy);
        }

        return self.childrenVectorArray;
    }

    if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
        if (backingObject->canHaveSelectedChildren()) {
            AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
            backingObject->selectedChildren(selectedChildrenCopy);
            return convertToNSArray(selectedChildrenCopy);
        }
        return nil;
    }

    if ([attributeName isEqualToString: NSAccessibilityVisibleChildrenAttribute]) {
        if (backingObject->isListBox()) {
            AccessibilityObject::AccessibilityChildrenVector visibleChildrenCopy;
            backingObject->visibleChildren(visibleChildrenCopy);
            return convertToNSArray(visibleChildrenCopy);
        }

        if (backingObject->isList())
            return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute];

        return nil;
    }


    if (backingObject->isWebArea()) {
        if ([attributeName isEqualToString:@"AXLinkUIElements"])
            return convertToNSArray(backingObject->documentLinks());

        if ([attributeName isEqualToString:@"AXLoaded"])
            return [NSNumber numberWithBool:backingObject->isLoaded()];
        if ([attributeName isEqualToString:@"AXLayoutCount"])
            return @(backingObject->layoutCount());
        if ([attributeName isEqualToString:NSAccessibilityLoadingProgressAttribute])
            return @(backingObject->estimatedLoadingProgress());
        if ([attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
            return [NSNumber numberWithBool:backingObject->preventKeyboardDOMEventDispatch()];
        if ([attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
            return [NSNumber numberWithBool:backingObject->caretBrowsingEnabled()];
        if ([attributeName isEqualToString:NSAccessibilityWebSessionIDAttribute])
            return @(backingObject->sessionID());
    }

    if (backingObject->isTextControl()) {
        if ([attributeName isEqualToString: NSAccessibilityNumberOfCharactersAttribute]) {
            int length = backingObject->textLength();
            if (length < 0)
                return nil;
            return @(length);
        }
        if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
            String selectedText = backingObject->selectedText();
            if (selectedText.isNull())
                return nil;
            return (NSString*)selectedText;
        }
        if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
            PlainTextRange textRange = backingObject->selectedTextRange();
            return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
        }
        // TODO: Get actual visible range. <rdar://problem/4712101>
        if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
            return backingObject->isPasswordField() ? nil : [NSValue valueWithRange: NSMakeRange(0, backingObject->textLength())];

        if ([attributeName isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) {
            int lineNumber = backingObject->insertionPointLineNumber();
            return lineNumber >= 0 ? @(lineNumber) : nil;
        }
    }

    if ([attributeName isEqualToString: NSAccessibilityURLAttribute]) {
        URL url = backingObject->url();
        if (url.isNull())
            return nil;
        return (NSURL*)url;
    }

    if ([attributeName isEqualToString:NSAccessibilityIncrementButtonAttribute]) {
        auto incrementButton = backingObject->incrementButton();
        return incrementButton ? incrementButton->wrapper() : nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityDecrementButtonAttribute]) {
        auto decrementButton = backingObject->decrementButton();
        return decrementButton ? decrementButton->wrapper() : nil;
    }

    if ([attributeName isEqualToString: @"AXVisited"])
        return [NSNumber numberWithBool: backingObject->isVisited()];

    if ([attributeName isEqualToString: NSAccessibilityTitleAttribute]) {
        if (backingObject->isAttachment()) {
            if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute])
                return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityTitleAttribute];
        }

        return backingObject->titleAttributeValue();
    }

    if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) {
        if (backingObject->isAttachment()) {
            if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute])
                return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
        }
        return [self baseAccessibilityDescription];
    }

    if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
        if (backingObject->isAttachment()) {
            if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
                return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
        }

        auto value = backingObject->value();
        return WTF::switchOn(value,
            [] (bool& typedValue) -> id { return @(typedValue); },
            [] (unsigned& typedValue) -> id { return @(typedValue); },
            [] (float& typedValue) -> id { return @(typedValue); },
            [] (String& typedValue) -> id { return (NSString *)typedValue; },
            [] (AccessibilityButtonState& typedValue) -> id { return @((unsigned)typedValue); },
            [] (AXCoreObject*& typedValue) { return typedValue ? (id)typedValue->wrapper() : nil; },
            [] (auto&) { return nil; }
        );
    }

    if ([attributeName isEqualToString:(NSString *)kAXMenuItemMarkCharAttribute]) {
        const unichar ch = 0x2713; // ✓ used on Mac for selected menu items.
        return (backingObject->isChecked()) ? [NSString stringWithCharacters:&ch length:1] : nil;
    }

    if ([attributeName isEqualToString: NSAccessibilityMinValueAttribute]) {
        // Indeterminate progress indicator should return 0.
        if (backingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !backingObject->hasARIAValueNow())
            return @0;
        return [NSNumber numberWithFloat:backingObject->minValueForRange()];
    }

    if ([attributeName isEqualToString: NSAccessibilityMaxValueAttribute]) {
        // Indeterminate progress indicator should return 0.
        if (backingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !backingObject->hasARIAValueNow())
            return @0;
        return [NSNumber numberWithFloat:backingObject->maxValueForRange()];
    }

    if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
        return [self baseAccessibilityHelpText];

    if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
        return [NSNumber numberWithBool: backingObject->isFocused()];

    if ([attributeName isEqualToString: NSAccessibilityEnabledAttribute])
        return [NSNumber numberWithBool: backingObject->isEnabled()];

    if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) {
        IntSize s = snappedIntRect(backingObject->elementRect()).size();
        return [NSValue valueWithSize: NSMakeSize(s.width(), s.height())];
    }

    if ([attributeName isEqualToString: NSAccessibilityPrimaryScreenHeightAttribute])
        return [self primaryScreenHeight];
    if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
        return [self position];
    if ([attributeName isEqualToString:NSAccessibilityPathAttribute])
        return [self path];

    if ([attributeName isEqualToString:@"AXLineRectsAndText"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<NSArray *>([protectedSelf = retainPtr(self)] () -> RetainPtr<NSArray> {
            return protectedSelf.get().lineRectsAndText;
        });
    }

    if ([attributeName isEqualToString:NSAccessibilityImageOverlayElementsAttribute]) {
        auto imageOverlayElements = backingObject->imageOverlayElements();
        return imageOverlayElements ? convertToNSArray(*imageOverlayElements) : nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityEmbeddedImageDescriptionAttribute])
        return backingObject->embeddedImageDescription();

    if ([attributeName isEqualToString:NSAccessibilityWindowAttribute]
        || [attributeName isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
        return [self windowElement:attributeName];

    if ([attributeName isEqualToString:NSAccessibilityAccessKeyAttribute]) {
        AtomString accessKey = backingObject->accessKey();
        if (accessKey.isNull())
            return nil;
        return accessKey;
    }

    if ([attributeName isEqualToString:NSAccessibilityLinkRelationshipTypeAttribute])
        return backingObject->linkRelValue();

    if ([attributeName isEqualToString:NSAccessibilityTabsAttribute]) {
        if (backingObject->isTabList()) {
            AccessibilityObject::AccessibilityChildrenVector tabsChildren;
            backingObject->tabChildren(tabsChildren);
            return convertToNSArray(tabsChildren);
        }
    }

    if ([attributeName isEqualToString:NSAccessibilityContentsAttribute])
        return convertToNSArray(backingObject->contents());

    if (backingObject->isTable() && backingObject->isExposable()) {
        if ([attributeName isEqualToString:NSAccessibilityRowsAttribute])
            return convertToNSArray(backingObject->rows());

        if ([attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute])
            return convertToNSArray(backingObject->visibleRows());

        // TODO: distinguish between visible and non-visible columns
        if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute]
            || [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute])
            return convertToNSArray(backingObject->columns());

        if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
            AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
            backingObject->selectedChildren(selectedChildrenCopy);
            return convertToNSArray(selectedChildrenCopy);
        }

        // HTML tables don't support these attributes.
        if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute]
            || [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
            return nil;

        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute])
            return convertToNSArray(backingObject->columnHeaders());

        if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
            auto* headerContainer = backingObject->headerContainer();
            return headerContainer ? headerContainer->wrapper() : nil;
        }

        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute])
            return convertToNSArray(backingObject->rowHeaders());

        if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute])
            return convertToNSArray(backingObject->cells());

        if ([attributeName isEqualToString:NSAccessibilityColumnCountAttribute])
            return @(backingObject->columnCount());

        if ([attributeName isEqualToString:NSAccessibilityRowCountAttribute])
            return @(backingObject->rowCount());

        if ([attributeName isEqualToString:NSAccessibilityARIAColumnCountAttribute])
            return @(backingObject->axColumnCount());

        if ([attributeName isEqualToString:NSAccessibilityARIARowCountAttribute])
            return @(backingObject->axRowCount());
    }

    if (backingObject->isTableColumn()) {
        if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
            return @(backingObject->columnIndex());

        // rows attribute for a column is the list of all the elements in that column at each row
        if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]
            || [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute])
            return convertToNSArray(backingObject->children());

        if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
            auto* header = backingObject->columnHeader();
            return header ? header->wrapper() : nil;
        }
    }

    if (backingObject->isTableCell()) {
        if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
            auto rowRange = backingObject->rowIndexRange();
            return [NSValue valueWithRange:NSMakeRange(rowRange.first, rowRange.second)];
        }

        if ([attributeName isEqualToString:NSAccessibilityColumnIndexRangeAttribute]) {
            auto columnRange = backingObject->columnIndexRange();
            return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
        }

        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute])
            return convertToNSArray(backingObject->columnHeaders());

        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute])
            return convertToNSArray(backingObject->rowHeaders());

        if ([attributeName isEqualToString:NSAccessibilityARIAColumnIndexAttribute])
            return @(backingObject->axColumnIndex());

        if ([attributeName isEqualToString:NSAccessibilityARIARowIndexAttribute])
            return @(backingObject->axRowIndex());
    }

    if (backingObject->isTree()) {
        if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
            AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
            backingObject->selectedChildren(selectedChildrenCopy);
            return convertToNSArray(selectedChildrenCopy);
        }
        if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]) {
            AccessibilityObject::AccessibilityChildrenVector rowsCopy;
            backingObject->ariaTreeRows(rowsCopy);
            return convertToNSArray(rowsCopy);
        }

        // TreeRoles do not support columns, but Mac AX expects to be able to ask about columns at the least.
        if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute])
            return @[];
    }

    if ([attributeName isEqualToString:NSAccessibilityIndexAttribute]) {
        if (backingObject->isTreeItem()) {
            AXCoreObject* parent = backingObject->parentObject();
            for (; parent && !parent->isTree(); parent = parent->parentObject())
            { }

            if (!parent)
                return nil;

            // Find the index of this item by iterating the parents.
            AccessibilityObject::AccessibilityChildrenVector rowsCopy;
            parent->ariaTreeRows(rowsCopy);
            size_t count = rowsCopy.size();
            for (size_t k = 0; k < count; ++k)
                if (rowsCopy[k]->wrapper() == self)
                    return @(k);

            return nil;
        }

        if (backingObject->isTableRow())
            return @(backingObject->rowIndex());
    }

    // The rows that are considered inside this row.
    if ([attributeName isEqualToString:NSAccessibilityDisclosedRowsAttribute]) {
        if (backingObject->isTreeItem() || backingObject->isARIATreeGridRow())
            return convertToNSArray(backingObject->disclosedRows());
    }

    // The row that contains this row. It should be the same as the first parent that is a treeitem.
    if ([attributeName isEqualToString:NSAccessibilityDisclosedByRowAttribute]) {
        if (backingObject->isTreeItem()) {
            AXCoreObject* parent = backingObject->parentObject();
            while (parent) {
                if (parent->isTreeItem())
                    return parent->wrapper();
                // If the parent is the tree itself, then this value == nil.
                if (parent->isTree())
                    return nil;
                parent = parent->parentObject();
            }
            return nil;
        }

        if (backingObject->isARIATreeGridRow()) {
            auto* row = backingObject->disclosedByRow();
            return row ? row->wrapper() : nil;
        }
    }

    if ([attributeName isEqualToString:NSAccessibilityDisclosureLevelAttribute]) {
        // Convert from 1-based level (from aria-level spec) to 0-based level (Mac)
        int level = backingObject->hierarchicalLevel();
        if (level > 0)
            level -= 1;
        return @(level);
    }
    if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
        return [NSNumber numberWithBool:backingObject->isExpanded()];

    if (backingObject->isList() && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
        return NSAccessibilityVerticalOrientationValue;

    if ([attributeName isEqualToString:@"AXSelectedTextMarkerRange"])
        return (id)[self selectedTextMarkerRange];

    if ([attributeName isEqualToString:@"AXStartTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            return (id)textMarkerForVisiblePosition(backingObject->axObjectCache(), startOfDocument(backingObject->document()));
        });
    }

    if ([attributeName isEqualToString:@"AXEndTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            return (id)textMarkerForVisiblePosition(backingObject->axObjectCache(), endOfDocument(backingObject->document()));
        });
    }

    if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
        return @(backingObject->blockquoteLevel());
    if ([attributeName isEqualToString:@"AXTableLevel"])
        return @(backingObject->tableLevel());

    if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
        AccessibilityObject::AccessibilityChildrenVector linkedUIElements;
        backingObject->linkedUIElements(linkedUIElements);
        return convertToNSArray(linkedUIElements);
    }

    if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
        return [NSNumber numberWithBool:backingObject->isSelected()];

    if ([attributeName isEqualToString: NSAccessibilityARIACurrentAttribute])
        return backingObject->currentValue();

    if ([attributeName isEqualToString: NSAccessibilityServesAsTitleForUIElementsAttribute] && backingObject->isMenuButton()) {
        AccessibilityObject* uiElement = downcast<AccessibilityRenderObject>(*backingObject).menuForMenuButton();
        if (uiElement)
            return @[uiElement->wrapper()];
    }

    if ([attributeName isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
        auto* object = backingObject->titleUIElement();
        return object ? object->wrapper() : nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityValueDescriptionAttribute])
        return backingObject->valueDescription();

    if ([attributeName isEqualToString:NSAccessibilityOrientationAttribute]) {
        AccessibilityOrientation elementOrientation = backingObject->orientation();
        if (elementOrientation == AccessibilityOrientation::Vertical)
            return NSAccessibilityVerticalOrientationValue;
        if (elementOrientation == AccessibilityOrientation::Horizontal)
            return NSAccessibilityHorizontalOrientationValue;
        if (elementOrientation == AccessibilityOrientation::Undefined)
            return NSAccessibilityUnknownOrientationValue;
        return nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityHorizontalScrollBarAttribute]) {
        AXCoreObject* scrollBar = backingObject->scrollBar(AccessibilityOrientation::Horizontal);
        if (scrollBar)
            return scrollBar->wrapper();
        return nil;
    }
    if ([attributeName isEqualToString:NSAccessibilityVerticalScrollBarAttribute]) {
        AXCoreObject* scrollBar = backingObject->scrollBar(AccessibilityOrientation::Vertical);
        if (scrollBar)
            return scrollBar->wrapper();
        return nil;
    }

    if ([attributeName isEqualToString:NSAccessibilitySortDirectionAttribute]) {
        switch (backingObject->sortDirection()) {
        case AccessibilitySortDirection::Ascending:
            return NSAccessibilityAscendingSortDirectionValue;
        case AccessibilitySortDirection::Descending:
            return NSAccessibilityDescendingSortDirectionValue;
        default:
            return NSAccessibilityUnknownSortDirectionValue;
        }
    }

    if ([attributeName isEqualToString:NSAccessibilityLanguageAttribute])
        return backingObject->language();

    if ([attributeName isEqualToString:NSAccessibilityExpandedAttribute])
        return [NSNumber numberWithBool:backingObject->isExpanded()];

    if ([attributeName isEqualToString:NSAccessibilityRequiredAttribute])
        return [NSNumber numberWithBool:backingObject->isRequired()];

    if ([attributeName isEqualToString:NSAccessibilityInvalidAttribute])
        return backingObject->invalidStatus();

    if ([attributeName isEqualToString:NSAccessibilityOwnsAttribute]) {
        AccessibilityObject::AccessibilityChildrenVector ariaOwns;
        backingObject->ariaOwnsElements(ariaOwns);
        return convertToNSArray(ariaOwns);
    }

    if ([attributeName isEqualToString:NSAccessibilityARIAPosInSetAttribute])
        return @(backingObject->posInSet());
    if ([attributeName isEqualToString:NSAccessibilityARIASetSizeAttribute])
        return @(backingObject->setSize());

    if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
        return [NSNumber numberWithBool:backingObject->isGrabbed()];

    if ([attributeName isEqualToString:NSAccessibilityDropEffectsAttribute])
        return createNSArray(backingObject->determineDropEffects()).autorelease();

    if ([attributeName isEqualToString:NSAccessibilityPlaceholderValueAttribute])
        return backingObject->placeholderValue();

    if ([attributeName isEqualToString:NSAccessibilityValueAutofillAvailableAttribute])
        return @(backingObject->isValueAutofillAvailable());

    if ([attributeName isEqualToString:NSAccessibilityValueAutofillTypeAttribute]) {
        switch (backingObject->valueAutofillButtonType()) {
        case AutoFillButtonType::None:
            return @"none";
        case AutoFillButtonType::Credentials:
            return @"credentials";
        case AutoFillButtonType::Contacts:
            return @"contacts";
        case AutoFillButtonType::StrongPassword:
            return @"strong password";
        case AutoFillButtonType::CreditCard:
            return @"credit card";
        }
    }

    if ([attributeName isEqualToString:NSAccessibilityValueAutofilledAttribute])
        return @(backingObject->isValueAutofilled());

    if ([attributeName isEqualToString:NSAccessibilityHasPopupAttribute])
        return [NSNumber numberWithBool:backingObject->hasPopup()];

    if ([attributeName isEqualToString:NSAccessibilityDatetimeValueAttribute])
        return backingObject->datetimeAttributeValue();

    if ([attributeName isEqualToString:NSAccessibilityInlineTextAttribute])
        return @(backingObject->isInlineText());

    // ARIA Live region attributes.
    if ([attributeName isEqualToString:NSAccessibilityARIALiveAttribute])
        return backingObject->liveRegionStatus();
    if ([attributeName isEqualToString:NSAccessibilityARIARelevantAttribute])
        return backingObject->liveRegionRelevant();
    if ([attributeName isEqualToString:NSAccessibilityARIAAtomicAttribute])
        return [NSNumber numberWithBool:backingObject->liveRegionAtomic()];
    if ([attributeName isEqualToString:NSAccessibilityElementBusyAttribute])
        return [NSNumber numberWithBool:backingObject->isBusy()];

    // MathML Attributes.
    if (backingObject->isMathElement()) {
        if ([attributeName isEqualToString:NSAccessibilityMathRootIndexAttribute]) {
            auto* rootIndex = backingObject->mathRootIndexObject();
            return rootIndex ? rootIndex->wrapper() : nil;
        }

        if ([attributeName isEqualToString:NSAccessibilityMathRootRadicandAttribute]) {
            auto radicand = backingObject->mathRadicand();
            return radicand ? convertToNSArray(*radicand) : nil;
        }

        if ([attributeName isEqualToString:NSAccessibilityMathFractionNumeratorAttribute])
            return (backingObject->mathNumeratorObject()) ? backingObject->mathNumeratorObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathFractionDenominatorAttribute])
            return (backingObject->mathDenominatorObject()) ? backingObject->mathDenominatorObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathBaseAttribute])
            return (backingObject->mathBaseObject()) ? backingObject->mathBaseObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathSubscriptAttribute])
            return (backingObject->mathSubscriptObject()) ? backingObject->mathSubscriptObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathSuperscriptAttribute])
            return (backingObject->mathSuperscriptObject()) ? backingObject->mathSuperscriptObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathUnderAttribute])
            return (backingObject->mathUnderObject()) ? backingObject->mathUnderObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathOverAttribute])
            return (backingObject->mathOverObject()) ? backingObject->mathOverObject()->wrapper() : 0;
        if ([attributeName isEqualToString:NSAccessibilityMathFencedOpenAttribute])
            return backingObject->mathFencedOpenString();
        if ([attributeName isEqualToString:NSAccessibilityMathFencedCloseAttribute])
            return backingObject->mathFencedCloseString();
        if ([attributeName isEqualToString:NSAccessibilityMathLineThicknessAttribute])
            return [NSNumber numberWithInteger:backingObject->mathLineThickness()];
        if ([attributeName isEqualToString:NSAccessibilityMathPostscriptsAttribute])
            return [self accessibilityMathPostscriptPairs];
        if ([attributeName isEqualToString:NSAccessibilityMathPrescriptsAttribute])
            return [self accessibilityMathPrescriptPairs];
    }

    if ([attributeName isEqualToString:NSAccessibilityExpandedTextValueAttribute])
        return backingObject->expandedTextValue();

    if ([attributeName isEqualToString:NSAccessibilityDOMIdentifierAttribute])
        return backingObject->identifierAttribute();
    if ([attributeName isEqualToString:NSAccessibilityDOMClassListAttribute]) {
        Vector<String> classList;
        backingObject->classList(classList);
        return createNSArray(classList).autorelease();
    }

    if ([attributeName isEqualToString:@"AXResolvedEditingStyles"])
        return [self baseAccessibilityResolvedEditingStyles];
    
    // This allows us to connect to a plugin that creates a shadow node for editing (like PDFs).
    if ([attributeName isEqualToString:@"_AXAssociatedPluginParent"])
        return [self associatedPluginParent];

    // this is used only by DumpRenderTree for testing
    if ([attributeName isEqualToString:@"AXClickPoint"])
        return [NSValue valueWithPoint:backingObject->clickPoint()];

    // This is used by DRT to verify CSS3 speech works.
    if ([attributeName isEqualToString:@"AXDRTSpeechAttribute"])
        return [self baseAccessibilitySpeechHint];

    if ([attributeName isEqualToString:@"AXAutocompleteValue"])
        return backingObject->autoCompleteValue();

    if ([attributeName isEqualToString:NSAccessibilityPopupValueAttribute])
        return backingObject->popupValue();

    if ([attributeName isEqualToString:@"AXKeyShortcutsValue"])
        return backingObject->keyShortcutsValue();

    if ([attributeName isEqualToString:@"AXARIAPressedIsPresent"])
        return [NSNumber numberWithBool:backingObject->pressedIsPresent()];

    if ([attributeName isEqualToString:@"AXIsMultiline"])
        return [NSNumber numberWithBool:backingObject->ariaIsMultiline()];

    if ([attributeName isEqualToString:@"AXReadOnlyValue"])
        return backingObject->readOnlyValue();

    if ([attributeName isEqualToString:@"AXIsActiveDescendantOfFocusedContainer"])
        return [NSNumber numberWithBool:backingObject->isActiveDescendantOfFocusedContainer()];

    if ([attributeName isEqualToString:@"AXDetailsElements"]) {
        AccessibilityObject::AccessibilityChildrenVector details;
        backingObject->ariaDetailsElements(details);
        return convertToNSArray(details);
    }

    if ([attributeName isEqualToString:NSAccessibilityBrailleLabelAttribute])
        return backingObject->brailleLabel();

    if ([attributeName isEqualToString:NSAccessibilityBrailleRoleDescriptionAttribute])
        return backingObject->brailleRoleDescription();

    if ([attributeName isEqualToString:NSAccessibilityRelativeFrameAttribute])
        return [NSValue valueWithRect:(NSRect)backingObject->relativeFrame()];

    if ([attributeName isEqualToString:@"AXErrorMessageElements"]) {
        AccessibilityObject::AccessibilityChildrenVector errorMessages;
        backingObject->ariaErrorMessageElements(errorMessages);
        return convertToNSArray(errorMessages);
    }

    // Multi-selectable
    if ([attributeName isEqualToString:NSAccessibilityIsMultiSelectableAttribute])
        return [NSNumber numberWithBool:backingObject->isMultiSelectable()];

    // Document attributes
    if ([attributeName isEqualToString:NSAccessibilityDocumentURIAttribute])
        return backingObject->documentURI();

    if ([attributeName isEqualToString:NSAccessibilityDocumentEncodingAttribute])
        return backingObject->documentEncoding();

    // Aria controls element
    if ([attributeName isEqualToString:NSAccessibilityAriaControlsAttribute]) {
        AccessibilityObject::AccessibilityChildrenVector ariaControls;
        backingObject->ariaControlsElements(ariaControls);
        return convertToNSArray(ariaControls);
    }

    if ([attributeName isEqualToString:NSAccessibilityFocusableAncestorAttribute]) {
        AXCoreObject* object = backingObject->focusableAncestor();
        return object ? object->wrapper() : nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityEditableAncestorAttribute]) {
        AXCoreObject* object = backingObject->editableAncestor();
        return object ? object->wrapper() : nil;
    }

    if ([attributeName isEqualToString:NSAccessibilityHighestEditableAncestorAttribute]) {
        AXCoreObject* object = backingObject->highestEditableAncestor();
        return object ? object->wrapper() : nil;
    }

    if ([attributeName isEqualToString:@"AXIsOnScreen"])
        return [NSNumber numberWithBool:backingObject->isOnScreen()];

    return nil;
}

- (NSString *)accessibilityPlatformMathSubscriptKey
{
    return NSAccessibilityMathSubscriptAttribute;
}

- (NSString *)accessibilityPlatformMathSuperscriptKey
{
    return NSAccessibilityMathSuperscriptAttribute;
}

- (id)accessibilityFocusedUIElement
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    auto focusedObject = backingObject->focusedUIElement();
    return focusedObject ? focusedObject->wrapper() : nil;
}

- (id)accessibilityHitTest:(NSPoint)point
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    backingObject->updateChildrenIfNecessary();
    auto* axObject = backingObject->accessibilityHitTest(IntPoint(point));

    if (axObject) {
        if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
            return [axObject->wrapper() attachmentView];
        auto* widget = axObject->widget();
        if (is<PluginViewBase>(widget))
            return NSAccessibilityUnignoredAncestor(widget->accessibilityHitTest(IntPoint(point)));
        return NSAccessibilityUnignoredAncestor(axObject->wrapper());
    }
    return NSAccessibilityUnignoredAncestor(self);
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return NO;

    if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
        return YES;

    if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
        return backingObject->canSetFocusAttribute();

    if ([attributeName isEqualToString: NSAccessibilityValueAttribute])
        return backingObject->canSetValueAttribute();

    if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
        return backingObject->canSetSelectedAttribute();

    if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute])
        return backingObject->canSetSelectedChildren();

    if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute]
        || [attributeName isEqualToString:NSAccessibilityExpandedAttribute])
        return backingObject->canSetExpandedAttribute();

    if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute])
        return YES;

    if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]
        || [attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]
        || [attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
        return backingObject->canSetTextRangeAttributes();

    if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
        return YES;

    if (backingObject->isWebArea()
        && ([attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute]
            || [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute]))
        return YES;

    return NO;
}

// accessibilityShouldUseUniqueId is an AppKit method we override so that
// objects will be given a unique ID, and therefore allow AppKit to know when they
// become obsolete (e.g. when the user navigates to a new web page, making this one
// unrendered but not deallocated because it is in the back/forward cache).
// It is important to call NSAccessibilityUnregisterUniqueIdForUIElement in the
// appropriate place (e.g. dealloc) to remove these non-retained references from
// AppKit's id mapping tables. We do this in detach by calling unregisterUniqueIdForUIElement.
//
// Registering an object is also required for observing notifications. Only registered objects can be observed.
ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (BOOL)accessibilityIsIgnored
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return YES;

    if (backingObject->isAttachment())
        return [[self attachmentView] accessibilityIsIgnored];
    return backingObject->accessibilityIsIgnored();
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSArray* )accessibilityParameterizedAttributeNames
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    if (backingObject->isAttachment())
        return nil;

    static NSArray *paramAttrs;
    static NSArray *textParamAttrs;
    static NSArray *tableParamAttrs;
    static NSArray *webAreaParamAttrs;
    if (paramAttrs == nil) {
        paramAttrs = [[NSArray alloc] initWithObjects:
            @"AXUIElementForTextMarker",
            @"AXTextMarkerRangeForUIElement",
            @"AXLineForTextMarker",
            @"AXTextMarkerRangeForLine",
            @"AXStringForTextMarkerRange",
            @"AXTextMarkerForPosition",
            @"AXBoundsForTextMarkerRange",
            @"AXAttributedStringForTextMarkerRange",
            @"AXAttributedStringForTextMarkerRangeWithOptions",
            @"AXTextMarkerRangeForTextMarkers",
            @"AXTextMarkerRangeForUnorderedTextMarkers",
            @"AXNextTextMarkerForTextMarker",
            @"AXPreviousTextMarkerForTextMarker",
            @"AXLeftWordTextMarkerRangeForTextMarker",
            @"AXRightWordTextMarkerRangeForTextMarker",
            @"AXLeftLineTextMarkerRangeForTextMarker",
            @"AXRightLineTextMarkerRangeForTextMarker",
            @"AXSentenceTextMarkerRangeForTextMarker",
            @"AXParagraphTextMarkerRangeForTextMarker",
            @"AXNextWordEndTextMarkerForTextMarker",
            @"AXPreviousWordStartTextMarkerForTextMarker",
            @"AXNextLineEndTextMarkerForTextMarker",
            @"AXPreviousLineStartTextMarkerForTextMarker",
            @"AXNextSentenceEndTextMarkerForTextMarker",
            @"AXPreviousSentenceStartTextMarkerForTextMarker",
            @"AXNextParagraphEndTextMarkerForTextMarker",
            @"AXPreviousParagraphStartTextMarkerForTextMarker",
            @"AXStyleTextMarkerRangeForTextMarker",
            @"AXLengthForTextMarkerRange",
            NSAccessibilityBoundsForRangeParameterizedAttribute,
            NSAccessibilityStringForRangeParameterizedAttribute,
            NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute,
            NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute,
            NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute,
            NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute,
            NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute,
            NSAccessibilitySelectTextWithCriteriaParameterizedAttribute,
            NSAccessibilitySearchTextWithCriteriaParameterizedAttribute,
            NSAccessibilityTextOperationParameterizedAttribute,
            nil];
    }

    if (textParamAttrs == nil) {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:paramAttrs]);
        [tempArray addObject:(NSString*)kAXLineForIndexParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXRangeForLineParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXStringForRangeParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXRangeForPositionParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXRangeForIndexParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXBoundsForRangeParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXRTFForRangeParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXAttributedStringForRangeParameterizedAttribute];
        [tempArray addObject:(NSString*)kAXStyleRangeForIndexParameterizedAttribute];
        textParamAttrs = [[NSArray alloc] initWithArray:tempArray.get()];
    }
    if (tableParamAttrs == nil) {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:paramAttrs]);
        [tempArray addObject:NSAccessibilityCellForColumnAndRowParameterizedAttribute];
        tableParamAttrs = [[NSArray alloc] initWithArray:tempArray.get()];
    }
    if (!webAreaParamAttrs) {
        auto tempArray = adoptNS([[NSMutableArray alloc] initWithArray:paramAttrs]);
        [tempArray addObject:NSAccessibilityTextMarkerForIndexParameterizedAttribute];
        [tempArray addObject:NSAccessibilityTextMarkerIsValidParameterizedAttribute];
        [tempArray addObject:NSAccessibilityIndexForTextMarkerParameterizedAttribute];
        webAreaParamAttrs = [[NSArray alloc] initWithArray:tempArray.get()];
    }

    if (backingObject->isPasswordField())
        return @[ NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute ];

    if (backingObject->isTextControl())
        return textParamAttrs;

    if (backingObject->isTable() && backingObject->isExposable())
        return tableParamAttrs;

    if (backingObject->isMenuRelated())
        return nil;

    if (backingObject->isWebArea())
        return webAreaParamAttrs;

    return paramAttrs;
}

ALLOW_DEPRECATED_DECLARATIONS_BEGIN

- (void)accessibilityPerformPressAction
{
    // In case anything we do by performing the press action causes an alert or other modal
    // behaviors, we need to return now, so that VoiceOver doesn't hang indefinitely.
    RunLoop::main().dispatch([self, protectedSelf = retainPtr(self)] {
        [self _accessibilityPerformPressAction];
    });
}

- (void)_accessibilityPerformPressAction
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return;

    if (backingObject->isAttachment())
        [[self attachmentView] accessibilityPerformAction:NSAccessibilityPressAction];
    else
        backingObject->press();
}

- (void)accessibilityPerformIncrementAction
{
    RunLoop::main().dispatch([self, protectedSelf = retainPtr(self)] {
        [self _accessibilityPerformIncrementAction];
    });
}

- (void)_accessibilityPerformIncrementAction
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return;

    if (backingObject->isAttachment())
        [[self attachmentView] accessibilityPerformAction:NSAccessibilityIncrementAction];
    else
        backingObject->increment();
}

- (void)accessibilityPerformDecrementAction
{
    RunLoop::main().dispatch([self, protectedSelf = retainPtr(self)] {
        [self _accessibilityPerformDecrementAction];
    });
}

- (void)_accessibilityPerformDecrementAction
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return;

    if (backingObject->isAttachment())
        [[self attachmentView] accessibilityPerformAction:NSAccessibilityDecrementAction];
    else
        backingObject->decrement();
}

ALLOW_DEPRECATED_DECLARATIONS_END

- (void)accessibilityPerformShowMenuAction
{
    if (self.axBackingObject->roleValue() == AccessibilityRole::ComboBox)
        self.axBackingObject->setIsExpanded(true);
    else {
        // This needs to be performed in an iteration of the run loop that did not start from an AX call.
        // If it's the same run loop iteration, the menu open notification won't be sent
        [self performSelector:@selector(accessibilityShowContextMenu) withObject:nil afterDelay:0.0];
    }
}

- (void)accessibilityShowContextMenu
{
    Accessibility::performFunctionOnMainThread([protectedSelf = retainPtr(self)] {
        [protectedSelf _accessibilityShowContextMenu];
    });
}

- (void)_accessibilityShowContextMenu
{
    ASSERT(isMainThread());
    
    if (!self.axBackingObject)
        return;
    
    Page* page = self.axBackingObject->page();
    if (!page)
        return;
    
    IntRect rect = snappedIntRect(self.axBackingObject->elementRect());
    FrameView* frameView = self.axBackingObject->documentFrameView();
    
    // On WK2, we need to account for the scroll position with regards to root view.
    // On WK1, we need to convert rect to window space to match mouse clicking.
    if (frameView) {
        // Find the appropriate scroll view to use to convert the contents to the window.
        for (auto* parent = self.axBackingObject->parentObject(); parent; parent = parent->parentObject()) {
            if (parent->isScrollView()) {
                if (auto* scrollView = parent->scrollView()) {
                    if (!frameView->platformWidget())
                        rect = scrollView->contentsToRootView(rect);
                    else
                        rect = scrollView->contentsToWindow(rect);
                }
                break;
            }
        }
    }

    page->contextMenuController().showContextMenuAt(page->mainFrame(), rect.center());
}

- (void)accessibilityScrollToVisible
{
    self.axBackingObject->scrollToMakeVisible();
}

- (void)_accessibilityScrollToMakeVisibleWithSubFocus:(NSRect)rect
{
    self.axBackingObject->scrollToMakeVisibleWithSubFocus(IntRect(rect));
}

- (void)_accessibilityScrollToGlobalPoint:(NSPoint)point
{
    self.axBackingObject->scrollToGlobalPoint(IntPoint(point));
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)accessibilityPerformAction:(NSString*)action
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return;

    if ([action isEqualToString:NSAccessibilityPressAction])
        [self accessibilityPerformPressAction];
    else if ([action isEqualToString:@"AXSyncPressAction"]) {
        // Used in layout tests, so that we don't have to wait for the async press action.
        [self _accessibilityPerformPressAction];
    }
    else if ([action isEqualToString:@"AXSyncIncrementAction"])
        [self _accessibilityPerformIncrementAction];
    else if ([action isEqualToString:@"AXSyncDecrementAction"])
        [self _accessibilityPerformDecrementAction];
    else if ([action isEqualToString:NSAccessibilityShowMenuAction])
        [self accessibilityPerformShowMenuAction];
    else if ([action isEqualToString:NSAccessibilityIncrementAction])
        [self accessibilityPerformIncrementAction];
    else if ([action isEqualToString:NSAccessibilityDecrementAction])
        [self accessibilityPerformDecrementAction];
    else if ([action isEqualToString:NSAccessibilityScrollToVisibleAction])
        [self accessibilityScrollToVisible];
    else if ([action isEqualToString:@"AXDismissAction"])
        backingObject->performDismissAction();
}

- (BOOL)accessibilityReplaceRange:(NSRange)range withText:(NSString *)string
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return NO;

    return backingObject->replaceTextInRange(String(string).isolatedCopy(), PlainTextRange(range));
}

- (BOOL)accessibilityInsertText:(NSString *)text
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return NO;

    return backingObject->insertText(String(text).isolatedCopy());
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
#if PLATFORM(MAC)
    // In case anything we do by changing values causes an alert or other modal
    // behaviors, we need to return now, so that VoiceOver doesn't hang indefinitely.
    callOnMainThread([value = retainPtr(value), attributeName = retainPtr(attributeName), protectedSelf = retainPtr(self)] {
        [protectedSelf _accessibilitySetValue:value.get() forAttribute:attributeName.get()];
    });
#else
    // dispatch_async on earlier versions can cause focus not to track.
    [self _accessibilitySetValue:value forAttribute:attributeName];
#endif
}

- (void)_accessibilitySetValue:(id)value forAttribute:(NSString *)attributeName
{
    AXTRACE(makeString("WebAccessibilityObjectWrapper _accessibilitySetValue: forAttribute:", String(attributeName)));

    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject) {
        AXLOG("No backingObject!!!");
        return;
    }

    AXTextMarkerRangeRef textMarkerRange = nil;
    NSNumber*               number = nil;
    NSString*               string = nil;
    NSRange                 range = {0, 0};
    NSArray*                array = nil;

    // decode the parameter
    if (AXObjectIsTextMarkerRange(value))
        textMarkerRange = (AXTextMarkerRangeRef)value;
    else if ([value isKindOfClass:[NSNumber class]])
        number = value;
    else if ([value isKindOfClass:[NSString class]])
        string = value;
    else if ([value isKindOfClass:[NSValue class]])
        range = [value rangeValue];
    else if ([value isKindOfClass:[NSArray class]])
        array = value;

    // handle the command
    if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) {
        ASSERT(textMarkerRange);
        Accessibility::performFunctionOnMainThread([&textMarkerRange, protectedSelf = retainPtr(self)] {
            if (auto* backingObject = protectedSelf.get().axBackingObject)
                backingObject->setSelectedVisiblePositionRange(visiblePositionRangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange));
        });
    } else if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) {
        backingObject->setFocused([number boolValue]);
    } else if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
        if (number && backingObject->canSetNumericValue())
            backingObject->setValue([number floatValue]);
        else if (string)
            backingObject->setValue(string);
    } else if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute]) {
        if (!number)
            return;
        backingObject->setSelected([number boolValue]);
    } else if ([attributeName isEqualToString:NSAccessibilitySelectedChildrenAttribute]) {
        if (!array || !backingObject->canSetSelectedChildren())
            return;

        AXCoreObject::AccessibilityChildrenVector selectedChildren;
        convertToVector(array, selectedChildren);
        backingObject->setSelectedChildren(selectedChildren);
    } else if (backingObject->isTextControl()) {
        if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
            backingObject->setSelectedText(string);
        } else if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
            backingObject->setSelectedTextRange(PlainTextRange(range.location, range.length));
        } else if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) {
            backingObject->makeRangeVisible(PlainTextRange(range.location, range.length));
        }
    } else if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute] || [attributeName isEqualToString:NSAccessibilityExpandedAttribute])
        backingObject->setIsExpanded([number boolValue]);
    else if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
        AccessibilityObject::AccessibilityChildrenVector selectedRows;
        convertToVector(array, selectedRows);
        if (backingObject->isTree() || (backingObject->isTable() && backingObject->isExposable()))
            backingObject->setSelectedRows(selectedRows);
    } else if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
        backingObject->setARIAGrabbed([number boolValue]);
    else if (backingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
        backingObject->setPreventKeyboardDOMEventDispatch([number boolValue]);
    else if (backingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
        backingObject->setCaretBrowsingEnabled([number boolValue]);
}

static RenderObject* rendererForView(NSView* view)
{
    if (![view conformsToProtocol:@protocol(WebCoreFrameView)])
        return nullptr;
    
    NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
    Frame* frame = [frameView _web_frame];
    if (!frame)
        return nullptr;
    
    Node* node = frame->document()->ownerElement();
    if (!node)
        return nullptr;
    
    return node->renderer();
}

- (id)_accessibilityParentForSubview:(NSView*)subview
{
    RenderObject* renderer = rendererForView(subview);
    if (!renderer)
        return nil;
    
    AccessibilityObject* obj = renderer->document().axObjectCache()->getOrCreate(renderer);
    if (obj)
        return obj->parentObjectUnignored()->wrapper();
    return nil;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSString*)accessibilityActionDescription:(NSString*)action
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    // we have no custom actions
    return NSAccessibilityActionDescription(action);
}

// The CFAttributedStringType representation of the text associated with this accessibility
// object that is specified by the given range.
- (NSAttributedString *)doAXAttributedStringForRange:(NSRange)range
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<NSAttributedString *>([&range, protectedSelf = retainPtr(self)] () -> RetainPtr<NSAttributedString> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto webRange = backingObject->rangeForPlainTextRange(range);
        return [protectedSelf doAXAttributedStringForTextMarkerRange:textMarkerRangeFromRange(backingObject->axObjectCache(), webRange) spellCheck:YES];
    });
}

// FIXME: No reason for this to be a method instead of a function; can get document from range.
- (NSRange)_convertToNSRange:(const SimpleRange&)range
{
    ASSERT(isMainThread());
    
    auto document = self.axBackingObject->document();
    if (!document)
        return NSMakeRange(NSNotFound, 0);

    auto documentElement = document->documentElement();
    if (!documentElement)
        return NSMakeRange(NSNotFound, 0);

    return characterRange(makeBoundaryPointBeforeNodeContents(*documentElement), range);
}

- (NSInteger)_indexForTextMarker:(AXTextMarkerRef)marker
{
    if (!marker)
        return NSNotFound;

    return Accessibility::retrieveValueFromMainThread<NSInteger>([&marker, protectedSelf = retainPtr(self)] () -> NSInteger {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return NSNotFound;

        if (auto* cache = backingObject->axObjectCache()) {
            CharacterOffset characterOffset = characterOffsetForTextMarker(cache, marker);
            auto range = cache->rangeForUnorderedCharacterOffsets(characterOffset, characterOffset);
            if (!range)
                return NSNotFound;

            return [protectedSelf _convertToNSRange:*range].location;
        }

        return NSNotFound;
    });
}

- (AXTextMarkerRef)_textMarkerForIndex:(NSInteger)textIndex
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRef>([&textIndex, protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRef> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto* cache = backingObject->axObjectCache();
        if (!cache)
            return nil;

        auto* document = backingObject->document();
        if (!document)
            return nil;

        auto* documentElement = document->documentElement();
        if (!documentElement)
            return nil;

        auto boundary = resolveCharacterLocation(makeRangeSelectingNodeContents(*documentElement), textIndex);
        auto characterOffset = cache->startOrEndCharacterOffsetForRange(makeSimpleRange(boundary), true);

        return textMarkerForCharacterOffset(cache, characterOffset);
    });
}

// The RTF representation of the text associated with this accessibility object that is
// specified by the given range.
- (NSData*)doAXRTFForRange:(NSRange)range
{
    NSAttributedString* attrString = [self doAXAttributedStringForRange:range];
    return [attrString RTFFromRange: NSMakeRange(0, [attrString length]) documentAttributes:@{ }];
}

#if ENABLE(TREE_DEBUGGING)
- (NSString *)debugDescriptionForTextMarker:(AXTextMarkerRef)textMarker
{
    return visiblePositionForTextMarker(self.axBackingObject->axObjectCache(), textMarker).debugDescription();
}

- (NSString *)debugDescriptionForTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange
{
    auto* backingObject = self.axBackingObject;
    if (!backingObject)
        return @"<null>";

    auto visiblePositionRange = visiblePositionRangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
    if (visiblePositionRange.isNull())
        return @"<null>";

    char description[2048];
    formatForDebugger(visiblePositionRange, description, sizeof(description));

    return [NSString stringWithUTF8String:description];
}

- (void)showNodeForTextMarker:(AXTextMarkerRef)textMarker
{
    auto visiblePosition = visiblePositionForTextMarker(self.axBackingObject->axObjectCache(), textMarker);
    Node* node = visiblePosition.deepEquivalent().deprecatedNode();
    if (!node)
        return;
    node->showNode();
    node->showNodePathForThis();
}

- (void)showNodeTreeForTextMarker:(AXTextMarkerRef)textMarker
{
    auto visiblePosition = visiblePositionForTextMarker(self.axBackingObject->axObjectCache(), textMarker);
    Node* node = visiblePosition.deepEquivalent().deprecatedNode();
    if (!node)
        return;
    node->showTreeForThis();
}

static void formatForDebugger(const VisiblePositionRange& range, char* buffer, unsigned length)
{
    strlcpy(buffer, makeString("from ", range.start.debugDescription(), " to ", range.end.debugDescription()).utf8().data(), length);
}
#endif

enum class TextUnit {
    LeftWord = 1,
    RightWord,
    NextWordEnd,
    PreviousWordStart,
    Sentence,
    NextSentenceEnd,
    PreviousSentenceStart,
    Paragraph,
    NextParagraphEnd,
    PreviousParagraphStart,
    Line,
    LeftLine,
    RightLine,
    NextLineEnd,
    PreviousLineStart,
};

- (AXTextMarkerRangeRef)textMarkerRangeAtTextMarker:(AXTextMarkerRef)textMarker forUnit:(TextUnit)textUnit
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRangeRef>([&textMarker, &textUnit, protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRangeRef> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto* cache = backingObject->axObjectCache();
        if (!cache)
            return nil;

        auto characterOffset = characterOffsetForTextMarker(cache, textMarker);
        std::optional<SimpleRange> range;
        switch (textUnit) {
        case TextUnit::LeftWord:
            range = cache->leftWordRange(characterOffset);
            break;
        case TextUnit::RightWord:
            range = cache->rightWordRange(characterOffset);
            break;
        case TextUnit::Sentence:
            range = cache->sentenceForCharacterOffset(characterOffset);
            break;
        case TextUnit::Paragraph:
            range = cache->paragraphForCharacterOffset(characterOffset);
            break;
        default:
            ASSERT_NOT_REACHED();
            break;
        }

        return textMarkerRangeFromRange(cache, range);
    });
}

- (AXTextMarkerRangeRef)lineTextMarkerRangeForTextMarker:(AXTextMarkerRef)textMarker forUnit:(TextUnit)textUnit
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRangeRef>([&textMarker, &textUnit, protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRangeRef> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto* cache = backingObject->axObjectCache();
        if (!cache)
            return nil;

        auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
        VisiblePositionRange visiblePositionRange;
        switch (textUnit) {
        case TextUnit::Line:
            visiblePositionRange = backingObject->lineRangeForPosition(visiblePosition);
            break;
        case TextUnit::LeftLine:
            visiblePositionRange = backingObject->leftLineVisiblePositionRange(visiblePosition);
            break;
        case TextUnit::RightLine:
            visiblePositionRange = backingObject->rightLineVisiblePositionRange(visiblePosition);
            break;
        default:
            ASSERT_NOT_REACHED();
            break;
        }

        return textMarkerRangeFromVisiblePositions(cache, visiblePositionRange.start, visiblePositionRange.end);
    });
}

- (AXTextMarkerRef)textMarkerForTextMarker:(AXTextMarkerRef)textMarker atUnit:(TextUnit)textUnit
{
    return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRef>([&textMarker, &textUnit, protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRef> {
        auto* backingObject = protectedSelf.get().axBackingObject;
        if (!backingObject)
            return nil;

        auto* cache = backingObject->axObjectCache();
        if (!cache)
            return nil;

        CharacterOffset oldOffset = characterOffsetForTextMarker(cache, textMarker);
        CharacterOffset newOffset;
        switch (textUnit) {
        case TextUnit::NextWordEnd:
            newOffset = cache->nextWordEndCharacterOffset(oldOffset);
            break;
        case TextUnit::PreviousWordStart:
            newOffset = cache->previousWordStartCharacterOffset(oldOffset);
            break;
        case TextUnit::NextSentenceEnd:
            newOffset = cache->nextSentenceEndCharacterOffset(oldOffset);
            break;
        case TextUnit::PreviousSentenceStart:
            newOffset = cache->previousSentenceStartCharacterOffset(oldOffset);
            break;
        case TextUnit::NextParagraphEnd:
            newOffset = cache->nextParagraphEndCharacterOffset(oldOffset);
            break;
        case TextUnit::PreviousParagraphStart:
            newOffset = cache->previousParagraphStartCharacterOffset(oldOffset);
            break;
        case TextUnit::NextLineEnd: {
            auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
            return textMarkerForVisiblePosition(cache, backingObject->nextLineEndPosition(visiblePosition));
        }
        case TextUnit::PreviousLineStart: {
            auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
            return textMarkerForVisiblePosition(cache, backingObject->previousLineStartPosition(visiblePosition));
        }
        default:
            ASSERT_NOT_REACHED();
            break;
        }

        return textMarkerForCharacterOffset(cache, newOffset);
    });
}

static BOOL isMatchingPlugin(AXCoreObject* axObject, const AccessibilitySearchCriteria& criteria)
{
    auto* widget = axObject->widget();
    if (!is<PluginViewBase>(widget))
        return false;

    return criteria.searchKeys.contains(AccessibilitySearchKey::AnyType)
        && (!criteria.visibleOnly || downcast<PluginViewBase>(widget)->isVisible());
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    AXTRACE(makeString("WebAccessibilityObjectWrapper accessibilityAttributeValue:", String(attribute)));
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    // Basic parameter validation.
    if (!attribute || !parameter)
        return nil;

    AXTextMarkerRef textMarker = nil;
    AXTextMarkerRangeRef textMarkerRange = nil;
    NSNumber* number = nil;
    NSArray* array = nil;
    NSDictionary* dictionary = nil;
    RefPtr<AXCoreObject> uiElement;
    NSPoint point = NSZeroPoint;
    bool pointSet = false;
    NSRange range = {0, 0};
    bool rangeSet = false;
    NSRect rect = NSZeroRect;

    // common parameter type check/casting.  Nil checks in handlers catch wrong type case.
    // NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from
    // a parameter of the wrong type.
    if (AXObjectIsTextMarker(parameter))
        textMarker = (AXTextMarkerRef)parameter;
    else if (AXObjectIsTextMarkerRange(parameter))
        textMarkerRange = (AXTextMarkerRangeRef)parameter;
    else if ([parameter isKindOfClass:[WebAccessibilityObjectWrapper class]])
        uiElement = [(WebAccessibilityObjectWrapper*)parameter axBackingObject];
    else if ([parameter isKindOfClass:[NSNumber class]])
        number = parameter;
    else if ([parameter isKindOfClass:[NSArray class]])
        array = parameter;
    else if ([parameter isKindOfClass:[NSDictionary class]])
        dictionary = parameter;
    else if ([parameter isKindOfClass:[NSValue class]] && !strcmp([(NSValue*)parameter objCType], @encode(NSPoint))) {
        pointSet = true;
        point = [(NSValue*)parameter pointValue];
    } else if ([parameter isKindOfClass:[NSValue class]] && !strcmp([(NSValue*)parameter objCType], @encode(NSRange))) {
        rangeSet = true;
        range = [(NSValue*)parameter rangeValue];
    } else if ([parameter isKindOfClass:[NSValue class]] && !strcmp([(NSValue*)parameter objCType], @encode(NSRect)))
        rect = [(NSValue*)parameter rectValue];
    else {
        // Attribute type is not supported. Allow super to handle.
        return [super accessibilityAttributeValue:attribute forParameter:parameter];
    }

    // dispatch
    if ([attribute isEqualToString:NSAccessibilitySelectTextWithCriteriaParameterizedAttribute]) {
        // To be deprecated.
        auto result = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = retainPtr(self)] () -> Vector<String> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return Vector<String>();

            auto criteria = accessibilityTextCriteriaForParameterizedAttribute(dictionary);
            criteria.second.textRanges = backingObject->findTextRanges(criteria.first);
            ASSERT(criteria.second.textRanges.size() <= 1);
            return backingObject->performTextOperation(criteria.second);
        });
        ASSERT(result.size() <= 1);
        if (result.size() > 0)
            return result[0];
        return String();
    }

    if ([attribute isEqualToString:NSAccessibilitySearchTextWithCriteriaParameterizedAttribute]) {
        auto criteria = accessibilitySearchTextCriteriaForParameterizedAttribute(dictionary);
        return Accessibility::retrieveAutoreleasedValueFromMainThread<NSArray *>([&criteria, protectedSelf = retainPtr(self)] () -> RetainPtr<NSArray> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;
            auto ranges = backingObject->findTextRanges(criteria);
            if (ranges.isEmpty())
                return nil;
            return createNSArray(ranges, [&] (auto& range) {
                return (id)textMarkerRangeFromRange(backingObject->axObjectCache(), range);
            }).autorelease();
        });
    }

    if ([attribute isEqualToString:NSAccessibilityTextOperationParameterizedAttribute]) {
        auto operationResult = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = retainPtr(self)] () -> Vector<String> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return Vector<String>();

            auto textOperation = accessibilityTextOperationForParameterizedAttribute(backingObject->axObjectCache(), dictionary);
            return backingObject->performTextOperation(textOperation);
        });
        if (operationResult.isEmpty())
            return nil;
        return createNSArray(operationResult).autorelease();
    }

    if ([attribute isEqualToString:NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute]) {
        AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
        NSUInteger widgetChildrenSize = 0;
        if (isMatchingPlugin(backingObject, criteria)) {
            // FIXME: We should also be searching the tree(s) resulting from `renderWidgetChildren` for matches.
            // This is tracked by https://bugs.webkit.org/show_bug.cgi?id=230167.
            if (auto* widgetChildren = [self renderWidgetChildren]) {
                widgetChildrenSize = [widgetChildren count];
                if (widgetChildrenSize >= criteria.resultsLimit)
                    return @(std::min(widgetChildrenSize, NSUInteger(criteria.resultsLimit)));
                criteria.resultsLimit -= widgetChildrenSize;
            }
        }

        AccessibilityObject::AccessibilityChildrenVector results;
        backingObject->findMatchingObjects(&criteria, results);
        return @(results.size() + widgetChildrenSize);
    }

    if ([attribute isEqualToString:NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute]) {
        AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
        NSArray *widgetChildren = nil;
        if (isMatchingPlugin(backingObject, criteria)) {
            // FIXME: We should also be searching the tree(s) resulting from `renderWidgetChildren` for matches.
            // This is tracked by https://bugs.webkit.org/show_bug.cgi?id=230167.
            if (auto* children = [self renderWidgetChildren]) {
                NSUInteger includedChildrenCount = std::min([children count], NSUInteger(criteria.resultsLimit));
                widgetChildren = [children subarrayWithRange:NSMakeRange(0, includedChildrenCount)];
                if ([widgetChildren count] >= criteria.resultsLimit)
                    return widgetChildren;
                criteria.resultsLimit -= [widgetChildren count];
            }
        }

        AccessibilityObject::AccessibilityChildrenVector results;
        backingObject->findMatchingObjects(&criteria, results);
        if (widgetChildren)
            return [widgetChildren arrayByAddingObjectsFromArray:convertToNSArray(results)];
        return convertToNSArray(results);
    }

    // TextMarker attributes.

    if ([attribute isEqualToString:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            IntRect webCoreRect = [protectedSelf screenToContents:enclosingIntRect(rect)];
            CharacterOffset characterOffset = cache->characterOffsetForBounds(webCoreRect, false);

            return (id)textMarkerForCharacterOffset(cache, characterOffset);
        });
    }

    if ([attribute isEqualToString:NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            IntRect webCoreRect = [protectedSelf screenToContents:enclosingIntRect(rect)];
            CharacterOffset characterOffset = cache->characterOffsetForBounds(webCoreRect, true);

            return (id)textMarkerForCharacterOffset(cache, characterOffset);
        });
    }

    // TextMarkerRange attributes.
    if ([attribute isEqualToString:@"AXTextMarkerRangeForNSRange"])
        return (id)backingObject->textMarkerRangeForNSRange(range);

    if ([attribute isEqualToString:NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute])
        return (id)[self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::Line];

    if ([attribute isEqualToString:NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&dictionary, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            auto criteria = accessibilityMisspellingSearchCriteriaForParameterizedAttribute(cache, dictionary);
            if (auto misspellingRange = backingObject->misspellingRange(*criteria.first, criteria.second))
                return (id)textMarkerRangeFromRange(cache, *misspellingRange);

            return nil;
        });
    }

    if ([attribute isEqualToString:NSAccessibilityTextMarkerIsValidParameterizedAttribute]) {
        bool result = Accessibility::retrieveValueFromMainThread<bool>([&textMarker, protectedSelf = retainPtr(self)] () -> bool {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return false;

            return !visiblePositionForTextMarker(backingObject->axObjectCache(), textMarker).isNull();
        });

        return [NSNumber numberWithBool:result];
    }

    if ([attribute isEqualToString:NSAccessibilityIndexForTextMarkerParameterizedAttribute])
        return [NSNumber numberWithInteger:[self _indexForTextMarker:textMarker]];

    if ([attribute isEqualToString:NSAccessibilityTextMarkerForIndexParameterizedAttribute])
        return (id)[self _textMarkerForIndex:[number integerValue]];

    if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* axObject = accessibilityObjectForTextMarker(backingObject->axObjectCache(), textMarker);
            if (!axObject)
                return nil;

            if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
                return [axObject->wrapper() attachmentView];

            return axObject->wrapper();
        });
    }

    if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&uiElement] () -> RetainPtr<id> {
            return (id)textMarkerRangeFromRange(uiElement.get()->axObjectCache(), uiElement.get()->elementRange());
        });
    }

    if ([attribute isEqualToString:@"AXLineForTextMarker"]) {
        int result = Accessibility::retrieveValueFromMainThread<int>([&textMarker, protectedSelf = retainPtr(self)] () -> int {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return -1;

            auto visiblePos = visiblePositionForTextMarker(backingObject->axObjectCache(), textMarker);
            return backingObject->lineForPosition(visiblePos);
        });
        return @(result);
    }

    if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&number, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            VisiblePositionRange vpRange;
            if ([number unsignedIntegerValue] != NSNotFound)
                vpRange = backingObject->visiblePositionRangeForLine([number unsignedIntValue]);

            return (id)textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), vpRange.start, vpRange.end);
        });
    }

    if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) {
        return Accessibility::retrieveValueFromMainThread<String>([&textMarkerRange, protectedSelf = retainPtr(self)] () -> String {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return String();

            auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
            return range ? backingObject->stringForRange(*range) : String();
        });
    }

    if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) {
        if (!pointSet)
            return nil;
        IntPoint webCorePoint = IntPoint(point);

        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&webCorePoint, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            return (id)textMarkerForVisiblePosition(backingObject->axObjectCache(), backingObject->visiblePositionForPoint(webCorePoint));
        });
    }

    if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
        NSRect rect = Accessibility::retrieveValueFromMainThread<NSRect>([&textMarkerRange, protectedSelf = retainPtr(self)] () -> NSRect {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return CGRectZero;

            auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
            if (!range)
                return CGRectZero;

            auto bounds = FloatRect(backingObject->boundsForRange(*range));
            return [protectedSelf convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
        });
        return [NSValue valueWithRect:rect];
    }

    if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
        NSRect rect = Accessibility::retrieveValueFromMainThread<NSRect>([&range, protectedSelf = retainPtr(self)] () -> NSRect {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return CGRectZero;

            auto start = backingObject->visiblePositionForIndex(range.location);
            auto end = backingObject->visiblePositionForIndex(range.location + range.length);
            auto webRange = makeSimpleRange({ start, end });
            if (!webRange)
                return CGRectZero;

            auto bounds = FloatRect(backingObject->boundsForRange(*webRange));
            return [protectedSelf convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
        });
        return [NSValue valueWithRect:rect];
    }

    if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
        if (backingObject->isTextControl()) {
            PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
            return backingObject->doAXStringForRange(plainTextRange);
        }

        return Accessibility::retrieveValueFromMainThread<String>([&range, protectedSelf = retainPtr(self)] () -> String {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return String();
            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return String();
            auto start = cache->characterOffsetForIndex(range.location, backingObject);
            auto end = cache->characterOffsetForIndex(range.location + range.length, backingObject);
            auto range = cache->rangeForUnorderedCharacterOffsets(start, end);
            if (!range)
                return { };
            return backingObject->stringForRange(*range);
        });
    }

    if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"])
        return [self doAXAttributedStringForTextMarkerRange:textMarkerRange spellCheck:YES];

    if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRangeWithOptions"]) {
        if (textMarkerRange)
            return [self doAXAttributedStringForTextMarkerRange:textMarkerRange spellCheck:NO];

        if (dictionary) {
            AXTextMarkerRangeRef textMarkerRange = nil;
            id parameter = [dictionary objectForKey:@"AXTextMarkerRange"];
            if (AXObjectIsTextMarkerRange(parameter))
                textMarkerRange = (AXTextMarkerRangeRef)parameter;

            BOOL spellCheck = NO;
            parameter = [dictionary objectForKey:@"AXSpellCheck"];
            if ([parameter isKindOfClass:[NSNumber class]])
                spellCheck = [parameter boolValue];

            return [self doAXAttributedStringForTextMarkerRange:textMarkerRange spellCheck:spellCheck];
        }

        return nil;
    }

    if ([attribute isEqualToString:@"AXTextMarkerRangeForTextMarkers"]) {
        if (array.count < 2
            || !AXObjectIsTextMarker([array objectAtIndex:0])
            || !AXObjectIsTextMarker([array objectAtIndex:1]))
            return nil;
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&array] () -> RetainPtr<id> {
            return (id)textMarkerRangeFromMarkers((AXTextMarkerRef)[array objectAtIndex:0], (AXTextMarkerRef)[array objectAtIndex:1]).get();
        });
    }

    if ([attribute isEqualToString:@"AXTextMarkerRangeForUnorderedTextMarkers"]) {
        if (array.count < 2
            || !AXObjectIsTextMarker([array objectAtIndex:0])
            || !AXObjectIsTextMarker([array objectAtIndex:1]))
            return nil;

        AXTextMarkerRef textMarker1 = (AXTextMarkerRef)[array objectAtIndex:0];
        AXTextMarkerRef textMarker2 = (AXTextMarkerRef)[array objectAtIndex:1];

        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker1, &textMarker2, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            auto characterOffset1 = characterOffsetForTextMarker(cache, textMarker1);
            auto characterOffset2 = characterOffsetForTextMarker(cache, textMarker2);
            auto range = cache->rangeForUnorderedCharacterOffsets(characterOffset1, characterOffset2);

            return (id)textMarkerRangeFromRange(cache, range);
        });
    }

    if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            CharacterOffset characterOffset = characterOffsetForTextMarker(cache, textMarker);
            return bridge_id_cast([protectedSelf nextTextMarkerForCharacterOffset:characterOffset]);
        });
    }

    if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            CharacterOffset characterOffset = characterOffsetForTextMarker(cache, textMarker);
            return bridge_id_cast([protectedSelf previousTextMarkerForCharacterOffset:characterOffset]);
        });
    }

    if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"])
        return (id)[self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::LeftWord];

    if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"])
        return (id)[self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::RightWord];

    if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"])
        return (id)[self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::LeftLine];

    if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"])
        return (id)[self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::RightLine];

    if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"])
        return (id)[self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::Sentence];

    if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"])
        return (id)[self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::Paragraph];

    if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextWordEnd];

    if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousWordStart];

    if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextLineEnd];

    if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousLineStart];

    if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextSentenceEnd];

    if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousSentenceStart];

    if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextParagraphEnd];

    if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"])
        return (id)[self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousParagraphStart];

    if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto* cache = backingObject->axObjectCache();
            if (!cache)
                return nil;

            VisiblePosition visiblePos = visiblePositionForTextMarker(cache, textMarker);
            VisiblePositionRange vpRange = backingObject->styleRangeForPosition(visiblePos);

            return (id)textMarkerRangeFromVisiblePositions(cache, vpRange.start, vpRange.end);
        });
    }

    if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
        int length = Accessibility::retrieveValueFromMainThread<int>([&textMarkerRange, protectedSelf = retainPtr(self)] () -> int {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return 0;

            auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
            if (!range)
                return 0;
            return AXObjectCache::lengthForRange(SimpleRange { *range });
        });
        if (length < 0)
            return nil;
        return @(length);
    }

    // Used only by DumpRenderTree (so far).
    if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarkerRange, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);

            return (id)startOrEndTextMarkerForRange(backingObject->axObjectCache(), range, true);
        });
    }

    if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) {
        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarkerRange, protectedSelf = retainPtr(self)] () -> RetainPtr<id> {
            auto* backingObject = protectedSelf.get().axBackingObject;
            if (!backingObject)
                return nil;

            auto range = rangeForTextMarkerRange(backingObject->axObjectCache(), textMarkerRange);
            return (id)startOrEndTextMarkerForRange(backingObject->axObjectCache(), range, false);
        });
    }

#if ENABLE(TREE_DEBUGGING)
    if ([attribute isEqualToString:@"AXTextMarkerDebugDescription"])
        return [self debugDescriptionForTextMarker:textMarker];

    if ([attribute isEqualToString:@"AXTextMarkerRangeDebugDescription"])
        return [self debugDescriptionForTextMarkerRange:textMarkerRange];

    if ([attribute isEqualToString:@"AXTextMarkerNodeDebugDescription"]) {
        [self showNodeForTextMarker:textMarker];
        return nil;
    }

    if ([attribute isEqualToString:@"AXTextMarkerNodeTreeDebugDescription"]) {
        [self showNodeTreeForTextMarker:textMarker];
        return nil;
    }
#endif

    if (backingObject->isTable() && backingObject->isExposable()) {
        if ([attribute isEqualToString:NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
            if (array == nil || [array count] != 2)
                return nil;
            auto* cell = backingObject->cellForColumnAndRow([[array objectAtIndex:0] unsignedIntValue], [[array objectAtIndex:1] unsignedIntValue]);
            return cell ? cell->wrapper() : nil;
        }
    }

    if (backingObject->isTextControl()) {
        if ([attribute isEqualToString: (NSString *)kAXLineForIndexParameterizedAttribute]) {
            int lineNumber = backingObject->doAXLineForIndex([number intValue]);
            if (lineNumber < 0)
                return nil;
            return @(lineNumber);
        }

        if ([attribute isEqualToString: (NSString *)kAXRangeForLineParameterizedAttribute]) {
            PlainTextRange textRange = backingObject->doAXRangeForLine([number intValue]);
            return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
        }

        if ([attribute isEqualToString: (NSString*)kAXStringForRangeParameterizedAttribute]) {
            PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
            return rangeSet ? (id)(backingObject->doAXStringForRange(plainTextRange)) : nil;
        }

        if ([attribute isEqualToString: (NSString*)kAXRangeForPositionParameterizedAttribute]) {
            if (!pointSet)
                return nil;
            IntPoint webCorePoint = IntPoint(point);
            PlainTextRange textRange = backingObject->doAXRangeForPosition(webCorePoint);
            return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
        }

        if ([attribute isEqualToString: (NSString*)kAXRangeForIndexParameterizedAttribute]) {
            PlainTextRange textRange = backingObject->doAXRangeForIndex([number intValue]);
            return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
        }

        if ([attribute isEqualToString: (NSString*)kAXBoundsForRangeParameterizedAttribute]) {
            if (!rangeSet)
                return nil;
            PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
            auto bounds = FloatRect(backingObject->doAXBoundsForRangeUsingCharacterOffset(plainTextRange));
            NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
            return [NSValue valueWithRect:rect];
        }

        if ([attribute isEqualToString: (NSString*)kAXRTFForRangeParameterizedAttribute])
            return rangeSet ? [self doAXRTFForRange:range] : nil;

        if ([attribute isEqualToString: (NSString*)kAXAttributedStringForRangeParameterizedAttribute])
            return rangeSet ? [self doAXAttributedStringForRange:range] : nil;

        if ([attribute isEqualToString: (NSString*)kAXStyleRangeForIndexParameterizedAttribute]) {
            PlainTextRange textRange = backingObject->doAXStyleRangeForIndex([number intValue]);
            return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
        }
    }

    // There are some parameters that super handles that are not explicitly returned by the list of the element's attributes.
    // In that case it must be passed to super.
    return [super accessibilityAttributeValue:attribute forParameter:parameter];
}

- (BOOL)accessibilitySupportsOverriddenAttributes
{
    return YES;
}

- (BOOL)accessibilityShouldUseUniqueId
{
    // All AX object wrappers should use unique ID's because it's faster within AppKit to look them up.
    return YES;
}

// API that AppKit uses for faster access
- (NSUInteger)accessibilityIndexOfChild:(id)child
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return NSNotFound;

    // Tree objects return their rows as their children. We can use the original method
    // here, because we won't gain any speed up.
    if (backingObject->isTree())
        return [super accessibilityIndexOfChild:child];

    NSArray *children = self.childrenVectorArray;
    if (!children.count)
        return [[self renderWidgetChildren] indexOfObject:child];

    NSUInteger count = [children count];
    for (NSUInteger i = 0; i < count; ++i) {
        WebAccessibilityObjectWrapper *wrapper = children[i];
        auto* object = wrapper.axBackingObject;
        if (!object)
            continue;

        if (wrapper == child || (object->isAttachment() && [wrapper attachmentView] == child))
            return i;
    }

    return NSNotFound;
}

ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
{
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return 0;

    if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
        // Tree items object returns a different set of children than those that are in children()
        // because an AXOutline (the mac role is becomes) has some odd stipulations.
        if (backingObject->isTree() || backingObject->isTreeItem())
            return [[self accessibilityAttributeValue:NSAccessibilityChildrenAttribute] count];

        auto childrenSize = self.childrenVectorSize;
        if (!childrenSize)
            return [[self renderWidgetChildren] count];

        return childrenSize;
    }

    return [super accessibilityArrayAttributeCount:attribute];
}
ALLOW_DEPRECATED_DECLARATIONS_END

- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
{
    AXTRACE(makeString("WebAccessibilityObjectWrapper accessibilityArrayAttributeValue:", String(attribute)));
    auto* backingObject = self.updateObjectBackingStore;
    if (!backingObject)
        return nil;

    if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
        if (!self.childrenVectorSize) {
            NSArray *children = [self renderWidgetChildren];
            if (!children)
                return nil;

            NSUInteger childCount = [children count];
            if (index >= childCount)
                return nil;

            NSUInteger arrayLength = std::min(childCount - index, maxCount);
            return [children subarrayWithRange:NSMakeRange(index, arrayLength)];
        }

        if (backingObject->isTree() || backingObject->isTreeItem()) {
            // Tree objects return their rows as their children & tree items return their contents sans rows.
            // We can use the original method in this case.
            return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
        }

        auto children = self.childrenVectorArray;
        unsigned childCount = [children count];
        if (index >= childCount)
            return nil;

        unsigned available = std::min(childCount - index, maxCount);

        NSMutableArray *subarray = [NSMutableArray arrayWithCapacity:available];
        for (unsigned added = 0; added < available; ++index, ++added) {
            WebAccessibilityObjectWrapper* wrapper = children[index];
            // The attachment view should be returned, otherwise AX palindrome errors occur.
            BOOL isAttachment = [wrapper isKindOfClass:[WebAccessibilityObjectWrapper class]] && wrapper.axBackingObject && wrapper.axBackingObject->isAttachment() && [wrapper attachmentView];
            [subarray addObject:isAttachment ? [wrapper attachmentView] : wrapper];
        }

        return subarray;
    }

    return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}

@end

#endif // ENABLE(ACCESSIBILITY) && PLATFORM(MAC)
