Title: [149858] trunk
Revision
149858
Author
[email protected]
Date
2013-05-09 17:57:24 -0700 (Thu, 09 May 2013)

Log Message

AX: VoiceOver is no longer seeing items in poorly formed tables
https://bugs.webkit.org/show_bug.cgi?id=115837

Reviewed by Darin Adler.

Source/WebCore: 

In case the author didn't include the rows of a table as the 
direct children, a table needs to dive down its descendant chain
until the rows are found. 

I also took the opportunity to clean up a bit around what the different
meanings of table are in the accessibility classes.

Test: accessibility/poorly-formed-aria-table.html

* accessibility/AccessibilityARIAGrid.cpp:
(WebCore::AccessibilityARIAGrid::addRowDescendant):
(WebCore::AccessibilityARIAGrid::addChildren):
* accessibility/AccessibilityARIAGrid.h:
(AccessibilityARIAGrid):
* accessibility/AccessibilityARIAGridRow.cpp:
(WebCore::AccessibilityARIAGridRow::parentTable):
(WebCore):
* accessibility/AccessibilityARIAGridRow.h:
(AccessibilityARIAGridRow):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::isTable):
* accessibility/AccessibilityTable.h:
(AccessibilityTable):
(WebCore::AccessibilityTable::isTable):
(WebCore::toAccessibilityTable):
* accessibility/AccessibilityTableRow.cpp:
(WebCore::AccessibilityTableRow::parentTable):

LayoutTests: 

* accessibility/poorly-formed-aria-table-expected.txt: Added.
* accessibility/poorly-formed-aria-table.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (149857 => 149858)


--- trunk/LayoutTests/ChangeLog	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/LayoutTests/ChangeLog	2013-05-10 00:57:24 UTC (rev 149858)
@@ -1,3 +1,13 @@
+2013-05-09  Chris Fleizach  <[email protected]>
+
+        AX: VoiceOver is no longer seeing items in poorly formed tables
+        https://bugs.webkit.org/show_bug.cgi?id=115837
+
+        Reviewed by Darin Adler.
+
+        * accessibility/poorly-formed-aria-table-expected.txt: Added.
+        * accessibility/poorly-formed-aria-table.html: Added.
+
 2013-05-09  Zoltan Horvath  <[email protected]>
 
         [Qt] REGRESSION (r148975) shape-inside-percentage.html and shape-inside-overflow-fixed-dimensions.html are failing after r148975

Added: trunk/LayoutTests/accessibility/poorly-formed-aria-table-expected.txt (0 => 149858)


--- trunk/LayoutTests/accessibility/poorly-formed-aria-table-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/accessibility/poorly-formed-aria-table-expected.txt	2013-05-10 00:57:24 UTC (rev 149858)
@@ -0,0 +1,12 @@
+This tests that if an ARIA table does not report the rows as its direct children, the table will still correctly report the rows.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS grid.rowAtIndex(0).isEqual(row1) is true
+PASS grid.rowAtIndex(1).isEqual(row2) is true
+PASS grid.rowCount is 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/accessibility/poorly-formed-aria-table.html (0 => 149858)


--- trunk/LayoutTests/accessibility/poorly-formed-aria-table.html	                        (rev 0)
+++ trunk/LayoutTests/accessibility/poorly-formed-aria-table.html	2013-05-10 00:57:24 UTC (rev 149858)
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script src=""
+
+<div id="content">
+
+<div role="grid" id="grid">
+  <div role="application">
+     <div role="application">
+         <div role="row" id="row1">
+            <div role="gridcell">1</div>
+         </div>
+         <div role="text">a</div>
+         <div role="row" id="row2">
+            <div role="gridcell">1</div>
+         </div>
+     </div>
+  </div>
+</div>
+
+</div>
+
+<div id="console"></div>
+<script>
+
+description("This tests that if an ARIA table does not report the rows as its direct children, the table will still correctly report the rows.")
+
+if (window.testRunner && window.accessibilityController) {
+ 
+    var grid = accessibilityController.accessibleElementById("grid");
+    var row1 = accessibilityController.accessibleElementById("row1");
+    var row2 = accessibilityController.accessibleElementById("row2");
+    
+ 
+    shouldBeTrue("grid.rowAtIndex(0).isEqual(row1)");
+    shouldBeTrue("grid.rowAtIndex(1).isEqual(row2)");
+    shouldBe("grid.rowCount", "2");
+
+    document.getElementById("content").style.visibility = 'hidden';    
+}
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (149857 => 149858)


--- trunk/Source/WebCore/ChangeLog	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/ChangeLog	2013-05-10 00:57:24 UTC (rev 149858)
@@ -1,3 +1,38 @@
+2013-05-09  Chris Fleizach  <[email protected]>
+
+        AX: VoiceOver is no longer seeing items in poorly formed tables
+        https://bugs.webkit.org/show_bug.cgi?id=115837
+
+        Reviewed by Darin Adler.
+
+        In case the author didn't include the rows of a table as the 
+        direct children, a table needs to dive down its descendant chain
+        until the rows are found. 
+
+        I also took the opportunity to clean up a bit around what the different
+        meanings of table are in the accessibility classes.
+
+        Test: accessibility/poorly-formed-aria-table.html
+
+        * accessibility/AccessibilityARIAGrid.cpp:
+        (WebCore::AccessibilityARIAGrid::addRowDescendant):
+        (WebCore::AccessibilityARIAGrid::addChildren):
+        * accessibility/AccessibilityARIAGrid.h:
+        (AccessibilityARIAGrid):
+        * accessibility/AccessibilityARIAGridRow.cpp:
+        (WebCore::AccessibilityARIAGridRow::parentTable):
+        (WebCore):
+        * accessibility/AccessibilityARIAGridRow.h:
+        (AccessibilityARIAGridRow):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::isTable):
+        * accessibility/AccessibilityTable.h:
+        (AccessibilityTable):
+        (WebCore::AccessibilityTable::isTable):
+        (WebCore::toAccessibilityTable):
+        * accessibility/AccessibilityTableRow.cpp:
+        (WebCore::AccessibilityTableRow::parentTable):
+
 2013-05-09  Yael Aharon  <[email protected]>
 
         REGRESSION: Disabled multiline select element now responds to (certain) clicks

Modified: trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp	2013-05-10 00:57:24 UTC (rev 149858)
@@ -81,7 +81,23 @@
     appendedRows.add(row);
     return true;
 }
-    
+
+void AccessibilityARIAGrid::addRowDescendant(AccessibilityObject* rowChild, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount)
+{
+    if (!rowChild)
+        return;
+
+    if (!rowChild->isTableRow()) {
+        // Although a "grid" should have rows as its direct descendants, if this is not a table row,
+        // dive deeper into the descendants to try to find a valid row.
+        AccessibilityChildrenVector children = rowChild->children();
+        size_t length = children.size();
+        for (size_t i = 0; i < length; ++i)
+            addRowDescendant(children[i].get(), appendedRows, columnCount);
+    } else
+        addTableCellChild(rowChild, appendedRows, columnCount);
+}
+
 void AccessibilityARIAGrid::addChildren()
 {
     ASSERT(!m_haveChildren); 
@@ -100,22 +116,8 @@
     // add only rows that are labeled as aria rows
     HashSet<AccessibilityObject*> appendedRows;
     unsigned columnCount = 0;
-    for (RefPtr<AccessibilityObject> child = firstChild(); child; child = child->nextSibling()) {
-
-        if (!addTableCellChild(child.get(), appendedRows, columnCount)) {
-            
-            // in case the render tree doesn't match the expected ARIA hierarchy, look at the children
-            if (!child->hasChildren())
-                child->addChildren();
-
-            // The children of this non-row will contain all non-ignored elements (recursing to find them). 
-            // This allows the table to dive arbitrarily deep to find the rows.
-            AccessibilityChildrenVector children = child->children();
-            size_t length = children.size();
-            for (size_t i = 0; i < length; ++i)
-                addTableCellChild(children[i].get(), appendedRows, columnCount);
-        }
-    }
+    for (RefPtr<AccessibilityObject> child = firstChild(); child; child = child->nextSibling())
+        addRowDescendant(child.get(), appendedRows, columnCount);
     
     // make the columns based on the number of columns in the first body
     for (unsigned i = 0; i < columnCount; ++i) {

Modified: trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.h (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.h	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityARIAGrid.h	2013-05-10 00:57:24 UTC (rev 149858)
@@ -55,6 +55,7 @@
     virtual bool isMultiSelectable() const { return true; }
     virtual bool isTableExposableThroughAccessibility() const { return true; }
     
+    void addRowDescendant(AccessibilityObject*, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount);
     bool addTableCellChild(AccessibilityObject*, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount);
 };
 

Modified: trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.cpp (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.cpp	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.cpp	2013-05-10 00:57:24 UTC (rev 149858)
@@ -116,6 +116,19 @@
     return 0;
 }
     
+AccessibilityObject* AccessibilityARIAGridRow::parentTable() const
+{
+    // The parent table might not be the direct ancestor of the row unfortunately. ARIA states that role="grid" should
+    // only have "row" elements, but if not, we still should handle it gracefully by finding the right table.
+    for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
+        // The parent table for an ARIA grid row should be an ARIA table.
+        if (parent->isTable() && parent->isAccessibilityTable() && toAccessibilityTable(parent)->isAriaTable())
+            return parent;
+    }
+    
+    return 0;
+}
+
 AccessibilityObject* AccessibilityARIAGridRow::headerObject()
 {
     AccessibilityChildrenVector rowChildren = children();

Modified: trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.h (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.h	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityARIAGridRow.h	2013-05-10 00:57:24 UTC (rev 149858)
@@ -48,6 +48,7 @@
     
 private:
     virtual bool isARIATreeGridRow() const;
+    virtual AccessibilityObject* parentTable() const;
 }; 
     
 } // namespace WebCore 

Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityObject.h	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h	2013-05-10 00:57:24 UTC (rev 149858)
@@ -413,6 +413,7 @@
     virtual bool isInputSlider() const { return false; }
     virtual bool isControl() const { return false; }
     virtual bool isList() const { return false; }
+    virtual bool isTable() const { return false; }
     virtual bool isAccessibilityTable() const { return false; }
     virtual bool isDataTable() const { return false; }
     virtual bool isTableRow() const { return false; }

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2013-05-10 00:57:24 UTC (rev 149858)
@@ -510,7 +510,7 @@
         return false;
     // Widgets are the replaced elements that we represent to AX as attachments
     bool isWidget = renderer->isWidget();
-    ASSERT(!isWidget || (renderer->isReplaced() && !isImage()));
+
     return isWidget && ariaRoleAttribute() == UnknownRole;
 }
 

Modified: trunk/Source/WebCore/accessibility/AccessibilityTable.h (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityTable.h	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityTable.h	2013-05-10 00:57:24 UTC (rev 149858)
@@ -47,9 +47,6 @@
 
     virtual void init();
 
-    virtual bool isAccessibilityTable() const;
-    virtual bool isDataTable() const;
-
     virtual AccessibilityRole roleValue() const;
     virtual bool isAriaTable() const { return false; }
     
@@ -84,13 +81,22 @@
     bool m_isAccessibilityTable;
 
     bool hasARIARole() const;
+
+    // isTable is whether it's an AccessibilityTable object.
+    virtual bool isTable() const OVERRIDE { return true; }
+    // isAccessibilityTable is whether it is exposed as an AccessibilityTable to the platform.
+    virtual bool isAccessibilityTable() const OVERRIDE;
+    // isDataTable is whether it is exposed as an AccessibilityTable because the heuristic
+    // think this "looks" like a data-based table (instead of a table used for layout).
+    virtual bool isDataTable() const OVERRIDE;
+
     virtual bool isTableExposableThroughAccessibility() const;
-    virtual bool computeAccessibilityIsIgnored() const;
+    virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
 };
     
 inline AccessibilityTable* toAccessibilityTable(AccessibilityObject* object)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isAccessibilityTable());
+    ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isTable());
     return static_cast<AccessibilityTable*>(object);
 }
     

Modified: trunk/Source/WebCore/accessibility/AccessibilityTableRow.cpp (149857 => 149858)


--- trunk/Source/WebCore/accessibility/AccessibilityTableRow.cpp	2013-05-10 00:12:25 UTC (rev 149857)
+++ trunk/Source/WebCore/accessibility/AccessibilityTableRow.cpp	2013-05-10 00:57:24 UTC (rev 149858)
@@ -102,11 +102,16 @@
     
 AccessibilityObject* AccessibilityTableRow::parentTable() const
 {
-    AccessibilityObject* parent = parentObjectUnignored();
-    if (!parent || !parent->isAccessibilityTable())
-        return 0;
+    // The parent table might not be the direct ancestor of the row unfortunately. ARIA states that role="grid" should
+    // only have "row" elements, but if not, we still should handle it gracefully by finding the right table.
+    for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
+        // If this is a table object, but not an accessibility table, we should stop because we don't want to
+        // choose another ancestor table as this row's table.
+        if (parent->isTable())
+            return parent->isAccessibilityTable() ? parent : 0;
+    }
     
-    return parent;
+    return 0;
 }
     
 AccessibilityObject* AccessibilityTableRow::headerObject()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to