Diff
Modified: trunk/LayoutTests/ChangeLog (261080 => 261081)
--- trunk/LayoutTests/ChangeLog 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/LayoutTests/ChangeLog 2020-05-04 14:35:10 UTC (rev 261081)
@@ -1,3 +1,17 @@
+2020-05-04 Andres Gonzalez <[email protected]>
+
+ Add WTR::AccessibilityUIElement::attributeValueAsync to retrieve attribute values in isolated tree mode.
+ https://bugs.webkit.org/show_bug.cgi?id=211341
+
+ Reviewed by Chris Fleizach.
+
+ This test exercises the new WTR::AccessibilityUIElement::atributeValueAsync method.
+ Instead of using shouldBeTrue that does not work with local variables,
+ uses debug to log results.
+
+ * accessibility/mac/primary-screen-height-expected.txt:
+ * accessibility/mac/primary-screen-height.html:
+
2020-05-03 Daniel Bates <[email protected]>
Sometimes cannot find <textarea> in list of editable elements
Modified: trunk/LayoutTests/accessibility/mac/primary-screen-height-expected.txt (261080 => 261081)
--- trunk/LayoutTests/accessibility/mac/primary-screen-height-expected.txt 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/LayoutTests/accessibility/mac/primary-screen-height-expected.txt 2020-05-04 14:35:10 UTC (rev 261081)
@@ -4,8 +4,8 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS screenHeightFromRootElement > 0 is true
-PASS screenHeightFromWebArea > 0 is true
+The screen height from the root element is > 0.
+The screen height from the web area is > 0.
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/accessibility/mac/primary-screen-height.html (261080 => 261081)
--- trunk/LayoutTests/accessibility/mac/primary-screen-height.html 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/LayoutTests/accessibility/mac/primary-screen-height.html 2020-05-04 14:35:10 UTC (rev 261081)
@@ -13,16 +13,23 @@
<script>
description("This tests the primary screen height is exposed to AX API from web process.");
if (window.accessibilityController) {
- var rootElement = accessibilityController.rootElement;
+ window.jsTestIsAsync = true;
+
+ var rootElement = accessibilityController.rootElement;
var webArea = accessibilityController.rootElement.childAtIndex(0);
- var screenHeightFromRootElement = rootElement.numberAttributeValue("_AXPrimaryScreenHeight");
- shouldBeTrue("screenHeightFromRootElement > 0");
+ rootElement.attributeValueAsync("_AXPrimaryScreenHeight", function(value) {
+ debug(value > 0 ? "The screen height from the root element is > 0."
+ : "The screen height from the root element should be > 0 but it is not.");
+ });
- var screenHeightFromWebArea = webArea.numberAttributeValue("_AXPrimaryScreenHeight");
- shouldBeTrue("screenHeightFromWebArea > 0");
+ webArea.attributeValueAsync("_AXPrimaryScreenHeight", function(value) {
+ debug(value > 0 ? "The screen height from the web area is > 0."
+ : "The screen height from the web area should be > 0 but it is not.");
+
+ finishJSTest();
+ });
}
-
</script>
<script src=""
</body>
Modified: trunk/Tools/ChangeLog (261080 => 261081)
--- trunk/Tools/ChangeLog 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/ChangeLog 2020-05-04 14:35:10 UTC (rev 261081)
@@ -1,3 +1,59 @@
+2020-05-04 Andres Gonzalez <[email protected]>
+
+ Add WTR::AccessibilityUIElement::attributeValueAsync to retrieve attribute values in isolated tree mode.
+ https://bugs.webkit.org/show_bug.cgi?id=211341
+
+ Reviewed by Chris Fleizach.
+
+ To simulate running WebAccessibilityObjectWrapper methods on the secondary
+ thread, WTR::AccessibilityUIElement dispatches those calls to the AX
+ thread. But some WebAccessibilityObjectWrapper calls cannot be fulfilled
+ on the secondary thread and in turn have to be dispatched to the main
+ thread. This was causing a thread lock during LayoutTests in isolated
+ tree mode since the initial dispatch to the secondary thread blocks the
+ main thread. The solution in this patch is to add an asynchronous
+ mechanism to retrieve attribute values.
+ - Added WTR::AccessibilityUIElement::attributeValueAsync.
+ - Made several fixes consisting of retaining variables in the main
+ thread whose values are computed on the secondary thread.
+
+ * WebKitTestRunner/InjectedBundle/AccessibilityController.cpp:
+ (WTR::AccessibilityController::executeOnAXThreadAndWait):
+ (WTR::AccessibilityController::executeOnAXThread):
+ (WTR::AccessibilityController::executeOnMainThread):
+ (WTR::AXThread::dispatchBarrier):
+ (WTR::AccessibilityController::executeOnAXThreadIfPossible): Renamed executeOnAXThreadAndWait.
+ * WebKitTestRunner/InjectedBundle/AccessibilityController.h:
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+ * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.h:
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.mm:
+ (WTR::webAccessibilityObjectWrapperClass):
+ (WTR::makeArrayRefForArray):
+ (WTR::makeObjectRefForDictionary):
+ (WTR::makeValueRefForValue):
+ (WTR::searchPredicateParameterizedAttributeForSearchCriteria):
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm:
+ (WTR::AccessibilityController::accessibleElementById):
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm:
+ (-[AccessibilityNotificationHandler startObserving]):
+ (-[AccessibilityNotificationHandler _notificationReceived:]):
+ (webAccessibilityObjectWrapperClass): Moved to AccessibilityCommonMac.
+ (makeValueRefForValue): Moved to AccessibilityCommonMac.
+ (makeArrayRefForArray): Moved to AccessibilityCommonMac.
+ (makeObjectRefForDictionary): Moved to AccessibilityCommonMac.
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+ (WTR::supportedAttributes):
+ (WTR::attributeValue):
+ (WTR::setAttributeValue):
+ (WTR::attributesOfElement):
+ (WTR::AccessibilityUIElement::getChildrenWithRange):
+ (WTR::AccessibilityUIElement::elementAtPoint):
+ (WTR::AccessibilityUIElement::indexOfChild):
+ (WTR::AccessibilityUIElement::selectedChildrenCount const):
+ (WTR::AccessibilityUIElement::attributeValueAsync):
+ (WTR::AccessibilityUIElement::selectTextWithCriteria):
+
2020-05-04 Commit Queue <[email protected]>
Unreviewed, reverting r261076.
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp 2020-05-04 14:35:10 UTC (rev 261081)
@@ -107,7 +107,7 @@
return AccessibilityUIElement::create(focusedElement);
}
-void AccessibilityController::executeOnAXThreadIfPossible(Function<void()>&& function)
+void AccessibilityController::executeOnAXThreadAndWait(Function<void()>&& function)
{
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
if (m_useMockAXThread) {
@@ -121,6 +121,30 @@
#endif
function();
}
+
+void AccessibilityController::executeOnAXThread(Function<void()>&& function)
+{
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+ if (m_useMockAXThread) {
+ AXThread::dispatch([function = WTFMove(function)] {
+ function();
+ });
+ } else
+#endif
+ function();
+}
+
+void AccessibilityController::executeOnMainThread(Function<void()>&& function)
+{
+ if (isMainThread()) {
+ function();
+ return;
+ }
+
+ AXThread::dispatchBarrier([function = WTFMove(function)] {
+ function();
+ });
+}
#endif // PLATFORM(COCOA)
RefPtr<AccessibilityUIElement> AccessibilityController::elementAtPoint(int x, int y)
@@ -157,7 +181,7 @@
void AXThread::dispatchBarrier(Function<void()>&& function)
{
- dispatch([function = WTFMove(function)]() mutable {
+ dispatch([function = WTFMove(function)] () mutable {
callOnMainThread(WTFMove(function));
});
}
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h 2020-05-04 14:35:10 UTC (rev 261081)
@@ -67,7 +67,9 @@
RefPtr<AccessibilityUIElement> accessibleElementById(JSStringRef idAttribute);
#if PLATFORM(COCOA)
- void executeOnAXThreadIfPossible(Function<void()>&&);
+ void executeOnAXThreadAndWait(Function<void()>&&);
+ void executeOnAXThread(Function<void()>&&);
+ void executeOnMainThread(Function<void()>&&);
#endif
bool addNotificationListener(JSValueRef functionCallback);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2020-05-04 14:35:10 UTC (rev 261081)
@@ -55,7 +55,7 @@
class AccessibilityUIElement : public JSWrappable {
#if PLATFORM(COCOA)
// Helper functions that dispatch the corresponding AccessibilityObjectWrapper method to the AX secondary thread when appropriate.
- friend NSArray* supportedAttributes(id);
+ friend RetainPtr<NSArray> supportedAttributes(id);
friend id attributeValue(id, NSString *);
friend void setAttributeValue(id, NSString *, id, bool synchronous);
#endif
@@ -121,6 +121,11 @@
JSValueRef uiElementArrayAttributeValue(JSStringRef attribute) const;
RefPtr<AccessibilityUIElement> uiElementAttributeValue(JSStringRef attribute) const;
bool boolAttributeValue(JSStringRef attribute);
+#if PLATFORM(MAC)
+ void attributeValueAsync(JSStringRef attribute, JSValueRef callback);
+#else
+ void attributeValueAsync(JSStringRef attribute, JSValueRef callback) { }
+#endif
void setBoolAttributeValue(JSStringRef attribute, bool value);
bool isAttributeSupported(JSStringRef attribute);
bool isAttributeSettable(JSStringRef attribute);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2020-05-04 14:35:10 UTC (rev 261081)
@@ -66,6 +66,7 @@
object uiElementArrayAttributeValue(DOMString attr);
AccessibilityUIElement uiElementAttributeValue(DOMString attr);
boolean boolAttributeValue(DOMString attr);
+ void attributeValueAsync(DOMString attributeName, object callbackFunction);
void setBoolAttributeValue(DOMString attr, boolean value);
boolean isAttributeSupported(DOMString attr);
boolean isAttributeSettable(DOMString attr);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.h (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.h 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.h 2020-05-04 14:35:10 UTC (rev 261081)
@@ -42,7 +42,9 @@
@end
namespace WTR {
-
+
+Class webAccessibilityObjectWrapperClass();
+JSValueRef makeValueRefForValue(JSContextRef, id value);
extern NSDictionary *searchPredicateParameterizedAttributeForSearchCriteria(JSContextRef, AccessibilityUIElement *startElement, bool isDirectionNext, unsigned resultsLimit, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
};
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.mm (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.mm 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityCommonMac.mm 2020-05-04 14:35:10 UTC (rev 261081)
@@ -31,7 +31,9 @@
#import "config.h"
#import "AccessibilityCommonMac.h"
+#import "JSWrapper.h"
#import <_javascript_Core/JSStringRefCF.h>
+#import <objc/runtime.h>
@implementation NSString (JSStringRefAdditions)
@@ -48,19 +50,69 @@
return adopt(JSStringCreateWithCFString((__bridge CFStringRef)self));
}
+@end
+
namespace WTR {
+Class webAccessibilityObjectWrapperClass()
+{
+ static Class cls = objc_getClass("WebAccessibilityObjectWrapper");
+ ASSERT(cls);
+ return cls;
+}
+
+static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
+{
+ NSUInteger count = array.count;
+ JSValueRef arguments[count];
+
+ for (NSUInteger i = 0; i < count; i++)
+ arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
+
+ return JSObjectMakeArray(context, count, arguments, nullptr);
+}
+
+static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
+{
+ JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
+
+ [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *) {
+ if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
+ JSObjectSetProperty(context, object, [key createJSStringRef].get(), propertyValue, kJSPropertyAttributeNone, nullptr);
+ }];
+
+ return object;
+}
+
+JSValueRef makeValueRefForValue(JSContextRef context, id value)
+{
+ if ([value isKindOfClass:[NSString class]])
+ return JSValueMakeString(context, [value createJSStringRef].get());
+ if ([value isKindOfClass:[NSNumber class]]) {
+ if (!strcmp([value objCType], @encode(BOOL)))
+ return JSValueMakeBoolean(context, [value boolValue]);
+ return JSValueMakeNumber(context, [value doubleValue]);
+ }
+ if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
+ return toJS(context, WTR::AccessibilityUIElement::create(static_cast<PlatformUIElement>(value)).ptr());
+ if ([value isKindOfClass:[NSDictionary class]])
+ return makeObjectRefForDictionary(context, value);
+ if ([value isKindOfClass:[NSArray class]])
+ return makeArrayRefForArray(context, value);
+ return nullptr;
+}
+
NSDictionary *searchPredicateParameterizedAttributeForSearchCriteria(JSContextRef context, AccessibilityUIElement *startElement, bool isDirectionNext, unsigned resultsLimit, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary];
-
+
if (startElement && startElement->platformUIElement())
[parameterizedAttribute setObject:startElement->platformUIElement() forKey:@"AXStartElement"];
-
+
[parameterizedAttribute setObject:(isDirectionNext) ? @"AXDirectionNext" : @"AXDirectionPrevious" forKey:@"AXDirection"];
-
+
[parameterizedAttribute setObject:@(resultsLimit) forKey:@"AXResultsLimit"];
-
+
if (searchKey) {
id searchKeyParameter = nil;
if (JSValueIsString(context, searchKey)) {
@@ -70,12 +122,12 @@
} else if (JSValueIsObject(context, searchKey)) {
JSObjectRef searchKeyArray = JSValueToObject(context, searchKey, nullptr);
unsigned searchKeyArrayLength = 0;
-
+
auto lengthPropertyString = adopt(JSStringCreateWithUTF8CString("length"));
JSValueRef searchKeyArrayLengthValue = JSObjectGetProperty(context, searchKeyArray, lengthPropertyString.get(), nullptr);
if (searchKeyArrayLengthValue && JSValueIsNumber(context, searchKeyArrayLengthValue))
searchKeyArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchKeyArrayLengthValue, nullptr));
-
+
for (unsigned i = 0; i < searchKeyArrayLength; ++i) {
JSValueRef searchKeyValue = JSObjectGetPropertyAtIndex(context, searchKeyArray, i, nullptr);
JSStringRef searchKeyString = JSValueToStringCopy(context, searchKeyValue, nullptr);
@@ -90,17 +142,16 @@
if (searchKeyParameter)
[parameterizedAttribute setObject:searchKeyParameter forKey:@"AXSearchKey"];
}
-
+
if (searchText && JSStringGetLength(searchText))
[parameterizedAttribute setObject:[NSString stringWithJSStringRef:searchText] forKey:@"AXSearchText"];
-
+
[parameterizedAttribute setObject:@(visibleOnly) forKey:@"AXVisibleOnly"];
-
+
[parameterizedAttribute setObject:@(immediateDescendantsOnly) forKey:@"AXImmediateDescendantsOnly"];
-
+
return parameterizedAttribute;
}
-
+
} // namespace WTR
-@end
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm 2020-05-04 14:35:10 UTC (rev 261081)
@@ -100,7 +100,7 @@
PlatformUIElement root = static_cast<PlatformUIElement>(WKAccessibilityRootObject(page));
RetainPtr<id> result;
- executeOnAXThreadIfPossible([&root, &idAttribute, &result] {
+ executeOnAXThreadAndWait([&root, &idAttribute, &result] {
result = findAccessibleObjectById(root, [NSString stringWithJSStringRef:idAttribute]);
});
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm 2020-05-04 14:35:10 UTC (rev 261081)
@@ -40,7 +40,6 @@
#import <_javascript_Core/JSStringRef.h>
#import <_javascript_Core/JSStringRefCF.h>
#import <WebKit/WKBundleFrame.h>
-#import <objc/runtime.h>
#import <wtf/RetainPtr.h>
@interface NSObject (WebAccessibilityObjectWrapperAdditions)
@@ -90,19 +89,12 @@
JSValueProtect(context, m_notificationFunctionCallback);
}
-static Class webAccessibilityObjectWrapperClass()
-{
- static Class cls = objc_getClass("WebAccessibilityObjectWrapper");
- ASSERT(cls);
- return cls;
-}
-
- (void)startObserving
{
// Once we start requesting notifications, it's on for the duration of the program.
// This is to avoid any race conditions between tests turning this flag on and off. Instead
// AccessibilityNotificationHandler can ignore events it doesn't care about.
- [webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
+ [WTR::webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
}
@@ -111,48 +103,6 @@
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-static JSValueRef makeValueRefForValue(JSContextRef context, id value)
-{
- if ([value isKindOfClass:[NSString class]])
- return JSValueMakeString(context, [value createJSStringRef].get());
- if ([value isKindOfClass:[NSNumber class]]) {
- if (!strcmp([value objCType], @encode(BOOL)))
- return JSValueMakeBoolean(context, [value boolValue]);
- return JSValueMakeNumber(context, [value doubleValue]);
- }
- if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
- return toJS(context, WTR::AccessibilityUIElement::create(static_cast<PlatformUIElement>(value)).ptr());
- if ([value isKindOfClass:[NSDictionary class]])
- return makeObjectRefForDictionary(context, value);
- if ([value isKindOfClass:[NSArray class]])
- return makeArrayRefForArray(context, value);
- return nullptr;
-}
-
-static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
-{
- NSUInteger count = array.count;
- JSValueRef arguments[count];
-
- for (NSUInteger i = 0; i < count; i++)
- arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
-
- return JSObjectMakeArray(context, count, arguments, nullptr);
-}
-
-static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
-{
- JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
-
- [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop)
- {
- if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
- JSObjectSetProperty(context, object, [key createJSStringRef].get(), propertyValue, kJSPropertyAttributeNone, nullptr);
- }];
-
- return object;
-}
-
- (void)_notificationReceived:(NSNotification *)notification
{
NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
@@ -167,7 +117,7 @@
JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
JSValueRef notificationNameArgument = JSValueMakeString(context, [notificationName createJSStringRef].get());
- JSValueRef userInfoArgument = makeObjectRefForDictionary(context, userInfo);
+ JSValueRef userInfoArgument = WTR::makeValueRefForValue(context, userInfo);
if (m_platformElement) {
// Listener for one element gets the notification name and userInfo.
JSValueRef arguments[2];
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (261080 => 261081)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2020-05-04 14:13:24 UTC (rev 261080)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2020-05-04 14:35:10 UTC (rev 261081)
@@ -117,12 +117,12 @@
return platformUIElement() == otherElement->platformUIElement();
}
-NSArray* supportedAttributes(id element)
+RetainPtr<NSArray> supportedAttributes(id element)
{
- NSArray *attributes;
+ RetainPtr<NSArray> attributes;
BEGIN_AX_OBJC_EXCEPTIONS
- AccessibilityUIElement::s_controller->executeOnAXThreadIfPossible([&attributes, &element] {
+ AccessibilityUIElement::s_controller->executeOnAXThreadAndWait([&attributes, &element] {
attributes = [element accessibilityAttributeNames];
});
END_AX_OBJC_EXCEPTIONS
@@ -132,21 +132,21 @@
id attributeValue(id element, NSString *attribute)
{
- id value;
+ RetainPtr<id> value;
BEGIN_AX_OBJC_EXCEPTIONS
- AccessibilityUIElement::s_controller->executeOnAXThreadIfPossible([&element, &attribute, &value] {
+ AccessibilityUIElement::s_controller->executeOnAXThreadAndWait([&element, &attribute, &value] {
value = [element accessibilityAttributeValue:attribute];
});
END_AX_OBJC_EXCEPTIONS
- return value;
+ return value.get();
}
void setAttributeValue(id element, NSString* attribute, id value, bool synchronous = false)
{
BEGIN_AX_OBJC_EXCEPTIONS
- AccessibilityUIElement::s_controller->executeOnAXThreadIfPossible([&element, &attribute, &value, &synchronous] {
+ AccessibilityUIElement::s_controller->executeOnAXThreadAndWait([&element, &attribute, &value, &synchronous] {
// FIXME: should always be asynchronous, fix tests.
synchronous ? [element _accessibilitySetValue:value forAttribute:attribute] :
[element accessibilitySetValue:value forAttribute:attribute];;;
@@ -198,10 +198,10 @@
static NSString *attributesOfElement(id accessibilityObject)
{
- NSArray* attributes = supportedAttributes(accessibilityObject);
+ RetainPtr<NSArray> attributes = supportedAttributes(accessibilityObject);
NSMutableString* attributesString = [NSMutableString string];
- for (NSString* attribute in attributes) {
+ for (NSString* attribute in attributes.get()) {
// Position provides useless and screen-specific information, so we do not
// want to include it for the sake of universally passing tests.
if ([attribute isEqualToString:@"AXPosition"])
@@ -373,7 +373,7 @@
{
BEGIN_AX_OBJC_EXCEPTIONS
RetainPtr<NSArray> children;
- s_controller->executeOnAXThreadIfPossible([&children, location, length, this] {
+ s_controller->executeOnAXThreadAndWait([&children, location, length, this] {
children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length];
});
elementVector = makeVector<RefPtr<AccessibilityUIElement>>(children.get());
@@ -418,8 +418,8 @@
RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
{
- id element;
- s_controller->executeOnAXThreadIfPossible([&x, &y, &element, this] {
+ RetainPtr<id> element;
+ s_controller->executeOnAXThreadAndWait([&x, &y, &element, this] {
element = [m_element accessibilityHitTest:NSMakePoint(x, y)];
});
@@ -426,7 +426,7 @@
if (!element)
return nullptr;
- return AccessibilityUIElement::create(element);
+ return AccessibilityUIElement::create(element.get());
}
unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
@@ -433,7 +433,7 @@
{
unsigned index;
id platformElement = element->platformUIElement();
- s_controller->executeOnAXThreadIfPossible([&platformElement, &index, this] {
+ s_controller->executeOnAXThreadAndWait([&platformElement, &index, this] {
index = [m_element accessibilityIndexOfChild:platformElement];
});
return index;
@@ -511,7 +511,7 @@
unsigned count = 0;
BEGIN_AX_OBJC_EXCEPTIONS
- s_controller->executeOnAXThreadIfPossible([&count, this] {
+ s_controller->executeOnAXThreadAndWait([&count, this] {
count = [m_element accessibilityArrayAttributeCount:NSAccessibilitySelectedChildrenAttribute];
});
END_AX_OBJC_EXCEPTIONS
@@ -613,6 +613,27 @@
return false;
}
+void AccessibilityUIElement::attributeValueAsync(JSStringRef attribute, JSValueRef callback)
+{
+ if (!attribute || !callback)
+ return;
+
+ BEGIN_AX_OBJC_EXCEPTIONS
+ s_controller->executeOnAXThread([attribute = retainPtr([NSString stringWithJSStringRef:attribute]), callback = WTFMove(callback), this] () mutable {
+ id value = [m_element accessibilityAttributeValue:attribute.get()];
+
+ s_controller->executeOnMainThread([value = retainPtr(value), callback = WTFMove(callback)] () {
+ auto mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ auto context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+ JSValueRef arguments[1];
+ arguments[0] = makeValueRefForValue(context, value.get());
+ JSObjectCallAsFunction(context, const_cast<JSObjectRef>(callback), 0, 1, arguments, 0);
+ });
+ });
+ END_AX_OBJC_EXCEPTIONS
+}
+
void AccessibilityUIElement::setBoolAttributeValue(JSStringRef attribute, bool value)
{
setAttributeValue(m_element.get(), [NSString stringWithJSStringRef:attribute], @(value), true);
@@ -1177,14 +1198,14 @@
{
BEGIN_AX_OBJC_EXCEPTIONS
NSDictionary *parameterizedAttribute = selectTextParameterizedAttributeForCriteria(context, ambiguityResolution, searchStrings, replacementString, activity);
- id result;
- s_controller->executeOnAXThreadIfPossible([¶meterizedAttribute, &result, this] {
+ RetainPtr<id> result;
+ s_controller->executeOnAXThreadAndWait([¶meterizedAttribute, &result, this] {
result = [m_element accessibilityAttributeValue:@"AXSelectTextWithCriteria" forParameter:parameterizedAttribute];
});
- if ([result isKindOfClass:[NSString class]])
- return [result createJSStringRef];
+ if ([result.get() isKindOfClass:[NSString class]])
+ return [result.get() createJSStringRef];
END_AX_OBJC_EXCEPTIONS
-
+
return nullptr;
}