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

cfleizach at apple.com cfleizach at apple.com
Wed Apr 7 23:33:07 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit e4784ce5e0967a9e9fec111c2a8aa9e3432a4722
Author: cfleizach at apple.com <cfleizach at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Nov 12 05:26:01 2009 +0000

    need to implement aria tree roles
    https://bugs.webkit.org/show_bug.cgi?id=31284
    
    Reviewed by Oliver Hunt.
    
    WebCore:
    
    Tests: platform/mac/accessibility/aria-multiselectable.html
           platform/mac/accessibility/aria-tree.html
    
    * accessibility/AccessibilityList.cpp:
    (WebCore::AccessibilityList::accessibilityIsIgnored):
    * accessibility/AccessibilityObject.cpp:
    (WebCore::AccessibilityObject::ariaTreeRows):
    (WebCore::AccessibilityObject::ariaTreeItemContent):
    (WebCore::AccessibilityObject::ariaTreeItemDisclosedRows):
    * accessibility/AccessibilityObject.h:
    (WebCore::):
    (WebCore::AccessibilityObject::isTree):
    (WebCore::AccessibilityObject::isTreeItem):
    (WebCore::AccessibilityObject::setIsExpanded):
    (WebCore::AccessibilityObject::canSetExpandedAttribute):
    (WebCore::AccessibilityObject::hierarchicalLevel):
    (WebCore::AccessibilityObject::setSelectedRows):
    (WebCore::AccessibilityObject::performDefaultAction):
    * accessibility/AccessibilityRenderObject.cpp:
    (WebCore::AccessibilityRenderObject::hierarchicalLevel):
    (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
    (WebCore::AccessibilityRenderObject::isExpanded):
    (WebCore::AccessibilityRenderObject::setElementAttributeValue):
    (WebCore::AccessibilityRenderObject::elementAttributeValue):
    (WebCore::AccessibilityRenderObject::setIsExpanded):
    (WebCore::AccessibilityRenderObject::isSelected):
    (WebCore::AccessibilityRenderObject::setSelected):
    (WebCore::AccessibilityRenderObject::setSelectedRows):
    (WebCore::createARIARoleMap):
    (WebCore::AccessibilityRenderObject::canSetExpandedAttribute):
    (WebCore::AccessibilityRenderObject::ariaTreeSelectedRows):
    (WebCore::AccessibilityRenderObject::ariaListboxSelectedChildren):
    (WebCore::AccessibilityRenderObject::selectedChildren):
    * accessibility/AccessibilityRenderObject.h:
    * accessibility/mac/AccessibilityObjectMac.mm:
    (WebCore::AccessibilityObject::accessibilityPlatformIncludesObject):
    * accessibility/mac/AccessibilityObjectWrapper.mm:
    (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
    (RoleEntry::):
    (-[AccessibilityObjectWrapper subrole]):
    (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
    (-[AccessibilityObjectWrapper accessibilityIsAttributeSettable:]):
    (-[AccessibilityObjectWrapper accessibilityPerformShowMenuAction]):
    (-[AccessibilityObjectWrapper accessibilitySetValue:forAttribute:]):
    (-[AccessibilityObjectWrapper accessibilityArrayAttributeCount:]):
    * html/HTMLAttributeNames.in:
    
    WebKitTools:
    
    * DumpRenderTree/AccessibilityUIElement.cpp:
    (disclosedRowAtIndexCallback):
    (selectedRowAtIndexCallback):
    (isEqualCallback):
    (isAttributeSettableCallback):
    (isActionSupportedCallback):
    (disclosedByRowCallback):
    (hierarchicalLevelCallback):
    (AccessibilityUIElement::getJSClass):
    * DumpRenderTree/AccessibilityUIElement.h:
    (AccessibilityUIElement::isEqual):
    * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp:
    (AccessibilityUIElement::hierarchicalLevel):
    (AccessibilityUIElement::disclosedRowAtIndex):
    (AccessibilityUIElement::selectedRowAtIndex):
    (AccessibilityUIElement::disclosedByRow):
    * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
    (AccessibilityUIElement::getChildAtIndex):
    (AccessibilityUIElement::disclosedRowAtIndex):
    (AccessibilityUIElement::selectedRowAtIndex):
    (AccessibilityUIElement::titleUIElement):
    (AccessibilityUIElement::parentElement):
    (AccessibilityUIElement::disclosedByRow):
    (AccessibilityUIElement::hierarchicalLevel):
    * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
    (AccessibilityUIElement::hierarchicalLevel):
    (AccessibilityUIElement::disclosedRowAtIndex):
    (AccessibilityUIElement::selectedRowAtIndex):
    (AccessibilityUIElement::disclosedByRow):
    
    LayoutTests:
    
    * accessibility/aria-readonly-expected.txt:
    * accessibility/aria-readonly.html:
    * platform/mac/accessibility/aria-multiselectable-expected.txt: Added.
    * platform/mac/accessibility/aria-multiselectable.html: Added.
    * platform/mac/accessibility/aria-tree-expected.txt: Added.
    * platform/mac/accessibility/aria-tree.html: Added.
    * platform/mac/accessibility/content-editable-expected.txt:
    * platform/mac/accessibility/radio-button-group-members-expected.txt:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50865 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e1a7bc6..75414f4 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2009-11-11  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        need to implement aria tree roles
+        https://bugs.webkit.org/show_bug.cgi?id=31284
+
+        * accessibility/aria-readonly-expected.txt:
+        * accessibility/aria-readonly.html:
+        * platform/mac/accessibility/aria-multiselectable-expected.txt: Added.
+        * platform/mac/accessibility/aria-multiselectable.html: Added.
+        * platform/mac/accessibility/aria-tree-expected.txt: Added.
+        * platform/mac/accessibility/aria-tree.html: Added.
+        * platform/mac/accessibility/content-editable-expected.txt:
+        * platform/mac/accessibility/radio-button-group-members-expected.txt:
+
 2009-11-11  Fumitoshi Ukai  <ukai at chromium.org>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/accessibility/aria-readonly-expected.txt b/LayoutTests/accessibility/aria-readonly-expected.txt
index 2220523..feadc06 100644
--- a/LayoutTests/accessibility/aria-readonly-expected.txt
+++ b/LayoutTests/accessibility/aria-readonly-expected.txt
@@ -4,12 +4,12 @@ This tests that the aria-readonly attribute works. The first and third text fiel
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS succeeded is 0
-PASS succeeded is 1
-PASS succeeded is 0
-PASS succeeded is 1
-PASS succeeded is 0
-PASS succeeded is 1
+PASS succeeded is false
+PASS succeeded is true
+PASS succeeded is false
+PASS succeeded is true
+PASS succeeded is false
+PASS succeeded is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/accessibility/aria-readonly.html b/LayoutTests/accessibility/aria-readonly.html
index 764d5a3..fa21757 100644
--- a/LayoutTests/accessibility/aria-readonly.html
+++ b/LayoutTests/accessibility/aria-readonly.html
@@ -27,27 +27,27 @@ var successfullyParsed = false;
           body.focus();
           var textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(0);
           var succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "0");
+          shouldBe("succeeded", "false");
 
           textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(1);
           succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "1");
+          shouldBe("succeeded", "true");
           
           textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(2);
           succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "0");
+          shouldBe("succeeded", "false");
             
           textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(3);
           succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "1");
+          shouldBe("succeeded", "true");
           
           textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(4);
           succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "0");
+          shouldBe("succeeded", "false");
 
           textField = accessibilityController.focusedElement.childAtIndex(0).childAtIndex(5);
           succeeded = textField.isAttributeSettable("AXValue");
-          shouldBe("succeeded", "1");
+          shouldBe("succeeded", "true");
     }
 
     successfullyParsed = true;
diff --git a/LayoutTests/platform/mac/accessibility/aria-multiselectable-expected.txt b/LayoutTests/platform/mac/accessibility/aria-multiselectable-expected.txt
new file mode 100644
index 0000000..e83599b
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-multiselectable-expected.txt
@@ -0,0 +1,18 @@
+Siamese
+Tabby
+This tests that aria trees that are multi selectable will return the right selected rows.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS treeitem1.role is 'AXRole: AXRow'
+PASS treeitem1.subrole is 'AXSubrole: AXOutlineRow'
+PASS treeitem2.role is 'AXRole: AXRow'
+PASS treeitem2.subrole is 'AXSubrole: AXOutlineRow'
+PASS selectedRow1.isEqual(treeitem1) is true
+PASS selectedRow2.isEqual(treeitem2) is true
+PASS selectedRow1.isEqual(treeitem2) is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/aria-multiselectable.html b/LayoutTests/platform/mac/accessibility/aria-multiselectable.html
new file mode 100644
index 0000000..10c05a1
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-multiselectable.html
@@ -0,0 +1,60 @@
+<!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">
+
+<ul id="tree" role="tree" aria-multiselectable="true" tabindex="0">
+    <li id="treeitem1" role="treeitem"><span>Siamese</span></li>
+    <li id="treeitem2" role="treeitem"><span>Tabby</span></li>
+</ul>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that aria trees that are multi selectable will return the right selected rows.");
+
+    if (window.accessibilityController) {
+
+          var tree = document.getElementById("tree");
+          tree.focus();
+
+          // Test tree attributes.
+          tree = accessibilityController.focusedElement;
+
+          var treeitem1 = tree.childAtIndex(0);
+          shouldBe("treeitem1.role", "'AXRole: AXRow'");
+          shouldBe("treeitem1.subrole", "'AXSubrole: AXOutlineRow'");
+          document.getElementById("treeitem1").setAttribute("aria-selected", true);
+
+          var treeitem2 = tree.childAtIndex(1);
+          shouldBe("treeitem2.role", "'AXRole: AXRow'");
+          shouldBe("treeitem2.subrole", "'AXSubrole: AXOutlineRow'");
+          document.getElementById("treeitem2").setAttribute("aria-selected", true);
+
+          // Test that the tree will give us both rows as selected (since its multi-selectable)
+          var selectedRow1 = tree.selectedRowAtIndex(0);
+          var selectedRow2 = tree.selectedRowAtIndex(1);
+
+          shouldBe("selectedRow1.isEqual(treeitem1)", "true");          
+          shouldBe("selectedRow2.isEqual(treeitem2)", "true");
+
+          // Test that if one of the items becomes de-selected, we still get the right selected row.
+          document.getElementById("treeitem1").setAttribute("aria-selected", false);
+          selectedRow1 = tree.selectedRowAtIndex(0);
+          shouldBe("selectedRow1.isEqual(treeitem2)", "true");          
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/accessibility/aria-tree-expected.txt b/LayoutTests/platform/mac/accessibility/aria-tree-expected.txt
new file mode 100644
index 0000000..7410164
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-tree-expected.txt
@@ -0,0 +1,36 @@
+Animals
+Birds
+Cats
+Siamese
+Tabby
+This tests that aria trees and tree items are converted into AXOutlines and AXRows, with all the right attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS tree.role is 'AXRole: AXOutline'
+PASS canSetRows is true
+PASS tree.childrenCount is 5
+PASS treeitem1.role is 'AXRole: AXRow'
+PASS treeitem1.subrole is 'AXSubrole: AXOutlineRow'
+PASS treeitem1.isExpanded is true
+PASS treeitem1.hierarchicalLevel is 1
+PASS canSetDisclosing is true
+PASS treeitem2.role is 'AXRole: AXRow'
+PASS treeitem2.subrole is 'AXSubrole: AXOutlineRow'
+PASS treeitem2.isExpanded is false
+PASS treeitem2.hierarchicalLevel is 2
+PASS treeitem2.disclosedByRow().isEqual(treeitem1) is true
+PASS canSetDisclosing is false
+PASS treeitem3.stringValue is 'AXValue: Birds'
+PASS canSetDisclosing is false
+PASS treeitem3.role is 'AXRole: AXRow'
+PASS treeitem3.subrole is 'AXSubrole: AXOutlineRow'
+PASS treeitem3.isExpanded is true
+PASS treeitem3.isSelected is false
+PASS treeitem3.isSelected is true
+PASS selectedRow.isEqual(treeitem3) is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/aria-tree.html b/LayoutTests/platform/mac/accessibility/aria-tree.html
new file mode 100644
index 0000000..a7a3979
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/aria-tree.html
@@ -0,0 +1,99 @@
+<!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">
+
+<ul id="tree" role="tree" aria-labelledby="treelabel" aria-activedescendant="tree0_item0_2_0_1" tabindex="0">
+    <li id="treeitem1" role="treeitem" aria-level="1" aria-expanded="true">
+        <span>
+            <span class="expander"></span>
+            Animals
+            </span>
+            <ul role="group">
+                <div id="treeitem2" role="treeitem" aria-level="2"><span>Birds</span></div>
+                <li id="treeitem3" role="treeitem" aria-level="2" aria-expanded="true">
+                    <span>
+                        <span class="expander"></span>
+                        Cats
+                    </span>
+                    <ul role="group">
+                        <li id="tree0_item0_1_0" role="treeitem"aria-level="3"><span>Siamese</span></li>
+                        <li id="tree0_item0_1_1" role="treeitem" aria-level="3"><span>Tabby</span></li>
+                    </ul>
+                </li>
+            </ul>
+        </span>
+    </li>
+</ul>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that aria trees and tree items are converted into AXOutlines and AXRows, with all the right attributes.");
+
+    if (window.accessibilityController) {
+
+          var tree = document.getElementById("tree");
+          tree.focus();
+
+          // Test tree attributes.
+          tree = accessibilityController.focusedElement;
+          shouldBe("tree.role", "'AXRole: AXOutline'");
+          var canSetRows = tree.isAttributeSettable('AXSelectedRows');
+          shouldBe("canSetRows", "true");
+          shouldBe("tree.childrenCount", "5");
+      
+          // Test tree item attributes.
+          var treeitem1 = tree.childAtIndex(0);
+          shouldBe("treeitem1.role", "'AXRole: AXRow'");
+          shouldBe("treeitem1.subrole", "'AXSubrole: AXOutlineRow'");
+          shouldBe("treeitem1.isExpanded", "true");
+          shouldBe("treeitem1.hierarchicalLevel", "1");
+          var canSetDisclosing = treeitem1.isAttributeSettable('AXDisclosing');
+          shouldBe("canSetDisclosing", "true");
+          
+          // Test more tree item attributes as we dive i,
+          var treeitem2 = treeitem1.disclosedRowAtIndex(0);
+          shouldBe("treeitem2.role", "'AXRole: AXRow'");
+          shouldBe("treeitem2.subrole", "'AXSubrole: AXOutlineRow'");
+          shouldBe("treeitem2.isExpanded", "false");
+          shouldBe("treeitem2.hierarchicalLevel", "2");
+          shouldBe("treeitem2.disclosedByRow().isEqual(treeitem1)", "true");
+          canSetDisclosing = treeitem2.isAttributeSettable('AXDisclosing');
+          shouldBe("canSetDisclosing", "false");
+
+          var treeitem3 = treeitem2.childAtIndex(0);
+          shouldBe("treeitem3.stringValue", "'AXValue: Birds'");
+          canSetDisclosing = treeitem3.isAttributeSettable('AXDisclosing');
+          shouldBe("canSetDisclosing", "false");
+
+          // Test more AXRow attributes and values as we dive further in.
+          treeitem3 = treeitem1.disclosedRowAtIndex(1);
+          shouldBe("treeitem3.role", "'AXRole: AXRow'");
+          shouldBe("treeitem3.subrole", "'AXSubrole: AXOutlineRow'");
+          shouldBe("treeitem3.isExpanded", "true");
+  
+          // test that the row can be selected correctly.
+          shouldBe("treeitem3.isSelected", "false");
+          document.getElementById("treeitem3").setAttribute("aria-selected", true);
+          shouldBe("treeitem3.isSelected", "true");
+
+          // Test that the tree reports the right selected row (treeitem3)
+          var selectedRow = tree.selectedRowAtIndex(0);
+          shouldBe("selectedRow.isEqual(treeitem3)", "true");          
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/accessibility/content-editable-expected.txt b/LayoutTests/platform/mac/accessibility/content-editable-expected.txt
index 96884a3..3c9e944 100644
--- a/LayoutTests/platform/mac/accessibility/content-editable-expected.txt
+++ b/LayoutTests/platform/mac/accessibility/content-editable-expected.txt
@@ -1,4 +1,4 @@
 Text
-Is settable: 1
+Is settable: true
 
 
diff --git a/LayoutTests/platform/mac/accessibility/radio-button-group-members-expected.txt b/LayoutTests/platform/mac/accessibility/radio-button-group-members-expected.txt
index c8004dc..69940f8 100644
--- a/LayoutTests/platform/mac/accessibility/radio-button-group-members-expected.txt
+++ b/LayoutTests/platform/mac/accessibility/radio-button-group-members-expected.txt
@@ -18,7 +18,7 @@ AXStartTextMarker: <AXRadioButton>
 AXEndTextMarker: <AXRadioButton>
 AXVisited: 0
 AXLinkedUIElements: <array of size 3>
-AXSelected: 0
+AXSelected: 1
 AXBlockQuoteLevel: 0
 AXTopLevelUIElement: <AXRadioButton>
 AXTitleUIElement: (null)
@@ -100,7 +100,7 @@ AXStartTextMarker: <AXRadioButton>
 AXEndTextMarker: <AXRadioButton>
 AXVisited: 0
 AXLinkedUIElements: <array of size 2>
-AXSelected: 0
+AXSelected: 1
 AXBlockQuoteLevel: 0
 AXTopLevelUIElement: <AXRadioButton>
 AXTitleUIElement: (null)
@@ -156,7 +156,7 @@ AXStartTextMarker: <AXRadioButton: 'Yes'>
 AXEndTextMarker: <AXRadioButton: 'Yes'>
 AXVisited: 0
 AXLinkedUIElements: <array of size 2>
-AXSelected: 0
+AXSelected: 1
 AXBlockQuoteLevel: 0
 AXTopLevelUIElement: <AXRadioButton: 'Yes'>
 AXTitleUIElement: (null)
@@ -212,7 +212,7 @@ AXStartTextMarker: <AXRadioButton>
 AXEndTextMarker: <AXRadioButton>
 AXVisited: 0
 AXLinkedUIElements: <array of size 1>
-AXSelected: 0
+AXSelected: 1
 AXBlockQuoteLevel: 0
 AXTopLevelUIElement: <AXRadioButton>
 AXTitleUIElement: (null)
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 69df18e..803b8a5 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,57 @@
+2009-11-11  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        need to implement aria tree roles
+        https://bugs.webkit.org/show_bug.cgi?id=31284
+
+        Tests: platform/mac/accessibility/aria-multiselectable.html
+               platform/mac/accessibility/aria-tree.html
+
+        * accessibility/AccessibilityList.cpp:
+        (WebCore::AccessibilityList::accessibilityIsIgnored):
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::ariaTreeRows):
+        (WebCore::AccessibilityObject::ariaTreeItemContent):
+        (WebCore::AccessibilityObject::ariaTreeItemDisclosedRows):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::):
+        (WebCore::AccessibilityObject::isTree):
+        (WebCore::AccessibilityObject::isTreeItem):
+        (WebCore::AccessibilityObject::setIsExpanded):
+        (WebCore::AccessibilityObject::canSetExpandedAttribute):
+        (WebCore::AccessibilityObject::hierarchicalLevel):
+        (WebCore::AccessibilityObject::setSelectedRows):
+        (WebCore::AccessibilityObject::performDefaultAction):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::hierarchicalLevel):
+        (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
+        (WebCore::AccessibilityRenderObject::isExpanded):
+        (WebCore::AccessibilityRenderObject::setElementAttributeValue):
+        (WebCore::AccessibilityRenderObject::elementAttributeValue):
+        (WebCore::AccessibilityRenderObject::setIsExpanded):
+        (WebCore::AccessibilityRenderObject::isSelected):
+        (WebCore::AccessibilityRenderObject::setSelected):
+        (WebCore::AccessibilityRenderObject::setSelectedRows):
+        (WebCore::createARIARoleMap):
+        (WebCore::AccessibilityRenderObject::canSetExpandedAttribute):
+        (WebCore::AccessibilityRenderObject::ariaTreeSelectedRows):
+        (WebCore::AccessibilityRenderObject::ariaListboxSelectedChildren):
+        (WebCore::AccessibilityRenderObject::selectedChildren):
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/mac/AccessibilityObjectMac.mm:
+        (WebCore::AccessibilityObject::accessibilityPlatformIncludesObject):
+        * accessibility/mac/AccessibilityObjectWrapper.mm:
+        (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
+        (RoleEntry::):
+        (-[AccessibilityObjectWrapper subrole]):
+        (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
+        (-[AccessibilityObjectWrapper accessibilityIsAttributeSettable:]):
+        (-[AccessibilityObjectWrapper accessibilityPerformShowMenuAction]):
+        (-[AccessibilityObjectWrapper accessibilitySetValue:forAttribute:]):
+        (-[AccessibilityObjectWrapper accessibilityArrayAttributeCount:]):
+        * html/HTMLAttributeNames.in:
+
 2009-11-11  Brent Fulgham  <bfulgham at webkit.org>
 
         Build fix after @r50760 with ENABLE_FILTERS.
diff --git a/WebCore/accessibility/AccessibilityList.cpp b/WebCore/accessibility/AccessibilityList.cpp
index 95239b0..f90fe0a 100644
--- a/WebCore/accessibility/AccessibilityList.cpp
+++ b/WebCore/accessibility/AccessibilityList.cpp
@@ -55,6 +55,10 @@ PassRefPtr<AccessibilityList> AccessibilityList::create(RenderObject* renderer)
 
 bool AccessibilityList::accessibilityIsIgnored() const
 {
+    // Is the platform interested in the object?
+    if (accessibilityPlatformIncludesObject() == IgnoreObject)
+        return true;
+    
     // lists don't appear on tiger/leopard on the mac
 #if ACCESSIBILITY_LISTS
     return false;
diff --git a/WebCore/accessibility/AccessibilityObject.cpp b/WebCore/accessibility/AccessibilityObject.cpp
index 7009c6e..215660f 100644
--- a/WebCore/accessibility/AccessibilityObject.cpp
+++ b/WebCore/accessibility/AccessibilityObject.cpp
@@ -753,6 +753,53 @@ AccessibilityObject* AccessibilityObject::anchorElementForNode(Node* node)
     return anchorRenderer->document()->axObjectCache()->getOrCreate(anchorRenderer);
 }
     
+void AccessibilityObject::ariaTreeRows(AccessibilityChildrenVector& result)
+{
+    AccessibilityChildrenVector axChildren = children();
+    unsigned count = axChildren.size();
+    for (unsigned k = 0; k < count; ++k) {
+        AccessibilityObject* obj = axChildren[k].get();
+        
+        // Add tree items as the rows.
+        if (obj->roleValue() == TreeItemRole) 
+            result.append(obj);
+
+        // Now see if this item also has rows hiding inside of it.
+        obj->ariaTreeRows(result);
+    }
+}
+    
+void AccessibilityObject::ariaTreeItemContent(AccessibilityChildrenVector& result)
+{
+    // The ARIA tree item content are the item that are not other tree items or their containing groups.
+    AccessibilityChildrenVector axChildren = children();
+    unsigned count = axChildren.size();
+    for (unsigned k = 0; k < count; ++k) {
+        AccessibilityObject* obj = axChildren[k].get();
+        AccessibilityRole role = obj->roleValue();
+        if (role == TreeItemRole || role == GroupRole)
+            continue;
+        
+        result.append(obj);
+    }
+}
+
+void AccessibilityObject::ariaTreeItemDisclosedRows(AccessibilityChildrenVector& result)
+{
+    AccessibilityChildrenVector axChildren = children();
+    unsigned count = axChildren.size();
+    for (unsigned k = 0; k < count; ++k) {
+        AccessibilityObject* obj = axChildren[k].get();
+        
+        // Add tree items as the rows.
+        if (obj->roleValue() == TreeItemRole)
+            result.append(obj);
+        // If it's not a tree item, then descend into the group to find more tree items.
+        else 
+            obj->ariaTreeRows(result);
+    }    
+}
+    
 const String& AccessibilityObject::actionVerb() const
 {
     // FIXME: Need to add verbs for select elements.
diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h
index b1109ef..80f1287 100644
--- a/WebCore/accessibility/AccessibilityObject.h
+++ b/WebCore/accessibility/AccessibilityObject.h
@@ -164,6 +164,8 @@ enum AccessibilityRole {
     TabRole,
     TabListRole,
     TabPanelRole,
+    TreeRole,
+    TreeItemRole,
     
     // ARIA Grouping roles
     LandmarkApplicationRole,
@@ -276,6 +278,8 @@ public:
     bool isTabItem() const { return roleValue() == TabRole; }
     bool isRadioGroup() const { return roleValue() == RadioGroupRole; }
     bool isComboBox() const { return roleValue() == ComboBoxRole; }
+    bool isTree() const { return roleValue() == TreeRole; }
+    bool isTreeItem() const { return roleValue() == TreeItemRole; }
     
     virtual bool isChecked() const { return false; }
     virtual bool isEnabled() const { return false; }
@@ -292,12 +296,14 @@ public:
     virtual bool isRequired() const { return false; }
     virtual bool isLinked() const { return false; }
     virtual bool isExpanded() const { return false; }
+    virtual void setIsExpanded(bool) { }
 
     virtual bool canSetFocusAttribute() const { return false; }
     virtual bool canSetTextRangeAttributes() const { return false; }
     virtual bool canSetValueAttribute() const { return false; }
     virtual bool canSetSelectedAttribute() const { return false; }
     virtual bool canSetSelectedChildrenAttribute() const { return false; }
+    virtual bool canSetExpandedAttribute() const { return false; }
     
     virtual bool hasIntValue() const { return false; }
 
@@ -378,17 +384,18 @@ public:
     virtual FrameView* topDocumentFrameView() const { return 0; }
     virtual FrameView* documentFrameView() const;
     virtual String language() const;
-
+    virtual unsigned hierarchicalLevel() const { return 0; }
+    
     virtual void setFocused(bool) { }
     virtual void setSelectedText(const String&) { }
     virtual void setSelectedTextRange(const PlainTextRange&) { }
     virtual void setValue(const String&) { }
     virtual void setSelected(bool) { }
-
+    virtual void setSelectedRows(AccessibilityChildrenVector&) { }
+    
     virtual void makeRangeVisible(const PlainTextRange&) { }
     virtual bool press() const;
     bool performDefaultAction() const { return press(); }
-    virtual void expandObject() const { }
     
     virtual AccessibilityOrientation orientation() const;
     virtual void increment() { }
@@ -460,7 +467,14 @@ public:
     virtual String stringRoleForMSAA() const { return String(); }
     virtual String nameForMSAA() const { return String(); }
     virtual String descriptionForMSAA() const { return String(); }
-
+    
+    // Used by an ARIA tree to get all its rows.
+    void ariaTreeRows(AccessibilityChildrenVector&);
+    // Used by an ARIA tree item to get all of its direct rows that it can disclose.
+    void ariaTreeItemDisclosedRows(AccessibilityChildrenVector&);
+    // Used by an ARIA tree item to get only its content, and not its child tree items and groups. 
+    void ariaTreeItemContent(AccessibilityChildrenVector&);
+    
 #if HAVE(ACCESSIBILITY)
 #if PLATFORM(GTK)
     AccessibilityObjectWrapper* wrapper() const;
diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp
index 9f4658b..69a4f4a 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -712,6 +712,40 @@ String AccessibilityRenderObject::helpText() const
     return String();
 }
     
+unsigned AccessibilityRenderObject::hierarchicalLevel() const
+{
+    if (!m_renderer)
+        return 0;
+
+    Node* node = m_renderer->node();
+    if (!node || !node->isElementNode())
+        return 0;
+    Element* element = static_cast<Element*>(node);
+    String ariaLevel = element->getAttribute(aria_levelAttr);
+    if (!ariaLevel.isEmpty())
+        return ariaLevel.toInt();
+    
+    // Only tree item will calculate its level through the DOM currently.
+    if (roleValue() != TreeItemRole)
+        return 0;
+    
+    // Hierarchy leveling starts at 0.
+    // We measure tree hierarchy by the number of groups that the item is within.
+    unsigned level = 0;
+    AccessibilityObject* parent = parentObject();
+    while (parent) {
+        AccessibilityRole parentRole = parent->roleValue();
+        if (parentRole == GroupRole)
+            level++;
+        else if (parentRole == TreeRole)
+            break;
+        
+        parent = parent->parentObject();
+    }
+    
+    return level;
+}
+    
 String AccessibilityRenderObject::language() const
 {
     if (!m_renderer)
@@ -1288,7 +1322,7 @@ bool AccessibilityRenderObject::ariaIsHidden() const
 
 bool AccessibilityRenderObject::accessibilityIsIgnored() const
 {
-    // is the platform is interested in this object?
+    // Is the platform interested in this object?
     AccessibilityObjectPlatformInclusion decision = accessibilityPlatformIncludesObject();
     if (decision == IncludeObject)
         return false;
@@ -1575,27 +1609,44 @@ bool AccessibilityRenderObject::isVisited() const
     return m_renderer->style()->pseudoState() == PseudoVisited;
 }
     
-void AccessibilityRenderObject::expandObject() const
+bool AccessibilityRenderObject::isExpanded() const
+{
+    if (equalIgnoringCase(getAttribute(aria_expandedAttr).string(), "true"))
+        return true;
+    
+    return false;  
+}
+
+void AccessibilityRenderObject::setElementAttributeValue(const QualifiedName& attributeName, bool value)
 {
-    // Combo boxes can be expanded (in different ways on different platforms).
-    // That action translates into setting the aria-expanded attribute to true
-    if (roleValue() != ComboBoxRole || !m_renderer)
+    if (!m_renderer)
         return;
     
     Node* node = m_renderer->node();
     if (!node || !node->isElementNode())
         return;
-
+    
     Element* element = static_cast<Element*>(node);
-    element->setAttribute(aria_expandedAttr, "true");
+    element->setAttribute(attributeName, (value) ? "true" : "false");        
 }
     
-bool AccessibilityRenderObject::isExpanded() const
+bool AccessibilityRenderObject::elementAttributeValue(const QualifiedName& attributeName)
 {
-    if (equalIgnoringCase(getAttribute(aria_expandedAttr).string(), "true"))
-        return true;
+    if (!m_renderer)
+        return false;
     
-    return false;  
+    return equalIgnoringCase(getAttribute(attributeName).string(), "true");
+}
+    
+void AccessibilityRenderObject::setIsExpanded(bool isExpanded)
+{
+    // Combo boxes and tree items can be expanded (in different ways on different platforms).
+    // That action translates into setting the aria-expanded attribute to true.
+    AccessibilityRole role = roleValue();
+    if (role != ComboBoxRole && role != TreeItemRole)
+        return;
+    
+    setElementAttributeValue(aria_expandedAttr, isExpanded);
 }
     
 bool AccessibilityRenderObject::isRequired() const
@@ -1615,9 +1666,14 @@ bool AccessibilityRenderObject::isSelected() const
     if (!node)
         return false;
     
-    if (equalIgnoringCase(getAttribute(aria_selectedAttr).string(), "true"))
+    String ariaSelected = getAttribute(aria_selectedAttr).string();
+    if (equalIgnoringCase(ariaSelected, "true"))
         return true;    
     
+    // ARIA says that selection should follow focus unless specifically set otherwise.
+    if (!equalIgnoringCase(ariaSelected, "false") && isFocused())
+        return true;
+    
     if (isTabItem() && isTabItemSelected())
         return true;
 
@@ -1712,6 +1768,26 @@ void AccessibilityRenderObject::changeValueByPercent(float percentChange)
     axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true);
 }
     
+void AccessibilityRenderObject::setSelected(bool enabled)
+{
+    setElementAttributeValue(aria_selectedAttr, enabled);
+}
+
+void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows)
+{
+    // Setting selected rows only works on trees for now.
+    if (roleValue() != TreeRole)
+        return;
+    
+    bool isMultiselectable = elementAttributeValue(aria_multiselectableAttr);
+    unsigned count = selectedRows.size();
+    if (count > 1 && !isMultiselectable)
+        count = 1;
+    
+    for (unsigned k = 0; k < count; ++k)
+        selectedRows[k]->setSelected(true);
+}
+    
 void AccessibilityRenderObject::setValue(const String& string)
 {
     if (!m_renderer)
@@ -2407,7 +2483,9 @@ static const ARIARoleMap& createARIARoleMap()
         { "textbox", TextAreaRole },
         { "timer", ApplicationTimerRole },
         { "toolbar", ToolbarRole },
-        { "tooltip", UserInterfaceTooltipRole }
+        { "tooltip", UserInterfaceTooltipRole },
+        { "tree", TreeRole },
+        { "treeitem", TreeItemRole }
     };
     ARIARoleMap& roleMap = *new ARIARoleMap;
         
@@ -2591,6 +2669,13 @@ bool AccessibilityRenderObject::canSetFocusAttribute() const
         return false;
     }
 }
+    
+bool AccessibilityRenderObject::canSetExpandedAttribute() const
+{
+    // An object can be expanded if it aria-expanded is true or false.
+    String ariaExpanded = getAttribute(aria_expandedAttr).string();
+    return equalIgnoringCase(ariaExpanded, "true") || equalIgnoringCase(ariaExpanded, "false");
+}
 
 bool AccessibilityRenderObject::canSetValueAttribute() const
 {
@@ -2708,17 +2793,34 @@ void AccessibilityRenderObject::addChildren()
     }
 }
 
+void AccessibilityRenderObject::ariaTreeSelectedRows(AccessibilityChildrenVector& result)
+{
+    // Get all the rows. 
+    AccessibilityChildrenVector allRows;
+    ariaTreeRows(allRows);
+
+    // Determine which rows are selected.
+    bool isMultiselectable = elementAttributeValue(aria_multiselectableAttr);
+
+    unsigned count = allRows.size();
+    for (unsigned k = 0; k < count; ++k) {
+        if (allRows[k]->isSelected()) {
+            result.append(allRows[k]);
+            if (!isMultiselectable)
+                break;
+        }
+    }
+}
+    
 void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& result)
 {
     AccessibilityObject* child = firstChild();
-    bool isMultiselectable = false;
     
     Element* element = static_cast<Element*>(renderer()->node());        
     if (!element || !element->isElementNode()) // do this check to ensure safety of static_cast above
         return;
 
-    String multiselectablePropertyStr = element->getAttribute("aria-multiselectable").string();
-    isMultiselectable = equalIgnoringCase(multiselectablePropertyStr, "true");
+    bool isMultiselectable = elementAttributeValue(aria_multiselectableAttr);
     
     while (child) {
         // every child should have aria-role option, and if so, check for selected attribute/state
@@ -2746,11 +2848,11 @@ void AccessibilityRenderObject::selectedChildren(AccessibilityChildrenVector& re
     ASSERT(result.isEmpty());
 
     // only listboxes should be asked for their selected children. 
-    if (ariaRoleAttribute() != ListBoxRole) { // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
-        ASSERT_NOT_REACHED(); 
-        return;
-    }
-    return ariaListboxSelectedChildren(result);
+    AccessibilityRole role = roleValue();
+    if (role == ListBoxRole) // native list boxes would be AccessibilityListBoxes, so only check for aria list boxes
+        ariaListboxSelectedChildren(result);
+    else if (role == TreeRole)
+        ariaTreeSelectedRows(result);
 }
 
 void AccessibilityRenderObject::ariaListboxVisibleChildren(AccessibilityChildrenVector& result)      
diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h
index ba2ea24..0407422 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.h
+++ b/WebCore/accessibility/AccessibilityRenderObject.h
@@ -104,12 +104,14 @@ public:
     virtual bool isRequired() const;
     virtual bool isLinked() const;
     virtual bool isExpanded() const;
-    
+    virtual void setIsExpanded(bool);
+
     const AtomicString& getAttribute(const QualifiedName&) const;
     virtual bool canSetFocusAttribute() const;
     virtual bool canSetTextRangeAttributes() const;
     virtual bool canSetValueAttribute() const;
-    
+    virtual bool canSetExpandedAttribute() const;
+
     virtual bool hasIntValue() const;
     
     virtual bool accessibilityIsIgnored() const;
@@ -146,7 +148,6 @@ public:
     
     virtual AXObjectCache* axObjectCache() const;
     
-    virtual void expandObject() const;
     virtual Element* actionElement() const;
     Element* mouseButtonListener() const;
     FrameView* frameViewIfRenderView() const;
@@ -188,12 +189,15 @@ public:
     virtual void getDocumentLinks(AccessibilityChildrenVector&);
     virtual FrameView* documentFrameView() const;
     virtual String language() const;
-    
+    virtual unsigned hierarchicalLevel() const;
+
     virtual const AccessibilityChildrenVector& children();
     
     virtual void setFocused(bool);
     virtual void setSelectedTextRange(const PlainTextRange&);
     virtual void setValue(const String&);
+    virtual void setSelected(bool);
+    virtual void setSelectedRows(AccessibilityChildrenVector&);
     virtual void changeValueByPercent(float percentChange);
     virtual void increment();
     virtual void decrement();
@@ -262,6 +266,11 @@ private:
     AccessibilityObject* accessibilityImageMapHitTest(HTMLAreaElement*, const IntPoint&) const;
     AccessibilityObject* accessibilityParentForImageMap(HTMLMapElement* map) const;
 
+    void ariaTreeSelectedRows(AccessibilityChildrenVector&);
+    
+    bool elementAttributeValue(const QualifiedName&);
+    void setElementAttributeValue(const QualifiedName&, bool);
+    
     String accessibilityDescriptionForElements(Vector<Element*> &elements) const;
     void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& name) const;
     
diff --git a/WebCore/accessibility/mac/AccessibilityObjectMac.mm b/WebCore/accessibility/mac/AccessibilityObjectMac.mm
index 217af54..722b03e 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectMac.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectMac.mm
@@ -43,6 +43,24 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const
 
 AccessibilityObjectPlatformInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
 {
+    // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline.
+    AccessibilityObject* axObj = parentObject();
+    bool isInTree = false;
+    while (axObj) {
+        if (axObj->isTree()) {
+            isInTree = true;
+            break;
+        }
+        axObj = axObj->parentObjectUnignored();
+    }
+    
+    // If the object is in a tree, only tree items should be exposed (and the children of tree items).
+    if (isInTree) {
+        AccessibilityRole role = roleValue();
+        if (role != TreeItemRole && role != StaticTextRole)
+            return IgnoreObject;
+    }
+    
     return DefaultBehavior;
 }
     
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index 9d12dd2..c6c6372 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -602,6 +602,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
     static NSArray* passwordFieldAttrs = nil;
     static NSArray *tabListAttrs = nil;
     static NSArray *comboBoxAttrs = nil;
+    static NSArray *outlineAttrs = nil;
+    static NSArray *outlineRowAttrs = nil;
     NSMutableArray* tempArray;
     if (attributes == nil) {
         attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
@@ -809,6 +811,24 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
         tabListAttrs = [[NSArray alloc] initWithArray:tempArray];
         [tempArray release];        
     }
+    if (outlineAttrs == nil) {
+        tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+        [tempArray addObject:NSAccessibilitySelectedRowsAttribute];
+        [tempArray addObject:NSAccessibilityRowsAttribute];
+        [tempArray addObject:NSAccessibilityColumnsAttribute];
+        outlineAttrs = [[NSArray alloc] initWithArray:tempArray];
+        [tempArray release];
+    }
+    if (outlineRowAttrs == nil) {
+        tempArray = [[NSMutableArray alloc] initWithArray:tableRowAttrs];
+        [tempArray addObject:NSAccessibilityIndexAttribute];
+        [tempArray addObject:NSAccessibilityDisclosingAttribute];
+        [tempArray addObject:NSAccessibilityDisclosedByRowAttribute];
+        [tempArray addObject:NSAccessibilityDisclosureLevelAttribute];
+        [tempArray addObject:NSAccessibilityDisclosedRowsAttribute];
+        outlineRowAttrs = [[NSArray alloc] initWithArray:tempArray];
+        [tempArray release];
+    }
     
     if (m_object->isPasswordField())
         return passwordFieldAttrs;
@@ -831,6 +851,11 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
     if (m_object->isTableCell())
         return tableCellAttrs;
     
+    if (m_object->isTree())
+        return outlineAttrs;
+    if (m_object->isTreeItem())
+        return outlineRowAttrs;
+    
     if (m_object->isListBox() || m_object->isList())
         return listBoxAttrs;
 
@@ -1024,6 +1049,8 @@ static const AccessibilityRoleMap& createAccessibilityRoleMap()
         { TabRole, NSAccessibilityRadioButtonRole },
         { TabListRole, NSAccessibilityTabGroupRole },
         { TabPanelRole, NSAccessibilityGroupRole },
+        { TreeRole, NSAccessibilityOutlineRole },
+        { TreeItemRole, NSAccessibilityRowRole },
     };
     AccessibilityRoleMap& roleMap = *new AccessibilityRoleMap;
     
@@ -1062,6 +1089,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         }
     }
     
+    if (m_object->isTreeItem())
+        return NSAccessibilityOutlineRowSubrole;
+    
     if (m_object->isList()) {
         AccessibilityList* listObject = static_cast<AccessibilityList*>(m_object);
         if (listObject->isUnorderedList() || listObject->isOrderedList())
@@ -1106,8 +1136,10 @@ static NSString* roleValueToNSString(AccessibilityRole value)
             return @"AXUserInterfaceTooltip";
         case TabPanelRole:
             return @"AXTabPanel";
+
+        // Default doesn't return anything, so roles defined below can be chosen.
         default:
-            return nil;
+            break;
     }
     
     if (m_object->isMediaTimeline())
@@ -1224,6 +1256,16 @@ static NSString* roleValueToNSString(AccessibilityRole value)
                 return fv->platformWidget();
         }
         
+        // Tree item (changed to AXRows) can only report the tree (AXOutline) as its parent.
+        if (m_object->isTreeItem()) {
+            AccessibilityObject* parent = m_object->parentObjectUnignored();
+            while (parent) {
+                if (parent->isTree())
+                    return parent->wrapper();
+                parent = parent->parentObjectUnignored();
+            }
+        }
+        
         return m_object->parentObjectUnignored()->wrapper();
     }
 
@@ -1233,6 +1275,19 @@ static NSString* roleValueToNSString(AccessibilityRole value)
             if (children != nil)
                 return children;
         }
+
+        // The tree's (AXOutline) children are supposed to be its rows and columns.
+        // The ARIA spec doesn't have columns, so we just need rows.
+        if (m_object->isTree())
+            return [self accessibilityAttributeValue:NSAccessibilityRowsAttribute];
+
+        // A tree item should only expose its content as its children (not its rows)
+        if (m_object->isTreeItem()) {
+            AccessibilityObject::AccessibilityChildrenVector contentCopy;
+            m_object->ariaTreeItemContent(contentCopy);
+            return convertToNSArray(contentCopy);
+        }
+        
         return convertToNSArray(m_object->children());
     }
     
@@ -1502,6 +1557,65 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         }  
     }
     
+    if (m_object->isTree()) {
+        if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
+            AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
+            m_object->selectedChildren(selectedChildrenCopy);
+            return convertToNSArray(selectedChildrenCopy);
+        }
+        if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]) {
+            AccessibilityObject::AccessibilityChildrenVector rowsCopy;
+            m_object->ariaTreeRows(rowsCopy);
+            return convertToNSArray(rowsCopy);            
+        }
+        
+        // TreeRoles do not support columns, but Mac AX expects to be able to ask about columns at the least.
+        if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute])
+            return [NSArray array];
+    }
+
+    if (m_object->isTreeItem()) {
+        if ([attributeName isEqualToString:NSAccessibilityIndexAttribute]) {
+            AccessibilityObject* parent = m_object->parentObject();
+            if (!parent)
+                return nil;
+            
+            // Find the index of this item by iterating the parents.
+            const AccessibilityObject::AccessibilityChildrenVector& children = parent->children();
+            unsigned count = children.size();
+            for (unsigned k = 0; k < count; ++k)
+                if (children[k]->wrapper() == self)
+                    return [NSNumber numberWithUnsignedInt:k];
+            
+            return nil;
+        }
+        
+        // The rows that are considered inside this row. 
+        if ([attributeName isEqualToString:NSAccessibilityDisclosedRowsAttribute]) {
+            AccessibilityObject::AccessibilityChildrenVector rowsCopy;
+            m_object->ariaTreeItemDisclosedRows(rowsCopy);
+            return convertToNSArray(rowsCopy);    
+        }
+
+        // The row that contains this row. It should be the same as the first parent that is a treeitem.
+        if ([attributeName isEqualToString:NSAccessibilityDisclosedByRowAttribute]) {
+            AccessibilityObject* parent = m_object->parentObject();
+            while (parent) {
+                if (parent->isTreeItem())
+                    return parent->wrapper();
+                // If the parent is the tree itself, then this value == nil.
+                if (parent->isTree())
+                    return nil;
+                parent = parent->parentObject();
+            }
+            return nil;
+        }
+        if ([attributeName isEqualToString:NSAccessibilityDisclosureLevelAttribute])
+            return [NSNumber numberWithInt:m_object->hierarchicalLevel()];
+        if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
+            return [NSNumber numberWithBool:m_object->isExpanded()];
+    }
+    
     if ((m_object->isListBox() || m_object->isList()) && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
         return NSAccessibilityVerticalOrientationValue;
 
@@ -1637,6 +1751,12 @@ static NSString* roleValueToNSString(AccessibilityRole value)
     if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute])
         return m_object->canSetSelectedChildrenAttribute();
 
+    if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
+        return m_object->canSetExpandedAttribute();
+
+    if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute])
+        return YES;
+
     if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute] ||
         [attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute] ||
         [attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
@@ -1804,7 +1924,7 @@ static NSString* roleValueToNSString(AccessibilityRole value)
 - (void)accessibilityPerformShowMenuAction
 {
     if (m_object->roleValue() == ComboBoxRole)
-        m_object->expandObject();
+        m_object->setIsExpanded(true);
     else {
         // This needs to be performed in an iteration of the run loop that did not start from an AX call. 
         // If it's the same run loop iteration, the menu open notification won't be sent
@@ -1923,6 +2043,13 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         } else if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) {
             m_object->makeRangeVisible(PlainTextRange(range.location, range.length));
         }
+    } else if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
+        m_object->setIsExpanded([number boolValue]);
+    else if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
+        AccessibilityObject::AccessibilityChildrenVector selectedRows;
+        convertToVector(array, selectedRows);
+        if (m_object->isTree())
+            m_object->setSelectedRows(selectedRows);
     }
 }
 
@@ -2283,6 +2410,11 @@ static RenderObject* rendererForView(NSView* view)
         return 0;
     
     if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+        // Tree items object returns a different set of children than those that are in children()
+        // because an AXOutline (the mac role is becomes) has some odd stipulations.
+        if (m_object->isTree() || m_object->isTreeItem())
+            return [[self accessibilityAttributeValue:NSAccessibilityChildrenAttribute] count];
+        
         const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
         if (children.isEmpty())
             return [[self renderWidgetChildren] count];
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index 15cf522..df39eb9 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -23,6 +23,7 @@ aria-label
 aria-labeledby
 aria-labelledby
 aria-level
+aria-multiselectable
 aria-pressed
 aria-readonly
 aria-required
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 7c3bb22..b849e00 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,40 @@
+2009-11-11  Chris Fleizach  <cfleizach at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        need to implement aria tree roles
+        https://bugs.webkit.org/show_bug.cgi?id=31284
+
+        * DumpRenderTree/AccessibilityUIElement.cpp:
+        (disclosedRowAtIndexCallback):
+        (selectedRowAtIndexCallback):
+        (isEqualCallback):
+        (isAttributeSettableCallback):
+        (isActionSupportedCallback):
+        (disclosedByRowCallback):
+        (hierarchicalLevelCallback):
+        (AccessibilityUIElement::getJSClass):
+        * DumpRenderTree/AccessibilityUIElement.h:
+        (AccessibilityUIElement::isEqual):
+        * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp:
+        (AccessibilityUIElement::hierarchicalLevel):
+        (AccessibilityUIElement::disclosedRowAtIndex):
+        (AccessibilityUIElement::selectedRowAtIndex):
+        (AccessibilityUIElement::disclosedByRow):
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (AccessibilityUIElement::getChildAtIndex):
+        (AccessibilityUIElement::disclosedRowAtIndex):
+        (AccessibilityUIElement::selectedRowAtIndex):
+        (AccessibilityUIElement::titleUIElement):
+        (AccessibilityUIElement::parentElement):
+        (AccessibilityUIElement::disclosedByRow):
+        (AccessibilityUIElement::hierarchicalLevel):
+        * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
+        (AccessibilityUIElement::hierarchicalLevel):
+        (AccessibilityUIElement::disclosedRowAtIndex):
+        (AccessibilityUIElement::selectedRowAtIndex):
+        (AccessibilityUIElement::disclosedByRow):
+
 2009-11-11  Shinichiro Hamaji  <hamaji at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
index 20c8621..eafe61e 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
@@ -161,6 +161,35 @@ static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef functio
     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(indexNumber));
 }
 
+static JSValueRef disclosedRowAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    int indexNumber = 0;
+    if (argumentCount == 1)
+        indexNumber = JSValueToNumber(context, arguments[0], exception);
+    
+    return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->disclosedRowAtIndex(indexNumber));
+}
+
+static JSValueRef selectedRowAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    int indexNumber = 0;
+    if (argumentCount == 1)
+        indexNumber = JSValueToNumber(context, arguments[0], exception);
+    
+    return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->selectedRowAtIndex(indexNumber));
+}
+
+static JSValueRef isEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    JSObjectRef otherElement = 0;
+    if (argumentCount == 1)
+        otherElement = JSValueToObject(context, arguments[0], exception);
+    else
+        return JSValueMakeBoolean(context, false);
+    
+    return JSValueMakeBoolean(context, toAXElement(thisObject)->isEqual(toAXElement(otherElement)));
+}
+
 static JSValueRef elementAtPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     int x = 0;
@@ -173,13 +202,12 @@ static JSValueRef elementAtPointCallback(JSContextRef context, JSObjectRef funct
     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->elementAtPoint(x, y));
 }
 
-
 static JSValueRef isAttributeSettableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     JSStringRef attribute = NULL;
     if (argumentCount == 1)
         attribute = JSValueToStringCopy(context, arguments[0], exception);    
-    JSValueRef result = JSValueMakeNumber(context, toAXElement(thisObject)->isAttributeSettable(attribute));
+    JSValueRef result = JSValueMakeBoolean(context, toAXElement(thisObject)->isAttributeSettable(attribute));
     if (attribute)
         JSStringRelease(attribute);
     return result;
@@ -191,7 +219,7 @@ static JSValueRef isActionSupportedCallback(JSContextRef context, JSObjectRef fu
     JSStringRef action = 0;
     if (argumentCount == 1)
         action = JSValueToStringCopy(context, arguments[0], exception);    
-    JSValueRef result = JSValueMakeNumber(context, toAXElement(thisObject)->isActionSupported(action));
+    JSValueRef result = JSValueMakeBoolean(context, toAXElement(thisObject)->isActionSupported(action));
     if (action)
         JSStringRelease(action);
     return result;
@@ -230,6 +258,11 @@ static JSValueRef parentElementCallback(JSContextRef context, JSObjectRef functi
     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->parentElement());
 }
 
+static JSValueRef disclosedByRowCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->disclosedByRow());
+}
+
 static JSValueRef setSelectedTextRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     unsigned location = UINT_MAX, length = 0;
@@ -379,6 +412,11 @@ static JSValueRef getIsExpandedCallback(JSContextRef context, JSObjectRef thisOb
     return JSValueMakeBoolean(context, toAXElement(thisObject)->isExpanded());
 }
 
+static JSValueRef hierarchicalLevelCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
+{
+    return JSValueMakeNumber(context, toAXElement(thisObject)->hierarchicalLevel());
+}
+
 static JSValueRef getValueDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
     JSRetainPtr<JSStringRef> valueDescription(Adopt, toAXElement(thisObject)->valueDescription());
@@ -432,6 +470,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "isSelected", getIsSelectedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isExpanded", getIsExpandedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "valueDescription", getValueDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "hierarchicalLevel", hierarchicalLevelCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { 0, 0, 0, 0 }
     };
 
@@ -462,9 +501,13 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "isAttributeSettable", isAttributeSettableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isActionSupported", isActionSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "parentElement", parentElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "disclosedByRow", disclosedByRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "increment", incrementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "decrement", decrementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "showMenu", showMenuCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "disclosedRowAtIndex", disclosedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "selectedRowAtIndex", selectedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "isEqual", isEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { 0, 0, 0 }
     };
 
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
index 1feacde..8800cbe 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
@@ -61,6 +61,8 @@ public:
 
     static JSObjectRef makeJSAccessibilityUIElement(JSContextRef, const AccessibilityUIElement&);
 
+    bool isEqual(AccessibilityUIElement* otherElement) { return platformUIElement() == otherElement->platformUIElement(); }
+    
     void getLinkedUIElements(Vector<AccessibilityUIElement>&);
     void getDocumentLinks(Vector<AccessibilityUIElement>&);
     void getChildren(Vector<AccessibilityUIElement>&);
@@ -107,6 +109,7 @@ public:
     bool isRequired() const;
     bool isSelected() const;
     bool isExpanded() const;
+    int hierarchicalLevel() const;
     double clickPointX();
     double clickPointY();
 
@@ -121,6 +124,11 @@ public:
     JSStringRef rowIndexRange();
     JSStringRef columnIndexRange();
     
+    // Tree/Outline specific attributes
+    AccessibilityUIElement selectedRowAtIndex(unsigned);
+    AccessibilityUIElement disclosedByRow();
+    AccessibilityUIElement disclosedRowAtIndex(unsigned);
+    
     // Parameterized attributes
     int lineForIndex(int);
     JSStringRef boundsForRange(unsigned location, unsigned length);
diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
index 230e06b..c1bf07d 100644
--- a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp
@@ -328,6 +328,12 @@ bool AccessibilityUIElement::isSelected() const
     return false;
 }
 
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+    // FIXME: implement
+    return 0;
+}
+
 bool AccessibilityUIElement::isExpanded() const
 {
     // FIXME: implement
@@ -450,6 +456,21 @@ void AccessibilityUIElement::showMenu()
     // FIXME: implement
 }
 
+AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
+{
+    return 0;
+}
+
 JSStringRef AccessibilityUIElement::accessibilityValue() const
 {
     // FIXME: implement
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
index 56c2cc0..7762f75 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -232,7 +232,25 @@ AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
 
     if (children.size() == 1)
         return children[0];
-    return nil;
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+{
+    NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute];
+    if (index < [rows count])
+        return [rows objectAtIndex:index];
+
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+{
+    NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute];
+    if (index < [rows count])
+        return [rows objectAtIndex:index];
+    
+    return 0;
 }
 
 AccessibilityUIElement AccessibilityUIElement::titleUIElement()
@@ -241,7 +259,7 @@ AccessibilityUIElement AccessibilityUIElement::titleUIElement()
     if (accessibilityObject)
         return AccessibilityUIElement(accessibilityObject);
     
-    return nil;
+    return 0;
 }
 
 AccessibilityUIElement AccessibilityUIElement::parentElement()
@@ -250,7 +268,16 @@ AccessibilityUIElement AccessibilityUIElement::parentElement()
     if (accessibilityObject)
         return AccessibilityUIElement(accessibilityObject);
     
-    return nil;
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
+{
+    id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute];
+    if (accessibilityObject)
+        return AccessibilityUIElement(accessibilityObject);
+    
+    return 0;
 }
 
 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
@@ -455,6 +482,14 @@ bool AccessibilityUIElement::isExpanded() const
     return false;
 }
 
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+    id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute];
+    if ([value isKindOfClass:[NSNumber class]])
+        return [value intValue];
+    return 0;
+}
+
 // parameterized attributes
 int AccessibilityUIElement::lineForIndex(int index)
 {
diff --git a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
index 3008782..8e20078 100644
--- a/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
@@ -257,6 +257,11 @@ bool AccessibilityUIElement::isSelected() const
     return false;
 }
 
+int AccessibilityUIElement::hierarchicalLevel() const
+{
+    return 0;
+}
+
 bool AccessibilityUIElement::isExpanded() const
 {
     return false;
@@ -400,6 +405,21 @@ void AccessibilityUIElement::showMenu()
 {
 }
 
+AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
+{
+    return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
+{
+    return 0;
+}
+
 JSStringRef AccessibilityUIElement::accessibilityValue() const
 {
     BSTR valueBSTR;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list