[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

cfleizach at apple.com cfleizach at apple.com
Thu Apr 8 00:54:18 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit e7600b2883eb9ea2c7d358e8aa5fd3218e0ce68a
Author: cfleizach at apple.com <cfleizach at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 5 07:46:08 2010 +0000

    Add ARIA "Live Region" support
    https://bugs.webkit.org/show_bug.cgi?id=33117
    
    Reviewed by Darin Adler.
    
    WebCore:
    
    Tests: platform/mac/accessibility/aria-liveregions-attributes.html
           platform/mac/accessibility/aria-liveregions-notifications.html
    
    * accessibility/AXObjectCache.cpp:
    (WebCore::AXObjectCache::contentChanged):
    * accessibility/AXObjectCache.h:
    (WebCore::AXObjectCache::):
    * accessibility/AccessibilityObject.cpp:
    (WebCore::AccessibilityObject::isChildOfARIALiveRegion):
    (WebCore::AccessibilityObject::supportsARIALiveRegion):
    * accessibility/AccessibilityObject.h:
    (WebCore::AccessibilityObject::contentChanged):
    (WebCore::AccessibilityObject::ariaLiveRegionStatus):
    (WebCore::AccessibilityObject::ariaLiveRegionRelevant):
    (WebCore::AccessibilityObject::ariaLiveRegionAtomic):
    (WebCore::AccessibilityObject::ariaLiveRegionBusy):
    * accessibility/AccessibilityRenderObject.cpp:
    (WebCore::AccessibilityRenderObject::elementAttributeValue):
    (WebCore::AccessibilityRenderObject::contentChanged):
    (WebCore::AccessibilityRenderObject::childrenChanged):
    (WebCore::AccessibilityRenderObject::ariaLiveRegionStatus):
    (WebCore::AccessibilityRenderObject::ariaLiveRegionRelevant):
    (WebCore::AccessibilityRenderObject::ariaLiveRegionAtomic):
    (WebCore::AccessibilityRenderObject::ariaLiveRegionBusy):
    * accessibility/AccessibilityRenderObject.h:
    (WebCore::AccessibilityRenderObject::areChildrenDirty):
    * accessibility/mac/AXObjectCacheMac.mm:
    (WebCore::AXObjectCache::postPlatformNotification):
    * accessibility/mac/AccessibilityObjectWrapper.h:
    * accessibility/mac/AccessibilityObjectWrapper.mm:
    (-[AccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
    (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
    (-[AccessibilityObjectWrapper accessibilitySetPostedNotificationCallback:]):
    (-[AccessibilityObjectWrapper accessibilityPostedNotification:]):
    * dom/Element.cpp:
    (WebCore::Element::updateAfterAttributeChanged):
    * html/HTMLAttributeNames.in:
    * rendering/RenderText.cpp:
    (WebCore::RenderText::setText):
    
    WebKitTools:
    
    * DumpRenderTree/AccessibilityUIElement.cpp:
    (indexOfChildCallback):
    (boolAttributeValueCallback):
    (stringAttributeValueCallback):
    (addNotificationListenerCallback):
    (AccessibilityUIElement::getJSClass):
    * DumpRenderTree/AccessibilityUIElement.h:
    * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp:
    (AccessibilityUIElement::indexOfChild):
    (AccessibilityUIElement::stringAttributeValue):
    (AccessibilityUIElement::boolAttributeValue):
    (AccessibilityUIElement::addNotificationListener):
    * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
    (AccessibilityUIElement::indexOfChild):
    (AccessibilityUIElement::stringAttributeValue):
    (AccessibilityUIElement::boolAttributeValue):
    (_accessibilityNotificationCallback):
    (AccessibilityUIElement::addNotificationListener):
    * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
    (AccessibilityUIElement::indexOfChild):
    (AccessibilityUIElement::stringAttributeValue):
    (AccessibilityUIElement::boolAttributeValue):
    (AccessibilityUIElement::addNotificationListener):
    
    LayoutTests:
    
    * accessibility/aria-activedescendant-crash.html:
    * platform/mac/accessibility/aria-liveregions-attributes-expected.txt: Added.
    * platform/mac/accessibility/aria-liveregions-attributes.html: Added.
    * platform/mac/accessibility/aria-liveregions-notifications-expected.txt: Added.
    * platform/mac/accessibility/aria-liveregions-notifications.html: Added.
    * platform/mac/accessibility/aria-menu-role-descriptions.html:
    * platform/mac/accessibility/slider-supports-actions.html:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52786 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e7f544f..f81ae26 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2010-01-04  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Add ARIA "Live Region" support
+        https://bugs.webkit.org/show_bug.cgi?id=33117
+
+        * accessibility/aria-activedescendant-crash.html:
+        * platform/mac/accessibility/aria-liveregions-attributes-expected.txt: Added.
+        * platform/mac/accessibility/aria-liveregions-attributes.html: Added.
+        * platform/mac/accessibility/aria-liveregions-notifications-expected.txt: Added.
+        * platform/mac/accessibility/aria-liveregions-notifications.html: Added.
+        * platform/mac/accessibility/aria-menu-role-descriptions.html:
+        * platform/mac/accessibility/slider-supports-actions.html:
+
 2010-01-04  Chris Evans  <cevans at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/accessibility/aria-activedescendant-crash.html b/LayoutTests/accessibility/aria-activedescendant-crash.html
index 506a912..47e28ad 100644
--- a/LayoutTests/accessibility/aria-activedescendant-crash.html
+++ b/LayoutTests/accessibility/aria-activedescendant-crash.html
@@ -7,7 +7,7 @@
                     layoutTestController.dumpAsText();
                 document.getElementById('bt').focus();
                 if (window.accessibilityController)
-                    var test = accessibilityController.focusedElement.attributeValue("aria-activedescendant");
+                    var test = accessibilityController.focusedElement.stringAttributeValue("aria-activedescendant");
                 document.getElementById('bt').click();
             }
         </script>
diff --git a/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes-expected.txt b/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes-expected.txt
new file mode 100644
index 0000000..717bb12
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes-expected.txt
@@ -0,0 +1,38 @@
+// This tests that elements that are not live regions do not have the live region attrs.
+no live region
+
+// These test that they have the correct default values for aria-live.
+test
+test
+test
+test
+test
+// These test that elements with live regions on have the right attributes
+h3
+
+This tests that the attributes used for ARIA live regions behave correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIABusy') is false
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIARelevant') is false
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIAAtomic') is false
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIALive') is false
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'assertive'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'assertive'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'polite'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'polite'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'off'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIALive') is 'polite'
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIARelevant') is 'additions'
+PASS accessibilityController.focusedElement.boolAttributeValue('AXARIABusy') is true
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIALive') is false
+PASS accessibilityController.focusedElement.isAttributeSupported('AXARIARelevant') is false
+PASS accessibilityController.focusedElement.boolAttributeValue('AXARIAAtomic') is true
+PASS accessibilityController.focusedElement.boolAttributeValue('AXARIABusy') is false
+PASS accessibilityController.focusedElement.stringAttributeValue('AXARIARelevant') is 'additions text'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes.html b/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes.html
new file mode 100644
index 0000000..8a2b780
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-liveregions-attributes.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script>
+var successfullyParsed = false;
+</script>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+// This tests that elements that are not live regions do not have the live region attrs.
+<h3 tabindex=0 id="h3">no live region</h3>
+
+// These test that they have the correct default values for aria-live.
+
+<div tabindex=0 id="alert" role="alert">test</div>
+<div tabindex=0 id="alertdialog" role="alertdialog">test</div>
+<div tabindex=0 id="log" role="log">test</div>
+<div tabindex=0 id="status" role="status">test</div>
+<div tabindex=0 id="timer" role="timer">test</div>
+
+// These test that elements with live regions on have the right attributes
+<div tabindex=0 id="liveregion" role="group" aria-busy="true" aria-live="polite" aria-relevant="additions">
+<h3 tabindex=0 aria-atomic="true" id="h3live">h3</h3>
+</div>
+
+<div tabindex=0 id="liveregion2" role="group" aria-live="polite">
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that the attributes used for ARIA live regions behave correctly.");
+
+    if (window.accessibilityController) {
+  
+          // Make sure that regular elements are not exposing ARIA live attributes.
+          document.getElementById("h3").focus();
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIABusy')", "false");
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIARelevant')", "false");
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIAAtomic')", "false");
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIALive')", "false");
+
+          // Make sure that specific aria roles get the right aria live values.
+          document.getElementById("alert").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'assertive'");
+
+          document.getElementById("alertdialog").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'assertive'");
+
+          document.getElementById("log").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'polite'");
+
+          document.getElementById("status").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'polite'");
+
+          document.getElementById("timer").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'off'");
+
+          // Test the other attributes for a live region
+          document.getElementById("liveregion").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIALive')", "'polite'");
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIARelevant')", "'additions'");
+          shouldBe("accessibilityController.focusedElement.boolAttributeValue('AXARIABusy')", "true");
+
+          document.getElementById("h3live").focus();
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIALive')", "false");
+          shouldBe("accessibilityController.focusedElement.isAttributeSupported('AXARIARelevant')", "false");
+          shouldBe("accessibilityController.focusedElement.boolAttributeValue('AXARIAAtomic')", "true");
+          shouldBe("accessibilityController.focusedElement.boolAttributeValue('AXARIABusy')", "false");
+
+          // when an element has no specific aria-relevant, it should be additions text by default.
+          document.getElementById("liveregion2").focus();
+          shouldBe("accessibilityController.focusedElement.stringAttributeValue('AXARIARelevant')", "'additions text'");
+ 
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications-expected.txt b/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications-expected.txt
new file mode 100644
index 0000000..6d401ff
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications-expected.txt
@@ -0,0 +1,11 @@
+ new text element
+This tests that ARIA live regions are sending out the correct notifications. We perform four operations (add, remove, change text, change alt tag), each one should trigger a live region notification
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS addedNotification is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications.html b/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications.html
new file mode 100644
index 0000000..d44281d
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-liveregions-notifications.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script>
+var successfullyParsed = false;
+</script>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<div role="group" tabindex=0 id="liveregion" aria-live="polite" aria-relevant="additions">
+<h3 id="innerlive">text</h3>
+<img src="test.gif" width=100 height=100 alt="alt text" tabindex=0 id="image">
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that ARIA live regions are sending out the correct notifications. We perform four operations (add, remove, change text, change alt tag), each one should trigger a live region notification");
+
+    var liveRegionChangeCount = 0;
+    function ariaCallback(notification) {
+        if (notification == "AXLiveRegionChanged") {
+            liveRegionChangeCount++;
+
+            // We should get a total of 4 live region changes.
+            if (liveRegionChangeCount == 4) {
+               window.layoutTestController.notifyDone();
+            }
+        }
+    }
+
+    if (window.accessibilityController) {
+        window.layoutTestController.waitUntilDone();
+
+        document.getElementById("liveregion").focus();
+        var liveRegion = window.accessibilityController.focusedElement;
+
+        var addedNotification = liveRegion.addNotificationListener(ariaCallback);
+        shouldBe("addedNotification", "true");
+
+        // this should trigger our live region callback for a text change.
+        document.getElementById("innerlive").innerText = "changed text";
+
+        // this should trigger our live region callback for a new element.
+        document.getElementById("liveregion").innerHTML += "new text element";
+
+        // this should also trigger our live region change because its a text alternative change. 
+        document.getElementById("image").setAttribute('alt', "new image text");
+
+        // Access the accessibility tree here because AX won't post the live region change
+        // notification twice when the children have already been marked as dirty.
+        liveRegion.childAtIndex(0);
+
+        // this should trigger our live region callback for a removed element.
+        document.getElementById("liveregion").removeChild(document.getElementById("innerlive")); 
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/accessibility/aria-menu-role-descriptions.html b/LayoutTests/platform/mac/accessibility/aria-menu-role-descriptions.html
index 0e9623b..cbb549c 100644
--- a/LayoutTests/platform/mac/accessibility/aria-menu-role-descriptions.html
+++ b/LayoutTests/platform/mac/accessibility/aria-menu-role-descriptions.html
@@ -27,11 +27,11 @@ var successfullyParsed = false;
           menu.focus();
 
           menu = accessibilityController.focusedElement;
-          var menuRole = menu.attributeValue("AXRoleDescription");
+          var menuRole = menu.stringAttributeValue("AXRoleDescription");
           shouldBe("menuRole.length > 0", "true");
 
           var menuItem = menu.childAtIndex(0);
-          var menuItemRole = menuItem.attributeValue("AXRoleDescription");
+          var menuItemRole = menuItem.stringAttributeValue("AXRoleDescription");
           shouldBe("menuItemRole.length > 0", "true");
     }
 
diff --git a/LayoutTests/platform/mac/accessibility/slider-supports-actions.html b/LayoutTests/platform/mac/accessibility/slider-supports-actions.html
index c334c40..4b9be6a 100644
--- a/LayoutTests/platform/mac/accessibility/slider-supports-actions.html
+++ b/LayoutTests/platform/mac/accessibility/slider-supports-actions.html
@@ -32,7 +32,7 @@ var successfullyParsed = false;
           var succeeded = obj.isActionSupported("AXDecrement") == true;
           shouldBe("succeeded", "true");
 
-          var succeeded = obj.attributeValue("AXOrientation") == "AXVerticalOrientation";
+          var succeeded = obj.stringAttributeValue("AXOrientation") == "AXVerticalOrientation";
           shouldBe("succeeded", "true");
 
           // test the input slider
@@ -45,7 +45,7 @@ var successfullyParsed = false;
           var succeeded = obj.isActionSupported("AXDecrement") == true;
           shouldBe("succeeded", "true");
 
-          var succeeded = obj.attributeValue("AXOrientation") == "AXHorizontalOrientation";
+          var succeeded = obj.stringAttributeValue("AXOrientation") == "AXHorizontalOrientation";
           shouldBe("succeeded", "true");
 
     }
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 997226e..096541d 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-01-04  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Add ARIA "Live Region" support
+        https://bugs.webkit.org/show_bug.cgi?id=33117
+
+        Tests: platform/mac/accessibility/aria-liveregions-attributes.html
+               platform/mac/accessibility/aria-liveregions-notifications.html
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::contentChanged):
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::):
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::isChildOfARIALiveRegion):
+        (WebCore::AccessibilityObject::supportsARIALiveRegion):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::contentChanged):
+        (WebCore::AccessibilityObject::ariaLiveRegionStatus):
+        (WebCore::AccessibilityObject::ariaLiveRegionRelevant):
+        (WebCore::AccessibilityObject::ariaLiveRegionAtomic):
+        (WebCore::AccessibilityObject::ariaLiveRegionBusy):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::elementAttributeValue):
+        (WebCore::AccessibilityRenderObject::contentChanged):
+        (WebCore::AccessibilityRenderObject::childrenChanged):
+        (WebCore::AccessibilityRenderObject::ariaLiveRegionStatus):
+        (WebCore::AccessibilityRenderObject::ariaLiveRegionRelevant):
+        (WebCore::AccessibilityRenderObject::ariaLiveRegionAtomic):
+        (WebCore::AccessibilityRenderObject::ariaLiveRegionBusy):
+        * accessibility/AccessibilityRenderObject.h:
+        (WebCore::AccessibilityRenderObject::areChildrenDirty):
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXObjectCache::postPlatformNotification):
+        * accessibility/mac/AccessibilityObjectWrapper.h:
+        * accessibility/mac/AccessibilityObjectWrapper.mm:
+        (-[AccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
+        (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
+        (-[AccessibilityObjectWrapper accessibilitySetPostedNotificationCallback:]):
+        (-[AccessibilityObjectWrapper accessibilityPostedNotification:]):
+        * dom/Element.cpp:
+        (WebCore::Element::updateAfterAttributeChanged):
+        * html/HTMLAttributeNames.in:
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::setText):
+
 2010-01-04  Chris Evans  <cevans at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/accessibility/AXObjectCache.cpp b/WebCore/accessibility/AXObjectCache.cpp
index 8cfd6c0..9eff5b6 100644
--- a/WebCore/accessibility/AXObjectCache.cpp
+++ b/WebCore/accessibility/AXObjectCache.cpp
@@ -288,20 +288,27 @@ AXID AXObjectCache::getAXID(AccessibilityObject* obj)
     return objID;
 }
 
-void AXObjectCache::removeAXID(AccessibilityObject* obj)
+void AXObjectCache::removeAXID(AccessibilityObject* object)
 {
-    if (!obj)
+    if (!object)
         return;
     
-    AXID objID = obj->axObjectID();
+    AXID objID = object->axObjectID();
     if (!objID)
         return;
     ASSERT(!HashTraits<AXID>::isDeletedValue(objID));
     ASSERT(m_idsInUse.contains(objID));
-    obj->setAXObjectID(0);
+    object->setAXObjectID(0);
     m_idsInUse.remove(objID);
 }
 
+void AXObjectCache::contentChanged(RenderObject* renderer)
+{
+    AccessibilityObject* object = getOrCreate(renderer);
+    if (object)
+        object->contentChanged(); 
+}
+    
 void AXObjectCache::childrenChanged(RenderObject* renderer)
 {
     if (!renderer)
diff --git a/WebCore/accessibility/AXObjectCache.h b/WebCore/accessibility/AXObjectCache.h
index cb4171a..986241e 100644
--- a/WebCore/accessibility/AXObjectCache.h
+++ b/WebCore/accessibility/AXObjectCache.h
@@ -80,6 +80,9 @@ public:
     void attachWrapper(AccessibilityObject*);
     void childrenChanged(RenderObject*);
     void selectedChildrenChanged(RenderObject*);
+    // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
+    void contentChanged(RenderObject*);
+    
     void handleActiveDescendantChanged(RenderObject*);
     void handleAriaRoleChanged(RenderObject*);
     void handleFocusedUIElementChanged(RenderObject* oldFocusedRenderer, RenderObject* newFocusedRenderer);
@@ -110,6 +113,7 @@ public:
         AXSelectedTextChanged,
         AXValueChanged,
         AXScrolledToAnchor,
+        AXLiveRegionChanged,
         AXMenuListValueChanged,
     };
 
diff --git a/WebCore/accessibility/AccessibilityObject.cpp b/WebCore/accessibility/AccessibilityObject.cpp
index ce91026..751813a 100644
--- a/WebCore/accessibility/AccessibilityObject.cpp
+++ b/WebCore/accessibility/AccessibilityObject.cpp
@@ -929,5 +929,25 @@ AccessibilityRole AccessibilityObject::ariaRoleToWebCoreRole(const String& value
     static const ARIARoleMap* roleMap = createARIARoleMap();
     return roleMap->get(value);
 }
+
+bool AccessibilityObject::isInsideARIALiveRegion() const
+{
+    if (supportsARIALiveRegion())
+        return true;
+    
+    for (AccessibilityObject* axParent = parentObject(); axParent; axParent = axParent->parentObject()) {
+        if (axParent->supportsARIALiveRegion())
+            return true;
+    }
+    
+    return false;
+}
+
+bool AccessibilityObject::supportsARIALiveRegion() const
+{
+    const AtomicString& liveRegion = ariaLiveRegionStatus();
+    return equalIgnoringCase(liveRegion, "polite") || equalIgnoringCase(liveRegion, "assertive");
+}
+
     
 } // namespace WebCore
diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h
index 4000325..263b678 100644
--- a/WebCore/accessibility/AccessibilityObject.h
+++ b/WebCore/accessibility/AccessibilityObject.h
@@ -424,6 +424,7 @@ public:
     virtual void decrement() { }
 
     virtual void childrenChanged() { }
+    virtual void contentChanged() { }
     virtual const AccessibilityChildrenVector& children() { return m_children; }
     virtual void addChildren() { }
     virtual bool canHaveChildren() const { return true; }
@@ -500,6 +501,14 @@ public:
     // Used by an ARIA tree item to get only its content, and not its child tree items and groups. 
     void ariaTreeItemContent(AccessibilityChildrenVector&);
     
+    // ARIA live-region features.
+    bool supportsARIALiveRegion() const;
+    bool isInsideARIALiveRegion() const;
+    virtual const AtomicString& ariaLiveRegionStatus() const { return nullAtom; }
+    virtual const AtomicString& ariaLiveRegionRelevant() const { return nullAtom; }
+    virtual bool ariaLiveRegionAtomic() const { return false; }
+    virtual bool ariaLiveRegionBusy() const { return false; }
+    
 #if HAVE(ACCESSIBILITY)
 #if PLATFORM(GTK)
     AccessibilityObjectWrapper* wrapper() const;
diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp
index c966634..d253b9d 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -1754,12 +1754,12 @@ void AccessibilityRenderObject::setElementAttributeValue(const QualifiedName& at
     element->setAttribute(attributeName, (value) ? "true" : "false");        
 }
     
-bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName)
+bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName) const
 {
     if (!m_renderer)
         return false;
     
-    return equalIgnoringCase(getAttribute(attributeName).string(), "true");
+    return equalIgnoringCase(getAttribute(attributeName), "true");
 }
     
 void AccessibilityRenderObject::setIsExpanded(bool isExpanded)
@@ -2776,22 +2776,50 @@ bool AccessibilityRenderObject::canSetTextRangeAttributes() const
     return isTextControl();
 }
 
+void AccessibilityRenderObject::contentChanged()
+{
+    // If this element supports ARIA live regions, then notify the AT of changes.
+    for (RenderObject* renderParent = m_renderer->parent(); renderParent; renderParent = renderParent->parent()) {
+        AccessibilityObject* parent = m_renderer->document()->axObjectCache()->get(renderParent);
+        if (!parent)
+            continue;
+        
+        // If we find a parent that has ARIA live region on, send the notification and stop processing.
+        // The spec does not talk about nested live regions.
+        if (parent->supportsARIALiveRegion()) {
+            axObjectCache()->postNotification(renderParent, AXObjectCache::AXLiveRegionChanged, true);
+            break;
+        }
+    }
+}
+    
 void AccessibilityRenderObject::childrenChanged()
 {
     // this method is meant as a quick way of marking dirty
     // a portion of the accessibility tree
     
-    markChildrenDirty();
-    
     if (!m_renderer)
         return;
     
     // Go up the render parent chain, marking children as dirty.
     // We can't rely on the accessibilityParent() because it may not exist and we must not create an AX object here either
-    for (RenderObject* renderParent = m_renderer->parent(); renderParent; renderParent = renderParent->parent()) {
+    // At the same time, process ARIA live region changes.
+    for (RenderObject* renderParent = m_renderer; renderParent; renderParent = renderParent->parent()) {
         AccessibilityObject* parent = m_renderer->document()->axObjectCache()->get(renderParent);
-        if (parent && parent->isAccessibilityRenderObject())
-            static_cast<AccessibilityRenderObject *>(parent)->markChildrenDirty();
+        if (!parent || !parent->isAccessibilityRenderObject())
+            continue;
+        
+        AccessibilityRenderObject* axParent = static_cast<AccessibilityRenderObject*>(parent);
+        // Only do work if the children haven't been marked dirty. This has the effect of blocking
+        // future live region change notifications until the AX tree has been accessed again. This
+        // is a good performance win for all parties.
+        if (!axParent->needsToUpdateChildren()) {
+            axParent->setNeedsToUpdateChildren();
+            
+            // If this element supports ARIA live regions, then notify the AT of changes.
+            if (axParent->supportsARIALiveRegion())
+                axObjectCache()->postNotification(renderParent, AXObjectCache::AXLiveRegionChanged, true);
+        }
     }
 }
     
@@ -2876,7 +2904,55 @@ void AccessibilityRenderObject::addChildren()
         }
     }
 }
+        
+const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusAssertive, ("assertive"));
+    DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusPolite, ("polite"));
+    DEFINE_STATIC_LOCAL(const AtomicString, liveRegionStatusOff, ("off"));
+    
+    const AtomicString& liveRegionStatus = getAttribute(aria_liveAttr);
+    // These roles have implicit live region status.
+    if (liveRegionStatus.isEmpty()) {
+        switch (roleValue()) {
+        case ApplicationAlertDialogRole:
+        case ApplicationAlertRole:
+            return liveRegionStatusAssertive;
+        case ApplicationLogRole:
+        case ApplicationStatusRole:
+            return liveRegionStatusPolite;
+        case ApplicationTimerRole:
+            return liveRegionStatusOff;
+        default:
+            break;
+        }
+    }
+
+    return liveRegionStatus;
+}
+
+const AtomicString& AccessibilityRenderObject::ariaLiveRegionRelevant() const
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, defaultLiveRegionRelevant, ("additions text"));
+    const AtomicString& relevant = getAttribute(aria_relevantAttr);
+
+    // Default aria-relevant = "additions text".
+    if (relevant.isEmpty())
+        return defaultLiveRegionRelevant;
+    
+    return relevant;
+}
+
+bool AccessibilityRenderObject::ariaLiveRegionAtomic() const
+{
+    return elementAttributeValue(aria_atomicAttr);    
+}
 
+bool AccessibilityRenderObject::ariaLiveRegionBusy() const
+{
+    return elementAttributeValue(aria_busyAttr);    
+}
+    
 void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& result)
 {
     // Get all the rows. 
diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h
index 8e59999..339e18b 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.h
+++ b/WebCore/accessibility/AccessibilityRenderObject.h
@@ -207,6 +207,7 @@ public:
     
     virtual void detach();
     virtual void childrenChanged();
+    virtual void contentChanged();
     virtual void addChildren();
     virtual bool canHaveChildren() const;
     virtual void selectedChildren(AccessibilityChildrenVector&);
@@ -283,14 +284,20 @@ private:
 
     void ariaSelectedRows(AccessibilityChildrenVector&);
     
-    bool elementAttributeValue(const QualifiedName&);
+    bool elementAttributeValue(const QualifiedName&) const;
     void setElementAttributeValue(const QualifiedName&, bool);
     
     String accessibilityDescriptionForElements(Vector<Element*> &elements) const;
     void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& name) const;
     
-    void markChildrenDirty() const { m_childrenDirty = true; }
-
+    virtual const AtomicString& ariaLiveRegionStatus() const;
+    virtual const AtomicString& ariaLiveRegionRelevant() const;
+    virtual bool ariaLiveRegionAtomic() const;
+    virtual bool ariaLiveRegionBusy() const;    
+    
+    void setNeedsToUpdateChildren() const { m_childrenDirty = true; }
+    bool needsToUpdateChildren() const { return m_childrenDirty; }
+    
     mutable AccessibilityRole m_roleForMSAA;
 };
     
diff --git a/WebCore/accessibility/mac/AXObjectCacheMac.mm b/WebCore/accessibility/mac/AXObjectCacheMac.mm
index bf1b22c..6f886fe 100644
--- a/WebCore/accessibility/mac/AXObjectCacheMac.mm
+++ b/WebCore/accessibility/mac/AXObjectCacheMac.mm
@@ -35,6 +35,10 @@
 
 #import <wtf/PassRefPtr.h>
 
+#ifndef NSAccessibilityLiveRegionChangedNotification
+#define NSAccessibilityLiveRegionChangedNotification @"AXLiveRegionChanged"
+#endif
+
 // The simple Cocoa calls in this file don't throw exceptions.
 
 namespace WebCore {
@@ -66,9 +70,6 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
             else
                 macNotification = NSAccessibilityFocusedUIElementChangedNotification;                
             break;
-        case AXCheckedStateChanged:
-            macNotification = "AXCheckedStateChanged";
-            break;
         case AXFocusedUIElementChanged:
             macNotification = NSAccessibilityFocusedUIElementChangedNotification;
             break;
@@ -87,11 +88,19 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
         case AXValueChanged:
             macNotification = NSAccessibilityValueChangedNotification;
             break;
+        case AXLiveRegionChanged:
+            macNotification = NSAccessibilityLiveRegionChangedNotification;
+            break;
+        // Does not exist on Mac.
+        case AXCheckedStateChanged:
         default:
             return;
     }
     
     NSAccessibilityPostNotification(obj->wrapper(), macNotification);
+    
+    // Used by DRT to know when notifications are posted.
+    [obj->wrapper() accessibilityPostedNotification:macNotification];
 }
 
 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*)
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.h b/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
index 910305b..1f0a9e3 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.h
@@ -52,6 +52,9 @@ class VisiblePosition;
 - (void)detach;
 - (WebCore::AccessibilityObject*)accessibilityObject;
 
+// Used to inform an element when a notification is posted for it. Used by DRT.
+- (void)accessibilityPostedNotification:(NSString *)notification;
+
 - (NSView*)attachmentView;
 
 @end
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index db429d9..482fe4f 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -132,6 +132,22 @@ using namespace std;
 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
 #endif
 
+#ifndef NSAccessibilityARIALiveAttribute
+#define NSAccessibilityARIALiveAttribute @"AXARIALive"
+#endif
+
+#ifndef NSAccessibilityARIAAtomicAttribute
+#define NSAccessibilityARIAAtomicAttribute @"AXARIAAtomic"
+#endif
+
+#ifndef NSAccessibilityARIARelevantAttribute
+#define NSAccessibilityARIARelevantAttribute @"AXARIARelevant"
+#endif
+
+#ifndef NSAccessibilityARIABusyAttribute
+#define NSAccessibilityARIABusyAttribute @"AXARIABusy"
+#endif
+
 #ifdef BUILDING_ON_TIGER
 typedef unsigned NSUInteger;
 #define NSAccessibilityValueDescriptionAttribute @"AXValueDescription"
@@ -603,6 +619,17 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
     if (m_object->isDataTable() && static_cast<AccessibilityTable*>(m_object)->supportsSelectedRows())
         [additional addObject:NSAccessibilitySelectedRowsAttribute];        
     
+    if (m_object->supportsARIALiveRegion()) {
+        [additional addObject:NSAccessibilityARIALiveAttribute];
+        [additional addObject:NSAccessibilityARIARelevantAttribute];
+    }
+        
+    // If an object is a child of a live region, then add these
+    if (m_object->isInsideARIALiveRegion()) {
+        [additional addObject:NSAccessibilityARIAAtomicAttribute];
+        [additional addObject:NSAccessibilityARIABusyAttribute];
+    }
+    
     return additional;
 }
 
@@ -1816,6 +1843,16 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         return dropEffectsArray;
     }
     
+    // ARIA Live region attributes.
+    if ([attributeName isEqualToString:NSAccessibilityARIALiveAttribute])
+        return m_object->ariaLiveRegionStatus();
+    if ([attributeName isEqualToString:NSAccessibilityARIARelevantAttribute])
+         return m_object->ariaLiveRegionRelevant();
+    if ([attributeName isEqualToString:NSAccessibilityARIAAtomicAttribute])
+        return [NSNumber numberWithBool:m_object->ariaLiveRegionAtomic()];
+    if ([attributeName isEqualToString:NSAccessibilityARIABusyAttribute])
+        return [NSNumber numberWithBool:m_object->ariaLiveRegionBusy()];
+    
     // this is used only by DumpRenderTree for testing
     if ([attributeName isEqualToString:@"AXClickPoint"])
         return [NSValue valueWithPoint:m_object->clickPoint()];
@@ -2613,6 +2650,21 @@ static RenderObject* rendererForView(NSView* view)
     return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
 }
 
+// These are used by DRT so that it can know when notifications are sent.
+typedef void (*AXPostedNotificationCallback)(id element, NSString* notification);
+static AXPostedNotificationCallback AXNotificationCallback = 0;
+
+- (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function
+{
+    AXNotificationCallback = function;
+}
+
+- (void)accessibilityPostedNotification:(NSString *)notification
+{
+    if (AXNotificationCallback)
+        AXNotificationCallback(self, notification);
+}
+
 @end
 
 #endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index b347264..9ebd328 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -592,6 +592,9 @@ void Element::updateAfterAttributeChanged(Attribute* attr)
     } else if (attrName == aria_valuenowAttr) {
         // If the valuenow attribute changes, AX clients need to be notified.
         axObjectCache->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
+    } else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == altAttr || attrName == titleAttr) {
+        // If the content of an element changes due to an attribute change, notify accessibility.
+        axObjectCache->contentChanged(renderer());
     }
 }
     
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index 420d6a7..3c4ff40 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -13,6 +13,8 @@ alink
 alt
 archive
 aria-activedescendant
+aria-atomic
+aria-busy
 aria-checked
 aria-controls
 aria-describedby
@@ -26,11 +28,13 @@ aria-label
 aria-labeledby
 aria-labelledby
 aria-level
+aria-live
 aria-multiselectable
 aria-orientation
 aria-owns
 aria-pressed
 aria-readonly
+aria-relevant
 aria-required
 aria-selected
 aria-valuemax
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 8006ba3..15ea496 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "RenderText.h"
 
+#include "AXObjectCache.h"
 #include "CharacterNames.h"
 #include "EllipsisBox.h"
 #include "FloatQuad.h"
@@ -1015,6 +1016,10 @@ void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
     setTextInternal(text);
     setNeedsLayoutAndPrefWidthsRecalc();
     m_knownNotToUseFallbackFonts = false;
+    
+    AXObjectCache* axObjectCache = document()->axObjectCache();
+    if (axObjectCache->accessibilityEnabled())
+        axObjectCache->contentChanged(this);
 }
 
 int RenderText::lineHeight(bool firstLine, bool) const
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index f67def5..e3724a7 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,34 @@
+2010-01-04  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Add ARIA "Live Region" support
+        https://bugs.webkit.org/show_bug.cgi?id=33117
+
+        * DumpRenderTree/AccessibilityUIElement.cpp:
+        (indexOfChildCallback):
+        (boolAttributeValueCallback):
+        (stringAttributeValueCallback):
+        (addNotificationListenerCallback):
+        (AccessibilityUIElement::getJSClass):
+        * DumpRenderTree/AccessibilityUIElement.h:
+        * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp:
+        (AccessibilityUIElement::indexOfChild):
+        (AccessibilityUIElement::stringAttributeValue):
+        (AccessibilityUIElement::boolAttributeValue):
+        (AccessibilityUIElement::addNotificationListener):
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (AccessibilityUIElement::indexOfChild):
+        (AccessibilityUIElement::stringAttributeValue):
+        (AccessibilityUIElement::boolAttributeValue):
+        (_accessibilityNotificationCallback):
+        (AccessibilityUIElement::addNotificationListener):
+        * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
+        (AccessibilityUIElement::indexOfChild):
+        (AccessibilityUIElement::stringAttributeValue):
+        (AccessibilityUIElement::boolAttributeValue):
+        (AccessibilityUIElement::addNotificationListener):
+
 2010-01-04  Eric Seidel  <eric at webkit.org>
 
         Reviewed by Adam Barth.
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
index 634c2f3..6bdc734 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
@@ -152,6 +152,16 @@ static JSValueRef stringForRangeCallback(JSContextRef context, JSObjectRef funct
     return JSValueMakeString(context, stringDescription.get());    
 }
 
+static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount != 1)
+        return 0;
+    
+    JSObjectRef otherElement = JSValueToObject(context, arguments[0], exception);
+    AccessibilityUIElement* childElement = toAXElement(otherElement);
+    return JSValueMakeNumber(context, (double)toAXElement(thisObject)->indexOfChild(childElement));
+}
+
 static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     int indexNumber = -1;
@@ -254,13 +264,25 @@ static JSValueRef isActionSupportedCallback(JSContextRef context, JSObjectRef fu
     return result;
 }
 
-static JSValueRef attributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+static JSValueRef boolAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    JSStringRef attribute = 0;
+    if (argumentCount == 1)
+        attribute = JSValueToStringCopy(context, arguments[0], exception);
+    bool val = toAXElement(thisObject)->boolAttributeValue(attribute);
+    JSValueRef result = JSValueMakeBoolean(context, val);
+    if (attribute)
+        JSStringRelease(attribute);
+    return result;
+}
+
+static JSValueRef stringAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     JSStringRef attribute = 0;
     if (argumentCount == 1)
         attribute = JSValueToStringCopy(context, arguments[0], exception);
-    JSRetainPtr<JSStringRef> attributeValue(Adopt, toAXElement(thisObject)->attributeValue(attribute));
-    JSValueRef result = JSValueMakeString(context, attributeValue.get());
+    JSRetainPtr<JSStringRef> stringAttributeValue(Adopt, toAXElement(thisObject)->stringAttributeValue(attribute));
+    JSValueRef result = JSValueMakeString(context, stringAttributeValue.get());
     if (attribute)
         JSStringRelease(attribute);
     return result;
@@ -510,6 +532,16 @@ static JSValueRef getURLCallback(JSContextRef context, JSObjectRef thisObject, J
     return JSValueMakeString(context, url.get());
 }
 
+static JSValueRef addNotificationListenerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount != 1)
+        return JSValueMakeBoolean(context, false);
+    
+    JSObjectRef callback = JSValueToObject(context, arguments[0], exception);
+    bool succeeded = toAXElement(thisObject)->addNotificationListener(callback);
+    return JSValueMakeBoolean(context, succeeded);
+}
+
 // Destruction
 
 static void finalize(JSObjectRef thisObject)
@@ -573,6 +605,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "indexOfChild", indexOfChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "elementAtPoint", elementAtPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "attributesOfColumnHeaders", attributesOfColumnHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "attributesOfRowHeaders", attributesOfRowHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -586,7 +619,8 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "cellForColumnAndRow", cellForColumnAndRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "titleUIElement", titleUIElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setSelectedTextRange", setSelectedTextRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
-        { "attributeValue", attributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "stringAttributeValue", stringAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "boolAttributeValue", boolAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isAttributeSupported", isAttributeSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isAttributeSettable", isAttributeSettableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isActionSupported", isActionSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -600,6 +634,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "ariaFlowToElementAtIndex", ariaFlowToElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "selectedRowAtIndex", selectedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isEqual", isEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "addNotificationListener", addNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { 0, 0, 0 }
     };
 
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
index 7105ea8..4bba135 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
@@ -70,6 +70,7 @@ public:
     
     AccessibilityUIElement elementAtPoint(int x, int y);
     AccessibilityUIElement getChildAtIndex(unsigned);
+    unsigned indexOfChild(AccessibilityUIElement*);
     int childrenCount();
     AccessibilityUIElement titleUIElement();
     AccessibilityUIElement parentElement();
@@ -85,7 +86,8 @@ public:
     void showMenu();
 
     // Attributes - platform-independent implementations
-    JSStringRef attributeValue(JSStringRef attribute);
+    JSStringRef stringAttributeValue(JSStringRef attribute);
+    bool boolAttributeValue(JSStringRef attribute);
     bool isAttributeSupported(JSStringRef attribute);
     bool isAttributeSettable(JSStringRef attribute);
     bool isActionSupported(JSStringRef action);
@@ -153,6 +155,10 @@ public:
     // Table-specific
     AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row);
 
+    // Notifications
+    // Function callback should take one argument, the name of the notification.
+    bool addNotificationListener(JSObjectRef functionCallback);
+    
 private:
     static JSClassRef getJSClass();
 
diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
index 3ff7810..0380048 100644
--- a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
@@ -102,6 +102,12 @@ AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
     return 0;
 }
 
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
+{ 
+    // FIXME: implement
+    return 0;
+}
+
 JSStringRef AccessibilityUIElement::allAttributes()
 {
     // FIXME: implement
@@ -448,12 +454,18 @@ void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned le
     // FIXME: implement
 }
 
-JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute)
+JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
 {
     // FIXME: implement
     return JSStringCreateWithCharacters(0, 0);
 }
 
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+    // FIXME: implement
+    return false;
+}
+
 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
 {
     // FIXME: implement
@@ -534,3 +546,10 @@ JSStringRef AccessibilityUIElement::url()
     // FIXME: implement
     return JSStringCreateWithCharacters(0, 0);
 }
+
+bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
+{
+    // FIXME: implement
+    return false;
+}
+
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
index 2e96280..0c9708a 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -52,8 +52,11 @@
 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
 #endif
 
- at interface NSObject (WebKitAccessibilityArrayCategory)
+typedef void (*AXPostedNotificationCallback)(id element, NSString* notification);
+
+ at interface NSObject (WebKitAccessibilityAdditions)
 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
+- (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function;
 @end
 
 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
@@ -237,6 +240,11 @@ AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
     return AccessibilityUIElement(element); 
 }
 
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
+{
+    return [m_element accessibilityIndexOfChild:element->platformUIElement()];
+}
+
 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
 {
     Vector<AccessibilityUIElement> children;
@@ -337,7 +345,7 @@ JSStringRef AccessibilityUIElement::allAttributes()
     return [attributes createJSStringRef];
 }
 
-JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute)
+JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
 {
     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
     if (![value isKindOfClass:[NSString class]])
@@ -345,6 +353,15 @@ JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute)
     return [value createJSStringRef];
 }
 
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+    id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
+    if (![value isKindOfClass:[NSNumber class]])
+        return NULL;
+    
+    return [value boolValue];
+}
+
 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
 {
     return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]];
@@ -727,3 +744,26 @@ JSStringRef AccessibilityUIElement::url()
     NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute];
     return [[url absoluteString] createJSStringRef];    
 }
+
+// The JavaScript callback we'll use when we get a notification
+static JSObjectRef AXNotificationFunctionCallback = 0;
+
+static void _accessibilityNotificationCallback(id element, NSString* notification)
+{
+    if (!AXNotificationFunctionCallback)
+        return;
+    
+    JSValueRef argument = JSValueMakeString([mainFrame globalContext], JSStringCreateWithCFString((CFStringRef)notification));    
+    JSObjectCallAsFunction([mainFrame globalContext], AXNotificationFunctionCallback, NULL, 1, &argument, NULL);
+}
+
+bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
+{
+    if (!functionCallback)
+        return false;
+ 
+    AXNotificationFunctionCallback = functionCallback;
+    [platformUIElement() accessibilitySetPostedNotificationCallback:_accessibilityNotificationCallback];
+    return true;
+}
+
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
index cce24c0..1668bbc 100644
--- a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
@@ -98,6 +98,12 @@ AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
     return COMPtr<IAccessible>(Query, child);
 }
 
+unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
+{ 
+    // FIXME: implement
+    return 0;
+}
+
 JSStringRef AccessibilityUIElement::allAttributes()
 {
     return JSStringCreateWithCharacters(0, 0);
@@ -403,11 +409,18 @@ void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned le
 {
 }
 
-JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute)
+JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
 {
+    // FIXME: implement
     return JSStringCreateWithCharacters(0, 0);
 }
 
+bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
+{
+    // FIXME: implement
+    return false;
+}
+
 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
 {
     return false;
@@ -484,3 +497,10 @@ JSStringRef AccessibilityUIElement::url()
     return JSStringCreateWithCharacters(0, 0);
 }
 
+bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
+{
+    // FIXME: implement
+    return false;
+}
+
+

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list