Skip to content
Permalink
Browse files
AX: Support ARIA 1.3 property aria-description
https://bugs.webkit.org/show_bug.cgi?id=206253

Reviewed by Andres Gonzalez.

Add support for aria-description on Apple platforms by mapping to AXCustomContent.

* LayoutTests/accessibility/aria-description-expected.txt: Added.
* LayoutTests/accessibility/aria-description.html: Added.
* LayoutTests/platform/ios-simulator/TestExpectations:
* LayoutTests/platform/mac-wk1/TestExpectations:
* LayoutTests/platform/win/TestExpectations:
* Source/WTF/wtf/PlatformHave.h:
* Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj:
* Source/WebCore/PAL/pal/cocoa/AccessibilitySoftLink.h: Added.
* Source/WebCore/PAL/pal/cocoa/AccessibilitySoftLink.mm: Added.
* Source/WebCore/accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::ariaDescription const):
* Source/WebCore/accessibility/AccessibilityObject.h:
* Source/WebCore/accessibility/AccessibilityObjectInterface.h:
* Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::initializeProperties):
* Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h:
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h:
* Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
(-[WebAccessibilityObjectWrapperBase accessibilityCustomContent]):
* Source/WebCore/html/HTMLAttributeNames.in:
* Tools/Scripts/webkitpy/port/mac.py:
(MacPort.architecture):
* Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::customContent const):
* Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
(WTR::AccessibilityUIElement::customContent const):
* Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElement::customContent const):

Canonical link: https://commits.webkit.org/253184@main
  • Loading branch information
fleizach committed Aug 6, 2022
1 parent eb5e242 commit 7c414e7250fbc66f4800a42bb2f79b845ad1e8f0
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 1 deletion.
@@ -0,0 +1,8 @@
This test ensures that aria-description maps to appropriate attributes.

Custom content: description: Longer description

PASS successfullyParsed is true

TEST COMPLETE
button
@@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/js-test.js"></script>
</head>
<body>

<div id="button" role="button" aria-description="Longer description">button</div>

<script>
var testOutput = "This test ensures that aria-description maps to appropriate attributes.\n\n";

if (window.accessibilityController) {
const button = accessibilityController.accessibleElementById("button");
testOutput += `Custom content: ${button.customContent}\n`;
debug(testOutput);
}
</script>
</body>
</html>


@@ -208,6 +208,9 @@ webkit.org/b/208988 webxr [ Skip ]
# Crash on EWS bot.
webrtc/vp8-then-h264-gpu-process-crash.html [ Skip ]

# ARIA description needs to be supported on GTK.
accessibility/aria-description.html [ Skip ]

#//////////////////////////////////////////////////////////////////////////////////////////
# End of Triaged Expectations
# Legacy Expectations sections below
@@ -8,6 +8,7 @@ accessibility/insert-newline.html [ Pass ]
accessibility/url-test.html [ Pass ]
accessibility/keyevents-posted-for-dismiss-action.html [ Pass ]
accessibility/embedded-image-description.html [ Pass ]
accessibility/aria-description.html [ Pass ]
fast/multicol/flexbox-rows.html [ Skip ]

fast/forms/input-text-word-wrap.html [ Skip ]
@@ -14,3 +14,4 @@ webkit.org/b/243074 imported/w3c/web-platform-tests/media-capabilities/decodingI
webkit.org/b/243074 imported/w3c/web-platform-tests/media-capabilities/encodingInfo.any.worker.html [ Pass Failure ]

webkit.org/b/243076 imported/w3c/web-platform-tests/resource-timing/redirects.html [ Pass Failure ]
accessibility/aria-description.html [ Skip ]
@@ -892,6 +892,7 @@ accessibility/visible-character-range-height-changes.html [ Skip ]
accessibility/visible-character-range-scrolling.html [ Skip ]
accessibility/visible-character-range-width-changes.html [ Skip ]
accessibility/model-element-attributes.html [ Skip ]
accessibility/aria-description.html [ Skip ]

# <rdar://problem/26050923> The result is probably still a pass, but we don't have a way
# to have platform specific results that are different between WK1 and WK2.
@@ -489,6 +489,7 @@ accessibility/listbox-clear-selection.html [ Skip ]
accessibility/embedded-image-description.html [ Skip ]
accessibility/img-no-alt-not-ignored-with-title.html [ Skip ]
accessibility/model-element-attributes.html [ Skip ]
accessibility/aria-description.html [ Skip ]

accessibility/visible-character-range-basic.html [ Skip ]
accessibility/visible-character-range-height-changes.html [ Skip ]
@@ -1309,3 +1309,10 @@
|| PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000))
#define HAVE_LOCKDOWN_MODE_PDF_ADDITIONS 1
#endif

#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101600) \
|| (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000) \
|| (PLATFORM(WATCHOS) && __WATCH_OS_VERSION_MIN_REQUIRED >= 70000) \
|| (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 140000)
#define HAVE_ACCESSIBILITY_FRAMEWORK 1
#endif
@@ -66,6 +66,8 @@
1CCA5F00280FABB4008A6F78 /* WebGPUCreateImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CCA5EFE280FABB4008A6F78 /* WebGPUCreateImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
1D2B413425F05E3500A3F70A /* ClockGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D2B413225F05E3400A3F70A /* ClockGeneric.cpp */; };
293EE4A824154F8F0047493D /* AccessibilitySupportSoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 293EE4A624154F8F0047493D /* AccessibilitySupportSoftLink.cpp */; };
297CB482288B11D700BB7971 /* AccessibilitySoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 297CB480288B11D700BB7971 /* AccessibilitySoftLink.h */; };
297CB483288B11D700BB7971 /* AccessibilitySoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 297CB481288B11D700BB7971 /* AccessibilitySoftLink.mm */; };
2E1342CD215AA10A007199D2 /* UIKitSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E1342CB215AA10A007199D2 /* UIKitSoftLink.mm */; };
31647FB0251759DD0010F8FB /* OpenGLSoftLinkCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31647FAE251759DB0010F8FB /* OpenGLSoftLinkCocoa.mm */; };
416E995323DAE6BE00E871CB /* AudioToolboxSoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 416E995123DAE6BD00E871CB /* AudioToolboxSoftLink.cpp */; };
@@ -848,6 +850,8 @@
1D2B413325F05E3500A3F70A /* ClockGeneric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClockGeneric.h; sourceTree = "<group>"; };
293EE4A624154F8F0047493D /* AccessibilitySupportSoftLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilitySupportSoftLink.cpp; sourceTree = "<group>"; };
293EE4A724154F8F0047493D /* AccessibilitySupportSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilitySupportSoftLink.h; sourceTree = "<group>"; };
297CB480288B11D700BB7971 /* AccessibilitySoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilitySoftLink.h; sourceTree = "<group>"; };
297CB481288B11D700BB7971 /* AccessibilitySoftLink.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = AccessibilitySoftLink.mm; sourceTree = "<group>"; };
29C15F4725D75F63001CE31C /* MediaAccessibilitySPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaAccessibilitySPI.h; sourceTree = "<group>"; };
29CDEB9E2548D055007C07B7 /* AXSpeechManagerSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AXSpeechManagerSPI.h; sourceTree = "<group>"; };
2D02E93B2056FAA700A13797 /* AudioToolboxSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioToolboxSPI.h; sourceTree = "<group>"; };
@@ -1330,6 +1334,8 @@
1C4876DE1F8D831300CCEEBD /* cocoa */ = {
isa = PBXGroup;
children = (
297CB480288B11D700BB7971 /* AccessibilitySoftLink.h */,
297CB481288B11D700BB7971 /* AccessibilitySoftLink.mm */,
57FD318822B3592F008D0E8B /* AppSSOSoftLink.h */,
57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */,
077E87B0226A460200A2AFF0 /* AVFoundationSoftLink.h */,
@@ -1664,6 +1670,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
297CB482288B11D700BB7971 /* AccessibilitySoftLink.h in Headers */,
DD20DDD527BC90D70093D175 /* AccessibilitySupportSoftLink.h in Headers */,
DD20DDD627BC90D70093D175 /* AccessibilitySupportSPI.h in Headers */,
DD20DD1A27BC90D60093D175 /* AppSSOSoftLink.h in Headers */,
@@ -1804,6 +1811,7 @@
DD20DE4527BC90D80093D175 /* PopupMenu.h in Headers */,
E34F26F62846D0D90076E549 /* PowerLogSPI.h in Headers */,
DD20DE0427BC90D80093D175 /* pthreadSPI.h in Headers */,
5CB898B2286274FA00CA3485 /* QuarantineSPI.h in Headers */,
DD20DE0527BC90D80093D175 /* QuartzCoreSPI.h in Headers */,
DD20DE3F27BC90D80093D175 /* QuickLookMacSPI.h in Headers */,
DD20DDC127BC90D70093D175 /* QuickLookSoftLink.h in Headers */,
@@ -1991,7 +1999,6 @@
DD20DDAE27BC90D70093D175 /* WebGPUTextureAspect.h in Headers */,
DD20DDAF27BC90D70093D175 /* WebGPUTextureBindingLayout.h in Headers */,
DD20DDB027BC90D70093D175 /* WebGPUTextureDescriptor.h in Headers */,
5CB898B2286274FA00CA3485 /* QuarantineSPI.h in Headers */,
DD20DDB127BC90D70093D175 /* WebGPUTextureDimension.h in Headers */,
DD20DDB227BC90D70093D175 /* WebGPUTextureFormat.h in Headers */,
DD20DD3E27BC90D60093D175 /* WebGPUTextureImpl.h in Headers */,
@@ -2103,6 +2110,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
297CB483288B11D700BB7971 /* AccessibilitySoftLink.mm in Sources */,
293EE4A824154F8F0047493D /* AccessibilitySupportSoftLink.cpp in Sources */,
57FD318A22B3593E008D0E8B /* AppSSOSoftLink.mm in Sources */,
416E995323DAE6BE00E871CB /* AudioToolboxSoftLink.cpp in Sources */,
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2022 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
*/

#pragma once

#if HAVE(ACCESSIBILITY_FRAMEWORK)

#import <Accessibility/Accessibility.h>
#import <wtf/SoftLinking.h>

SOFT_LINK_FRAMEWORK_FOR_HEADER(PAL, Accessibility);

SOFT_LINK_CLASS_FOR_HEADER(PAL, AXCustomContent);

#endif
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2022 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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"

#if HAVE(ACCESSIBILITY_FRAMEWORK)

#import <wtf/SoftLinking.h>

SOFT_LINK_FRAMEWORK_FOR_SOURCE_WITH_EXPORT(PAL, Accessibility, PAL_EXPORT);

SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, Accessibility, AXCustomContent, PAL_EXPORT);

#endif
@@ -413,6 +413,7 @@ class AccessibilityObject : public AXCoreObject, public CanMakeWeakPtr<Accessibi
String brailleRoleDescription() const override { return getAttribute(HTMLNames::aria_brailleroledescriptionAttr); }
String embeddedImageDescription() const override;
std::optional<AccessibilityChildrenVector> imageOverlayElements() override { return std::nullopt; }
String extendedDescription() const override { return getAttribute(HTMLNames::aria_descriptionAttr); }

// Abbreviations
String expandedTextValue() const override { return String(); }
@@ -1075,6 +1075,7 @@ class AXCoreObject : public ThreadSafeRefCounted<AXCoreObject> {
virtual String brailleRoleDescription() const = 0;
virtual String embeddedImageDescription() const = 0;
virtual std::optional<AccessibilityChildrenVector> imageOverlayElements() = 0;
virtual String extendedDescription() const = 0;

virtual bool supportsARIAOwns() const = 0;
virtual bool isActiveDescendantOfFocusedContainer() const = 0;
@@ -397,6 +397,10 @@ void AXIsolatedObject::initializeProperties(Ref<AXCoreObject> coreObject, IsRoot
if (object.isWidget())
setProperty(AXPropertyName::IsWidget, true);

auto extendedDescription = object.extendedDescription();
if (extendedDescription.length())
setProperty(AXPropertyName::ExtendedDescription, extendedDescription.isolatedCopy());

initializePlatformProperties(coreObject, isRoot);
}

@@ -282,6 +282,7 @@ class AXIsolatedObject final : public AXCoreObject {
String brailleRoleDescription() const override { return stringAttributeValue(AXPropertyName::BrailleRoleDescription); }
String embeddedImageDescription() const override { return stringAttributeValue(AXPropertyName::EmbeddedImageDescription); }
std::optional<AccessibilityChildrenVector> imageOverlayElements() override { return std::nullopt; }
String extendedDescription() const override { return stringAttributeValue(AXPropertyName::ExtendedDescription); }

String computedRoleString() const override { return stringAttributeValue(AXPropertyName::ComputedRoleString); }
bool isValueAutofillAvailable() const override { return boolAttributeValue(AXPropertyName::IsValueAutofillAvailable); }
@@ -107,6 +107,7 @@ enum class AXPropertyName : uint16_t {
EditableAncestor,
EmbeddedImageDescription,
ExpandedTextValue,
ExtendedDescription,
FileUploadButtonReturnsValueInTitle,
FocusableAncestor,
HasARIAValueNow,
@@ -31,6 +31,8 @@

#if ENABLE(ACCESSIBILITY)

#import <Accessibility/Accessibility.h>

#import "AXObjectCache.h"
#import "AccessibilityARIAGridRow.h"
#import "AccessibilityList.h"
@@ -59,6 +61,7 @@
#import "TextIterator.h"
#import "VisibleUnits.h"
#import <wtf/cocoa/VectorCocoa.h>
#import <pal/cocoa/AccessibilitySoftLink.h>

#if PLATFORM(MAC)
#import "WebAccessibilityObjectWrapperMac.h"
@@ -403,6 +406,24 @@ - (BOOL)isIsolatedObject
return [(NSString *)self.axBackingObject->speechHintAttributeValue() componentsSeparatedByString:@" "];
}

#if HAVE(ACCESSIBILITY_FRAMEWORK)
- (NSArray<AXCustomContent *> *)accessibilityCustomContent
{
auto* backingObject = [self baseUpdateBackingStore];
if (!backingObject)
return nil;

RetainPtr<NSMutableArray<AXCustomContent *>> accessibilityCustomContent = nil;
auto extendedDescription = backingObject->extendedDescription();
if (extendedDescription.length()) {
accessibilityCustomContent = adoptNS([[NSMutableArray alloc] init]);
[accessibilityCustomContent addObject:[PAL::getAXCustomContentClass() customContentWithLabel:WEB_UI_STRING("description", "description detail") value:extendedDescription]];
}

return accessibilityCustomContent.autorelease();
}
#endif

- (NSString *)baseAccessibilityHelpText
{
return self.axBackingObject->helpTextAttributeValue();
@@ -27,6 +27,7 @@ aria-colspan
aria-controls
aria-current
aria-describedby
aria-description
aria-details
aria-disabled
aria-dropeffect
@@ -113,6 +113,7 @@ JSValueRef AccessibilityUIElement::mathRootRadicand() const { return { }; }

#if !PLATFORM(COCOA) || !ENABLE(ACCESSIBILITY)
RefPtr<AccessibilityUIElement> AccessibilityUIElement::focusedElement() const { return nullptr; }
JSRetainPtr<JSStringRef> AccessibilityUIElement::customContent() const { return nullptr; }

bool AccessibilityUIElement::hasDocumentRoleAncestor() const { return false; }
bool AccessibilityUIElement::hasWebApplicationAncestor() const { return false; }
@@ -235,6 +235,7 @@ class AccessibilityUIElement : public JSWrappable {
int columnCount();
JSValueRef rowHeaders() const;
JSValueRef columnHeaders() const;
JSRetainPtr<JSStringRef> customContent() const;

// Tree/Outline specific attributes
RefPtr<AccessibilityUIElement> selectedRowAtIndex(unsigned);
@@ -179,6 +179,7 @@
long columnCount();
object columnHeaders();
object rowHeaders();
readonly attribute DOMString customContent;

object detailsElements();
object errorMessageElements();
@@ -39,6 +39,10 @@
#import <wtf/Vector.h>
#import <wtf/cocoa/VectorCocoa.h>

#if HAVE(ACCESSIBILITY_FRAMEWORK)
#import <Accessibility/Accessibility.h>
#endif

typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);

@interface NSObject (UIAccessibilityHidden)
@@ -485,6 +489,18 @@ + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef
return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::customContent() const
{
#if HAVE(ACCESSIBILITY_FRAMEWORK)
auto customContent = adoptNS([[NSMutableArray alloc] init]);
for (AXCustomContent *content in [m_element accessibilityCustomContent])
[customContent addObject:[NSString stringWithFormat:@"%@: %@", content.label, content.value]];
return [[customContent.get() componentsJoinedByString:@"\n"] createJSStringRef];
#else
return nullptr;
#endif
}

bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
{
if (JSStringIsEqualToUTF8CString(attribute, "AXHasTouchEventListener"))
@@ -42,6 +42,10 @@
#import <wtf/Vector.h>
#import <wtf/cocoa/VectorCocoa.h>

#if HAVE(ACCESSIBILITY_FRAMEWORK)
#import <Accessibility/Accessibility.h>
#endif

#define NSAccessibilityDOMIdentifierAttribute @"AXDOMIdentifier"

#ifndef NSAccessibilityOwnsAttribute
@@ -393,6 +397,23 @@ void setAttributeValue(id element, NSString* attribute, id value, bool synchrono
END_AX_OBJC_EXCEPTIONS
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::customContent() const
{
BEGIN_AX_OBJC_EXCEPTIONS
#if HAVE(ACCESSIBILITY_FRAMEWORK)
auto customContent = adoptNS([[NSMutableArray alloc] init]);
s_controller->executeOnAXThreadAndWait([this, &customContent] {
for (AXCustomContent *content in [m_element accessibilityCustomContent])
[customContent addObject:[NSString stringWithFormat:@"%@: %@", content.label, content.value]];
});

return [[customContent.get() componentsJoinedByString:@"\n"] createJSStringRef];
#else
return nullptr;
#endif
END_AX_OBJC_EXCEPTIONS
}

JSValueRef AccessibilityUIElement::rowHeaders() const
{
BEGIN_AX_OBJC_EXCEPTIONS

0 comments on commit 7c414e7

Please sign in to comment.