Source/WebCore: AccessibilityController should support listening to notifications...
authordmazzoni@google.com <dmazzoni@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Dec 2011 21:27:16 +0000 (21:27 +0000)
committerdmazzoni@google.com <dmazzoni@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Dec 2011 21:27:16 +0000 (21:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72866

Changes accessibilitySetShouldRepostNotifications from an instance method
into a class method so that it can be used for global notification listeners,
not just for listeners on a particular object.

Reviewed by Chris Fleizach.

Test: accessibility/notification-listeners.html

* accessibility/mac/WebAccessibilityObjectWrapper.h:
* accessibility/mac/WebAccessibilityObjectWrapper.mm:
(+[WebAccessibilityObjectWrapper accessibilitySetShouldRepostNotifications:]):
(-[WebAccessibilityObjectWrapper accessibilityPostedNotification:]):

Tools: Accessibility: AccessibilityController should support listening to notifications on all elements.
https://bugs.webkit.org/show_bug.cgi?id=72866

Adds addNotificationListener and removeNotificationListener methods
to AccessibilityController, to listen to notifications on any element
rather than a specific element. Mac (DRT and WKTR) and Chromium (DRT)
implementations are all contained in this change.

On Mac, refactors AccessibilityNotificationHandler into its own
source file that can be used by both AccessibilityController and
AccessibilityUIElement. (Both DRT and WKTR.)

Reviewed by Chris Fleizach.

* DumpRenderTree/AccessibilityController.cpp:
(addNotificationListenerCallback):
(removeNotificationListenerCallback):
(AccessibilityController::getJSClass):
* DumpRenderTree/AccessibilityController.h:
* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/chromium/AccessibilityController.cpp:
(AccessibilityController::AccessibilityController):
(AccessibilityController::notificationReceived):
(AccessibilityController::addNotificationListenerCallback):
(AccessibilityController::removeNotificationListenerCallback):
* DumpRenderTree/chromium/AccessibilityController.h:
* DumpRenderTree/gtk/AccessibilityControllerGtk.cpp:
(AccessibilityController::addNotificationListener):
(AccessibilityController::removeNotificationListener):
* DumpRenderTree/mac/AccessibilityControllerMac.mm:
(AccessibilityController::~AccessibilityController):
(AccessibilityController::addNotificationListener):
(AccessibilityController::removeNotificationListener):
* DumpRenderTree/mac/AccessibilityNotificationHandler.h: Added.
* DumpRenderTree/mac/AccessibilityNotificationHandler.mm: Added.
(-[NSString createJSStringRef]):
(-[AccessibilityNotificationHandler init]):
(-[AccessibilityNotificationHandler setPlatformElement:]):
(-[AccessibilityNotificationHandler dealloc]):
(-[AccessibilityNotificationHandler setCallback:]):
(-[AccessibilityNotificationHandler startObserving]):
(-[AccessibilityNotificationHandler _notificationReceived:]):
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(AccessibilityUIElement::addNotificationListener):
* DumpRenderTree/win/AccessibilityControllerWin.cpp:
(notificationListenerProc):
(AccessibilityController::addNotificationListener):
(AccessibilityController::removeNotificationListener):
(AccessibilityController::winNotificationReceived):
(AccessibilityController::winAddNotificationListener):
* DumpRenderTree/win/AccessibilityUIElementWin.cpp:
(AccessibilityUIElement::addNotificationListener):
* WebKitTestRunner/InjectedBundle/AccessibilityController.cpp:
(WTR::AccessibilityController::addNotificationListener):
(WTR::AccessibilityController::removeNotificationListener):
* WebKitTestRunner/InjectedBundle/AccessibilityController.h:
(WTR::AccessibilityController::logAccessibilityEvents):
* WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp:
(WTR::AccessibilityTextMarker::AccessibilityTextMarker):
* WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp:
(WTR::AccessibilityTextMarkerRange::AccessibilityTextMarkerRange):
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl:
* WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm: Added.
(WTR::AccessibilityController::addNotificationListener):
(WTR::AccessibilityController::removeNotificationListener):
* WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.h: Added.
* WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm: Added.
(-[NSString createJSStringRef]):
(-[AccessibilityNotificationHandler init]):
(-[AccessibilityNotificationHandler setPlatformElement:]):
(-[AccessibilityNotificationHandler dealloc]):
(-[AccessibilityNotificationHandler setCallback:]):
(-[AccessibilityNotificationHandler startObserving]):
(-[AccessibilityNotificationHandler _notificationReceived:]):
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElement::AccessibilityUIElement):
(WTR::AccessibilityUIElement::verticalScrollbar):
(WTR::AccessibilityUIElement::addNotificationListener):
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:

LayoutTests: Accessibility: AccessibilityController should support listening to notifications on all elements.
https://bugs.webkit.org/show_bug.cgi?id=72866

Previously, the Mac implementation of AccessibilityUIElement.addNotificationListener
incorrectly triggered on notifications from all elements. Now it only triggers on
notifications from the correct element, and a new addNotificationListener method
in AccessibilityController can be used to trigger on notifications from all elements.

Updates 2 tests that depended on the old incorrect behavior.

Reviewed by Chris Fleizach.

* accessibility/notification-listeners.html: Added.
* platform/chromium/accessibility/notification-listeners-expected.txt: Added.
* platform/gtk/Skipped:
* platform/mac/accessibility/aria-expanded-notifications.html:
* platform/mac/accessibility/aria-listbox-selectedchildren-change.html:
* platform/mac/accessibility/notification-listeners-expected.txt: Added.
* platform/win/Skipped:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@102378 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/notification-listeners.html [new file with mode: 0644]
LayoutTests/platform/chromium/accessibility/notification-listeners-expected.txt [new file with mode: 0644]
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac/accessibility/aria-expanded-notifications.html
LayoutTests/platform/mac/accessibility/aria-listbox-selectedchildren-change.html
LayoutTests/platform/mac/accessibility/notification-listeners-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/Skipped
Source/WebCore/ChangeLog
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.h
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm
Tools/ChangeLog
Tools/DumpRenderTree/AccessibilityController.cpp
Tools/DumpRenderTree/AccessibilityController.h
Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
Tools/DumpRenderTree/chromium/AccessibilityController.cpp
Tools/DumpRenderTree/chromium/AccessibilityController.h
Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp
Tools/DumpRenderTree/mac/AccessibilityControllerMac.mm
Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.h [new file with mode: 0644]
Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm [new file with mode: 0644]
Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
Tools/DumpRenderTree/win/AccessibilityControllerWin.cpp
Tools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.cpp
Tools/WebKitTestRunner/InjectedBundle/AccessibilityController.h
Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm [new file with mode: 0644]
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.h [new file with mode: 0644]
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm [new file with mode: 0644]
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj

index 3d55c65..3d7bc58 100644 (file)
@@ -1,3 +1,25 @@
+2011-12-08  Dominic Mazzoni  <dmazzoni@google.com>
+
+        Accessibility: AccessibilityController should support listening to notifications on all elements.
+        https://bugs.webkit.org/show_bug.cgi?id=72866
+
+        Previously, the Mac implementation of AccessibilityUIElement.addNotificationListener
+        incorrectly triggered on notifications from all elements. Now it only triggers on
+        notifications from the correct element, and a new addNotificationListener method
+        in AccessibilityController can be used to trigger on notifications from all elements.
+
+        Updates 2 tests that depended on the old incorrect behavior.
+
+        Reviewed by Chris Fleizach.
+
+        * accessibility/notification-listeners.html: Added.
+        * platform/chromium/accessibility/notification-listeners-expected.txt: Added.
+        * platform/gtk/Skipped:
+        * platform/mac/accessibility/aria-expanded-notifications.html:
+        * platform/mac/accessibility/aria-listbox-selectedchildren-change.html:
+        * platform/mac/accessibility/notification-listeners-expected.txt: Added.
+        * platform/win/Skipped:
+
 2011-12-08  Andrey Kosyakov  <caseq@chromium.org>
 
         Unreviewed. Removed suppressions for inspector extensions tests following a fix in r10231.
diff --git a/LayoutTests/accessibility/notification-listeners.html b/LayoutTests/accessibility/notification-listeners.html
new file mode 100644 (file)
index 0000000..b090753
--- /dev/null
@@ -0,0 +1,79 @@
+<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>
+
+<p id="description"></p>
+
+<select id="select" value="Select"><option>A<option>B</select>
+
+<div id="slider" tabindex="0" role="slider" aria-valuenow="5">Slider</div>
+
+<div id="console"></div>
+
+<script>
+description("This tests that a notification listener on an element only listens to that one element, and that a global notification listener listens to all notifications.");
+
+function runTest() {
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    window.jsTestIsAsync = true;
+
+    window.selectNotificationCount = 0;
+    window.sliderNotificationCount = 0;
+    window.globalNotificationCount = 0;
+
+    if (window.accessibilityController) {
+        document.getElementById("select").focus();
+        window.select = accessibilityController.focusedElement;
+        select.addNotificationListener(function(notification) {
+            selectNotificationCount++;
+            debug("SELECT " + notification);
+        });
+
+        document.getElementById("slider").focus();
+        window.slider = accessibilityController.focusedElement;
+        slider.addNotificationListener(function(notification) {
+            sliderNotificationCount++;
+            debug("SLIDER " + notification);
+        });
+
+        accessibilityController.addNotificationListener(function(element, notification) {
+            if (element.isEqual(slider) || element.isEqual(select)) {
+                globalNotificationCount++;
+                debug("GLOBAL " + notification + " on element with role " + element.role);
+            }
+        });
+    }
+
+    // This should trigger a "invalid status changed" notification on the select.
+    document.getElementById("select").setAttribute("aria-invalid", "true");
+
+    // This should trigger a "value changed" notification on the slider.
+    document.getElementById("slider").setAttribute("aria-valuenow", "6");
+
+    window.setTimeout(function() {
+        shouldBe("selectNotificationCount", "1");
+        shouldBe("sliderNotificationCount", "1");
+        shouldBe("globalNotificationCount", "2");
+
+        if (window.accessibilityController) {
+            accessibilityController.removeNotificationListener();
+            select.removeNotificationListener();
+            slider.removeNotificationListener();
+        }
+
+        finishJSTest();
+    }, 10);
+}
+
+runTest();
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/chromium/accessibility/notification-listeners-expected.txt b/LayoutTests/platform/chromium/accessibility/notification-listeners-expected.txt
new file mode 100644 (file)
index 0000000..d5030bb
--- /dev/null
@@ -0,0 +1,18 @@
+This tests that a notification listener on an element only listens to that one element, and that a global notification listener listens to all notifications.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Slider
+SELECT InvalidStatusChanged
+GLOBAL InvalidStatusChanged on element with role AXRole: AXPopUpButton
+SLIDER ValueChanged
+GLOBAL ValueChanged on element with role AXRole: AXSlider
+PASS selectNotificationCount is 1
+PASS sliderNotificationCount is 1
+PASS globalNotificationCount is 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index 0873e2d..029b078 100644 (file)
@@ -423,6 +423,7 @@ accessibility/language-attribute.html
 accessibility/legend.html
 accessibility/lists.html
 accessibility/loading-iframe-updates-axtree.html
+accessibility/notification-listeners.html
 accessibility/onclick-handlers.html
 accessibility/placeholder.html
 accessibility/plugin.html
index 48bce04..e95c088 100644 (file)
     var notifyCount = 0;
     var notifyName = 0;
     // The order of notifications should be Row Count, Row Collapsed, Row Count, Row Expanded
-    function notifyCallback(notification) {  
+    function notifyCallback(element, notification) {  
         notifyName = notification;
         document.getElementById("notifications").innerHTML += "Notification: " + notifyName + "<br>";
         if (notifyCount == 3) {
-            axTree.removeNotificationListener();
+            accessibilityController.removeNotificationListener();
             window.layoutTestController.notifyDone();
         }
         notifyCount++;
@@ -47,7 +47,7 @@
 
         axTree = window.accessibilityController.focusedElement;
 
-        var addedNotification = axTree.addNotificationListener(notifyCallback);
+        var addedNotification = accessibilityController.addNotificationListener(notifyCallback);
         shouldBe("addedNotification", "true");
 
         // the first aria-expanded should generate row count, row collapsed.
index bee5ea1..c1f3751 100644 (file)
 
     var listbox = 0;
     var notificationCount = 0;
-    function ariaCallback(notification) {
+    function ariaCallback(element, notification) {
         if (notification == "AXSelectedChildrenChanged") {
             notificationCount++;
 
             // We should get a total of 4 live region changes.
             if (notificationCount == 2) {
-               listbox.removeNotificationListener();
+               window.accessibilityController.removeNotificationListener();
                window.layoutTestController.notifyDone();
             }
         }
@@ -38,7 +38,7 @@
         document.getElementById("listbox").focus();
         listbox = window.accessibilityController.focusedElement;
 
-        var addedNotification = listbox.addNotificationListener(ariaCallback);
+        var addedNotification = window.accessibilityController.addNotificationListener(ariaCallback);
         shouldBe("addedNotification", "true");
 
         // These should each trigger a notification that the selected children changed.
diff --git a/LayoutTests/platform/mac/accessibility/notification-listeners-expected.txt b/LayoutTests/platform/mac/accessibility/notification-listeners-expected.txt
new file mode 100644 (file)
index 0000000..d4376be
--- /dev/null
@@ -0,0 +1,18 @@
+This tests that a notification listener on an element only listens to that one element, and that a global notification listener listens to all notifications.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Slider
+SELECT AXInvalidStatusChanged
+GLOBAL AXInvalidStatusChanged on element with role AXRole: AXPopUpButton
+SLIDER AXValueChanged
+GLOBAL AXValueChanged on element with role AXRole: AXSlider
+PASS selectNotificationCount is 1
+PASS sliderNotificationCount is 1
+PASS globalNotificationCount is 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index 6f9484a..c23b582 100644 (file)
@@ -582,6 +582,7 @@ accessibility/media-element.html
 accessibility/nochildren-elements.html
 accessibility/non-data-table-cell-title-ui-element.html
 accessibility/non-native-image-crash.html
+accessibility/notification-listeners.html
 accessibility/onclick-handlers.html
 accessibility/aria-option-role.html
 accessibility/placeholder.html
index 6b577ce..d3dae37 100644 (file)
@@ -1,3 +1,21 @@
+2011-12-08  Dominic Mazzoni  <dmazzoni@google.com>
+
+        AccessibilityController should support listening to notifications on all elements.
+        https://bugs.webkit.org/show_bug.cgi?id=72866
+
+        Changes accessibilitySetShouldRepostNotifications from an instance method
+        into a class method so that it can be used for global notification listeners,
+        not just for listeners on a particular object.
+
+        Reviewed by Chris Fleizach.
+
+        Test: accessibility/notification-listeners.html
+
+        * accessibility/mac/WebAccessibilityObjectWrapper.h:
+        * accessibility/mac/WebAccessibilityObjectWrapper.mm:
+        (+[WebAccessibilityObjectWrapper accessibilitySetShouldRepostNotifications:]):
+        (-[WebAccessibilityObjectWrapper accessibilityPostedNotification:]):
+
 2011-12-08  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: Rename createScriptCallStack() without parameters to createScriptCallStackForInspector().
index 984f7fa..282722f 100644 (file)
@@ -41,6 +41,7 @@ class VisiblePosition;
 - (id)initWithAccessibilityObject:(WebCore::AccessibilityObject*)axObject;
 - (void)detach;
 - (WebCore::AccessibilityObject*)accessibilityObject;
++ (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
 
 // Used to inform an element when a notification is posted for it. Used by DRT.
 - (void)accessibilityPostedNotification:(NSString *)notificationName;
index 845e81f..a604ae6 100644 (file)
@@ -3177,7 +3177,7 @@ static RenderObject* rendererForView(NSView* view)
 
 // This is set by DRT when it wants to listen for notifications.
 static BOOL accessibilityShouldRepostNotifications;
-- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost
++ (void)accessibilitySetShouldRepostNotifications:(BOOL)repost
 {
     accessibilityShouldRepostNotifications = repost;
 }
@@ -3186,7 +3186,7 @@ static BOOL accessibilityShouldRepostNotifications;
 {
     if (accessibilityShouldRepostNotifications) {
         NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @"notificationName", nil];
-        [[NSNotificationCenter defaultCenter] postNotificationName:@"AXDRTNotification" object:nil userInfo:userInfo];
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"AXDRTNotification" object:self userInfo:userInfo];
     }
 }
 
index ec569fb..4433e68 100644 (file)
@@ -1,3 +1,85 @@
+2011-12-08  Dominic Mazzoni  <dmazzoni@google.com>
+
+        Accessibility: AccessibilityController should support listening to notifications on all elements.
+        https://bugs.webkit.org/show_bug.cgi?id=72866
+
+        Adds addNotificationListener and removeNotificationListener methods
+        to AccessibilityController, to listen to notifications on any element
+        rather than a specific element. Mac (DRT and WKTR) and Chromium (DRT)
+        implementations are all contained in this change.
+
+        On Mac, refactors AccessibilityNotificationHandler into its own
+        source file that can be used by both AccessibilityController and
+        AccessibilityUIElement. (Both DRT and WKTR.)
+
+        Reviewed by Chris Fleizach.
+
+        * DumpRenderTree/AccessibilityController.cpp:
+        (addNotificationListenerCallback):
+        (removeNotificationListenerCallback):
+        (AccessibilityController::getJSClass):
+        * DumpRenderTree/AccessibilityController.h:
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/chromium/AccessibilityController.cpp:
+        (AccessibilityController::AccessibilityController):
+        (AccessibilityController::notificationReceived):
+        (AccessibilityController::addNotificationListenerCallback):
+        (AccessibilityController::removeNotificationListenerCallback):
+        * DumpRenderTree/chromium/AccessibilityController.h:
+        * DumpRenderTree/gtk/AccessibilityControllerGtk.cpp:
+        (AccessibilityController::addNotificationListener):
+        (AccessibilityController::removeNotificationListener):
+        * DumpRenderTree/mac/AccessibilityControllerMac.mm:
+        (AccessibilityController::~AccessibilityController):
+        (AccessibilityController::addNotificationListener):
+        (AccessibilityController::removeNotificationListener):
+        * DumpRenderTree/mac/AccessibilityNotificationHandler.h: Added.
+        * DumpRenderTree/mac/AccessibilityNotificationHandler.mm: Added.
+        (-[NSString createJSStringRef]):
+        (-[AccessibilityNotificationHandler init]):
+        (-[AccessibilityNotificationHandler setPlatformElement:]):
+        (-[AccessibilityNotificationHandler dealloc]):
+        (-[AccessibilityNotificationHandler setCallback:]):
+        (-[AccessibilityNotificationHandler startObserving]):
+        (-[AccessibilityNotificationHandler _notificationReceived:]):
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (AccessibilityUIElement::addNotificationListener):
+        * DumpRenderTree/win/AccessibilityControllerWin.cpp:
+        (notificationListenerProc):
+        (AccessibilityController::addNotificationListener):
+        (AccessibilityController::removeNotificationListener):
+        (AccessibilityController::winNotificationReceived):
+        (AccessibilityController::winAddNotificationListener):
+        * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
+        (AccessibilityUIElement::addNotificationListener):
+        * WebKitTestRunner/InjectedBundle/AccessibilityController.cpp:
+        (WTR::AccessibilityController::addNotificationListener):
+        (WTR::AccessibilityController::removeNotificationListener):
+        * WebKitTestRunner/InjectedBundle/AccessibilityController.h:
+        (WTR::AccessibilityController::logAccessibilityEvents):
+        * WebKitTestRunner/InjectedBundle/AccessibilityTextMarker.cpp:
+        (WTR::AccessibilityTextMarker::AccessibilityTextMarker):
+        * WebKitTestRunner/InjectedBundle/AccessibilityTextMarkerRange.cpp:
+        (WTR::AccessibilityTextMarkerRange::AccessibilityTextMarkerRange):
+        * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityController.idl:
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm: Added.
+        (WTR::AccessibilityController::addNotificationListener):
+        (WTR::AccessibilityController::removeNotificationListener):
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.h: Added.
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm: Added.
+        (-[NSString createJSStringRef]):
+        (-[AccessibilityNotificationHandler init]):
+        (-[AccessibilityNotificationHandler setPlatformElement:]):
+        (-[AccessibilityNotificationHandler dealloc]):
+        (-[AccessibilityNotificationHandler setCallback:]):
+        (-[AccessibilityNotificationHandler startObserving]):
+        (-[AccessibilityNotificationHandler _notificationReceived:]):
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+        (WTR::AccessibilityUIElement::AccessibilityUIElement):
+        (WTR::AccessibilityUIElement::verticalScrollbar):
+        (WTR::AccessibilityUIElement::addNotificationListener):
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+
 2011-12-08  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         [Qt][WK2] Unreviewed buildfix after r102352.
index 4fcd4f5..b367d5c 100644 (file)
@@ -97,6 +97,24 @@ static JSValueRef getElementAtPointCallback(JSContextRef context, JSObjectRef fu
     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, controller->elementAtPoint(x, y));
 }
 
+static JSValueRef addNotificationListenerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount != 1)
+        return JSValueMakeBoolean(context, false);
+    
+    AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
+    JSObjectRef callback = JSValueToObject(context, arguments[0], exception);
+    bool succeeded = controller->addNotificationListener(callback);
+    return JSValueMakeBoolean(context, succeeded);
+}
+
+static JSValueRef removeNotificationListenerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    AccessibilityController* controller = static_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
+    controller->removeNotificationListener();
+    return JSValueMakeUndefined(context);
+}
+
 JSClassRef AccessibilityController::getJSClass()
 {
     static JSStaticFunction staticFunctions[] = {
@@ -105,6 +123,8 @@ JSClassRef AccessibilityController::getJSClass()
         { "logScrollingStartEvents", logScrollingStartEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "logAccessibilityEvents", logAccessibilityEventsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "elementAtPoint", getElementAtPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "addNotificationListener", addNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "removeNotificationListener", removeNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { 0, 0, 0 }
     };
 
index 25a3a02..1d52353 100644 (file)
@@ -54,8 +54,15 @@ public:
 
     void resetToConsistentState();
 
-    void addNotificationListener(PlatformUIElement, JSObjectRef functionCallback);
-    void notificationReceived(PlatformUIElement, const std::string& eventName);
+    // Global notification listener, captures notifications on any object.
+    bool addNotificationListener(JSObjectRef functionCallback);
+    void removeNotificationListener();
+
+#if PLATFORM(WIN)
+    // Helper methods so this class can add the listeners on behalf of AccessibilityUIElement.
+    void winAddNotificationListener(PlatformUIElement, JSObjectRef functionCallback);
+    void winNotificationReceived(PlatformUIElement, const std::string& eventName);
+#endif
 
 private:
     static JSClassRef getJSClass();
@@ -69,6 +76,10 @@ private:
     HWINEVENTHOOK m_notificationsEventHook;
     HashMap<PlatformUIElement, JSObjectRef> m_notificationListeners;
 #endif
+
+#if PLATFORM(MAC)
+    RetainPtr<NotificationHandler> m_globalNotificationHandler;
+#endif
 };
 
 #endif // AccessibilityController_h
index 468528e..2032302 100644 (file)
@@ -77,6 +77,8 @@
                5DB9AC9F0F722C3600684641 /* WebKitWeightWatcher800.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */; };
                5DB9ACA00F722C3600684641 /* WebKitWeightWatcher900.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */; };
                5DE8AE4413A2C15900D6A37D /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DE8AE4313A2C15800D6A37D /* libWebCoreTestSupport.dylib */; };
+               80045AED147718E7008290A8 /* AccessibilityNotificationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 80045AEB147718E7008290A8 /* AccessibilityNotificationHandler.h */; };
+               80045AEE147718E7008290A8 /* AccessibilityNotificationHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 80045AEC147718E7008290A8 /* AccessibilityNotificationHandler.mm */; };
                8465E2C70FFA8DF2003B8342 /* PixelDumpSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */; };
                933BF5AB0F93FA5C000F0441 /* PlainTextController.h in Headers */ = {isa = PBXBuildFile; fileRef = 933BF5A90F93FA5C000F0441 /* PlainTextController.h */; };
                933BF5AC0F93FA5C000F0441 /* PlainTextController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 933BF5AA0F93FA5C000F0441 /* PlainTextController.mm */; };
                53CBB830134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CyclicRedundancyCheck.cpp; sourceTree = "<group>"; };
                53CBB831134E42F3001CE6A4 /* CyclicRedundancyCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CyclicRedundancyCheck.h; sourceTree = "<group>"; };
                5DE8AE4313A2C15800D6A37D /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               80045AEB147718E7008290A8 /* AccessibilityNotificationHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AccessibilityNotificationHandler.h; path = mac/AccessibilityNotificationHandler.h; sourceTree = "<group>"; };
+               80045AEC147718E7008290A8 /* AccessibilityNotificationHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityNotificationHandler.mm; path = mac/AccessibilityNotificationHandler.mm; sourceTree = "<group>"; };
                8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PixelDumpSupport.cpp; sourceTree = "<group>"; };
                9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
                933BF5A90F93FA5C000F0441 /* PlainTextController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlainTextController.h; path = mac/PlainTextController.h; sourceTree = "<group>"; };
                1422A2690AF6F45200E1A883 /* Controllers */ = {
                        isa = PBXGroup;
                        children = (
+                               80045AEB147718E7008290A8 /* AccessibilityNotificationHandler.h */,
+                               80045AEC147718E7008290A8 /* AccessibilityNotificationHandler.mm */,
                                BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */,
                                BCD08A580E10496B00A7D0C1 /* AccessibilityController.h */,
                                BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */,
                                29CFBA10122736E600BC30C0 /* AccessibilityTextMarker.h in Headers */,
                                3A5626CC131CA036002BE6D9 /* StorageTrackerDelegate.h in Headers */,
                                417DAA1D137B3E24007C57FB /* WebCoreTestSupport.h in Headers */,
+                               80045AED147718E7008290A8 /* AccessibilityNotificationHandler.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                29CFBA11122736E600BC30C0 /* AccessibilityTextMarker.cpp in Sources */,
                                29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */,
                                3A5626CB131CA02A002BE6D9 /* StorageTrackerDelegate.mm in Sources */,
+                               80045AEE147718E7008290A8 /* AccessibilityNotificationHandler.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index f388fa5..860a747 100644 (file)
@@ -45,6 +45,8 @@ AccessibilityController::AccessibilityController(TestShell* shell)
 {
 
     bindMethod("logAccessibilityEvents", &AccessibilityController::logAccessibilityEventsCallback);
+    bindMethod("addNotificationListener", &AccessibilityController::addNotificationListenerCallback);
+    bindMethod("removeNotificationListener", &AccessibilityController::removeNotificationListenerCallback);
 
     bindProperty("focusedElement", &AccessibilityController::focusedElementGetterCallback);
     bindProperty("rootElement", &AccessibilityController::rootElementGetterCallback);
@@ -93,8 +95,19 @@ bool AccessibilityController::shouldLogAccessibilityEvents()
 
 void AccessibilityController::notificationReceived(const WebKit::WebAccessibilityObject& target, const char* notificationName)
 {
+    // Call notification listeners on the element.
     AccessibilityUIElement* element = m_elements.getOrCreate(target);
     element->notificationReceived(notificationName);
+
+    // Call global notification listeners.
+    size_t callbackCount = m_notificationCallbacks.size();
+    for (size_t i = 0; i < callbackCount; i++) {
+        CppVariant arguments[2];
+        arguments[0].set(*element->getAsCppVariant());
+        arguments[1].set(notificationName);
+        CppVariant invokeResult;
+        m_notificationCallbacks[i].invokeDefault(arguments, 2, invokeResult);
+    }
 }
 
 void AccessibilityController::logAccessibilityEventsCallback(const CppArgumentList&, CppVariant* result)
@@ -103,6 +116,23 @@ void AccessibilityController::logAccessibilityEventsCallback(const CppArgumentLi
     result->setNull();
 }
 
+void AccessibilityController::addNotificationListenerCallback(const CppArgumentList& arguments, CppVariant* result)
+{
+    if (arguments.size() < 1 || !arguments[0].isObject()) {
+        result->setNull();
+        return;
+    }
+
+    m_notificationCallbacks.push_back(arguments[0]);
+    result->setNull();
+}
+
+void AccessibilityController::removeNotificationListenerCallback(const CppArgumentList&, CppVariant* result)
+{
+    // FIXME: Implement this.
+    result->setNull();
+}
+
 void AccessibilityController::focusedElementGetterCallback(CppVariant* result)
 {
     result->set(*(getFocusedElement()->getAsCppVariant()));
index 01da6fb..954edb9 100644 (file)
@@ -64,6 +64,8 @@ private:
     // Bound methods and properties
     void logAccessibilityEventsCallback(const CppArgumentList&, CppVariant*);
     void fallbackCallback(const CppArgumentList&, CppVariant*);
+    void addNotificationListenerCallback(const CppArgumentList&, CppVariant*);
+    void removeNotificationListenerCallback(const CppArgumentList&, CppVariant*);
 
     void focusedElementGetterCallback(CppVariant*);
     void rootElementGetterCallback(CppVariant*);
@@ -73,6 +75,8 @@ private:
 
     AccessibilityUIElementList m_elements;
 
+    std::vector<CppVariant> m_notificationCallbacks;
+
     TestShell* m_shell;
 };
 
index da70efc..ceeb8df 100644 (file)
@@ -97,10 +97,11 @@ void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEve
     loggingAccessibilityEvents = true;
 }
 
-void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef)
+bool AccessibilityController::addNotificationListener(JSObjectRef)
 {
+    return false;
 }
 
-void AccessibilityController::notificationReceived(PlatformUIElement, const std::string&)
+void AccessibilityController::removeNotificationListener()
 {
 }
index 475b839..6fc0dd0 100644 (file)
@@ -27,6 +27,7 @@
 #import "DumpRenderTree.h"
 #import "AccessibilityController.h"
 
+#import "AccessibilityNotificationHandler.h"
 #import "AccessibilityUIElement.h"
 #import <AppKit/NSColor.h>
 #import <Foundation/Foundation.h>
@@ -40,6 +41,8 @@ AccessibilityController::AccessibilityController()
 
 AccessibilityController::~AccessibilityController()
 {
+    // The notification handler should be nil because removeNotificationListener() should have been called in the test.
+    ASSERT(!m_globalNotificationHandler);
 }
 
 AccessibilityUIElement AccessibilityController::elementAtPoint(int x, int y)
@@ -81,10 +84,25 @@ void AccessibilityController::setLogAccessibilityEvents(bool)
 {
 }
 
-void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef)
+bool AccessibilityController::addNotificationListener(JSObjectRef functionCallback)
 {
+    if (!functionCallback)
+        return false;
+    // Mac programmers should not be adding more than one global notification listener.
+    // Other platforms may be different.
+    if (m_globalNotificationHandler)
+        return false;
+    m_globalNotificationHandler = [[AccessibilityNotificationHandler alloc] init];
+    [m_globalNotificationHandler.get() setCallback:functionCallback];
+    [m_globalNotificationHandler.get() startObserving];
+
+    return true;
 }
 
-void AccessibilityController::notificationReceived(PlatformUIElement, const std::string&)
+void AccessibilityController::removeNotificationListener()
 {
+    // Mac programmers should not be trying to remove a listener that's already removed.
+    ASSERT(m_globalNotificationHandler);
+    m_globalNotificationHandler.clear();
 }
diff --git a/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.h b/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.h
new file mode 100644 (file)
index 0000000..19386ce
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#ifndef AccessibilityNotificationHandler_h
+#define AccessibilityNotificationHandler_h
+
+#import <JavaScriptCore/JSObjectRef.h>
+
+@interface AccessibilityNotificationHandler : NSObject {
+    id m_platformElement;
+    JSObjectRef m_notificationFunctionCallback;
+}
+
+- (id)init;
+- (void)setPlatformElement:(id)platformElement;
+- (void)setCallback:(JSObjectRef)callback;
+- (void)startObserving;
+
+@end
+
+#endif // AccessibilityNotificationHandler_h
diff --git a/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm b/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm
new file mode 100644 (file)
index 0000000..13d08c9
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "DumpRenderTree.h"
+#import "AccessibilityNotificationHandler.h"
+#import "AccessibilityUIElement.h"
+
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebTypesInternal.h>
+#import <wtf/RetainPtr.h>
+
+@interface NSObject (WebAccessibilityObjectWrapperAdditions)
++ (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
+@end
+
+@interface NSString (JSStringRefAdditions)
+- (JSStringRef)createJSStringRef;
+@end
+
+@implementation NSString (JSStringRefAdditions)
+
+- (JSStringRef)createJSStringRef
+{
+    return JSStringCreateWithCFString((CFStringRef)self);
+}
+
+@end
+
+@implementation AccessibilityNotificationHandler
+
+- (id)init
+{
+    if (!(self = [super init]))
+        return nil;
+
+    m_platformElement = nil;
+    return self;
+}
+
+- (void)setPlatformElement:(id)platformElement
+{
+    m_platformElement = platformElement;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
+    m_notificationFunctionCallback = 0;
+    
+    [super dealloc];
+}
+
+- (void)setCallback:(JSObjectRef)callback
+{
+    if (!callback)
+        return;
+    if (m_notificationFunctionCallback) 
+        JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
+    
+    m_notificationFunctionCallback = callback;
+    JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback);
+}
+
+- (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.
+    id webAccessibilityObjectWrapperClass = NSClassFromString(@"WebAccessibilityObjectWrapper");
+    ASSERT(webAccessibilityObjectWrapperClass);
+    [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
+}
+
+- (void)_notificationReceived:(NSNotification *)notification
+{
+    NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
+    if (!notificationName)
+        return;
+    if (m_platformElement && m_platformElement != [notification object])
+        return;
+
+    JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
+    JSValueRef notificationNameArgument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
+    if (m_platformElement) {
+        // Listener for one element just gets one argument, the notification name.
+        JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &notificationNameArgument, 0);
+    } else {
+        // A global listener gets the element and the notification name as arguments.
+        JSValueRef arguments[2];
+        arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement([mainFrame globalContext], AccessibilityUIElement([notification object]));
+        arguments[1] = notificationNameArgument;
+        JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 2, arguments, 0);
+    }
+}
+
+@end
+
index 27b10dc..5b041db 100644 (file)
@@ -25,6 +25,7 @@
 
 #import "config.h"
 #import "DumpRenderTree.h"
+#import "AccessibilityNotificationHandler.h"
 #import "AccessibilityUIElement.h"
 
 #import <Foundation/Foundation.h>
@@ -60,7 +61,6 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
 
 @interface NSObject (WebKitAccessibilityAdditions)
 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
-- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
 - (NSUInteger)accessibilityIndexOfChild:(id)child;
 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;
 @end
@@ -88,66 +88,6 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
 
 @end
 
-@interface AccessibilityNotificationHandler : NSObject
-{
-    id m_platformElement;
-    JSObjectRef m_notificationFunctionCallback;
-}
-
-@end
-
-@implementation AccessibilityNotificationHandler
-
-- (id)initWithPlatformElement:(id)platformElement
-{
-    self = [super init];
-
-    m_platformElement = platformElement;
-    
-    // Once an object starts 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 just listen when they want to.
-    [m_platformElement accessibilitySetShouldRepostNotifications:YES];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
-
-    return self;
-}
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
-    m_notificationFunctionCallback = 0;
-    
-    [super dealloc];
-}
-
-- (void)_notificationReceived:(NSNotification *)notification
-{
-    NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
-    if (!notificationName)
-        return;
-    
-    JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
-    JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
-    JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &argument, 0);
-}
-
-- (void)setCallback:(JSObjectRef)callback
-{
-    if (!callback)
-        return;
-    // Release the old callback.
-    if (m_notificationFunctionCallback) 
-        JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
-    
-    m_notificationFunctionCallback = callback;
-    JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback);
-}
-
-@end
-
 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
     : m_element(element)
     , m_notificationHandler(0)
@@ -1229,8 +1169,10 @@ bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallbac
     // Other platforms may be different.
     if (m_notificationHandler)
         return false;
-    m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()];
+    m_notificationHandler = [[AccessibilityNotificationHandler alloc] init];
+    [m_notificationHandler setPlatformElement:platformUIElement()];
     [m_notificationHandler setCallback:functionCallback];
+    [m_notificationHandler startObserving];
 
     return true;
 }
index 8845423..644efe5 100644 (file)
@@ -269,7 +269,7 @@ static void CALLBACK notificationListenerProc(HWINEVENTHOOK, DWORD event, HWND h
 
     COMPtr<IAccessible> childAccessible(Query, childDispatch);
 
-    sharedFrameLoadDelegate->accessibilityController()->notificationReceived(childAccessible, stringEvent(event));
+    sharedFrameLoadDelegate->accessibilityController()->winNotificationReceived(childAccessible, stringEvent(event));
 
     VariantClear(&vChild);
 }
@@ -281,7 +281,16 @@ static COMPtr<IAccessibleComparable> comparableObject(const COMPtr<IServiceProvi
     return comparable;
 }
 
-void AccessibilityController::notificationReceived(PlatformUIElement element, const string& eventName)
+bool AccessibilityController::addNotificationListener(JSObjectRef functionCallback)
+{
+    return false;
+}
+
+void AccessibilityController::removeNotificationListener()
+{
+}
+
+void AccessibilityController::winNotificationReceived(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);
@@ -311,7 +320,7 @@ void AccessibilityController::notificationReceived(PlatformUIElement element, co
     }
 }
 
-void AccessibilityController::addNotificationListener(PlatformUIElement element, JSObjectRef functionCallback)
+void AccessibilityController::winAddNotificationListener(PlatformUIElement element, JSObjectRef functionCallback)
 {
     if (!m_notificationsEventHook)
         m_notificationsEventHook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandle(0), notificationListenerProc, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
index e9b7fc2..2863b5c 100644 (file)
@@ -613,7 +613,7 @@ bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallbac
     if (!functionCallback)
         return false;
 
-    sharedFrameLoadDelegate->accessibilityController()->addNotificationListener(m_element, functionCallback);
+    sharedFrameLoadDelegate->accessibilityController()->winAddNotificationListener(m_element, functionCallback);
     return true;
 }
 
index 42585b4..440f952 100644 (file)
@@ -92,6 +92,12 @@ PassRefPtr<AccessibilityUIElement> AccessibilityController::elementAtPoint(int x
     RefPtr<AccessibilityUIElement> uiElement = rootElement();
     return uiElement->elementAtPoint(x, y);
 }
+
+// Unsupported methods on various platforms. As they're implemented on other platforms this list should be modified.
+#if !PLATFORM(MAC)
+bool AccessibilityController::addNotificationListener(JSValueRef) { return false; }
+bool AccessibilityController::removeNotificationListener() { return false; }
+#endif
     
 } // namespace WTR
 
index ae73a75..08b90e2 100644 (file)
@@ -49,18 +49,23 @@ public:
     PassRefPtr<AccessibilityUIElement> focusedElement();
     PassRefPtr<AccessibilityUIElement> elementAtPoint(int x, int y);
 
+    bool addNotificationListener(JSValueRef functionCallback);
+    bool removeNotificationListener();
+
     // Here for consistency with DRT. Not implemented because they don't do anything on the Mac.
     void logFocusEvents() { }
     void logValueChangeEvents() { }
     void logScrollingStartEvents() { }
     void logAccessibilityEvents() { }
-    void addNotificationListener(AccessibilityUIElement*, JSValueRef functionCallback) { }
-    void notificationReceived(AccessibilityUIElement*, JSStringRef eventName) { }
     
     void resetToConsistentState() { }
 
 private:
     AccessibilityController();
+
+#if PLATFORM(MAC)
+    RetainPtr<NotificationHandler> m_globalNotificationHandler;
+#endif
 };
 
 } // namespace WTR
index 4c3233e..2df8c27 100644 (file)
@@ -30,8 +30,8 @@ module WTR {
         readonly attribute AccessibilityUIElement focusedElement;
         AccessibilityUIElement elementAtPoint(in int x, in int y);
         
-        void addNotificationListener(in AccessibilityUIElement element, in object functionCallback);
-        void notificationReceived(in AccessibilityUIElement element, in DOMString eventName);
+        boolean addNotificationListener(in object functionCallback);
+        boolean removeNotificationListener();
 
         void logFocusEvents();
         void logValueChangeEvents();
diff --git a/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm b/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityControllerMac.mm
new file mode 100644 (file)
index 0000000..863e740
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "AccessibilityController.h"
+#import "AccessibilityNotificationHandler.h"
+
+namespace WTR {
+
+bool AccessibilityController::addNotificationListener(JSValueRef functionCallback)
+{
+    if (!functionCallback)
+        return false;
+
+    // Mac programmers should not be adding more than one global notification listener.
+    // Other platforms may be different.
+    if (m_globalNotificationHandler)
+        return false;
+    m_globalNotificationHandler = [[AccessibilityNotificationHandler alloc] init];
+    [m_globalNotificationHandler.get() setCallback:functionCallback];
+    [m_globalNotificationHandler.get() startObserving];
+
+    return true;
+}
+
+bool AccessibilityController::removeNotificationListener()
+{
+    // Mac programmers should not be trying to remove a listener that's already removed.
+    ASSERT(m_globalNotificationHandler);
+    m_globalNotificationHandler.clear();
+
+    return true;
+}
+
+} // namespace WTR
diff --git a/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.h b/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.h
new file mode 100644 (file)
index 0000000..6725d19
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#ifndef AccessibilityNotificationHandler_h
+#define AccessibilityNotificationHandler_h
+
+#import <JavaScriptCore/JSObjectRef.h>
+
+@interface AccessibilityNotificationHandler : NSObject {
+    id m_platformElement;
+    JSValueRef m_notificationFunctionCallback;
+}
+
+- (id)init;
+- (void)setPlatformElement:(id)platformElement;
+- (void)setCallback:(JSValueRef)callback;
+- (void)startObserving;
+
+@end
+
+#endif // AccessibilityNotificationHandler_h
diff --git a/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm b/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm
new file mode 100644 (file)
index 0000000..1d85bca
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2011 Google 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:
+ *
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "InjectedBundle.h"
+#import "InjectedBundlePage.h"
+#import "JSWrapper.h"
+#import "AccessibilityNotificationHandler.h"
+#import "AccessibilityUIElement.h"
+
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
+#import <WebKit2/WKBundleFrame.h>
+#import <wtf/RetainPtr.h>
+
+@interface NSObject (WebAccessibilityObjectWrapperAdditions)
++ (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
+@end
+
+@interface NSString (JSStringRefAdditions)
+- (JSStringRef)createJSStringRef;
+@end
+
+@implementation NSString (JSStringRefAdditions)
+
+- (JSStringRef)createJSStringRef
+{
+    return JSStringCreateWithCFString((CFStringRef)self);
+}
+
+@end
+
+@implementation AccessibilityNotificationHandler
+
+- (id)init
+{
+    if (!(self = [super init]))
+        return nil;
+
+    return self;
+}
+
+- (void)setPlatformElement:(id)platformElement
+{
+    m_platformElement = platformElement;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+    JSValueUnprotect(context, m_notificationFunctionCallback);
+    m_notificationFunctionCallback = 0;
+
+    [super dealloc];
+}
+
+- (void)setCallback:(JSValueRef)callback
+{
+    if (!callback)
+        return;
+
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+    if (m_notificationFunctionCallback)
+        JSValueUnprotect(context, m_notificationFunctionCallback);
+
+    m_notificationFunctionCallback = callback;
+    JSValueProtect(context, m_notificationFunctionCallback);
+}
+
+- (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.
+    id webAccessibilityObjectWrapperClass = NSClassFromString(@"WebAccessibilityObjectWrapper");
+    ASSERT(webAccessibilityObjectWrapperClass);
+    [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
+}
+
+- (void)_notificationReceived:(NSNotification *)notification
+{
+    NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
+    if (!notificationName)
+        return;
+    if (m_platformElement && m_platformElement != [notification object])
+        return;
+
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+
+    JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
+    JSValueRef notificationNameArgument = JSValueMakeString(context, jsNotification.get());
+    if (m_platformElement) {
+        // Listener for one element just gets one argument, the notification name.
+        JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 1, &notificationNameArgument, 0);
+    } else {
+        // A global listener gets the element and the notification name as arguments.
+        JSValueRef arguments[2];
+        arguments[0] = toJS(context, WTF::getPtr(WTR::AccessibilityUIElement::create([notification object])));
+        arguments[1] = notificationNameArgument;
+        JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 2, arguments, 0);
+    }
+}
+
+@end
+
index ee11dd9..e150825 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #import "config.h"
+#import "AccessibilityNotificationHandler.h"
 #import "AccessibilityUIElement.h"
 #import "InjectedBundle.h"
 #import "InjectedBundlePage.h"
@@ -60,7 +61,6 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
 
 @interface NSObject (WebKitAccessibilityAdditions)
 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
-- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
 - (NSUInteger)accessibilityIndexOfChild:(id)child;
 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;
 @end
@@ -88,76 +88,6 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
 
 @end
 
-@interface AccessibilityNotificationHandler : NSObject
-{
-    id m_platformElement;
-    JSValueRef m_notificationFunctionCallback;
-}
-
-@end
-
-@implementation AccessibilityNotificationHandler
-
-- (id)initWithPlatformElement:(id)platformElement
-{
-    self = [super init];
-
-    m_platformElement = platformElement;
-    
-    // Once an object starts 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 just listen when they want to.
-    [m_platformElement accessibilitySetShouldRepostNotifications:YES];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
-
-    return self;
-}
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-
-    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
-    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
-    
-    JSValueUnprotect(context, m_notificationFunctionCallback);
-    m_notificationFunctionCallback = 0;
-    
-    [super dealloc];
-}
-
-- (void)_notificationReceived:(NSNotification *)notification
-{
-    NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
-    if (!notificationName)
-        return;
-    
-    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
-    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
-
-    JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
-    JSValueRef argument = JSValueMakeString(context, jsNotification.get());
-    JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 1, &argument, 0);
-}
-
-- (void)setCallback:(JSValueRef)callback
-{
-    if (!callback)
-        return;
-    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::shared().page()->page());
-    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
-
-    // Release the old callback.
-    if (m_notificationFunctionCallback) 
-        JSValueUnprotect(context, m_notificationFunctionCallback);
-    
-    m_notificationFunctionCallback = callback;
-    JSValueProtect(context, m_notificationFunctionCallback);
-}
-
-@end
-
 namespace WTR {
 
 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
@@ -1247,8 +1177,10 @@ bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback
     // Other platforms may be different.
     if (m_notificationHandler)
         return false;
-    m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()];
+    m_notificationHandler = [[AccessibilityNotificationHandler alloc] init];
+    [m_notificationHandler setPlatformElement:platformUIElement()];
     [m_notificationHandler setCallback:functionCallback];
+    [m_notificationHandler startObserving];
 
     return true;
 }
index 0fc67b5..a322f39 100644 (file)
@@ -50,6 +50,8 @@
                6510A78B11EC643800410867 /* WebKitWeightWatcher800.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6510A78011EC643800410867 /* WebKitWeightWatcher800.ttf */; };
                6510A78C11EC643800410867 /* WebKitWeightWatcher900.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6510A78111EC643800410867 /* WebKitWeightWatcher900.ttf */; };
                65EB85A011EC67CC0034D300 /* ActivateFonts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65EB859F11EC67CC0034D300 /* ActivateFonts.mm */; };
+               8034C6621487636400AC32E9 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8034C6611487636400AC32E9 /* AccessibilityControllerMac.mm */; };
+               8097338A14874A5A008156D9 /* AccessibilityNotificationHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8097338914874A5A008156D9 /* AccessibilityNotificationHandler.mm */; };
                A664BC7613A5F3A9009A7B25 /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 41230E16138C78BF00BCCFCA /* libWebCoreTestSupport.dylib */; };
                BC14E4DB120E02D000826C0C /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC14E4D9120E02D000826C0C /* GCController.cpp */; };
                BC14E4EA120E03D800826C0C /* JSGCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC14E4E8120E03D800826C0C /* JSGCController.cpp */; };
                6510A78111EC643800410867 /* WebKitWeightWatcher900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher900.ttf; path = fonts/WebKitWeightWatcher900.ttf; sourceTree = "<group>"; };
                65EB859D11EC67CC0034D300 /* ActivateFonts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivateFonts.h; sourceTree = "<group>"; };
                65EB859F11EC67CC0034D300 /* ActivateFonts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ActivateFonts.mm; sourceTree = "<group>"; };
+               8034C6611487636400AC32E9 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; };
+               8097338814874A5A008156D9 /* AccessibilityNotificationHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AccessibilityNotificationHandler.h; path = mac/AccessibilityNotificationHandler.h; sourceTree = "<group>"; };
+               8097338914874A5A008156D9 /* AccessibilityNotificationHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityNotificationHandler.mm; path = mac/AccessibilityNotificationHandler.mm; sourceTree = "<group>"; };
                8DD76FA10486AA7600D96B5E /* WebKitTestRunner */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WebKitTestRunner; sourceTree = BUILT_PRODUCTS_DIR; };
                BC14E4D8120E02D000826C0C /* GCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCController.h; sourceTree = "<group>"; };
                BC14E4D9120E02D000826C0C /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; };
                29A8FCE0145F035D009045A6 /* Accessibility */ = {
                        isa = PBXGroup;
                        children = (
+                               8034C6611487636400AC32E9 /* AccessibilityControllerMac.mm */,
+                               8097338814874A5A008156D9 /* AccessibilityNotificationHandler.h */,
+                               8097338914874A5A008156D9 /* AccessibilityNotificationHandler.mm */,
                                29210EA2144CAAA500835BB5 /* AccessibilityController.cpp */,
                                29210EA3144CAAA500835BB5 /* AccessibilityController.h */,
                                29210EA9144CACB200835BB5 /* AccessibilityUIElement.cpp */,
                                29A8FCDD145F0337009045A6 /* JSAccessibilityTextMarkerRange.cpp in Sources */,
                                29A8FCE2145F037B009045A6 /* AccessibilityTextMarkerRange.cpp in Sources */,
                                29A8FCE5145F0464009045A6 /* AccessibilityTextMarkerRangeMac.mm in Sources */,
+                               8097338A14874A5A008156D9 /* AccessibilityNotificationHandler.mm in Sources */,
+                               8034C6621487636400AC32E9 /* AccessibilityControllerMac.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };