Changeset 154697 in webkit


Ignore:
Timestamp:
Aug 27, 2013 10:16:03 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[GTK] Missing DRT AccessibilityUIElement::addNotificationListener implementation
https://bugs.webkit.org/show_bug.cgi?id=119883

Tools:

Implemented the notification listener for AccessibilityUIElement. The signal is generated
by AXObjectCache::postPlatformNotification() and received by axObjectEventListener().
axObjectEventListener will then invoke JSObjectCallAsFunction() with the respective
callback function. The global callback function and callbacks for specific elements are
stored in a HashMap in AccessibilityCallbacksAtk.cpp.

Patch by Denis Nomiyama <d.nomiyama@samsung.com> on 2013-08-27
Reviewed by Chris Fleizach.

  • DumpRenderTree/AccessibilityUIElement.h: Added a notification handler for GTK+
  • DumpRenderTree/atk/AccessibilityCallbacks.h: Added addAccessibilityNotificationListener()

and removeAccessibilityNotificationListener()

  • DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp:

(axObjectEventListener): Call JS callback for global notification or for a specific element
(disconnectAccessibilityCallbacks): Only disconnect if logging is off and there is no
notification handler
(addAccessibilityNotificationHandler): Add notification listener to the list
(removeAccessibilityNotificationHandler): Remove notification listener from the list

  • DumpRenderTree/atk/AccessibilityControllerAtk.cpp:

(AccessibilityController::setLogAccessibilityEvents): Set logging off before disconnecting

  • DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp: Added.

(AccessibilityNotificationHandler::AccessibilityNotificationHandler): Create handler
(AccessibilityNotificationHandler::~AccessibilityNotificationHandler): Destroy handler.
Remove handler from the list and disconnect callbacks
(AccessibilityNotificationHandler::setNotificationFunctionCallback): Set the notification
callback and connect callbacks to signals

  • DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h: Added.

(AccessibilityNotificationHandler::setPlatformElement): Set platform element
(AccessibilityNotificationHandler::platformElement): Get platform element
(AccessibilityNotificationHandler::notificationFunctionCallback): Get notification callback

  • DumpRenderTree/atk/AccessibilityUIElementAtk.cpp:

(AccessibilityUIElement::addNotificationListener): Create notification handler, set the
platform element and the notification callback
(AccessibilityUIElement::removeNotificationListener):

  • DumpRenderTree/efl/CMakeLists.txt: Added AccessibilityNotificationHandlerAtk.cpp/h
  • GNUmakefile.am: Added AccessibilityNotificationHandlerAtk.cpp/h

LayoutTests:

Unskipped the checkbox notification test in a11y and added the expected results.

Patch by Denis Nomiyama <d.nomiyama@samsung.com> on 2013-08-27
Reviewed by Chris Fleizach.

  • platform/gtk/TestExpectations: Unskipped the checkbox notification test in a11y.
  • platform/gtk/accessibility/aria-checkbox-sends-notification-expected.txt: Added.
Location:
trunk
Files:
3 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r154687 r154697  
     12013-08-27  Denis Nomiyama  <d.nomiyama@samsung.com>
     2
     3        [GTK] Missing DRT AccessibilityUIElement::addNotificationListener implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=119883
     5
     6        Unskipped the checkbox notification test in a11y and added the expected results.
     7
     8        Reviewed by Chris Fleizach.
     9
     10        * platform/gtk/TestExpectations: Unskipped the checkbox notification test in a11y.
     11        * platform/gtk/accessibility/aria-checkbox-sends-notification-expected.txt: Added.
     12
    1132013-08-27  Ádám Kallai  <kadam@inf.u-szeged.hu>
    214
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r154477 r154697  
    783783webkit.org/b/98350 accessibility/aria-invalid.html [ Timeout ]
    784784
    785 # Missing DRT AccessibilityController::addNotificationListener implementation
    786 webkit.org/b/70606 accessibility/aria-checkbox-sends-notification.html [ Timeout ]
    787 
    788785Bug(GTK) media/progress-events-generated-correctly.html [ Failure Timeout ]
    789786
  • trunk/Tools/ChangeLog

    r154668 r154697  
     12013-08-27  Denis Nomiyama  <d.nomiyama@samsung.com>
     2
     3        [GTK] Missing DRT AccessibilityUIElement::addNotificationListener implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=119883
     5
     6        Implemented the notification listener for AccessibilityUIElement. The signal is generated
     7        by AXObjectCache::postPlatformNotification() and received by axObjectEventListener().
     8        axObjectEventListener will then invoke JSObjectCallAsFunction() with the respective
     9        callback function. The global callback function and callbacks for specific elements are
     10        stored in a HashMap in AccessibilityCallbacksAtk.cpp.
     11
     12        Reviewed by Chris Fleizach.
     13
     14        * DumpRenderTree/AccessibilityUIElement.h: Added a notification handler for GTK+
     15        * DumpRenderTree/atk/AccessibilityCallbacks.h: Added addAccessibilityNotificationListener()
     16        and removeAccessibilityNotificationListener()
     17        * DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp:
     18        (axObjectEventListener): Call JS callback for global notification or for a specific element
     19        (disconnectAccessibilityCallbacks): Only disconnect if logging is off and there is no
     20        notification handler
     21        (addAccessibilityNotificationHandler): Add notification listener to the list
     22        (removeAccessibilityNotificationHandler): Remove notification listener from the list
     23        * DumpRenderTree/atk/AccessibilityControllerAtk.cpp:
     24        (AccessibilityController::setLogAccessibilityEvents): Set logging off before disconnecting
     25        * DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp: Added.
     26        (AccessibilityNotificationHandler::AccessibilityNotificationHandler): Create handler
     27        (AccessibilityNotificationHandler::~AccessibilityNotificationHandler): Destroy handler.
     28        Remove handler from the list and disconnect callbacks
     29        (AccessibilityNotificationHandler::setNotificationFunctionCallback): Set the notification
     30        callback and connect callbacks to signals
     31        * DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h: Added.
     32        (AccessibilityNotificationHandler::setPlatformElement): Set platform element
     33        (AccessibilityNotificationHandler::platformElement): Get platform element
     34        (AccessibilityNotificationHandler::notificationFunctionCallback): Get notification callback
     35        * DumpRenderTree/atk/AccessibilityUIElementAtk.cpp:
     36        (AccessibilityUIElement::addNotificationListener): Create notification handler, set the
     37        platform element and the notification callback
     38        (AccessibilityUIElement::removeNotificationListener):
     39        * DumpRenderTree/efl/CMakeLists.txt: Added AccessibilityNotificationHandlerAtk.cpp/h
     40        * GNUmakefile.am: Added AccessibilityNotificationHandlerAtk.cpp/h
     41
    1422013-08-27  Carlos Garcia Campos  <cgarcia@igalia.com>
    243
  • trunk/Tools/DumpRenderTree/AccessibilityUIElement.h

    r151179 r154697  
    4747typedef COMPtr<IAccessible> PlatformUIElement;
    4848#elif HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
     49#include "AccessibilityNotificationHandlerAtk.h"
    4950#include <atk/atk.h>
    5051typedef AtkObject* PlatformUIElement;
     
    274275    NotificationHandler m_notificationHandler;
    275276#endif
     277
     278#if PLATFORM(GTK) || PLATFORM(EFL)
     279    RefPtr<AccessibilityNotificationHandler> m_notificationHandler;
     280#endif
    276281};
    277282
  • trunk/Tools/DumpRenderTree/atk/AccessibilityCallbacks.h

    r142451 r154697  
    3030#define AccessibilityCallbacks_h
    3131
     32#include "AccessibilityNotificationHandlerAtk.h"
     33#include "AccessibilityUIElement.h"
     34
     35const PlatformUIElement GlobalNotificationKey = 0;
     36
    3237void connectAccessibilityCallbacks();
    3338void disconnectAccessibilityCallbacks();
     39void addAccessibilityNotificationHandler(AccessibilityNotificationHandler*);
     40void removeAccessibilityNotificationHandler(AccessibilityNotificationHandler*);
    3441
    3542#endif
  • trunk/Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp

    r142451 r154697  
    3333
    3434#include "AccessibilityController.h"
     35#include "AccessibilityNotificationHandlerAtk.h"
    3536#include "DumpRenderTree.h"
     37#include "JSRetainPtr.h"
    3638#include <atk/atk.h>
    3739#include <wtf/gobject/GOwnPtr.h>
     
    5355static guint propertyChangedListenerId = 0;
    5456static guint visibleDataChangedListenerId = 0;
     57static HashMap<PlatformUIElement, AccessibilityNotificationHandler*> notificationHandlers;
     58
     59extern bool loggingAccessibilityEvents;
    5560
    5661static void printAccessibilityEvent(AtkObject* accessible, const gchar* signalName, const gchar* signalValue)
     
    8893    GOwnPtr<gchar> signalName;
    8994    GOwnPtr<gchar> signalValue;
     95    String notificationName;
    9096
    9197    g_signal_query(signalHint->signal_id, &signalQuery);
     
    94100        signalName.set(g_strdup_printf("state-change:%s", g_value_get_string(&paramValues[1])));
    95101        signalValue.set(g_strdup_printf("%d", g_value_get_boolean(&paramValues[2])));
     102        if (!g_strcmp0(g_value_get_string(&paramValues[1]), "checked"))
     103            notificationName = "CheckedStateChanged";
    96104    } else if (!g_strcmp0(signalQuery.signal_name, "focus-event")) {
    97105        signalName.set(g_strdup("focus-event"));
     
    105113        signalName.set(g_strdup(signalQuery.signal_name));
    106114
    107     printAccessibilityEvent(accessible, signalName.get(), signalValue.get());
     115    if (loggingAccessibilityEvents)
     116        printAccessibilityEvent(accessible, signalName.get(), signalValue.get());
     117
     118#if PLATFORM(GTK)
     119    JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
     120#else
     121    JSContextRef jsContext = 0;
     122#endif
     123    if (!jsContext)
     124        return TRUE;
     125
     126    if (notificationName.length()) {
     127        for (HashMap<PlatformUIElement, AccessibilityNotificationHandler*>::iterator it = notificationHandlers.begin(); it != notificationHandlers.end(); ++it) {
     128            if (it->key == accessible || it->key == GlobalNotificationKey) {
     129                JSRetainPtr<JSStringRef> jsNotificationEventName(Adopt, JSStringCreateWithUTF8CString(reinterpret_cast<const char*>(notificationName.utf8().data())));
     130                JSValueRef notificationNameArgument = JSValueMakeString(jsContext, jsNotificationEventName.get());
     131                AccessibilityNotificationHandler* notificationHandler = it->value;
     132                if (notificationHandler->platformElement()) {
     133                    JSValueRef argument = notificationNameArgument;
     134                    // Listener for one element just gets one argument, the notification name.
     135                    JSObjectCallAsFunction(jsContext, notificationHandler->notificationFunctionCallback(), 0, 1, &argument, 0);
     136                } else {
     137                    // A global listener gets the element and the notification name as arguments.
     138                    JSValueRef arguments[2];
     139                    arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement(jsContext, AccessibilityUIElement(accessible));
     140                    arguments[1] = notificationNameArgument;
     141                    JSObjectCallAsFunction(jsContext, notificationHandler->notificationFunctionCallback(), 0, 2, arguments, 0);
     142                }
     143            }
     144        }
     145    }
    108146
    109147    return TRUE;
     
    141179void disconnectAccessibilityCallbacks()
    142180{
     181    // Only disconnect if logging is off and there is no notification handler.
     182    if (loggingAccessibilityEvents || !notificationHandlers.isEmpty())
     183        return;
     184
    143185    // AtkObject signals.
    144186    if (stateChangeListenerId) {
     
    168210}
    169211
    170 #endif
     212void addAccessibilityNotificationHandler(AccessibilityNotificationHandler* notificationHandler)
     213{
     214    if (!notificationHandler)
     215        return;
     216
     217#if PLATFORM(GTK)
     218    JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
     219#else
     220    JSContextRef jsContext = 0;
     221#endif
     222    if (!jsContext)
     223        return;
     224
     225    JSValueProtect(jsContext, notificationHandler->notificationFunctionCallback());
     226    // Check if this notification handler is related to a specific element.
     227    if (notificationHandler->platformElement()) {
     228        if (notificationHandlers.contains(notificationHandler->platformElement())) {
     229            JSValueUnprotect(jsContext, notificationHandlers.find(notificationHandler->platformElement())->value->notificationFunctionCallback());
     230            notificationHandlers.remove(notificationHandler->platformElement());
     231        }
     232        notificationHandlers.add(notificationHandler->platformElement(), notificationHandler);
     233    } else {
     234        if (notificationHandlers.contains(GlobalNotificationKey)) {
     235            JSValueUnprotect(jsContext, notificationHandlers.find(GlobalNotificationKey)->value->notificationFunctionCallback());
     236            notificationHandlers.remove(GlobalNotificationKey);
     237        }
     238        notificationHandlers.add(GlobalNotificationKey, notificationHandler);
     239    }
     240
     241    connectAccessibilityCallbacks();
     242}
     243
     244void removeAccessibilityNotificationHandler(AccessibilityNotificationHandler* notificationHandler)
     245{
     246    if (!notificationHandler)
     247        return;
     248
     249#if PLATFORM(GTK)
     250    JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(mainFrame);
     251#else
     252    JSGlobalContextRef jsContext = 0;
     253#endif
     254    if (!jsContext)
     255        return;
     256
     257    for (HashMap<PlatformUIElement, AccessibilityNotificationHandler*>::iterator it = notificationHandlers.begin(); it != notificationHandlers.end(); ++it) {
     258        if (it->value == notificationHandler) {
     259            JSValueUnprotect(jsContext, notificationHandler->notificationFunctionCallback());
     260            notificationHandlers.remove(it);
     261        }
     262    }
     263}
     264
     265#endif
  • trunk/Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp

    r152397 r154697  
    3636#include <atk/atk.h>
    3737
    38 static bool loggingAccessibilityEvents = false;
     38bool loggingAccessibilityEvents = false;
    3939
    4040AccessibilityController::AccessibilityController()
     
    7171
    7272    if (!logAccessibilityEvents) {
     73        loggingAccessibilityEvents = false;
    7374        disconnectAccessibilityCallbacks();
    74         loggingAccessibilityEvents = false;
    7575        return;
    7676    }
  • trunk/Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp

    r153435 r154697  
    3030#if HAVE(ACCESSIBILITY)
    3131
     32#include "AccessibilityNotificationHandlerAtk.h"
    3233#include <JavaScriptCore/JSStringRef.h>
    3334#include <JavaScriptCore/OpaqueJSString.h>
     
    10281029bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
    10291030{
    1030     // FIXME: implement
    1031     return false;
     1031    if (!functionCallback)
     1032        return false;
     1033
     1034    // Only one notification listener per element.
     1035    if (m_notificationHandler)
     1036        return false;
     1037
     1038    m_notificationHandler = new AccessibilityNotificationHandler();
     1039    m_notificationHandler->setPlatformElement(platformUIElement());
     1040    m_notificationHandler->setNotificationFunctionCallback(functionCallback);
     1041
     1042    return true;
    10321043}
    10331044
    10341045void AccessibilityUIElement::removeNotificationListener()
    10351046{
    1036     // FIXME: implement
     1047    // Programmers should not be trying to remove a listener that's already removed.
     1048    ASSERT(m_notificationHandler);
     1049
     1050    m_notificationHandler = 0;
    10371051}
    10381052
  • trunk/Tools/DumpRenderTree/efl/CMakeLists.txt

    r151402 r154697  
    1111    ${TOOLS_DIR}/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp
    1212    ${TOOLS_DIR}/DumpRenderTree/atk/AccessibilityControllerAtk.cpp
     13    ${TOOLS_DIR}/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp
    1314    ${TOOLS_DIR}/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp
    1415    ${TOOLS_DIR}/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp
  • trunk/Tools/GNUmakefile.am

    r153421 r154697  
    156156        Tools/DumpRenderTree/atk/AccessibilityCallbacksAtk.cpp \
    157157        Tools/DumpRenderTree/atk/AccessibilityControllerAtk.cpp \
     158        Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.cpp \
     159        Tools/DumpRenderTree/atk/AccessibilityNotificationHandlerAtk.h \
    158160        Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp \
    159161        Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp \
Note: See TracChangeset for help on using the changeset viewer.