[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.17-1283-gcf603cf
cfleizach at apple.com
cfleizach at apple.com
Wed Jan 6 00:21:30 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 033cddae5409a7f7a2be18964d52a458aada0d6f
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