[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

jhoneycutt at apple.com jhoneycutt at apple.com
Thu Feb 4 21:32:43 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit e3ab4b49c06e3223fd24a82e1d7db74ea7ce4d12
Author: jhoneycutt at apple.com <jhoneycutt at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 29 21:55:58 2010 +0000

    MSAA: Crash when posting a notification for a detached object
    
    https://bugs.webkit.org/show_bug.cgi?id=34309
    <rdar://problem/7409759>
    
    Reviewed by Darin Adler.
    
    WebCore:
    
    Test: platform/win/accessibility/detached-object-notification-crash.html
    
    * accessibility/AccessibilityRenderObject.cpp:
    (AccessibilityRenderObject::document):
    Null check m_renderer. This is the bug fix; the other changes in the
    patch are for the test.
    
    * accessibility/win/AXObjectCacheWin.cpp:
    (WebCore::AXObjectCache::postPlatformNotification):
    Map AXValueChanged to EVENT_OBJECT_VALUECHANGED, so we'll post a
    notification when AXValueChanged is posted. Receiving an event of this
    type tells us that the test passed.
    
    WebKit/win:
    
    * AccessibleBase.cpp:
    (AccessibleBase::QueryService):
    If an unrecognized service ID is passed, return early. Otherwise, return
    the result of QueryInterface.
    (AccessibleBase::QueryInterface):
    Add static_casts. Check for new UUIDs.
    (AccessibleBase::isSameObject):
    Query the object for AccessibleBase. Return whether the pointers or the
    wrapped objects match.
    
    * AccessibleBase.h:
    Give the class a UUID so we can query for it in isSameObject(). Inherit
    from IAccessibleComparable; inherit from IServiceProvider so clients can
    use QueryService to query for a custom interface.
    
    * Interfaces/AccessibleComparable.idl: Added. Declares a function that
    can be called to compare to accessible objects.
    
    * Interfaces/WebKit.idl:
    Include the new IDL.
    
    * WebKit.vcproj/Interfaces.vcproj:
    Add the new IDL to the project.
    
    WebKitTools:
    
    * DumpRenderTree/AccessibilityController.h:
    Declare new functions. Add new members to store the event hook and the
    mapping of accessibility elements to their JS callbacks.
    
    * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp:
    (AccessibilityController::notificationReceived):
    Stubbed.
    (AccessibilityController::addNotificationListener):
    Stubbed.
    
    * DumpRenderTree/mac/AccessibilityControllerMac.mm:
    (AccessibilityController::notificationReceived):
    Stubbed.
    (AccessibilityController::addNotificationListener):
    Stubbed.
    
    * DumpRenderTree/win/AccessibilityControllerWin.cpp:
    (AccessibilityController::AccessibilityController):
    Initialize the event hook.
    (AccessibilityController::~AccessibilityController):
    Remove the event hook. Unprotect all of the JS functions that are stored
    in the map.
    (logEventProc):
    Clean-up a variable.
    (stringEvent):
    Return a string description of the MSAA event code.
    (notificationListenerProc):
    Get the accessible object from the event, and query it for IAccessible.
    Call the AccessibilityController's notificationReceived().
    (comparableObject):
    Use QueryService to obtain the IAccessibleComparable for the
    IServiceProvider.
    (AccessibilityController::notificationReceived):
    Iterate the map of objects that have registered for notification
    callbacks. Query each for IServiceProvider, then use comparableObject()
    to get an IAccessibleComparable. If we find an object matching the
    notified object, call its callback, passing the event that was received.
    (AccessibilityController::addNotificationListener):
    If we have not created the event hook, create it. Protect the JS
    callback function object, and add the object and its callback to our
    map.
    
    * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
    (AccessibilityUIElement::addNotificationListener):
    Call through to the AccessibilityController's addNotificationListener().
    
    * DumpRenderTree/win/DumpRenderTreeWin.h:
    Add an extern declaration for the shared FrameLoadDelegate extern, so we
    can access it from AccessibilityController.
    
    * DumpRenderTree/win/FrameLoadDelegate.h:
    (FrameLoadDelegate::accessibilityController):
    Return the AccessibilityController.
    
    LayoutTests:
    
    * platform/win/accessibility/detached-object-notification-crash-expected.txt: Added.
    * platform/win/accessibility/detached-object-notification-crash.html: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54078 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ba72390..9ae4669 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-01-28  Jon Honeycutt  <jhoneycutt at apple.com>
+
+        MSAA: Crash when posting a notification for a detached object
+
+        https://bugs.webkit.org/show_bug.cgi?id=34309
+        <rdar://problem/7409759>
+
+        Reviewed by Darin Adler.
+
+        * platform/win/accessibility/detached-object-notification-crash-expected.txt: Added.
+        * platform/win/accessibility/detached-object-notification-crash.html: Added.
+
 2010-01-29  Darin Fisher  <darin at chromium.org>
 
         Okayed by Oliver Hunt.
diff --git a/LayoutTests/platform/win/accessibility/detached-object-notification-crash-expected.txt b/LayoutTests/platform/win/accessibility/detached-object-notification-crash-expected.txt
new file mode 100644
index 0000000..de08737
--- /dev/null
+++ b/LayoutTests/platform/win/accessibility/detached-object-notification-crash-expected.txt
@@ -0,0 +1,6 @@
+ 
+This tests that posting a notification for a deleted element does not cause a crash.
+
+
+PASS: Didn't crash.
+
diff --git a/LayoutTests/platform/win/accessibility/detached-object-notification-crash.html b/LayoutTests/platform/win/accessibility/detached-object-notification-crash.html
new file mode 100644
index 0000000..2ed3c4c
--- /dev/null
+++ b/LayoutTests/platform/win/accessibility/detached-object-notification-crash.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+    <link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+    <script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+
+<body id="body">
+
+<input id="avnElement">
+<input id="avnElement2">
+
+<p>This tests that posting a notification for a deleted element does
+not cause a crash.</p>
+
+<p id="notDRT">This test should only be run inside of DumpRenderTree.</p>
+
+<p id="console"></p>
+
+<script>
+    function notificationReceived(event)
+    {
+        if (event != "value change event")
+            return;
+
+        debug("PASS: Didn't crash.");
+        layoutTestController.notifyDone();
+    }
+    if (window.layoutTestController && window.accessibilityController) {
+        document.getElementById("notDRT").style.visibility = "hidden";
+
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+
+        var element = document.getElementById("avnElement");
+        element.focus();
+
+        element.setAttribute("aria-valuenow", 2);
+        document.getElementById("body").removeChild(element);
+
+        var element2 = document.getElementById("avnElement2");
+        element2.focus();
+
+        accessibilityController.focusedElement.addNotificationListener(notificationReceived);
+
+        element2.setAttribute("aria-valuenow", 2);
+    }
+</script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index f851d88..a4388b3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,25 @@
+2010-01-28  Jon Honeycutt  <jhoneycutt at apple.com>
+
+        MSAA: Crash when posting a notification for a detached object
+
+        https://bugs.webkit.org/show_bug.cgi?id=34309
+        <rdar://problem/7409759>
+
+        Reviewed by Darin Adler.
+
+        Test: platform/win/accessibility/detached-object-notification-crash.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (AccessibilityRenderObject::document):
+        Null check m_renderer. This is the bug fix; the other changes in the
+        patch are for the test.
+
+        * accessibility/win/AXObjectCacheWin.cpp:
+        (WebCore::AXObjectCache::postPlatformNotification):
+        Map AXValueChanged to EVENT_OBJECT_VALUECHANGED, so we'll post a
+        notification when AXValueChanged is posted. Receiving an event of this
+        type tells us that the test passed.
+
 2010-01-29  Darin Fisher  <darin at chromium.org>
 
         Okayed by Oliver Hunt.
diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp
index 8cd51ae..d738ca8 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -2026,6 +2026,8 @@ RenderView* AccessibilityRenderObject::topRenderer() const
 
 Document* AccessibilityRenderObject::document() const
 {
+    if (!m_renderer)
+        return 0;
     return m_renderer->document();
 }
 
diff --git a/WebCore/accessibility/win/AXObjectCacheWin.cpp b/WebCore/accessibility/win/AXObjectCacheWin.cpp
index 8b7d99e..21e61d9 100644
--- a/WebCore/accessibility/win/AXObjectCacheWin.cpp
+++ b/WebCore/accessibility/win/AXObjectCacheWin.cpp
@@ -83,6 +83,7 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
             msaaEvent = EVENT_SYSTEM_SCROLLINGSTART;
             break;
 
+        case AXValueChanged:
         case AXMenuListValueChanged:
             msaaEvent = EVENT_OBJECT_VALUECHANGE;
             break;
diff --git a/WebKit/win/AccessibleBase.cpp b/WebKit/win/AccessibleBase.cpp
index 978a339..0704771 100644
--- a/WebKit/win/AccessibleBase.cpp
+++ b/WebKit/win/AccessibleBase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -77,15 +77,30 @@ AccessibleBase* AccessibleBase::createInstance(AccessibilityObject* obj)
     return new AccessibleBase(obj);
 }
 
+HRESULT AccessibleBase::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
+{
+    if (!IsEqualGUID(guidService, SID_AccessibleComparable)) {
+        *ppvObject = 0;
+        return E_INVALIDARG;
+    }
+    return QueryInterface(riid, ppvObject);
+}
+
 // IUnknown
 HRESULT STDMETHODCALLTYPE AccessibleBase::QueryInterface(REFIID riid, void** ppvObject)
 {
     if (IsEqualGUID(riid, __uuidof(IAccessible)))
-        *ppvObject = this;
+        *ppvObject = static_cast<IAccessible*>(this);
     else if (IsEqualGUID(riid, __uuidof(IDispatch)))
-        *ppvObject = this;
+        *ppvObject = static_cast<IAccessible*>(this);
     else if (IsEqualGUID(riid, __uuidof(IUnknown)))
-        *ppvObject = this;
+        *ppvObject = static_cast<IAccessible*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IAccessibleComparable)))
+        *ppvObject = static_cast<IAccessibleComparable*>(this);
+    else if (IsEqualGUID(riid, __uuidof(IServiceProvider)))
+        *ppvObject = static_cast<IServiceProvider*>(this);
+    else if (IsEqualGUID(riid, __uuidof(AccessibleBase)))
+        *ppvObject = static_cast<AccessibleBase*>(this);
     else {
         *ppvObject = 0;
         return E_NOINTERFACE;
@@ -699,3 +714,10 @@ AccessibleBase* AccessibleBase::wrapper(AccessibilityObject* obj)
         result = createInstance(obj);
     return result;
 }
+
+HRESULT AccessibleBase::isSameObject(IAccessibleComparable* other, BOOL* result)
+{
+    COMPtr<AccessibleBase> otherAccessibleBase(Query, other);
+    *result = (otherAccessibleBase == this || otherAccessibleBase->m_object == m_object);
+    return S_OK;
+}
diff --git a/WebKit/win/AccessibleBase.h b/WebKit/win/AccessibleBase.h
index 3b6bce8..ca1703f 100644
--- a/WebKit/win/AccessibleBase.h
+++ b/WebKit/win/AccessibleBase.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,14 +26,18 @@
 #ifndef AccessibleBase_h
 #define AccessibleBase_h
 
-#include <oleacc.h>
 #include <WebCore/AccessibilityObject.h>
 #include <WebCore/AccessibilityObjectWrapperWin.h>
+#include <WebKit/WebKit.h>
+#include <oleacc.h>
 
-class AccessibleBase : public IAccessible, public WebCore::AccessibilityObjectWrapper {
+class DECLSPEC_UUID("3dbd565b-db22-4d88-8e0e-778bde54524a") AccessibleBase : public IAccessibleComparable, public IServiceProvider, public WebCore::AccessibilityObjectWrapper {
 public:
     static AccessibleBase* createInstance(WebCore::AccessibilityObject*);
 
+    // IServiceProvider
+    virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppv);
+
     // IUnknown
     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
     virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++m_refCount; }
@@ -89,6 +93,9 @@ public:
         m_object = 0;
     }
 
+    // IAccessibleComparable
+    virtual HRESULT STDMETHODCALLTYPE isSameObject(IAccessibleComparable* other, BOOL* result);
+
 protected:
     AccessibleBase(WebCore::AccessibilityObject*);
     virtual ~AccessibleBase();
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index e1895be..f3a2d05 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,36 @@
+2010-01-28  Jon Honeycutt  <jhoneycutt at apple.com>
+
+        MSAA: Crash when posting a notification for a detached object
+
+        https://bugs.webkit.org/show_bug.cgi?id=34309
+        <rdar://problem/7409759>
+
+        Reviewed by Darin Adler.
+
+        * AccessibleBase.cpp:
+        (AccessibleBase::QueryService):
+        If an unrecognized service ID is passed, return early. Otherwise, return
+        the result of QueryInterface.
+        (AccessibleBase::QueryInterface):
+        Add static_casts. Check for new UUIDs.
+        (AccessibleBase::isSameObject):
+        Query the object for AccessibleBase. Return whether the pointers or the
+        wrapped objects match.
+
+        * AccessibleBase.h:
+        Give the class a UUID so we can query for it in isSameObject(). Inherit
+        from IAccessibleComparable; inherit from IServiceProvider so clients can
+        use QueryService to query for a custom interface.
+
+        * Interfaces/AccessibleComparable.idl: Added. Declares a function that
+        can be called to compare to accessible objects.
+
+        * Interfaces/WebKit.idl:
+        Include the new IDL.
+
+        * WebKit.vcproj/Interfaces.vcproj:
+        Add the new IDL to the project.
+
 2010-01-27  Aaron Boodman  <aa at chromium.org>
 
         Expand NotificationCenter::checkPermission() interface.
diff --git a/WebKit/win/Interfaces/AccessibleComparable.idl b/WebKit/win/Interfaces/AccessibleComparable.idl
new file mode 100644
index 0000000..710e0d1
--- /dev/null
+++ b/WebKit/win/Interfaces/AccessibleComparable.idl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 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. ``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
+ * 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. 
+ */
+
+#ifndef DO_NO_IMPORTS
+import "oaidl.idl";
+import "ocidl.idl";
+#endif
+
+import "oleacc.idl";
+
+cpp_quote("extern const GUID  __declspec(selectany) SID_AccessibleComparable = { 0x62b8cb5f, 0xfb7a, 0x4faf, 0x81, 0xe8, 0x52, 0xb6, 0x5f, 0x12, 0x8b, 0x31 };")
+
+[
+    object,
+    uuid(4f0381ad-dab3-42ad-9ca2-a85b0ae041c0),
+    hidden,
+    dual,
+    pointer_default(unique)
+]
+interface IAccessibleComparable : IAccessible
+{
+    HRESULT isSameObject([in] IAccessibleComparable* other, [out, retval] BOOL* result);
+}
diff --git a/WebKit/win/Interfaces/WebKit.idl b/WebKit/win/Interfaces/WebKit.idl
index 5ae1ad9..3cd748c 100644
--- a/WebKit/win/Interfaces/WebKit.idl
+++ b/WebKit/win/Interfaces/WebKit.idl
@@ -55,6 +55,7 @@ cpp_quote(" */")
 import "oaidl.idl";
 import "ocidl.idl";
 
+#include "AccessibleComparable.idl"
 #include "WebScrollbarTypes.idl"
 #include "JavaScriptCoreAPITypes.idl"
 #include "IWebScriptObject.idl"
diff --git a/WebKit/win/WebKit.vcproj/Interfaces.vcproj b/WebKit/win/WebKit.vcproj/Interfaces.vcproj
index 5d87acd..c6a0add 100644
--- a/WebKit/win/WebKit.vcproj/Interfaces.vcproj
+++ b/WebKit/win/WebKit.vcproj/Interfaces.vcproj
@@ -152,6 +152,26 @@
 	</References>
 	<Files>
 		<File
+			RelativePath="..\Interfaces\AccessibleComparable.idl"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				ExcludedFromBuild="true"
+				>
+				<Tool
+					Name="VCMIDLTool"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				ExcludedFromBuild="true"
+				>
+				<Tool
+					Name="VCMIDLTool"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
 			RelativePath="..\Interfaces\DOMCore.idl"
 			>
 			<FileConfiguration
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index d5dcb06..945462c 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,66 @@
+2010-01-28  Jon Honeycutt  <jhoneycutt at apple.com>
+
+        MSAA: Crash when posting a notification for a detached object
+
+        https://bugs.webkit.org/show_bug.cgi?id=34309
+        <rdar://problem/7409759>
+
+        Reviewed by Darin Adler.
+
+        * DumpRenderTree/AccessibilityController.h:
+        Declare new functions. Add new members to store the event hook and the
+        mapping of accessibility elements to their JS callbacks.
+
+        * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp:
+        (AccessibilityController::notificationReceived):
+        Stubbed.
+        (AccessibilityController::addNotificationListener):
+        Stubbed.
+
+        * DumpRenderTree/mac/AccessibilityControllerMac.mm:
+        (AccessibilityController::notificationReceived):
+        Stubbed.
+        (AccessibilityController::addNotificationListener):
+        Stubbed.
+
+        * DumpRenderTree/win/AccessibilityControllerWin.cpp:
+        (AccessibilityController::AccessibilityController):
+        Initialize the event hook.
+        (AccessibilityController::~AccessibilityController):
+        Remove the event hook. Unprotect all of the JS functions that are stored
+        in the map.
+        (logEventProc):
+        Clean-up a variable.
+        (stringEvent):
+        Return a string description of the MSAA event code.
+        (notificationListenerProc):
+        Get the accessible object from the event, and query it for IAccessible.
+        Call the AccessibilityController's notificationReceived().
+        (comparableObject):
+        Use QueryService to obtain the IAccessibleComparable for the
+        IServiceProvider.
+        (AccessibilityController::notificationReceived):
+        Iterate the map of objects that have registered for notification
+        callbacks. Query each for IServiceProvider, then use comparableObject()
+        to get an IAccessibleComparable. If we find an object matching the
+        notified object, call its callback, passing the event that was received.
+        (AccessibilityController::addNotificationListener):
+        If we have not created the event hook, create it. Protect the JS
+        callback function object, and add the object and its callback to our
+        map.
+
+        * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
+        (AccessibilityUIElement::addNotificationListener):
+        Call through to the AccessibilityController's addNotificationListener().
+
+        * DumpRenderTree/win/DumpRenderTreeWin.h:
+        Add an extern declaration for the shared FrameLoadDelegate extern, so we
+        can access it from AccessibilityController.
+
+        * DumpRenderTree/win/FrameLoadDelegate.h:
+        (FrameLoadDelegate::accessibilityController):
+        Return the AccessibilityController.
+
 2010-01-29  Shinichiro Hamaji  <hamaji at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebKitTools/DumpRenderTree/AccessibilityController.h b/WebKitTools/DumpRenderTree/AccessibilityController.h
index 5a75c2c..de58f84 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityController.h
+++ b/WebKitTools/DumpRenderTree/AccessibilityController.h
@@ -26,14 +26,15 @@
 #ifndef AccessibilityController_h
 #define AccessibilityController_h
 
+#include "AccessibilityUIElement.h"
 #include <JavaScriptCore/JSObjectRef.h>
+#include <string>
+#include <wtf/HashMap.h>
 #include <wtf/Platform.h>
 #if PLATFORM(WIN)
 #include <windows.h>
 #endif
 
-class AccessibilityUIElement;
-
 class AccessibilityController {
 public:
     AccessibilityController();
@@ -51,6 +52,9 @@ public:
 
     void resetToConsistentState();
 
+    void addNotificationListener(PlatformUIElement, JSObjectRef functionCallback);
+    void notificationReceived(PlatformUIElement, const std::string& eventName);
+
 private:
     static JSClassRef getJSClass();
 
@@ -58,6 +62,9 @@ private:
     HWINEVENTHOOK m_focusEventHook;
     HWINEVENTHOOK m_valueChangeEventHook;
     HWINEVENTHOOK m_scrollingStartEventHook;
+
+    HWINEVENTHOOK m_allEventsHook;
+    HashMap<PlatformUIElement, JSObjectRef> m_notificationListeners;
 #endif
 };
 
diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
index d95f854..12653fc 100644
--- a/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
@@ -77,3 +77,11 @@ void AccessibilityController::setLogScrollingStartEvents(bool)
 void AccessibilityController::setLogValueChangeEvents(bool)
 {
 }
+
+void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef)
+{
+}
+
+void AccessibilityController::notificationReceived(PlatformUIElement, const std::string&)
+{
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
index 4895a1a..4d2da6e 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
@@ -65,3 +65,11 @@ void AccessibilityController::setLogScrollingStartEvents(bool)
 void AccessibilityController::setLogValueChangeEvents(bool)
 {
 }
+
+void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef)
+{
+}
+
+void AccessibilityController::notificationReceived(PlatformUIElement, const std::string&)
+{
+}
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp
index 1abb71e..6b35948 100644
--- a/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityControllerWin.cpp
@@ -28,7 +28,10 @@
 
 #include "AccessibilityUIElement.h"
 #include "DumpRenderTree.h"
+#include "FrameLoadDelegate.h"
 #include <JavaScriptCore/Assertions.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JavaScriptCore/JSStringRef.h>
 #include <WebCore/COMPtr.h>
 #include <WebKit/WebKit.h>
 #include <oleacc.h>
@@ -40,6 +43,7 @@ AccessibilityController::AccessibilityController()
     : m_focusEventHook(0)
     , m_scrollingStartEventHook(0)
     , m_valueChangeEventHook(0)
+    , m_allEventsHook(0)
 {
 }
 
@@ -47,6 +51,12 @@ AccessibilityController::~AccessibilityController()
 {
     setLogFocusEvents(false);
     setLogValueChangeEvents(false);
+
+    if (m_allEventsHook)
+        UnhookWinEvent(m_allEventsHook);
+
+    for (HashMap<PlatformUIElement, JSObjectRef>::iterator it = m_notificationListeners.begin(); it != m_notificationListeners.end(); ++it)
+        JSValueUnprotect(frame->globalContext(), it->second);
 }
 
 AccessibilityUIElement AccessibilityController::focusedElement()
@@ -91,7 +101,7 @@ AccessibilityUIElement AccessibilityController::rootElement()
     return rootAccessible;
 }
 
-static void CALLBACK logEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD, DWORD)
+static void CALLBACK logEventProc(HWINEVENTHOOK, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD, DWORD)
 {
     // Get the accessible object for this event.
     COMPtr<IAccessible> parentObject;
@@ -133,6 +143,8 @@ static void CALLBACK logEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND
             printf("Received unknown event for object '%S'.\n", name.c_str());
             break;
     }
+
+    VariantClear(&vChild);
 }
 
 void AccessibilityController::setLogFocusEvents(bool logFocusEvents)
@@ -194,3 +206,83 @@ void AccessibilityController::setLogScrollingStartEvents(bool logScrollingStartE
 
     ASSERT(m_scrollingStartEventHook);
 }
+
+static string stringEvent(DWORD event)
+{
+    switch(event) {
+        case EVENT_OBJECT_VALUECHANGE:
+            return "value change event";
+        default:
+            return "unknown event";
+    }
+}
+
+static void CALLBACK notificationListenerProc(HWINEVENTHOOK, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD, DWORD)
+{
+    // Get the accessible object for this event.
+    COMPtr<IAccessible> parentObject;
+
+    VARIANT vChild;
+    VariantInit(&vChild);
+
+    HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &parentObject, &vChild);
+    ASSERT(SUCCEEDED(hr));
+
+    COMPtr<IDispatch> childDispatch;
+    if (FAILED(parentObject->get_accChild(vChild, &childDispatch))) {
+        VariantClear(&vChild);
+        return;
+    }
+
+    COMPtr<IAccessible> childAccessible(Query, childDispatch);
+
+    sharedFrameLoadDelegate->accessibilityController()->notificationReceived(childAccessible, stringEvent(event));
+
+    VariantClear(&vChild);
+}
+
+static COMPtr<IAccessibleComparable> comparableObject(const COMPtr<IServiceProvider>& serviceProvider)
+{
+    COMPtr<IAccessibleComparable> comparable;
+    serviceProvider->QueryService(SID_AccessibleComparable, __uuidof(IAccessibleComparable), reinterpret_cast<void**>(&comparable));
+    return comparable;
+}
+
+void AccessibilityController::notificationReceived(PlatformUIElement element, const string& eventName)
+{
+    for (HashMap<PlatformUIElement, JSObjectRef>::iterator it = m_notificationListeners.begin(); it != m_notificationListeners.end(); ++it) {
+        COMPtr<IServiceProvider> thisServiceProvider(Query, it->first);
+        if (!thisServiceProvider)
+            continue;
+
+        COMPtr<IAccessibleComparable> thisComparable = comparableObject(thisServiceProvider);
+        if (!thisComparable)
+            continue;
+
+        COMPtr<IServiceProvider> elementServiceProvider(Query, element);
+        if (!elementServiceProvider)
+            continue;
+
+        COMPtr<IAccessibleComparable> elementComparable = comparableObject(elementServiceProvider);
+        if (!elementComparable)
+            continue;
+
+        BOOL isSame = FALSE;
+        thisComparable->isSameObject(elementComparable.get(), &isSame);
+        if (!isSame)
+            continue;
+
+        JSRetainPtr<JSStringRef> jsNotification(Adopt, JSStringCreateWithUTF8CString(eventName.c_str()));
+        JSValueRef argument = JSValueMakeString(frame->globalContext(), jsNotification.get());
+        JSObjectCallAsFunction(frame->globalContext(), it->second, NULL, 1, &argument, NULL);
+    }
+}
+
+void AccessibilityController::addNotificationListener(PlatformUIElement element, JSObjectRef functionCallback)
+{
+    if (!m_allEventsHook)
+        m_allEventsHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
+
+    JSValueProtect(frame->globalContext(), functionCallback);
+    m_notificationListeners.add(element, functionCallback);
+}
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
index 9aff5e6..301112f 100644
--- a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
@@ -26,6 +26,9 @@
 #include "config.h"
 #include "AccessibilityUIElement.h"
 
+#include "AccessibilityController.h"
+#include "DumpRenderTree.h"
+#include "FrameLoadDelegate.h"
 #include <JavaScriptCore/JSStringRef.h>
 #include <tchar.h>
 #include <string>
@@ -530,8 +533,11 @@ JSStringRef AccessibilityUIElement::url()
 
 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
 {
-    // FIXME: implement
-    return false;
+    if (!functionCallback)
+        return false;
+
+    sharedFrameLoadDelegate->accessibilityController()->addNotificationListener(m_element, functionCallback);
+    return true;
 }
 
 bool AccessibilityUIElement::isSelectable() const
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
index 54ec87b..499c57b 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h
@@ -32,6 +32,7 @@
 struct IWebFrame;
 struct IWebScriptWorld;
 struct IWebView;
+struct FrameLoadDelegate;
 struct PolicyDelegate;
 typedef const struct __CFString* CFStringRef;
 typedef struct HWND__* HWND;
@@ -60,4 +61,6 @@ unsigned worldIDForWorld(IWebScriptWorld*);
 
 extern UINT_PTR waitToDumpWatchdog;
 
+extern COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
+
 #endif // DumpRenderTreeWin_h
diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
index cc6653b..329c17f 100644
--- a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
+++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.h
@@ -44,6 +44,8 @@ public:
 
     void resetToConsistentState();
 
+    AccessibilityController* accessibilityController() const { return m_accessibilityController.get(); }
+
     // IUnknown
     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
     virtual ULONG STDMETHODCALLTYPE AddRef(void);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list