Title: [287071] trunk
Revision
287071
Author
[email protected]
Date
2021-12-15 06:15:06 -0800 (Wed, 15 Dec 2021)

Log Message

[GTK][a11y] Add support for loading events when building with ATSPI
https://bugs.webkit.org/show_bug.cgi?id=234344

Reviewed by Joanmarie Diggs.

Source/WebCore:

Emit document:load-complete, document:reload, document:load-stopped and object:state-changed:busy.

* accessibility/atspi/AXObjectCacheAtspi.cpp:
(WebCore::AXObjectCache::frameLoadingEventPlatformNotification):
* accessibility/atspi/AccessibilityAtspi.cpp:
(WebCore::AccessibilityAtspi::loadEvent):
* accessibility/atspi/AccessibilityAtspi.h:
* accessibility/atspi/AccessibilityObjectAtspi.cpp:
(WebCore::AccessibilityObjectAtspi::loadEvent):
* accessibility/atspi/AccessibilityObjectAtspi.h:

Tools:

Add a test case to check loading events.

* TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp:
(AccessibilityTest::shouldProcessEvent): Helper to make the filters conditions easier to read.
(AccessibilityTest::startEventMonitor): Make it possible to use the monitor without filtering events.
(testDocumentLoadEvents):
(beforeAll):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287070 => 287071)


--- trunk/Source/WebCore/ChangeLog	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/ChangeLog	2021-12-15 14:15:06 UTC (rev 287071)
@@ -1,5 +1,23 @@
 2021-12-15  Carlos Garcia Campos  <[email protected]>
 
+        [GTK][a11y] Add support for loading events when building with ATSPI
+        https://bugs.webkit.org/show_bug.cgi?id=234344
+
+        Reviewed by Joanmarie Diggs.
+
+        Emit document:load-complete, document:reload, document:load-stopped and object:state-changed:busy.
+
+        * accessibility/atspi/AXObjectCacheAtspi.cpp:
+        (WebCore::AXObjectCache::frameLoadingEventPlatformNotification):
+        * accessibility/atspi/AccessibilityAtspi.cpp:
+        (WebCore::AccessibilityAtspi::loadEvent):
+        * accessibility/atspi/AccessibilityAtspi.h:
+        * accessibility/atspi/AccessibilityObjectAtspi.cpp:
+        (WebCore::AccessibilityObjectAtspi::loadEvent):
+        * accessibility/atspi/AccessibilityObjectAtspi.h:
+
+2021-12-15  Carlos Garcia Campos  <[email protected]>
+
         [GTK][a11y] Register the wrappers tree when there's an event listener registered
         https://bugs.webkit.org/show_bug.cgi?id=234338
 

Modified: trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp (287070 => 287071)


--- trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp	2021-12-15 14:15:06 UTC (rev 287071)
@@ -305,8 +305,36 @@
         wrapper->textInserted(insertedText, position);
 }
 
-void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* object, AXLoadingEvent loadingEvent)
+void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* coreObject, AXLoadingEvent loadingEvent)
 {
+    RELEASE_ASSERT(isMainThread());
+    if (!coreObject)
+        return;
+
+    if (coreObject->roleValue() != AccessibilityRole::WebArea)
+        return;
+
+    auto* wrapper = coreObject->wrapper();
+    if (!wrapper)
+        return;
+
+    switch (loadingEvent) {
+    case AXObjectCache::AXLoadingStarted:
+        wrapper->stateChanged("busy", true);
+        break;
+    case AXObjectCache::AXLoadingReloaded:
+        wrapper->stateChanged("busy", true);
+        wrapper->loadEvent("Reload");
+        break;
+    case AXObjectCache::AXLoadingFailed:
+        wrapper->stateChanged("busy", false);
+        wrapper->loadEvent("LoadStopped");
+        break;
+    case AXObjectCache::AXLoadingFinished:
+        wrapper->stateChanged("busy", false);
+        wrapper->loadEvent("LoadComplete");
+        break;
+    }
 }
 
 void AXObjectCache::platformHandleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode)

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp (287070 => 287071)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp	2021-12-15 14:15:06 UTC (rev 287071)
@@ -464,6 +464,21 @@
     });
 }
 
+void AccessibilityAtspi::loadEvent(AccessibilityObjectAtspi& atspiObject, CString&& event)
+{
+    RELEASE_ASSERT(isMainThread());
+    m_queue->dispatch([this, atspiObject = Ref { atspiObject }, event = WTFMove(event)] {
+        if (!m_connection)
+            return;
+
+        if (!shouldEmitSignal("Document", event.data()))
+            return;
+
+        g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Document", event.data(),
+            g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr);
+    });
+}
+
 struct RoleNameEntry {
     const char* name;
     const char* localizedName;

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h (287070 => 287071)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h	2021-12-15 14:15:06 UTC (rev 287071)
@@ -72,6 +72,8 @@
 
     void selectionChanged(AccessibilityObjectAtspi&);
 
+    void loadEvent(AccessibilityObjectAtspi&, CString&&);
+
     static const char* localizedRoleName(AccessibilityRole);
 
     void addAccessible(AccessibilityObjectAtspi&);

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp (287070 => 287071)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp	2021-12-15 14:15:06 UTC (rev 287071)
@@ -1237,6 +1237,12 @@
     m_root.atspi().stateChanged(*this, name, value);
 }
 
+void AccessibilityObjectAtspi::loadEvent(const char* event)
+{
+    RELEASE_ASSERT(isMainThread());
+    m_root.atspi().loadEvent(*this, event);
+}
+
 unsigned AccessibilityObjectAtspi::role() const
 {
     RELEASE_ASSERT(!isMainThread());

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h (287070 => 287071)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h	2021-12-15 14:15:06 UTC (rev 287071)
@@ -135,6 +135,7 @@
     WEBCORE_EXPORT bool doAction() const;
 
     WEBCORE_EXPORT String documentAttribute(const String&) const;
+    void loadEvent(const char*);
 
     WEBCORE_EXPORT unsigned selectionCount() const;
     WEBCORE_EXPORT AccessibilityObjectAtspi* selectedChild(unsigned) const;

Modified: trunk/Tools/ChangeLog (287070 => 287071)


--- trunk/Tools/ChangeLog	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Tools/ChangeLog	2021-12-15 14:15:06 UTC (rev 287071)
@@ -1,5 +1,20 @@
 2021-12-15  Carlos Garcia Campos  <[email protected]>
 
+        [GTK][a11y] Add support for loading events when building with ATSPI
+        https://bugs.webkit.org/show_bug.cgi?id=234344
+
+        Reviewed by Joanmarie Diggs.
+
+        Add a test case to check loading events.
+
+        * TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp:
+        (AccessibilityTest::shouldProcessEvent): Helper to make the filters conditions easier to read.
+        (AccessibilityTest::startEventMonitor): Make it possible to use the monitor without filtering events.
+        (testDocumentLoadEvents):
+        (beforeAll):
+
+2021-12-15  Carlos Garcia Campos  <[email protected]>
+
         [GTK][a11y] Register the wrappers tree when there's an event listener registered
         https://bugs.webkit.org/show_bug.cgi?id=234338
 

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp (287070 => 287071)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp	2021-12-15 13:48:20 UTC (rev 287070)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp	2021-12-15 14:15:06 UTC (rev 287071)
@@ -114,16 +114,28 @@
         return !g_strcmp0(applicationName.get(), "TestWebKitAccessibility");
     }
 
-    void startEventMonitor(AtspiAccessible* source, Vector<CString>&& events)
+    bool shouldProcessEvent(AtspiEvent* event)
     {
+        // source = std::nullopt -> no filter.
+        if (!m_eventMonitor.source)
+            return true;
+
+        // source = nullptr -> filter by application.
+        if (!m_eventMonitor.source.value())
+            return accessibleApplicationIsTestProgram(event->source);
+
+        // source != nullptr -> filter by accessible.
+        return m_eventMonitor.source.value() == event->source;
+    }
+
+    void startEventMonitor(std::optional<AtspiAccessible*> source, Vector<CString>&& events)
+    {
         m_eventMonitor.source = source;
         m_eventMonitor.eventTypes = WTFMove(events);
         m_eventMonitor.listener = adoptGRef(atspi_event_listener_new([](AtspiEvent* event, gpointer userData) {
             auto* test = static_cast<AccessibilityTest*>(userData);
-            if ((test->m_eventMonitor.source && event->source == test->m_eventMonitor.source)
-                || (!test->m_eventMonitor.source && accessibleApplicationIsTestProgram(event->source))) {
+            if (test->shouldProcessEvent(event))
                 test->m_eventMonitor.events.append(static_cast<AtspiEvent*>(g_boxed_copy(ATSPI_TYPE_EVENT, event)));
-            }
         }, this, nullptr));
 
         for (const auto& event : m_eventMonitor.eventTypes)
@@ -175,7 +187,7 @@
         GRefPtr<AtspiEventListener> listener;
         Vector<CString> eventTypes;
         Vector<UniqueAtspiEvent> events;
-        AtspiAccessible* source { nullptr };
+        std::optional<AtspiAccessible*> source;
     } m_eventMonitor;
 };
 
@@ -2118,6 +2130,56 @@
 #endif
 }
 
+static void testDocumentLoadEvents(AccessibilityTest* test, gconstpointer)
+{
+    test->showInWindow();
+    test->loadURI("about:blank");
+    test->waitUntilLoadFinished();
+    test->startEventMonitor(std::nullopt, { "document:", "object:state-changed:busy" });
+    test->loadHtml(
+        "<html>"
+        "  <body>"
+        "    <p>Loading events test</p>"
+        "  </body>"
+        "</html>",
+        nullptr);
+    test->waitUntilLoadFinished();
+    auto events = test->stopEventMonitor(3);
+    g_assert_cmpuint(events.size(), ==, 3);
+    g_assert_cmpstr(events[0]->type, ==, "object:state-changed:busy");
+    g_assert_cmpuint(events[0]->detail1, ==, 1);
+    g_assert_cmpstr(events[1]->type, ==, "object:state-changed:busy");
+    g_assert_cmpuint(events[1]->detail1, ==, 0);
+    g_assert_false(events[0]->source == events[1]->source);
+    g_assert_true(ATSPI_IS_ACCESSIBLE(events[0]->source));
+    g_assert_cmpint(atspi_accessible_get_role(events[0]->source, nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB);
+    g_assert_cmpstr(events[2]->type, ==, "document:load-complete");
+    g_assert_true(events[1]->source == events[2]->source);
+    g_assert_true(ATSPI_IS_ACCESSIBLE(events[1]->source));
+    g_assert_cmpint(atspi_accessible_get_role(events[1]->source, nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB);
+    events = { };
+
+    test->startEventMonitor(std::nullopt, { "document:", "object:state-changed:busy" });
+    webkit_web_view_reload(test->m_webView);
+    test->waitUntilLoadFinished();
+    events = test->stopEventMonitor(4);
+    g_assert_cmpuint(events.size(), ==, 4);
+    g_assert_cmpstr(events[0]->type, ==, "object:state-changed:busy");
+    g_assert_cmpuint(events[0]->detail1, ==, 1);
+    g_assert_cmpstr(events[1]->type, ==, "document:reload");
+    g_assert_true(events[0]->source == events[1]->source);
+    g_assert_true(ATSPI_IS_ACCESSIBLE(events[0]->source));
+    g_assert_cmpint(atspi_accessible_get_role(events[0]->source, nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB);
+    g_assert_cmpstr(events[2]->type, ==, "object:state-changed:busy");
+    g_assert_cmpuint(events[2]->detail1, ==, 0);
+    g_assert_false(events[1]->source == events[2]->source);
+    g_assert_cmpstr(events[3]->type, ==, "document:load-complete");
+    g_assert_true(events[2]->source == events[3]->source);
+    g_assert_true(ATSPI_IS_ACCESSIBLE(events[2]->source));
+    g_assert_cmpint(atspi_accessible_get_role(events[2]->source, nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB);
+    events = { };
+}
+
 static void testImageBasic(AccessibilityTest* test, gconstpointer)
 {
     test->showInWindow(800, 600);
@@ -2819,6 +2881,7 @@
     AccessibilityTest::add("WebKitAccessibility", "hypertext/basic", testHypertextBasic);
     AccessibilityTest::add("WebKitAccessibility", "action/basic", testActionBasic);
     AccessibilityTest::add("WebKitAccessibility", "document/basic", testDocumentBasic);
+    AccessibilityTest::add("WebKitAccessibility", "document/load-events", testDocumentLoadEvents);
     AccessibilityTest::add("WebKitAccessibility", "image/basic", testImageBasic);
     AccessibilityTest::add("WebKitAccessibility", "selection/listbox", testSelectionListBox);
     AccessibilityTest::add("WebKitAccessibility", "selection/menulist", testSelectionMenuList);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to