Diff
Modified: trunk/Source/WebCore/ChangeLog (287386 => 287387)
--- trunk/Source/WebCore/ChangeLog 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Source/WebCore/ChangeLog 2021-12-23 08:53:38 UTC (rev 287387)
@@ -1,3 +1,31 @@
+2021-12-23 Carlos Garcia Campos <[email protected]>
+
+ [GTK][a11y] WTR: add support for notifications when building with ATSPI
+ https://bugs.webkit.org/show_bug.cgi?id=234550
+
+ Reviewed by Adrian Perez de Castro.
+
+ Add private API for WTR notifications.
+
+ * accessibility/atspi/AccessibilityAtspi.cpp:
+ (WebCore::AccessibilityAtspi::childrenChanged):
+ (WebCore::AccessibilityAtspi::stateChanged):
+ (WebCore::AccessibilityAtspi::textChanged):
+ (WebCore::AccessibilityAtspi::textCaretMoved):
+ (WebCore::AccessibilityAtspi::valueChanged):
+ (WebCore::AccessibilityAtspi::selectionChanged):
+ (WebCore::AccessibilityAtspi::loadEvent):
+ (WebCore::AccessibilityAtspi::addNotificationObserver):
+ (WebCore::AccessibilityAtspi::removeNotificationObserver):
+ (WebCore::AccessibilityAtspi::notifyStateChanged const):
+ (WebCore::AccessibilityAtspi::notifySelectionChanged const):
+ (WebCore::AccessibilityAtspi::notifyTextChanged const):
+ (WebCore::AccessibilityAtspi::notifyTextCaretMoved const):
+ (WebCore::AccessibilityAtspi::notifyChildrenChanged const):
+ (WebCore::AccessibilityAtspi::notifyValueChanged const):
+ (WebCore::AccessibilityAtspi::notifyLoadEvent const):
+ * accessibility/atspi/AccessibilityAtspi.h:
+
2021-12-23 Philippe Normand <[email protected]>
[GStreamer] test fast/mediastream/get-display-media-settings.html fails
Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp (287386 => 287387)
--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp 2021-12-23 08:53:38 UTC (rev 287387)
@@ -345,6 +345,11 @@
void AccessibilityAtspi::childrenChanged(AccessibilityObjectAtspi& atspiObject, AccessibilityObjectAtspi& child, ChildrenChanged change)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyChildrenChanged(atspiObject, child, change);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, child = Ref { child }, change] {
if (!m_connection)
return;
@@ -362,6 +367,11 @@
void AccessibilityAtspi::stateChanged(AccessibilityObjectAtspi& atspiObject, const char* name, bool value)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyStateChanged(atspiObject, name, value);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, name = CString(name), value] {
if (!m_connection)
return;
@@ -377,6 +387,11 @@
void AccessibilityAtspi::textChanged(AccessibilityObjectAtspi& atspiObject, const char* changeType, CString&& text, unsigned offset, unsigned length)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyTextChanged(atspiObject);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, changeType = CString(changeType), text = WTFMove(text), offset, length] {
if (!m_connection)
return;
@@ -407,6 +422,11 @@
void AccessibilityAtspi::textCaretMoved(AccessibilityObjectAtspi& atspiObject, unsigned caretOffset)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyTextCaretMoved(atspiObject, caretOffset);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, caretOffset] {
if (!m_connection)
return;
@@ -437,6 +457,11 @@
void AccessibilityAtspi::valueChanged(AccessibilityObjectAtspi& atspiObject, double value)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyValueChanged(atspiObject);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, value] {
if (!m_connection)
return;
@@ -452,6 +477,11 @@
void AccessibilityAtspi::selectionChanged(AccessibilityObjectAtspi& atspiObject)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifySelectionChanged(atspiObject);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }] {
if (!m_connection)
return;
@@ -467,6 +497,11 @@
void AccessibilityAtspi::loadEvent(AccessibilityObjectAtspi& atspiObject, CString&& event)
{
RELEASE_ASSERT(isMainThread());
+
+#if ENABLE(DEVELOPER_MODE)
+ notifyLoadEvent(atspiObject, event);
+#endif
+
m_queue->dispatch([this, atspiObject = Ref { atspiObject }, event = WTFMove(event)] {
if (!m_connection)
return;
@@ -713,6 +748,99 @@
} // namespace Accessibility
+#if ENABLE(DEVELOPER_MODE)
+void AccessibilityAtspi::addNotificationObserver(void* context, NotificationObserver&& observer)
+{
+ m_notificationObservers.add(context, WTFMove(observer));
+}
+
+void AccessibilityAtspi::removeNotificationObserver(void* context)
+{
+ m_notificationObservers.remove(context);
+}
+
+void AccessibilityAtspi::notifyStateChanged(AccessibilityObjectAtspi& atspiObject, const char* name, bool value) const
+{
+ if (m_notificationObservers.isEmpty())
+ return;
+
+ auto notificationName = [&](const char* name) -> const char* {
+ if (!g_strcmp0(name, "checked"))
+ return "CheckedStateChanged";
+ if (!g_strcmp0(name, "invalid-entry"))
+ return "AXInvalidStatusChanged";
+ if (!g_strcmp0(name, "active"))
+ return "ActiveStateChanged";
+ if (!g_strcmp0(name, "busy"))
+ return "AXElementBusyChanged";
+ if (!g_strcmp0(name, "enabled"))
+ return "AXDisabledStateChanged";
+ if (!g_strcmp0(name, "expanded"))
+ return "AXExpandedChanged";
+ if (!g_strcmp0(name, "pressed"))
+ return "AXPressedStateChanged";
+ if (!g_strcmp0(name, "read-only"))
+ return "AXReadOnlyStatusChanged";
+ if (!g_strcmp0(name, "required"))
+ return "AXRequiredStatusChanged";
+ if (!g_strcmp0(name, "sensitive"))
+ return "AXSensitiveStateChanged";
+ if (!g_strcmp0(name, "focused") && value)
+ return "AXFocusedUIElementChanged";
+
+ return nullptr;
+ };
+
+ const char* notification = notificationName(name);
+ if (!notification)
+ return;
+
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, notification, value);
+}
+
+void AccessibilityAtspi::notifySelectionChanged(AccessibilityObjectAtspi& atspiObject) const
+{
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, "AXSelectedChildrenChanged", nullptr);
+}
+
+void AccessibilityAtspi::notifyTextChanged(AccessibilityObjectAtspi& atspiObject) const
+{
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, "AXTextChanged", nullptr);
+}
+
+void AccessibilityAtspi::notifyTextCaretMoved(AccessibilityObjectAtspi& atspiObject, unsigned caretOffset) const
+{
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, "AXTextCaretMoved", caretOffset);
+}
+
+void AccessibilityAtspi::notifyChildrenChanged(AccessibilityObjectAtspi& atspiObject, AccessibilityObjectAtspi& child, ChildrenChanged change) const
+{
+ const char* notification = change == ChildrenChanged::Added ? "AXChildrenAdded" : "AXChildrenRemoved";
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, notification, child);
+}
+
+void AccessibilityAtspi::notifyValueChanged(AccessibilityObjectAtspi& atspiObject) const
+{
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, "AXValueChanged", nullptr);
+}
+
+void AccessibilityAtspi::notifyLoadEvent(AccessibilityObjectAtspi& atspiObject, const CString& event) const
+{
+ if (event != "LoadComplete")
+ return;
+
+ for (const auto& observer : m_notificationObservers.values())
+ observer(atspiObject, "AXLoadComplete", nullptr);
+}
+
+#endif
+
} // namespace WebCore
#endif // ENABLE(ACCESSIBILITY) && USE(ATSPI)
Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h (287386 => 287387)
--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h 2021-12-23 08:53:38 UTC (rev 287387)
@@ -78,6 +78,13 @@
void addAccessible(AccessibilityObjectAtspi&);
+#if ENABLE(DEVELOPER_MODE)
+ using NotificationObserverParameter = std::variant<std::nullptr_t, String, bool, unsigned, Ref<AccessibilityObjectAtspi>>;
+ using NotificationObserver = Function<void(AccessibilityObjectAtspi&, const char*, NotificationObserverParameter)>;
+ WEBCORE_EXPORT void addNotificationObserver(void*, NotificationObserver&&);
+ WEBCORE_EXPORT void removeNotificationObserver(void*);
+#endif
+
private:
void registerTrees() const;
void initializeRegistry();
@@ -89,6 +96,16 @@
bool shouldEmitSignal(const char* interface, const char* name, const char* detail = "");
+#if ENABLE(DEVELOPER_MODE)
+ void notifyStateChanged(AccessibilityObjectAtspi&, const char*, bool) const;
+ void notifySelectionChanged(AccessibilityObjectAtspi&) const;
+ void notifyTextChanged(AccessibilityObjectAtspi&) const;
+ void notifyTextCaretMoved(AccessibilityObjectAtspi&, unsigned) const;
+ void notifyChildrenChanged(AccessibilityObjectAtspi&, AccessibilityObjectAtspi&, ChildrenChanged) const;
+ void notifyValueChanged(AccessibilityObjectAtspi&) const;
+ void notifyLoadEvent(AccessibilityObjectAtspi&, const CString&) const;
+#endif
+
static GDBusInterfaceVTable s_cacheFunctions;
Ref<WorkQueue> m_queue;
@@ -101,6 +118,9 @@
unsigned m_cacheID { 0 };
HashMap<String, AccessibilityObjectAtspi*> m_cache;
bool m_inGetItems { false };
+#if ENABLE(DEVELOPER_MODE)
+ HashMap<void*, NotificationObserver> m_notificationObservers;
+#endif
};
} // namespace WebCore
Modified: trunk/Tools/ChangeLog (287386 => 287387)
--- trunk/Tools/ChangeLog 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/ChangeLog 2021-12-23 08:53:38 UTC (rev 287387)
@@ -1,3 +1,28 @@
+2021-12-23 Carlos Garcia Campos <[email protected]>
+
+ [GTK][a11y] WTR: add support for notifications when building with ATSPI
+ https://bugs.webkit.org/show_bug.cgi?id=234550
+
+ Reviewed by Adrian Perez de Castro.
+
+ Add AccessibilityNotificationHandler class to handle the ATSPI notifications.
+
+ * WebKitTestRunner/InjectedBundle/AccessibilityController.cpp:
+ * WebKitTestRunner/InjectedBundle/AccessibilityController.h:
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+ * WebKitTestRunner/InjectedBundle/atspi/AccessibilityControllerAtspi.cpp:
+ (WTR::AccessibilityController::resetToConsistentState): Remove the global event listener if there's one active.
+ (WTR::AccessibilityController::addNotificationListener): Create a global event listener.
+ (WTR::AccessibilityController::removeNotificationListener): Remove the global event listener.
+ * WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.cpp: Added.
+ (WTR::AccessibilityNotificationHandler::AccessibilityNotificationHandler):
+ (WTR::AccessibilityNotificationHandler::~AccessibilityNotificationHandler):
+ * WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.h: Added.
+ * WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp:
+ (WTR::AccessibilityUIElement::addNotificationListener): Create the element event listener.
+ (WTR::AccessibilityUIElement::removeNotificationListener): Remove the element event listener.
+ * WebKitTestRunner/PlatformGTK.cmake:
+
2021-12-22 Alex Christensen <[email protected]>
Re-enable WebPushD.HandleInjectedPush API test
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp 2021-12-23 08:53:38 UTC (rev 287387)
@@ -36,6 +36,10 @@
#include <WebKit/WKBundlePage.h>
#include <WebKit/WKBundlePagePrivate.h>
+#if USE(ATSPI)
+#include "AccessibilityNotificationHandler.h"
+#endif
+
namespace WTR {
Ref<AccessibilityController> AccessibilityController::create()
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h 2021-12-23 08:53:38 UTC (rev 287387)
@@ -44,6 +44,9 @@
namespace WTR {
class AccessibilityUIElement;
+#if USE(ATSPI)
+class AccessibilityNotificationHandler;
+#endif
class AccessibilityController : public JSWrappable {
public:
@@ -99,6 +102,8 @@
RetainPtr<id> m_globalNotificationHandler;
#elif USE(ATK)
RefPtr<AccessibilityNotificationHandler> m_globalNotificationHandler;
+#elif USE(ATSPI)
+ std::unique_ptr<AccessibilityNotificationHandler> m_globalNotificationHandler;
#endif
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2021-12-23 08:53:38 UTC (rev 287387)
@@ -59,6 +59,9 @@
namespace WTR {
class AccessibilityController;
+#if USE(ATSPI)
+class AccessibilityNotificationHandler;
+#endif
class AccessibilityUIElement : public JSWrappable {
#if PLATFORM(COCOA)
@@ -435,6 +438,7 @@
#elif USE(ATSPI)
static RefPtr<AccessibilityController> s_controller;
RefPtr<WebCore::AccessibilityObjectAtspi> m_element;
+ std::unique_ptr<AccessibilityNotificationHandler> m_notificationHandler;
#endif
#endif
};
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityControllerAtspi.cpp (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityControllerAtspi.cpp 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityControllerAtspi.cpp 2021-12-23 08:53:38 UTC (rev 287387)
@@ -29,6 +29,7 @@
#include "AccessibilityController.h"
#if HAVE(ACCESSIBILITY) && USE(ATSPI)
+#include "AccessibilityNotificationHandler.h"
#include "AccessibilityUIElement.h"
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
@@ -41,6 +42,8 @@
void AccessibilityController::resetToConsistentState()
{
+ if (m_globalNotificationHandler)
+ removeNotificationListener();
}
static WebCore::AccessibilityObjectAtspi* findAccessibleObjectById(WebCore::AccessibilityObjectAtspi& axObject, const String& elementID)
@@ -105,12 +108,21 @@
bool AccessibilityController::addNotificationListener(JSValueRef functionCallback)
{
+ if (!functionCallback)
+ return false;
+
+ if (m_globalNotificationHandler)
+ return false;
+
+ m_globalNotificationHandler = makeUnique<AccessibilityNotificationHandler>(functionCallback);
return true;
}
bool AccessibilityController::removeNotificationListener()
{
- return false;
+ ASSERT(m_globalNotificationHandler);
+ m_globalNotificationHandler = nullptr;
+ return true;
}
void AccessibilityController::updateIsolatedTreeMode()
Added: trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.cpp (0 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.cpp (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.cpp 2021-12-23 08:53:38 UTC (rev 287387)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+#include "config.h"
+#include "AccessibilityNotificationHandler.h"
+
+#if HAVE(ACCESSIBILITY) && USE(ATSPI)
+#include "InjectedBundlePage.h"
+#include "JSWrapper.h"
+#include <_javascript_Core/OpaqueJSString.h>
+#include <WebCore/AccessibilityObjectAtspi.h>
+#include <WebCore/AccessibilityRootAtspi.h>
+#include <WebKit/WKBundleFrame.h>
+#include <WebKit/WKBundlePage.h>
+#include <WebKit/WKBundlePagePrivate.h>
+
+namespace WTR {
+
+AccessibilityNotificationHandler::AccessibilityNotificationHandler(JSValueRef callback, PlatformUIElement element)
+ : m_callback(callback)
+ , m_element(element)
+{
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
+ JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
+ JSValueProtect(jsContext, m_callback);
+
+ auto& atspi = m_element ? m_element->root().atspi() : static_cast<WebCore::AccessibilityObjectAtspi*>(WKAccessibilityRootObject(page))->root().atspi();
+ atspi.addNotificationObserver(this, [this](WebCore::AccessibilityObjectAtspi& element, const char* notificationName, WebCore::AccessibilityAtspi::NotificationObserverParameter parameter) {
+ if (m_element && m_element.get() != &element)
+ return;
+
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
+ JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+ JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(notificationName));
+ JSValueRef jsParameter = WTF::switchOn(parameter,
+ [&](String& stringValue) -> JSValueRef {
+ JSRetainPtr<JSStringRef> jsStringValue(Adopt, OpaqueJSString::tryCreate(stringValue).get());
+ return JSValueMakeString(jsContext, jsStringValue.get());
+ },
+ [&](bool& boolValue) -> JSValueRef {
+ return JSValueMakeBoolean(jsContext, boolValue);
+ },
+ [&](unsigned& unsignedValue) -> JSValueRef {
+ return JSValueMakeNumber(jsContext, unsignedValue);
+ },
+ [&](Ref<WebCore::AccessibilityObjectAtspi>& elementValue) -> JSValueRef {
+ return toJS(jsContext, AccessibilityUIElement::create(elementValue.ptr()).ptr());
+ },
+ [&](auto&) -> JSValueRef {
+ return JSValueMakeUndefined(jsContext);
+ });
+
+ if (m_element) {
+ // Listener for one element gets the notification name parameter.
+ JSValueRef arguments[2];
+ arguments[0] = JSValueMakeString(jsContext, jsNotificationEventName.get());
+ arguments[1] = jsParameter;
+ JSObjectCallAsFunction(jsContext, const_cast<JSObjectRef>(m_callback), 0, 2, arguments, 0);
+ } else {
+ // A global listener gets the element, notification name and parameter.
+ JSValueRef arguments[3];
+ arguments[0] = toJS(jsContext, AccessibilityUIElement::create(&element).ptr());
+ arguments[1] = JSValueMakeString(jsContext, jsNotificationEventName.get());
+ arguments[2] = jsParameter;
+ JSObjectCallAsFunction(jsContext, const_cast<JSObjectRef>(m_callback), 0, 3, arguments, 0);
+ }
+ });
+}
+
+AccessibilityNotificationHandler::~AccessibilityNotificationHandler()
+{
+ WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+ auto& atspi = m_element ? m_element->root().atspi() : static_cast<WebCore::AccessibilityObjectAtspi*>(WKAccessibilityRootObject(page))->root().atspi();
+ atspi.removeNotificationObserver(this);
+
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
+ JSContextRef jsContext = WKBundleFrameGetJavaScriptContext(mainFrame);
+ JSValueUnprotect(jsContext, m_callback);
+}
+
+} // namespace WTR
+
+#endif // HAVE(ACCESSIBILITY) && USE(ATSPI)
Added: trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.h (0 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.h (rev 0)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityNotificationHandler.h 2021-12-23 08:53:38 UTC (rev 287387)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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) && USE(ATSPI)
+
+#include "AccessibilityUIElement.h"
+#include <_javascript_Core/JSObjectRef.h>
+#include <wtf/FastMalloc.h>
+
+namespace WTR {
+
+class AccessibilityNotificationHandler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit AccessibilityNotificationHandler(JSValueRef, PlatformUIElement = nullptr);
+ ~AccessibilityNotificationHandler();
+
+private:
+ JSValueRef m_callback;
+ RefPtr<WebCore::AccessibilityObjectAtspi> m_element;
+};
+
+} // namespace WTR
+
+#endif // HAVE(ACCESSIBILITY) && USE(ATSPI)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp 2021-12-23 08:53:38 UTC (rev 287387)
@@ -27,6 +27,7 @@
#include "AccessibilityUIElement.h"
#if HAVE(ACCESSIBILITY) && USE(ATSPI)
+#include "AccessibilityNotificationHandler.h"
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include <_javascript_Core/JSStringRef.h>
@@ -1321,11 +1322,20 @@
bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
{
- return false;
+ if (!functionCallback)
+ return false;
+
+ if (m_notificationHandler)
+ return false;
+
+ m_notificationHandler = makeUnique<AccessibilityNotificationHandler>(functionCallback, m_element.get());
+ return true;
}
bool AccessibilityUIElement::removeNotificationListener()
{
+ ASSERT(m_notificationHandler);
+ m_notificationHandler = nullptr;
return true;
}
Modified: trunk/Tools/WebKitTestRunner/PlatformGTK.cmake (287386 => 287387)
--- trunk/Tools/WebKitTestRunner/PlatformGTK.cmake 2021-12-23 08:46:14 UTC (rev 287386)
+++ trunk/Tools/WebKitTestRunner/PlatformGTK.cmake 2021-12-23 08:53:38 UTC (rev 287387)
@@ -45,6 +45,7 @@
InjectedBundle/atk/AccessibilityUIElementAtk.cpp
InjectedBundle/atspi/AccessibilityControllerAtspi.cpp
+ InjectedBundle/atspi/AccessibilityNotificationHandler.cpp
InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
InjectedBundle/gtk/ActivateFontsGtk.cpp
@@ -57,6 +58,7 @@
${ATK_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
${WebKitTestRunner_DIR}/InjectedBundle/atk
+ ${WebKitTestRunner_DIR}/InjectedBundle/atspi
${WebKitTestRunner_DIR}/InjectedBundle/gtk
)