Commit b8ae4a5e authored by bdakin@apple.com's avatar bdakin@apple.com

WebKitTools:

2008-06-25  Beth Dakin  <bdakin@apple.com>

        Reviewed by Sam Weinig.

        This patch adds support to the AccessibilityController to query the 
        following attributes specifically, without a full attribute dump: 
        AXRole, AXTitle, and AXDescription.

        * DumpRenderTree/AccessibilityController.cpp:
        (allAttributesForFocusedElementCallback):
        (roleOfFocusedElementCallback):
        (titleOfFocusedElementCallback):
        (descriptionOfFocusedElementCallback):
        (AccessibilityController::staticFunctions):
        * DumpRenderTree/AccessibilityController.h:
        * DumpRenderTree/mac/AccessibilityControllerMac.mm:
        (AccessibilityController::allAttributesForFocusedElement):
        (concatenateAttributeAndValue):
        (AccessibilityController::roleOfFocusedElement):
        (AccessibilityController::titleOfFocusedElement):
        (AccessibilityController::descriptionOfFocusedElement):

LayoutTests:

2008-06-25  Beth Dakin  <bdakin@apple.com>

        Reviewed by Sam Weinig.

        New tests that exercise the ability to query the following 
        accessibility attributes individually: role, title, and 
        description.

        * accessibility/aria-describedby-on-input-expected.txt: Added.
        * accessibility/aria-describedby-on-input.html: Added.
        * accessibility/aria-labelledby-on-input-expected.txt: Added.
        * accessibility/aria-labelledby-on-input.html: Added.
        * accessibility/aria-roles-expected.txt: Added.
        * accessibility/aria-roles.html: Added.
        * accessibility/document-attributes.html:
        * accessibility/resources: Added.
        * accessibility/resources/cake.png: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34802 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 880c7a4f
2008-06-25 Beth Dakin <bdakin@apple.com>
Reviewed by Sam Weinig.
New tests that exercise the ability to query the following
accessibility attributes individually: role, title, and
description.
* accessibility/aria-describedby-on-input-expected.txt: Added.
* accessibility/aria-describedby-on-input.html: Added.
* accessibility/aria-labelledby-on-input-expected.txt: Added.
* accessibility/aria-labelledby-on-input.html: Added.
* accessibility/aria-roles-expected.txt: Added.
* accessibility/aria-roles.html: Added.
* accessibility/document-attributes.html:
* accessibility/resources: Added.
* accessibility/resources/cake.png: Added.
2008-06-25 Justin Garcia <justin.garcia@apple.com>
Reviewed by John.
This computer will self-destruct in minutes.
Allows you to specify the number of minutes after which the computer will self-destruct.
The accessibility description is "AXDescription: Allows you to specify the number of minutes after which the computer will self-destruct.
"
<html>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
<body>
<span id="message">This computer will self-destruct in</span>
<input id="time" type="text" value="10" aria-describedby="description"/>
<span id="unit"> minutes.</span>
<div id="description">Allows you to specify the number of minutes after which the computer will self-destruct.</div>
<div id="result"></div>
<script>
if (window.accessibilityController) {
var labeledItem = document.getElementById("time");
labeledItem.focus();
var result = document.getElementById("result");
result.innerText = "\nThe accessibility description is \""
+ accessibilityController.descriptionOfFocusedElement()
+ "\"";
}
</script>
</body>
</html>
This computer will self-destruct in minutes.
The accessibility title is "AXTitle: This computer will self-destruct in
10 minutes.
"
<html>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
<body>
<span id="message">This computer will self-destruct in</span>
<input id="time" type="text" value="10" aria-labelledby="message time unit"/>
<span id="unit"> minutes.</span>
<div id="result"></div>
<script>
if (window.accessibilityController) {
var labeledItem = document.getElementById("time");
labeledItem.focus();
var result = document.getElementById("result");
result.innerText = "\nThe accessibility title is \"" + accessibilityController.titleOfFocusedElement() + "\"";
}
</script>
</body>
</html>
The following should be a checkbox:
X
Actual checkboxes:
Broccoli
Asparagus
This test PASSES in DumpRenderTree. The role is AXRole: AXCheckBox
The following should be a button:
X
Actual button:
Hello This test PASSES in DumpRenderTree. The role is AXRole: AXButton
The following should be a heading:
X
Actual heading:
Hello
This test PASSES in DumpRenderTree. The role is AXRole: AXHeading
The following should be a link:
X
Actual link:
Hello This test PASSES in DumpRenderTree. The role is AXRole: AXLink
The following should be a radio button:
X
Actual radio buttons:
Broccoli
Asparagus
This test PASSES in DumpRenderTree. The role is AXRole: AXRadioButton
The following should be a text box:
X
Actual text box:
This test PASSES in DumpRenderTree. The role is AXRole: AXTextArea
The following should be an image:
X
Actual image:
This test PASSES in DumpRenderTree. The role is AXRole: AXImage
The following should be a list:
X
Actual list:
Broccoli
Beets
This test PASSES in DumpRenderTree. The role is AXRole: AXGroup
The following should be a slider:
X
Actual slider:
This test PASSES in DumpRenderTree. The role is AXRole: AXGroup
<html>
<head>
<title>ARIA roles simple tests</title>
<style>
.newRole {
border: 2px solid blue;
background-color: lightblue;
}
</style>
</head>
<body>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
function validateRole(aria, real, result) {
if (!window.accessibilityController)
return;
aria.focus();
var ariaRole = accessibilityController.roleOfFocusedElement();
real.focus();
var realRole = accessibilityController.roleOfFocusedElement();
if (ariaRole == realRole)
result.innerText = "This test PASSES in DumpRenderTree. The role is " + ariaRole;
else
result.innerText = "This test FAILS in DumpRenderTree. The ARIA role is " + ariaRole + ", but the real role is "
+ realRole;
}
</script>
<!--Checkbox-->
<div class="newRole">
<p>The following should be a checkbox:</p>
<p><span tabindex="0" role="checkbox" id="ariaCheckBox">X</span></p>
<p>Actual checkboxes:</p>
<form>
<input type="checkbox" name="broccoli" id="realCheckBox">Broccoli<br>
<input type="checkbox" name="asparagus">Asparagus<br>
</form>
<span id="resultCheckBox"></span>
<script>
validateRole(document.getElementById('ariaCheckBox'),
document.getElementById('realCheckBox'),
document.getElementById('resultCheckBox'));
</script>
</div>
<br/>
<!--Button-->
<div class="newRole">
<p>The following should be a button:</p>
<p><span tabindex="0" role="button" id="ariaButton">X</span></p>
<p>Actual button:</p>
<button id="realButton">Hello</button>
<span id="resultButton"></span>
<script>
validateRole(document.getElementById('ariaButton'),
document.getElementById('realButton'),
document.getElementById('resultButton'));
</script>
</div>
<br/>
<!--Heading-->
<div class="newRole">
<p>The following should be a heading:</p>
<p><span tabindex="0" role="heading" id="ariaHeading">X</span></p>
<p>Actual heading:</p>
<h1 id="realHeading">Hello</h1>
<span id="resultHeading"></span>
<script>
validateRole(document.getElementById('ariaHeading'),
document.getElementById('realHeading'),
document.getElementById('resultHeading'));
</script>
</div>
<br/>
<!--Link-->
<div class="newRole">
<p>The following should be a link:</p>
<p><span tabindex="0" role="link" id="ariaLink">X</span></p>
<p>Actual link:</p>
<a href="/" id="realLink">Hello</a>
<span id="resultLink"></span>
<script>
validateRole(document.getElementById('ariaLink'),
document.getElementById('realLink'),
document.getElementById('resultLink'));
</script>
</div>
<br/>
<!--Radio-->
<div class="newRole">
<p>The following should be a radio button:</p>
<p><span tabindex="0" role="radio" id="ariaRadio">X</span></p>
<p>Actual radio buttons:</p>
<form>
<input type="radio" name="broccoli" id="realRadio">Broccoli<br>
<input type="radio" name="asparagus">Asparagus<br>
</form>
<span id="resultRadio"></span>
<script>
validateRole(document.getElementById('ariaRadio'),
document.getElementById('realRadio'),
document.getElementById('resultRadio'));
</script>
</div>
<br/>
<!--Textbox-->
<div class="newRole">
<p>The following should be a text box:</p>
<p><span tabindex="0" role="textbox" id="ariaTextBox">X</span></p>
<p>Actual text box:</p>
<textarea id="realTextBox">Hello</textarea>
<span id="resultTextBox"></span>
<script>
validateRole(document.getElementById('ariaTextBox'),
document.getElementById('realTextBox'),
document.getElementById('resultTextBox'));
</script>
</div>
<br/>
<!--Image-->
<div class="newRole">
<p>The following should be an image:</p>
<p><span tabindex="0" role="img" alt="Hello" id="ariaImage">X</span></p>
<p>Actual image:</p>
<img src="resources/cake.png" alt="Giant cupcake" tabindex="0" id="realImage"></img>
<span id="resultImage"></span>
<script>
validateRole(document.getElementById('ariaImage'),
document.getElementById('realImage'),
document.getElementById('resultImage'));
</script>
</div>
<br/>
<!--List-->
<div class="newRole">
<p>The following should be a list:</p>
<p><span tabindex="0" role="list" id="ariaList">X</span></p>
<p>Actual list:</p>
<ul id="realList">
<li>Broccoli</li>
<li>Beets</li>
</ul>
<span id="resultList"></span>
<script>
validateRole(document.getElementById('ariaList'),
document.getElementById('realList'),
document.getElementById('resultList'));
</script>
</div>
<br/>
<!--Slider-->
<div class="newRole">
<p>The following should be a slider:</p>
<p><span tabindex="0" role="slider" id="ariaSlider">X</span></p>
<p>Actual slider:</p>
<input type="range" tabindex=0 id="realSlider"></input>
<span id="resultSlider"></span>
<script>
validateRole(document.getElementById('ariaSlider'),
document.getElementById('realSlider'),
document.getElementById('resultSlider'));
</script>
</div>
<br/>
</body>
</html>
......@@ -12,7 +12,7 @@
onload = function()
{
if (window.accessibilityController)
log(accessibilityController.dumpCurrentAttributes());
log(accessibilityController.allAttributesOfFocusedElement());
else
log("This test requires DumpRenderTree to run.")
}
......
2008-06-25 Beth Dakin <bdakin@apple.com>
Reviewed by Sam Weinig.
This patch adds support to the AccessibilityController to query the
following attributes specifically, without a full attribute dump:
AXRole, AXTitle, and AXDescription.
* DumpRenderTree/AccessibilityController.cpp:
(allAttributesForFocusedElementCallback):
(roleOfFocusedElementCallback):
(titleOfFocusedElementCallback):
(descriptionOfFocusedElementCallback):
(AccessibilityController::staticFunctions):
* DumpRenderTree/AccessibilityController.h:
* DumpRenderTree/mac/AccessibilityControllerMac.mm:
(AccessibilityController::allAttributesForFocusedElement):
(concatenateAttributeAndValue):
(AccessibilityController::roleOfFocusedElement):
(AccessibilityController::titleOfFocusedElement):
(AccessibilityController::descriptionOfFocusedElement):
2008-06-24 Dan Bernstein <mitz@apple.com>
Reviewed by Stephanie Lewis.
......
......@@ -35,13 +35,34 @@ AccessibilityController::~AccessibilityController()
{
}
static JSValueRef dumpCurrentAttributesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
static JSValueRef allAttributesOfFocusedElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
JSRetainPtr<JSStringRef> attributes(Adopt, controller->dumpCurrentAttributes());
JSRetainPtr<JSStringRef> attributes(Adopt, controller->allAttributesOfFocusedElement());
return JSValueMakeString(context, attributes.get());
}
static JSValueRef roleOfFocusedElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
JSRetainPtr<JSStringRef> role(Adopt, controller->roleOfFocusedElement());
return JSValueMakeString(context, role.get());
}
static JSValueRef titleOfFocusedElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
JSRetainPtr<JSStringRef> title(Adopt, controller->titleOfFocusedElement());
return JSValueMakeString(context, title.get());
}
static JSValueRef descriptionOfFocusedElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityController* controller = reinterpret_cast<AccessibilityController*>(JSObjectGetPrivate(thisObject));
JSRetainPtr<JSStringRef> description(Adopt, controller->descriptionOfFocusedElement());
return JSValueMakeString(context, description.get());
}
// Object Creation
void AccessibilityController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
......@@ -71,7 +92,10 @@ JSClassRef AccessibilityController::getJSClass()
JSStaticFunction* AccessibilityController::staticFunctions()
{
static JSStaticFunction staticFunctions[] = {
{ "dumpCurrentAttributes", dumpCurrentAttributesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "allAttributesOfFocusedElement", allAttributesOfFocusedElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "roleOfFocusedElement", roleOfFocusedElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "titleOfFocusedElement", titleOfFocusedElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "descriptionOfFocusedElement", descriptionOfFocusedElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
......
......@@ -36,7 +36,10 @@ public:
void makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception);
// Controller Methods - platfrom independant implementations
JSStringRef dumpCurrentAttributes();
JSStringRef allAttributesOfFocusedElement();
JSStringRef roleOfFocusedElement();
JSStringRef titleOfFocusedElement();
JSStringRef descriptionOfFocusedElement();
private:
static JSClassRef getJSClass();
......
......@@ -60,7 +60,7 @@ static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObjec
return [valueObject description];
}
JSStringRef AccessibilityController::dumpCurrentAttributes()
JSStringRef AccessibilityController::allAttributesOfFocusedElement()
{
WebHTMLView* view = [[mainFrame frameView] documentView];
id accessibilityObject = [view accessibilityFocusedUIElement];
......@@ -86,3 +86,41 @@ JSStringRef AccessibilityController::dumpCurrentAttributes()
return JSStringCreateWithCharacters(buffer.data(), buffer.size());
}
static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
{
Vector<UniChar> buffer([attribute length]);
[attribute getCharacters:buffer.data()];
buffer.append(':');
buffer.append(' ');
Vector<UniChar> valueBuffer([value length]);
[value getCharacters:valueBuffer.data()];
buffer.append(valueBuffer);
return JSStringCreateWithCharacters(buffer.data(), buffer.size());
}
JSStringRef AccessibilityController::roleOfFocusedElement()
{
WebHTMLView* view = [[mainFrame frameView] documentView];
id accessibilityObject = [view accessibilityFocusedUIElement];
NSString* role = descriptionOfValue([accessibilityObject accessibilityAttributeValue:@"AXRole"], accessibilityObject);
return concatenateAttributeAndValue(@"AXRole", role);
}
JSStringRef AccessibilityController::titleOfFocusedElement()
{
WebHTMLView* view = [[mainFrame frameView] documentView];
id accessibilityObject = [view accessibilityFocusedUIElement];
NSString* title = descriptionOfValue([accessibilityObject accessibilityAttributeValue:@"AXTitle"], accessibilityObject);
return concatenateAttributeAndValue(@"AXTitle", title);
}
JSStringRef AccessibilityController::descriptionOfFocusedElement()
{
WebHTMLView* view = [[mainFrame frameView] documentView];
id accessibilityObject = [view accessibilityFocusedUIElement];
id description = descriptionOfValue([accessibilityObject accessibilityAttributeValue:@"AXDescription"], accessibilityObject);
return concatenateAttributeAndValue(@"AXDescription", description);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment