+2008-08-19 chris fleizach <cfleizach@apple.com>
+
+ Reviewed by Beth Dakin
+
+ Tests for Tables through accessibility. Testing covers:
+ Attributes of tables
+ When cells have various cell spans
+ Retrieving cells
+ Detecting tables
+ When tables have multiple sections
+ When tables use the rules attribute
+
+ Tables only work on SnowLeopard, so a snow leopard folder was created
+
+ * accessibility/table-attributes-expected.txt: Added.
+ * accessibility/table-attributes.html: Added.
+ * accessibility/table-cell-spans-expected.txt: Added.
+ * accessibility/table-cell-spans.html: Added.
+ * accessibility/table-cells-expected.txt: Added.
+ * accessibility/table-cells.html: Added.
+ * accessibility/table-detection-expected.txt: Added.
+ * accessibility/table-detection.html: Added.
+ * accessibility/table-sections-expected.txt: Added.
+ * accessibility/table-sections.html: Added.
+ * accessibility/table-with-rules-expected.txt: Added.
+ * accessibility/table-with-rules.html: Added.
+ * platform/mac-snowleopard: Added.
+ * platform/mac-snowleopard/accessibility: Added.
+ * platform/mac-snowleopard/accessibility/table-attributes-expected.txt: Added.
+ * platform/mac-snowleopard/accessibility/table-cell-spans-expected.txt: Added.
+ * platform/mac-snowleopard/accessibility/table-cells-expected.txt: Added.
+ * platform/mac-snowleopard/accessibility/table-detection-expected.txt: Added.
+ * platform/mac-snowleopard/accessibility/table-sections-expected.txt: Added.
+ * platform/mac-snowleopard/accessibility/table-with-rules-expected.txt: Added.
+
2008-08-19 Alexey Proskuryakov <ap@webkit.org>
https://bugs.webkit.org/show_bug.cgi?id=19762
--- /dev/null
+Example #1: Nested Stubs
+Ruritanian
+Population
+Survey All
+Genders By Gender
+Males Females
+All Regions North 3333 1111 2222
+South 3333 1111 2222
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+ <table id="testTable" align="center" border="1" cellpadding="5" cellspacing="0"
+ summary="This is the summary text that should appear as a description">
+ <caption> Example #1: Nested Stubs </caption>
+ <tr>
+ <th class="center" colspan="2" rowspan="2">Ruritanian<br> Population
+ <br> Survey</th>
+ <th class="center" rowspan="2">All<br> Genders</th>
+
+ <th class="center" colspan="2">By Gender</th>
+ </tr>
+ <tr>
+ <th class="center">Males</th>
+ <th class="center">Females</th>
+ </tr>
+ <tr>
+
+ <th align="left" rowspan="2">All Regions</th>
+ <th>North</th>
+ <td align="right">3333</td>
+ <td align="right">1111</td>
+ <td align="right">2222</td>
+ </tr>
+
+ <tr>
+ <th>South</th>
+ <td align="right">3333</td>
+ <td align="right">1111</td>
+ <td align="right">2222</td>
+ </tr>
+ </table>
+
+ <div id="result"></div>
+
+ <script>
+ if (window.accessibilityController) {
+ var body = document.getElementById("body");
+ body.focus();
+ var table = accessibilityController.focusedElement.childAtIndex(0);
+
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumnHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRowHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumns() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRows() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfVisibleCells() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfHeader() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+Cell A
+COLSPAN="2"
+ROWSPAN="2" Cell B
+COLSPAN="2"
+2,3 2,4
+Cell C
+ROWSPAN="2" 3,2 3,3 3,4
+4,2 4,3 4,4
+----------------------
+{ 0, 0 }
+
+{0, 0}, {0, 0}
+
+----------------------
+{ 1, 1 }
+
+{0, 0}, {0, 0}
+
+----------------------
+{ 3, 0 }
+
+{0, 0}, {0, 0}
+
+----------------------
+{ 2, 0 }
+
+{0, 0}, {0, 0}
+
+----------------------
+{ 2, 3 }
+
+{0, 0}, {0, 0}
+
+----------------------
+{ 10, 10 }
+
+{0, 0}, {0, 0}
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+ <!-- Test image map -->
+ <table id="testTable" align="center" border="1" cellpadding="5" cellspacing="0">
+ <tr>
+ <td class="center" colspan="2" rowspan="2" width="50%">Cell A<br>
+ COLSPAN="2"<br> ROWSPAN="2"</td>
+
+ <td class="center" colspan="2">Cell B<br> COLSPAN="2"</td>
+ </tr>
+ <tr>
+ <td class="center">2,3</td>
+ <td class="center">2,4</td>
+ </tr>
+
+ <tr class="center">
+ <td class="center" rowspan="2">Cell C<br> ROWSPAN="2"</td>
+ <td class="center" width="25%">3,2</td>
+ <td class="center">3,3</td>
+ <td class="center">3,4</td>
+ </tr>
+
+ <tr>
+ <td class="center">4,2</td>
+ <td class="center">4,3</td>
+ <td class="center">4,4</td>
+ </tr>
+ </table>
+
+ <div id="result"></div>
+
+
+ <script>
+ if (window.accessibilityController) {
+ var result = document.getElementById("result");
+
+ var body = document.getElementById("body");
+ body.focus();
+ var table = accessibilityController.focusedElement.childAtIndex(0);
+
+ var cell = table.cellForColumnAndRow(0,0);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 0, 0 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+
+ var cell = table.cellForColumnAndRow(1,1);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 1, 1 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+
+ var cell = table.cellForColumnAndRow(0,3);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 3, 0 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+
+ cell = table.cellForColumnAndRow(0,2);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 2, 0 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+
+ cell = table.cellForColumnAndRow(3,2);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 2, 3 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+
+ cell = table.cellForColumnAndRow(10,10);
+ result.innerText += "----------------------\n";
+ result.innerText += "{ 10, 10 }\n";
+ result.innerText += cell.allAttributes() + "\n";
+ result.innerText += cell.rowIndexRange() + ", " + cell.columnIndexRange() + "\n\n";
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+Example #1: Nested Stubs
+Ruritanian
+Population
+Survey All
+Genders By Gender
+Males Females
+All Regions North 3333 1111 2222
+South 3333 1111 2222
+South 3333 1111 2222
+South 3333 1111 2222
+------------------------
+[0,0]
+
+------------------------
+[3,1]
+
+------------------------
+[1,1]
+
+------------------------
+[2,2]
+
+------------------------
+[3,5]
+
+------------------------
+[100,0]
+
+------------------------
+[0,100]
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+
+ <table id="testTable" align="center" border="1" cellpadding="5" cellspacing="0">
+ <caption> Example #1: Nested Stubs </caption>
+ <tr>
+ <th class="center" colspan="2" rowspan="2">Ruritanian<br> Population
+ <br> Survey</th>
+ <th class="center" rowspan="2">All<br> Genders</th>
+
+ <th class="center" colspan="2">By Gender</th>
+ </tr>
+ <tr>
+ <th class="center">Males</th>
+ <th class="center">Females</th>
+ </tr>
+ <tr>
+
+ <th align="left" rowspan="2">All Regions</th>
+ <th>North</th>
+ <td align="right">3333</td>
+ <td align="right">1111</td>
+ <td align="right">2222</td>
+ </tr>
+
+ <tr>
+ <th>South</th>
+ <td align="right">3333</td>
+ <td align="right">1111</td>
+ <td align="right">2222</td>
+ </tr>
+ <tr>
+ <th>South</th>
+ <td align="right">3333</td>
+ <td align="right" colspan="2">1111</td>
+ <td align="right">2222</td>
+ </tr>
+ <tr>
+ <th>South</th>
+ <td align="right" colspan="2">3333</td>
+ <td align="right">1111</td>
+ <td align="right">2222</td>
+ </tr>
+ </table>
+
+ <div id="result"></div>
+
+ <script>
+ if (window.accessibilityController) {
+ var result = document.getElementById("result");
+
+ var body = document.getElementById("body");
+ body.focus();
+ var table = accessibilityController.focusedElement.childAtIndex(0);
+
+ result.innerText += "------------------------\n";
+ result.innerText += "[0,0]\n" + table.cellForColumnAndRow(0,0).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[3,1]\n" + table.cellForColumnAndRow(3,1).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[1,1]\n" + table.cellForColumnAndRow(1,1).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[2,2]\n" + table.cellForColumnAndRow(2,2).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[3,5]\n" + table.cellForColumnAndRow(3,5).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[100,0]\n" + table.cellForColumnAndRow(100,0).allAttributes() + "\n";
+ result.innerText += "------------------------\n";
+ result.innerText += "[0,100]\n" + table.cellForColumnAndRow(0,100).allAttributes() + "\n";
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+This should be a table because it has a thead
+asdf asdf
+asdf asdf
+This should be a table because cells have borders
+asdf asdf
+This should not be a table because it's cells do not have borders
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+asdf asdf
+// This should be a table because cells have different colors
+asdf asdf
+// This should not be a table because cells have different but no spacing
+asdf asdf
+// This should not be a table because cells have the same colors even though there is spacing
+asdf asdf
+// this should be a table because it has the "rules" attr
+asdf asdf
+--------------------------
+
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+
+
+--------------------------
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+ This should be a table because it has a thead
+ <table border=0>
+ <thead><tr><td>asdf</td><td>asdf</td></tr></thead>
+ <tr><td>asdf</td><td>asdf</td></tr>
+ </table>
+
+ This should be a table because cells have borders
+ <table border=1>
+ <tr><td >asdf</td><td>asdf</td></tr>
+ </table>
+
+ This should not be a table because it's cells do not have borders
+ <table style='border: 1px solid black'>
+ <tr><td >asdf</td><td>asdf</td></tr>
+ </table>
+
+ // This should be a table because a cell has a special attribute
+ <table border=0 cellpadding=0>
+ <tr><td abbr="abbr tag">asdf</td><td>asdf</td></tr>
+ </table>
+
+ // This should be a table because a cell has a special attribute
+ <table border=0 cellpadding=0>
+ <tr><td axis="abbr tag">asdf</td><td>asdf</td></tr>
+ </table>
+
+ // This should be a table because a cell has a special attribute
+ <table border=0 cellpadding=0>
+ <tr><td id="test">asdf</td><td>asdf</td></tr>
+ <tr><td headers="test">asdf</td><td>asdf</td></tr>
+ </table>
+
+ // This should be a table because cells have different colors
+ <table border=0 cellpadding=0>
+ <tr><td bgcolor="red">asdf</td><td bgcolor="blue">asdf</td></tr>
+ </table>
+
+ // This should not be a table because cells have different but no spacing
+ <table border=0 cellpadding=0 cellspacing=0>
+ <tr><td style="background-color: red;">asdf</td><td style="background-color: blue;">asdf</td></tr>
+ </table>
+
+ // This should not be a table because cells have the same colors even though there is spacing
+ <table border=0 cellpadding=0 bgcolor="green" cellspacing=3>
+ <tr><td style="background-color: green;">asdf</td><td style="background-color: green;">asdf</td></tr>
+ </table>
+
+ // this should be a table because it has the "rules" attr
+ <table rules="cols" border=0 cellpadding=0>
+ <tr><td>asdf</td><td>asdf</td></tr>
+ </table>
+
+ <div id="result"></div>
+
+ <script>
+ if (window.accessibilityController) {
+ var body = document.getElementById("body");
+ body.focus();
+ var table = accessibilityController.focusedElement;
+
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfChildren() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+Example #1: Nested Stubs
+1 a b
+1 e f
+1 c d
+1 c1 d1
+
+
+1 a b
+1 c d
+1 c1 d1
+1 c d
+1 c1 d1
+1 c d
+1 c1 d1
+1 e f
+--------------------------
+THEAD, TFOOT table
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+--------------------------
+Multi-TBODY table
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
+
+--------------------------
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+ <table id="testTable" align="center" border="1" cellpadding="5" cellspacing="0"
+ summary="This is the summary text that should appear as a description">
+ <caption> Example #1: Nested Stubs </caption>
+ <thead><tr><th>1</th><th>a</th><td>b</td></tr></thead>
+ <tfoot><tr><td>1</td><td>e</td><td>f</td></tr></tfoot>
+ <tr><th>1</th><td>c</td><td>d</td></tr>
+ <tr><th>1</th><td>c1</td><td>d1</td></tr>
+ </table>
+ <br><br>
+
+ <table id="testTable2" align="center" border="1" cellpadding="5" cellspacing="0">
+ <thead><tr><th>1</th><th>a</th><td>b</td></tr></thead>
+ <tbody>
+ <tr><th>1</th><td>c</td><td>d</td></tr>
+ <tr><th>1</th><td>c1</td><td>d1</td></tr>
+ </tbody>
+ <tbody>
+ <tr><th>1</th><td>c</td><td>d</td></tr>
+ <tr><th>1</th><td>c1</td><td>d1</td></tr>
+ </tbody>
+ <tbody>
+ <tr><th>1</th><td>c</td><td>d</td></tr>
+ <tr><th>1</th><td>c1</td><td>d1</td></tr>
+ </tbody>
+ <tfoot><tr><td>1</td><td>e</td><td>f</td></tr></tfoot>
+ </table>
+
+ <div id="result"></div>
+
+ <script>
+ if (window.accessibilityController) {
+ var body = document.getElementById("body");
+ body.focus();
+ var table = accessibilityController.focusedElement.childAtIndex(0);
+
+ result.innerText += "--------------------------\n";
+ result.innerText += "THEAD, TFOOT table\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumnHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRowHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumns() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRows() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfVisibleCells() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfHeader() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+
+ // second table
+ table1 = accessibilityController.focusedElement.childAtIndex(2);
+
+ result.innerText += "--------------------------\n";
+ result.innerText += "Multi-TBODY table\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumnHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRowHeaders() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfColumns() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfRows() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfVisibleCells() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+ result.innerText += table.attributesOfHeader() + "\n\n";
+ result.innerText += "--------------------------\n\n";
+
+
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+asdf asdf
+asdf asdf
+asdf asdf
+asdf asdf
+asdf asdf
+
+------------------------------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+
--- /dev/null
+<html>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<body id="body">
+
+ <table id="testTable1" rules="rows"><tr><td>asdf</td><td>asdf</td></tr></table>
+ <table id="testTable2" rules="all"><tr><td>asdf</td><td>asdf</td></tr></table>
+ <table id="testTable3" rules="col"><tr><td>asdf</td><td>asdf</td></tr></table>
+ <table id="testTable4" rules="groups"><tr><td>asdf</td><td>asdf</td></tr></table>
+ <table id="testTable5"><tr><td>asdf</td><td>asdf</td></tr></table>
+
+ <BR>------------------------------------<BR>
+
+ <div id="result"></div>
+
+ <script>
+ if (window.accessibilityController) {
+ var result = document.getElementById("result");
+ var body = document.getElementById("body");
+ body.focus();
+
+ // these should be the tables. in this order
+ // the last two tables should not show up as tables
+ for (var k = 1; k < 6; k++) {
+ var table = accessibilityController.focusedElement.childAtIndex(k);
+ result.innerText += table.allAttributes() + "\n\n";
+ }
+ }
+ </script>
+</body>
+</html>
--- /dev/null
+Example #1: Nested Stubs
+Ruritanian
+Population
+Survey All
+Genders By Gender
+Males Females
+All Regions North 3333 1111 2222
+South 3333 1111 2222
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 2>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {69, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {119, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {3, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {119, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {3, 2}
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {52, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {90, 60}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 2}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {53, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 2>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {143, 126}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 0
+AXHeader: <AXColumn>
+AXRows: <array of size 2>
+AXVisibleRows: <array of size 2>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {143, 126}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 1
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {69, 126}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 2
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {119, 126}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 3
+AXHeader: <AXColumn>
+AXRows: <array of size 4>
+AXVisibleRows: <array of size 4>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {119, 126}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 4
+AXHeader: <AXColumn>
+AXRows: <array of size 4>
+AXVisibleRows: <array of size 4>
+
+------------
+
+
+--------------------------
+
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {331, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 0
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 2>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {331, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 1
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 5>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {331, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 2
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 4>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {331, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 3
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 2>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {69, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {119, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {3, 2}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {52, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {67, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {4, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {90, 60}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 2}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {53, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {69, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {52, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {67, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {4, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {53, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {69, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {52, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {67, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {4, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 5>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {331, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+
+------------
+
+
+--------------------------
+
+
--- /dev/null
+Cell A
+COLSPAN="2"
+ROWSPAN="2" Cell B
+COLSPAN="2"
+2,3 2,4
+Cell C
+ROWSPAN="2" 3,2 3,3 3,4
+4,2 4,3 4,4
+----------------------
+{ 0, 0 }
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {246, 78}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+{0, 2}, {0, 2}
+
+----------------------
+{ 1, 1 }
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {246, 78}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+{0, 2}, {0, 2}
+
+----------------------
+{ 3, 0 }
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 2>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {123, 60}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 2}
+AXColumnIndexRange: NSRange: {0, 1}
+
+{2, 2}, {0, 1}
+
+----------------------
+{ 2, 0 }
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 2>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {123, 60}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 2}
+AXColumnIndexRange: NSRange: {0, 1}
+
+{2, 2}, {0, 1}
+
+----------------------
+{ 2, 3 }
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {123, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+{2, 1}, {3, 1}
+
+----------------------
+{ 10, 10 }
+
+{0, 0}, {0, 0}
+
+
--- /dev/null
+Example #1: Nested Stubs
+Ruritanian
+Population
+Survey All
+Genders By Gender
+Males Females
+All Regions North 3333 1111 2222
+South 3333 1111 2222
+South 3333 1111 2222
+South 3333 1111 2222
+------------------------
+[0,0]
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------------------
+[3,1]
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {52, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------------------
+[1,1]
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {143, 66}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 2}
+AXColumnIndexRange: NSRange: {0, 2}
+
+------------------------
+[2,2]
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {69, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------------------
+[3,5]
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXCell>
+AXSize: NSSize: {52, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {5, 1}
+AXColumnIndexRange: NSRange: {3, 1}
+
+------------------------
+[100,0]
+
+------------------------
+[0,100]
+
+
--- /dev/null
+This should be a table because it has a thead
+asdf asdf
+asdf asdf
+This should be a table because cells have borders
+asdf asdf
+This should not be a table because it's cells do not have borders
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+// This should be a table because a cell has a special attribute
+asdf asdf
+asdf asdf
+// This should be a table because cells have different colors
+asdf asdf
+// This should not be a table because cells have different but no spacing
+asdf asdf
+// This should not be a table because cells have the same colors even though there is spacing
+asdf asdf
+// this should be a table because it has the "rules" attr
+asdf asdf
+--------------------------
+
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 5>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {62, 48}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 2>
+AXVisibleRows: <array of size 2>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 4>
+AXColumnHeaderUIElements: <array of size 2>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {68, 28}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {58, 22}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {58, 22}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 5>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {58, 42}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 2>
+AXVisibleRows: <array of size 2>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 4>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {58, 22}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {55, 18}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+------------
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 1>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {784, 36}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXGroup>
+AXEndTextMarker: <AXGroup>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+------------
+
+
+--------------------------
+
+
--- /dev/null
+Example #1: Nested Stubs
+1 a b
+1 e f
+1 c d
+1 c1 d1
+
+
+1 a b
+1 c d
+1 c1 d1
+1 c d
+1 c1 d1
+1 c d
+1 c1 d1
+1 e f
+--------------------------
+THEAD, TFOOT table
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {20, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 0
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {27, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 1
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {28, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 2
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+
+
+--------------------------
+
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 0
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 1
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 2
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 3
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+
+------------
+
+
+--------------------------
+
+--------------------------
+Multi-TBODY table
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {20, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 0
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {27, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 1
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+AXRole: AXColumn
+AXSubrole: (null)
+AXRoleDescription: column
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXColumn>
+AXSize: NSSize: {28, 90}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXColumn>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+AXIndex: 2
+AXHeader: <AXColumn>
+AXRows: <array of size 3>
+AXVisibleRows: <array of size 3>
+
+------------
+
+
+--------------------------
+
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 0
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 1
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 2
+
+------------
+AXRole: AXRow
+AXSubrole: (null)
+AXRoleDescription: row
+AXChildren: <array of size 3>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXRow>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXRow>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXRow>
+AXEndTextMarker: <AXRow>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXIndex: 3
+
+------------
+
+
+--------------------------
+
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {0, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {1, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {2, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {20, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {0, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {27, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {1, 1}
+
+------------
+AXRole: AXCell
+AXSubrole: (null)
+AXRoleDescription: cell
+AXChildren: <array of size 1>
+AXHelp: This is the summary text that should appear as a description
+AXParent: <AXCell>
+AXSize: NSSize: {28, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXCell>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXCell>
+AXEndTextMarker: <AXCell>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRowIndexRange: NSRange: {3, 1}
+AXColumnIndexRange: NSRange: {2, 1}
+
+------------
+
+
+--------------------------
+
+AXRole: AXGroup
+AXSubrole: (null)
+AXRoleDescription: group
+AXChildren: <array of size 3>
+AXHelp:
+AXParent: <AXGroup>
+AXSize: NSSize: {75, 30}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 0
+AXWindow: <AXGroup>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: (null)
+AXEndTextMarker: (null)
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: (null)
+
+------------
+
+
+--------------------------
+
+
--- /dev/null
+asdf asdf
+asdf asdf
+asdf asdf
+asdf asdf
+asdf asdf
+
+------------------------------------
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {59, 22}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {62, 24}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+
+AXRole: AXTable
+AXSubrole: (null)
+AXRoleDescription: table
+AXChildren: <array of size 4>
+AXHelp:
+AXParent: <AXTable>
+AXSize: NSSize: {56, 22}
+AXTitle:
+AXDescription:
+AXValue:
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXTable>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXTable>
+AXEndTextMarker: <AXTable>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXRows: <array of size 1>
+AXVisibleRows: <array of size 1>
+AXColumns: <array of size 2>
+AXVisibleColumns: <array of size 2>
+AXVisibleCells: <array of size 2>
+AXColumnHeaderUIElements: <array of size 0>
+AXRowHeaderUIElements: <array of size 0>
+AXHeader: <AXTable>
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+AXRole: AXStaticText
+AXSubrole: (null)
+AXRoleDescription: text
+AXChildren: <array of size 0>
+AXHelp:
+AXParent: <AXStaticText>
+AXSize: NSSize: {26, 18}
+AXTitle:
+AXDescription:
+AXValue: asdf
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXStaticText>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXStaticText>
+AXEndTextMarker: <AXStaticText>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+
+
+
+2008-08-19 chris fleizach <cfleizach@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ <rdar://problem/4003764> Expose tables as AXTables
+
+ Tests: accessibility/table-attributes.html
+ accessibility/table-cell-spans.html
+ accessibility/table-cells.html
+ accessibility/table-detection.html
+ accessibility/table-sections.html
+ accessibility/table-with-rules.html
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::get):
+ * page/AccessibilityObject.h:
+ (WebCore::):
+ (WebCore::AccessibilityObject::isDataTable):
+ (WebCore::AccessibilityObject::isTableRow):
+ (WebCore::AccessibilityObject::isTableColumn):
+ (WebCore::AccessibilityObject::isTableCell):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::canSetFocusAttribute):
+ * page/AccessibilityTable.cpp: Added.
+ (WebCore::AccessibilityTable::AccessibilityTable):
+ (WebCore::AccessibilityTable::~AccessibilityTable):
+ (WebCore::AccessibilityTable::create):
+ (WebCore::AccessibilityTable::isTableExposableThroughAccessibility):
+ (WebCore::AccessibilityTable::clearChildren):
+ (WebCore::AccessibilityTable::addChildren):
+ (WebCore::AccessibilityTable::headerContainer):
+ (WebCore::AccessibilityTable::columns):
+ (WebCore::AccessibilityTable::rows):
+ (WebCore::AccessibilityTable::rowHeaders):
+ (WebCore::AccessibilityTable::columnHeaders):
+ (WebCore::AccessibilityTable::cells):
+ (WebCore::AccessibilityTable::columnCount):
+ (WebCore::AccessibilityTable::rowCount):
+ (WebCore::AccessibilityTable::cellForColumnAndRow):
+ (WebCore::AccessibilityTable::roleValue):
+ (WebCore::AccessibilityTable::accessibilityIsIgnored):
+ (WebCore::AccessibilityTable::title):
+ (WebCore::AccessibilityTable::isDataTable):
+ * page/AccessibilityTable.h: Added.
+ * page/AccessibilityTableCell.cpp: Added.
+ (WebCore::AccessibilityTableCell::AccessibilityTableCell):
+ (WebCore::AccessibilityTableCell::~AccessibilityTableCell):
+ (WebCore::AccessibilityTableCell::create):
+ (WebCore::AccessibilityTableCell::accessibilityIsIgnored):
+ (WebCore::AccessibilityTableCell::rowIndexRange):
+ (WebCore::AccessibilityTableCell::columnIndexRange):
+ * page/AccessibilityTableCell.h: Added.
+ (WebCore::AccessibilityTableCell::isTableCell):
+ (WebCore::AccessibilityTableCell::roleValue):
+ * page/AccessibilityTableColumn.cpp: Added.
+ (WebCore::AccessibilityTableColumn::AccessibilityTableColumn):
+ (WebCore::AccessibilityTableColumn::~AccessibilityTableColumn):
+ (WebCore::AccessibilityTableColumn::create):
+ (WebCore::AccessibilityTableColumn::setParentTable):
+ (WebCore::AccessibilityTableColumn::elementRect):
+ (WebCore::AccessibilityTableColumn::size):
+ (WebCore::AccessibilityTableColumn::children):
+ (WebCore::AccessibilityTableColumn::headerObject):
+ (WebCore::AccessibilityTableColumn::headerObjectForSection):
+ (WebCore::AccessibilityTableColumn::addChildren):
+ * page/AccessibilityTableColumn.h: Added.
+ (WebCore::AccessibilityTableColumn::parentObject):
+ (WebCore::AccessibilityTableColumn::roleValue):
+ (WebCore::AccessibilityTableColumn::accessibilityIsIgnored):
+ (WebCore::AccessibilityTableColumn::isTableColumn):
+ (WebCore::AccessibilityTableColumn::setColumnIndex):
+ (WebCore::AccessibilityTableColumn::columnIndex):
+ * page/AccessibilityTableHeaderContainer.cpp: Added.
+ (WebCore::AccessibilityTableHeaderContainer::AccessibilityTableHeaderContainer):
+ (WebCore::AccessibilityTableHeaderContainer::~AccessibilityTableHeaderContainer):
+ (WebCore::AccessibilityTableHeaderContainer::create):
+ (WebCore::AccessibilityTableHeaderContainer::children):
+ (WebCore::AccessibilityTableHeaderContainer::elementRect):
+ (WebCore::AccessibilityTableHeaderContainer::size):
+ (WebCore::AccessibilityTableHeaderContainer::addChildren):
+ * page/AccessibilityTableHeaderContainer.h: Added.
+ (WebCore::AccessibilityTableHeaderContainer::roleValue):
+ (WebCore::AccessibilityTableHeaderContainer::setParentTable):
+ (WebCore::AccessibilityTableHeaderContainer::parentObject):
+ (WebCore::AccessibilityTableHeaderContainer::accessibilityIsIgnored):
+ * page/AccessibilityTableRow.cpp: Added.
+ (WebCore::AccessibilityTableRow::AccessibilityTableRow):
+ (WebCore::AccessibilityTableRow::~AccessibilityTableRow):
+ (WebCore::AccessibilityTableRow::create):
+ (WebCore::AccessibilityTableRow::accessibilityIsIgnored):
+ (WebCore::AccessibilityTableRow::headerObject):
+ * page/AccessibilityTableRow.h: Added.
+ (WebCore::AccessibilityTableRow::isTableRow):
+ (WebCore::AccessibilityTableRow::roleValue):
+ (WebCore::AccessibilityTableRow::setRowIndex):
+ (WebCore::AccessibilityTableRow::rowIndex):
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
+ (RoleEntry::):
+ (-[AccessibilityObjectWrapper roleDescription]):
+ (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[AccessibilityObjectWrapper accessibilityParameterizedAttributeNames]):
+ (-[AccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
2008-08-19 Steve Falkenburg <sfalken@apple.com>
Build fix.
1CFCEEFA0AACC7A700348750 /* DOMHTMLInputElementPrivate.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 1CFCEEF90AACC79000348750 /* DOMHTMLInputElementPrivate.h */; };
2955BE2C0E2548EC00893AB5 /* AccessibilityImageMapLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 2955BE2A0E2548EC00893AB5 /* AccessibilityImageMapLink.h */; };
2955BE2D0E2548EC00893AB5 /* AccessibilityImageMapLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2955BE2B0E2548EC00893AB5 /* AccessibilityImageMapLink.cpp */; };
+ 29800C3B0E522A5300025536 /* AccessibilityTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 29800C390E522A5300025536 /* AccessibilityTable.h */; };
+ 29800C3C0E522A5300025536 /* AccessibilityTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29800C3A0E522A5300025536 /* AccessibilityTable.cpp */; };
+ 29800C950E524C8B00025536 /* AccessibilityTableRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 29800C930E524C8B00025536 /* AccessibilityTableRow.h */; };
+ 29800C960E524C8B00025536 /* AccessibilityTableRow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29800C940E524C8B00025536 /* AccessibilityTableRow.cpp */; };
+ 29800C990E524DA500025536 /* AccessibilityTableColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 29800C970E524DA500025536 /* AccessibilityTableColumn.h */; };
+ 29800C9A0E524DA500025536 /* AccessibilityTableColumn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29800C980E524DA500025536 /* AccessibilityTableColumn.cpp */; };
299984BD0DC8598500F8D261 /* AccessibilityRenderObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299984BB0DC8598500F8D261 /* AccessibilityRenderObject.cpp */; };
299984BE0DC8598500F8D261 /* AccessibilityRenderObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 299984BC0DC8598500F8D261 /* AccessibilityRenderObject.h */; };
2999869E0DD0DEEA00F8D261 /* AccessibilityListBoxOption.h in Headers */ = {isa = PBXBuildFile; fileRef = 2999869A0DD0DEEA00F8D261 /* AccessibilityListBoxOption.h */; };
2999869F0DD0DEEA00F8D261 /* AccessibilityListBoxOption.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2999869B0DD0DEEA00F8D261 /* AccessibilityListBoxOption.cpp */; };
299986A00DD0DEEA00F8D261 /* AccessibilityListBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2999869C0DD0DEEA00F8D261 /* AccessibilityListBox.h */; };
299986A10DD0DEEA00F8D261 /* AccessibilityListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2999869D0DD0DEEA00F8D261 /* AccessibilityListBox.cpp */; };
+ 29AAC36D0E534E86008F9B3B /* AccessibilityTableCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 29AAC36B0E534E86008F9B3B /* AccessibilityTableCell.h */; };
+ 29AAC36E0E534E86008F9B3B /* AccessibilityTableCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29AAC36C0E534E86008F9B3B /* AccessibilityTableCell.cpp */; };
+ 29AAC51F0E53963B008F9B3B /* AccessibilityTableHeaderContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 29AAC51D0E53963B008F9B3B /* AccessibilityTableHeaderContainer.h */; };
+ 29AAC5200E53963B008F9B3B /* AccessibilityTableHeaderContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29AAC51E0E53963B008F9B3B /* AccessibilityTableHeaderContainer.cpp */; };
2D9066060BE141D400956998 /* LayoutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D9066040BE141D400956998 /* LayoutState.cpp */; };
2D9066070BE141D400956998 /* LayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D9066050BE141D400956998 /* LayoutState.h */; settings = {ATTRIBUTES = (Private, ); }; };
31288E720E3005D6003619AE /* WebKitCSSKeyframeRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */; };
1CFCEEF90AACC79000348750 /* DOMHTMLInputElementPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMHTMLInputElementPrivate.h; sourceTree = "<group>"; };
2955BE2A0E2548EC00893AB5 /* AccessibilityImageMapLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityImageMapLink.h; sourceTree = "<group>"; };
2955BE2B0E2548EC00893AB5 /* AccessibilityImageMapLink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityImageMapLink.cpp; sourceTree = "<group>"; };
+ 29800C390E522A5300025536 /* AccessibilityTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTable.h; sourceTree = "<group>"; };
+ 29800C3A0E522A5300025536 /* AccessibilityTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTable.cpp; sourceTree = "<group>"; };
+ 29800C930E524C8B00025536 /* AccessibilityTableRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTableRow.h; sourceTree = "<group>"; };
+ 29800C940E524C8B00025536 /* AccessibilityTableRow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTableRow.cpp; sourceTree = "<group>"; };
+ 29800C970E524DA500025536 /* AccessibilityTableColumn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTableColumn.h; sourceTree = "<group>"; };
+ 29800C980E524DA500025536 /* AccessibilityTableColumn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTableColumn.cpp; sourceTree = "<group>"; };
299984BB0DC8598500F8D261 /* AccessibilityRenderObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityRenderObject.cpp; sourceTree = "<group>"; };
299984BC0DC8598500F8D261 /* AccessibilityRenderObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityRenderObject.h; sourceTree = "<group>"; };
2999869A0DD0DEEA00F8D261 /* AccessibilityListBoxOption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityListBoxOption.h; sourceTree = "<group>"; };
2999869B0DD0DEEA00F8D261 /* AccessibilityListBoxOption.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityListBoxOption.cpp; sourceTree = "<group>"; };
2999869C0DD0DEEA00F8D261 /* AccessibilityListBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityListBox.h; sourceTree = "<group>"; };
2999869D0DD0DEEA00F8D261 /* AccessibilityListBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityListBox.cpp; sourceTree = "<group>"; };
+ 29AAC36B0E534E86008F9B3B /* AccessibilityTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTableCell.h; sourceTree = "<group>"; };
+ 29AAC36C0E534E86008F9B3B /* AccessibilityTableCell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTableCell.cpp; sourceTree = "<group>"; };
+ 29AAC51D0E53963B008F9B3B /* AccessibilityTableHeaderContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTableHeaderContainer.h; sourceTree = "<group>"; };
+ 29AAC51E0E53963B008F9B3B /* AccessibilityTableHeaderContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTableHeaderContainer.cpp; sourceTree = "<group>"; };
2D9066040BE141D400956998 /* LayoutState.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutState.cpp; sourceTree = "<group>"; };
2D9066050BE141D400956998 /* LayoutState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutState.h; sourceTree = "<group>"; };
2D90660B0665D937006B6F1A /* ClipboardMac.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ClipboardMac.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
4B17CBC80D945B370053F183 /* AccessibilityObject.h */,
299984BB0DC8598500F8D261 /* AccessibilityRenderObject.cpp */,
299984BC0DC8598500F8D261 /* AccessibilityRenderObject.h */,
+ 29800C3A0E522A5300025536 /* AccessibilityTable.cpp */,
+ 29800C390E522A5300025536 /* AccessibilityTable.h */,
+ 29AAC36C0E534E86008F9B3B /* AccessibilityTableCell.cpp */,
+ 29AAC36B0E534E86008F9B3B /* AccessibilityTableCell.h */,
+ 29800C980E524DA500025536 /* AccessibilityTableColumn.cpp */,
+ 29800C970E524DA500025536 /* AccessibilityTableColumn.h */,
+ 29AAC51E0E53963B008F9B3B /* AccessibilityTableHeaderContainer.cpp */,
+ 29AAC51D0E53963B008F9B3B /* AccessibilityTableHeaderContainer.h */,
+ 29800C940E524C8B00025536 /* AccessibilityTableRow.cpp */,
+ 29800C930E524C8B00025536 /* AccessibilityTableRow.h */,
BC80C9890CD2950500A0B7B3 /* AnimationController.cpp */,
BC80C98A0CD2950500A0B7B3 /* AnimationController.h */,
4B24F9A70DA7050B00269E58 /* AXObjectCache.cpp */,
31C0FF4B0E4CEFDD007D6FE5 /* DOMWebKitAnimationEventInternal.h in Headers */,
31C0FF4C0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.h in Headers */,
31C0FF4E0E4CEFDD007D6FE5 /* DOMWebKitTransitionEventInternal.h in Headers */,
+ 29800C3B0E522A5300025536 /* AccessibilityTable.h in Headers */,
+ 29800C950E524C8B00025536 /* AccessibilityTableRow.h in Headers */,
+ 29800C990E524DA500025536 /* AccessibilityTableColumn.h in Headers */,
+ 29AAC36D0E534E86008F9B3B /* AccessibilityTableCell.h in Headers */,
+ 29AAC51F0E53963B008F9B3B /* AccessibilityTableHeaderContainer.h in Headers */,
08A484780E5272C500C3FE76 /* ScriptElement.h in Headers */,
A8FA6E5D0E4CFDED00D5CF49 /* Pattern.h in Headers */,
);
31C0FF3F0E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.cpp in Sources */,
31C0FF4A0E4CEFDD007D6FE5 /* DOMWebKitAnimationEvent.mm in Sources */,
31C0FF4D0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.mm in Sources */,
+ 29800C3C0E522A5300025536 /* AccessibilityTable.cpp in Sources */,
+ 29800C960E524C8B00025536 /* AccessibilityTableRow.cpp in Sources */,
+ 29800C9A0E524DA500025536 /* AccessibilityTableColumn.cpp in Sources */,
+ 29AAC36E0E534E86008F9B3B /* AccessibilityTableCell.cpp in Sources */,
+ 29AAC5200E53963B008F9B3B /* AccessibilityTableHeaderContainer.cpp in Sources */,
08A484770E5272C500C3FE76 /* ScriptElement.cpp in Sources */,
A8FA6E5E0E4CFDED00D5CF49 /* Pattern.cpp in Sources */,
A80A38FE0E50CC8200A25EBC /* PatternCG.cpp in Sources */,
#include "AccessibilityListBoxOption.h"
#include "AccessibilityImageMapLink.h"
#include "AccessibilityRenderObject.h"
+#include "AccessibilityTable.h"
+#include "AccessibilityTableCell.h"
+#include "AccessibilityTableColumn.h"
+#include "AccessibilityTableHeaderContainer.h"
+#include "AccessibilityTableRow.h"
#include "RenderObject.h"
#include <wtf/PassRefPtr.h>
if (!obj) {
if (renderer->isListBox())
obj = AccessibilityListBox::create(renderer);
+ else if (renderer->isTable())
+ obj = AccessibilityTable::create(renderer);
+ else if (renderer->isTableRow())
+ obj = AccessibilityTableRow::create(renderer);
+ else if (renderer->isTableCell())
+ obj = AccessibilityTableCell::create(renderer);
else
obj = AccessibilityRenderObject::create(renderer);
case ImageMapLinkRole:
obj = AccessibilityImageMapLink::create();
break;
+ case ColumnRole:
+ obj = AccessibilityTableColumn::create();
+ break;
+ case TableHeaderContainerRole:
+ obj = AccessibilityTableHeaderContainer::create();
+ break;
default:
obj = 0;
}
LinkRole,
DisclosureTriangleRole,
GridRole,
-
+ CellRole,
// AppKit includes SortButtonRole but it is misnamed and really a subrole of ButtonRole so we do not include it here.
// WebCore-specific roles
WebAreaRole,
HeadingRole,
ListBoxRole,
- ListBoxOptionRole
+ ListBoxOptionRole,
+ TableHeaderContainerRole
};
struct VisiblePositionRange {
virtual bool isProgressIndicator() const { return false; };
virtual bool isSlider() const { return false; };
virtual bool isControl() const { return false; };
+ virtual bool isDataTable() const { return false; };
+ virtual bool isTableRow() const { return false; };
+ virtual bool isTableColumn() const { return false; };
+ virtual bool isTableCell() const { return false; };
virtual bool isChecked() const { return false; };
virtual bool isEnabled() const { return false; };
case CheckBoxRole:
case RadioButtonRole:
return true;
- case UnknownRole:
- case SliderRole:
- case TabGroupRole:
- case StaticTextRole:
- case ScrollAreaRole:
- case MenuButtonRole:
- case TableRole:
- case ApplicationRole:
- case GroupRole:
- case RadioGroupRole:
- case ListRole:
- case ScrollBarRole:
- case ValueIndicatorRole:
- case ImageRole:
- case MenuBarRole:
- case MenuRole:
- case MenuItemRole:
- case ColumnRole:
- case RowRole:
- case ToolbarRole:
- case BusyIndicatorRole:
- case ProgressIndicatorRole:
- case WindowRole:
- case DrawerRole:
- case SystemWideRole:
- case OutlineRole:
- case IncrementorRole:
- case BrowserRole:
- case ComboBoxRole:
- case SplitGroupRole:
- case SplitterRole:
- case ColorWellRole:
- case GrowAreaRole:
- case SheetRole:
- case HelpTagRole:
- case MatteRole:
- case RulerRole:
- case RulerMarkerRole:
- case LinkRole:
- case DisclosureTriangleRole:
- case GridRole:
- case ImageMapRole:
- case ListMarkerRole:
- case WebAreaRole:
- case HeadingRole:
- case ListBoxRole:
- case ListBoxOptionRole:
+ default:
return false;
}
ASSERT_NOT_REACHED();
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTable.h"
+
+#include "AccessibilityTableCell.h"
+#include "AccessibilityTableColumn.h"
+#include "AccessibilityTableHeaderContainer.h"
+#include "AccessibilityTableRow.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableCaptionElement.h"
+#include "HTMLTableCellElement.h"
+#include "RenderObject.h"
+#include "RenderTable.h"
+#include "RenderTableCell.h"
+#include "RenderTableSection.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTable::AccessibilityTable(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer),
+ m_headerContainer(0)
+{
+ // AXTables should be in SnowLeopard only
+#if PLATFORM(MAC) && (defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD))
+ m_isAccessibilityTable = false;
+#else
+ m_isAccessibilityTable = isTableExposableThroughAccessibility();
+#endif
+
+}
+
+AccessibilityTable::~AccessibilityTable()
+{
+}
+
+PassRefPtr<AccessibilityTable> AccessibilityTable::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTable(renderer));
+}
+
+bool AccessibilityTable::isTableExposableThroughAccessibility()
+{
+ if (!m_renderer || !m_renderer->isTable())
+ return false;
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+
+ // this employs a heuristic to determine if this table should appear.
+ // Only "data" tables should be exposed as tables.
+ // Unfortunately, there is no good way to determine the difference
+ // between a "layout" table and a "data" table
+
+ Node* tableNode = table->element();
+ if (!tableNode || !tableNode->hasTagName(tableTag))
+ return false;
+
+ // if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
+ HTMLTableElement* tableElement = static_cast<HTMLTableElement*>(tableNode);
+ if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption())
+ return true;
+
+ // if someone used "rules" attribute than the table should appear
+ if (!tableElement->rules().isEmpty())
+ return true;
+
+ // go through the cell's and check for tell-tale signs of "data" table status
+ // cells have borders, or use attributes like headers, abbr, scope or axis
+ RenderTableSection* firstBody = table->firstBody();
+ int numCols = firstBody->numColumns();
+ int numRows = firstBody->numRows();
+
+ // store the background color of the table to check against cell's background colors
+ RenderStyle* tableStyle = table->style();
+ if (!tableStyle)
+ return false;
+ Color tableBGColor = tableStyle->backgroundColor();
+
+ // check no more than 2 rows for the sake of speed.
+ for (int row = 0; row < numRows && row < 2; ++row) {
+ for (int col = 0; col < numCols; ++col) {
+ RenderTableCell* cell = firstBody->cellAt(row, col).cell;
+ if (!cell)
+ continue;
+ Node* cellNode = cell->element();
+ if (!cellNode)
+ continue;
+
+ HTMLTableCellElement* cellElement = static_cast<HTMLTableCellElement*>(cellNode);
+
+ if (!cellElement->headers().isEmpty() || !cellElement->abbr().isEmpty() ||
+ !cellElement->axis().isEmpty() || !cellElement->scope().isEmpty())
+ return true;
+
+ RenderStyle* renderStyle = cell->style();
+ if (!renderStyle)
+ continue;
+
+ // at least one cell had a border, it is probably a data table
+ if (renderStyle->border().hasBorder())
+ return true;
+
+ // do our cells have a different color from the table and is there cell spacing?
+ // then probably this is a data table (there were no borders... spacing and
+ // colors take the place of borders)
+ if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0 &&
+ tableBGColor != renderStyle->backgroundColor())
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void AccessibilityTable::clearChildren()
+{
+ m_children.clear();
+ m_rows.clear();
+ m_columns.clear();
+ m_haveChildren = false;
+}
+
+void AccessibilityTable::addChildren()
+{
+ if (!isDataTable()) {
+ AccessibilityRenderObject::addChildren();
+ return;
+ }
+
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_renderer)
+ return;
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+ AXObjectCache* axCache = m_renderer->document()->axObjectCache();
+
+ // go through all the available sections to pull out the rows
+ // and add them as children
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ while (tableSection) {
+
+ HashSet<AccessibilityObject*> appendedRows;
+
+ unsigned numRows = tableSection->numRows();
+ unsigned numCols = tableSection->numColumns();
+ for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) {
+ for (unsigned colIndex = 0; colIndex < numCols; ++colIndex) {
+
+ RenderTableCell* cell = tableSection->cellAt(rowIndex, colIndex).cell;
+ if (!cell)
+ continue;
+
+ AccessibilityObject* rowObject = axCache->get(cell->parent());
+ if (!rowObject->isTableRow())
+ continue;
+
+ AccessibilityTableRow* row = static_cast<AccessibilityTableRow*>(rowObject);
+ // we need to check every cell for a new row, because cell spans
+ // can cause us to mess rows if we just check the first column
+ if (appendedRows.contains(row))
+ continue;
+
+ row->setRowIndex((int)m_rows.size());
+ m_rows.append(row);
+ m_children.append(row);
+ appendedRows.add(row);
+ }
+ }
+
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ // make the columns based on the number of columns in the first body
+ unsigned length = table->firstBody()->numColumns();
+ for (unsigned i = 0; i < length; ++i) {
+ AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->get(ColumnRole));
+ column->setColumnIndex((int)i);
+ column->setParentTable(this);
+ m_columns.append(column);
+ m_children.append(column);
+ }
+
+ AccessibilityObject* headerContainerObject = headerContainer();
+ if (headerContainerObject)
+ m_children.append(headerContainerObject);
+}
+
+AccessibilityObject* AccessibilityTable::headerContainer()
+{
+ if (m_headerContainer)
+ return m_headerContainer;
+
+ m_headerContainer = static_cast<AccessibilityTableHeaderContainer*>(axObjectCache()->get(TableHeaderContainerRole));
+ m_headerContainer->setParentTable(this);
+
+ return m_headerContainer;
+}
+
+AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::columns()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_columns;
+}
+
+AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::rows()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_rows;
+}
+
+void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned rowCount = m_rows.size();
+ for (unsigned k = 0; k < rowCount; ++k) {
+ AccessibilityObject* header = static_cast<AccessibilityTableRow*>(m_rows[k].get())->headerObject();
+ if (!header)
+ continue;
+ headers.append(header);
+ }
+}
+
+void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ unsigned colCount = m_columns.size();
+ for (unsigned k = 0; k < colCount; ++k) {
+ AccessibilityObject* header = static_cast<AccessibilityTableColumn*>(m_columns[k].get())->headerObject();
+ if (!header)
+ continue;
+ headers.append(header);
+ }
+}
+
+void AccessibilityTable::cells(AccessibilityObject::AccessibilityChildrenVector& cells)
+{
+ if (!m_renderer)
+ return;
+
+ if (!hasChildren())
+ addChildren();
+
+ int numRows = m_rows.size();
+ for (int row = 0; row < numRows; ++row) {
+ AccessibilityChildrenVector rowChildren = m_rows[row]->children();
+ cells.append(rowChildren);
+ }
+}
+
+const unsigned AccessibilityTable::columnCount()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_columns.size();
+}
+
+const unsigned AccessibilityTable::rowCount()
+{
+ if (!hasChildren())
+ addChildren();
+
+ return m_rows.size();
+}
+
+AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row)
+{
+ if (!m_renderer)
+ return 0;
+
+ if (!hasChildren())
+ addChildren();
+
+ RenderTable* table = static_cast<RenderTable*>(m_renderer);
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ RenderTableCell* cell = 0;
+ unsigned rowCount = 0;
+ unsigned rowOffset = 0;
+ while (tableSection) {
+
+ rowCount += tableSection->numRows();
+ unsigned numCols = tableSection->numColumns();
+
+ if (row < rowCount && column < numCols) {
+ int sectionSpecificRow = row - rowOffset;
+ cell = tableSection->cellAt(sectionSpecificRow, column).cell;
+
+ // we didn't find the cell, which means there's spanning happening
+ // search backwards to find the spanning cell
+ if (!cell) {
+
+ // first try rows
+ for (int testRow = sectionSpecificRow-1; testRow >= 0; --testRow) {
+ cell = tableSection->cellAt(testRow, column).cell;
+ // cell overlapped. use this one
+ if (cell && ((cell->row() + (cell->rowSpan()-1)) >= (int)sectionSpecificRow))
+ break;
+ cell = nil;
+ }
+
+ if (!cell) {
+ // try cols
+ for (int testCol = column-1; testCol >= 0; --testCol) {
+ cell = tableSection->cellAt(sectionSpecificRow, testCol).cell;
+ // cell overlapped. use this one
+ if (cell && ((cell->col() + (cell->colSpan()-1)) >= (int)column))
+ break;
+ cell = nil;
+ }
+ }
+ }
+ }
+
+ if (cell)
+ break;
+
+ rowOffset += rowCount;
+ // we didn't find anything between the rows we should have
+ if (row < rowOffset)
+ break;
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ if (!cell)
+ return 0;
+
+ AccessibilityObject* cellObject = axObjectCache()->get(cell);
+ ASSERT(cellObject->isTableCell());
+
+ return static_cast<AccessibilityTableCell*>(cellObject);
+}
+
+AccessibilityRole AccessibilityTable::roleValue() const
+{
+ return isDataTable() ? TableRole : GroupRole;
+}
+
+bool AccessibilityTable::accessibilityIsIgnored() const
+{
+ return !isDataTable();
+}
+
+String AccessibilityTable::title() const
+{
+ String title;
+ if (!m_renderer)
+ return title;
+
+ // see if there is a caption
+ Node *tableElement = m_renderer->element();
+ if (tableElement) {
+ HTMLTableCaptionElement* caption = static_cast<HTMLTableElement*>(tableElement)->caption();
+ if (caption)
+ title = caption->innerText();
+ }
+
+ // try the standard
+ if (title.isEmpty())
+ title = AccessibilityRenderObject::title();
+
+ return title;
+}
+
+bool AccessibilityTable::isDataTable() const
+{
+ if (!m_renderer)
+ return false;
+
+ return m_isAccessibilityTable;
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTable_h
+#define AccessibilityTable_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class String;
+class AccessibilityTableCell;
+class AccessibilityTableHeaderContainer;
+
+class AccessibilityTable : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTable(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTable> create(RenderObject*);
+ virtual ~AccessibilityTable();
+
+ virtual bool isDataTable() const;
+ virtual AccessibilityRole roleValue() const;
+
+ virtual bool accessibilityIsIgnored() const;
+
+ virtual void addChildren();
+ virtual void clearChildren();
+
+ AccessibilityChildrenVector& columns();
+ AccessibilityChildrenVector& rows();
+
+ const unsigned columnCount();
+ const unsigned rowCount();
+
+ virtual String title() const;
+
+ // all the cells in the table
+ void cells(AccessibilityChildrenVector&);
+ AccessibilityTableCell* cellForColumnAndRow(unsigned column, unsigned row);
+
+ void columnHeaders(AccessibilityChildrenVector&);
+ void rowHeaders(AccessibilityChildrenVector&);
+
+ // an object that contains, as children, all the objects that act as headers
+ AccessibilityObject* headerContainer();
+
+private:
+ AccessibilityChildrenVector m_rows;
+ AccessibilityChildrenVector m_columns;
+
+ AccessibilityTableHeaderContainer* m_headerContainer;
+ mutable bool m_isAccessibilityTable;
+
+ bool isTableExposableThroughAccessibility();
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTable_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableCell.h"
+
+#include "AXObjectCache.h"
+#include "RenderObject.h"
+#include "RenderTableCell.h"
+
+using namespace std;
+
+namespace WebCore {
+
+AccessibilityTableCell::AccessibilityTableCell(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityTableCell::~AccessibilityTableCell()
+{
+}
+
+PassRefPtr<AccessibilityTableCell> AccessibilityTableCell::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTableCell(renderer));
+}
+
+bool AccessibilityTableCell::accessibilityIsIgnored() const
+{
+ if (!m_renderer)
+ return true;
+
+ AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableCell*>(m_renderer)->table());
+ return renderTable->accessibilityIsIgnored();
+}
+
+void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange)
+{
+ if (!m_renderer)
+ return;
+
+ RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ rowRange.first = renderCell->row();
+ rowRange.second = renderCell->rowSpan();
+
+ // since our table might have multiple sections, we have to offset our row appropriately
+ RenderTableSection* section = renderCell->section();
+ RenderTable* table = renderCell->table();
+ if (!table || !section)
+ return;
+
+ RenderTableSection* tableSection = table->header();
+ if (!tableSection)
+ tableSection = table->firstBody();
+
+ unsigned rowOffset = 0;
+ while (tableSection) {
+ if (tableSection == section)
+ break;
+ rowOffset += tableSection->numRows();
+ tableSection = table->sectionBelow(tableSection, true);
+ }
+
+ rowRange.first += rowOffset;
+}
+
+void AccessibilityTableCell::columnIndexRange(pair<int, int>& columnRange)
+{
+ if (!m_renderer)
+ return;
+
+ RenderTableCell *renderCell = static_cast<RenderTableCell*>(m_renderer);
+ columnRange.first = renderCell->col();
+ columnRange.second = renderCell->colSpan();
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTableCell_h
+#define AccessibilityTableCell_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class AccessibilityTableCell : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTableCell(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTableCell> create(RenderObject*);
+ virtual ~AccessibilityTableCell();
+
+ virtual bool isTableCell() const { return true; };
+ virtual AccessibilityRole roleValue() const { return CellRole; };
+
+ virtual bool accessibilityIsIgnored() const;
+
+ // fills in the start location and row span of cell
+ void rowIndexRange(pair<int, int>& rowRange);
+ // fills in the start location and column span of cell
+ void columnIndexRange(pair<int, int>& columnRange);
+
+private:
+ int m_rowIndex;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableCell_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableColumn.h"
+
+#include "AccessibilityTableCell.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "RenderTable.h"
+#include "RenderTableSection.h"
+#include "RenderTableCell.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTableColumn::AccessibilityTableColumn()
+ : m_parentTable(0)
+{
+}
+
+AccessibilityTableColumn::~AccessibilityTableColumn()
+{
+}
+
+PassRefPtr<AccessibilityTableColumn> AccessibilityTableColumn::create()
+{
+ return adoptRef(new AccessibilityTableColumn());
+}
+
+void AccessibilityTableColumn::setParentTable(AccessibilityTable* table)
+{
+ m_parentTable = table;
+
+ clearChildren();
+ addChildren();
+}
+
+IntRect AccessibilityTableColumn::elementRect() const
+{
+ // this will be filled in when addChildren is called
+ return m_columnRect;
+}
+
+IntSize AccessibilityTableColumn::size() const
+{
+ return elementRect().size();
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTableColumn::children()
+{
+ if (!m_haveChildren)
+ addChildren();
+ return m_children;
+}
+
+AccessibilityObject* AccessibilityTableColumn::headerObject()
+{
+ if (!m_parentTable)
+ return 0;
+
+ RenderTable* table = static_cast<RenderTable*>(m_parentTable->renderer());
+
+ AccessibilityObject* headerObject = 0;
+
+ // try the <thead> section first. this doesn't require th tags
+ headerObject = headerObjectForSection(table->header(), false);
+
+ if (headerObject)
+ return headerObject;
+
+ // now try for <th> tags in the first body
+ headerObject = headerObjectForSection(table->firstBody(), true);
+
+ return headerObject;
+}
+
+AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTableSection* section, bool thTagRequired)
+{
+ if (!section)
+ return 0;
+
+ int numCols = section->numColumns();
+ if (m_columnIndex >= numCols)
+ return 0;
+
+ RenderTableCell* cell = 0;
+ // also account for cells that have a span
+ for (int testCol = m_columnIndex; testCol >= 0; --testCol) {
+ RenderTableCell* testCell = section->cellAt(0, testCol).cell;
+ if (!testCell)
+ continue;
+
+ // we've reached a cell that doesn't even overlap our column
+ // it can't be our header
+ if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex)
+ break;
+
+ Node* node = testCell->element();
+ if (!node)
+ continue;
+
+ if (thTagRequired && !node->hasTagName(thTag))
+ continue;
+
+ cell = testCell;
+ }
+
+ if (!cell)
+ return 0;
+
+ return m_parentTable->axObjectCache()->get(cell);
+}
+
+void AccessibilityTableColumn::addChildren()
+{
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_parentTable)
+ return;
+
+ int numRows = m_parentTable->rowCount();
+
+ for (int i = 0; i < numRows; i++) {
+ AccessibilityTableCell* cell = m_parentTable->cellForColumnAndRow(m_columnIndex, i);
+ if (!cell)
+ continue;
+
+ // make sure the last one isn't the same as this one (rowspan cells)
+ if (m_children.size() > 0 && m_children.last() == cell)
+ continue;
+
+ m_children.append(cell);
+ m_columnRect.unite(cell->elementRect());
+ }
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTableColumn_h
+#define AccessibilityTableColumn_h
+
+#include "AccessibilityObject.h"
+#include "AccessibilityTable.h"
+#include "IntRect.h"
+
+namespace WebCore {
+
+class RenderTableSection;
+
+class AccessibilityTableColumn : public AccessibilityObject {
+
+private:
+ AccessibilityTableColumn();
+public:
+ static PassRefPtr<AccessibilityTableColumn> create();
+ virtual ~AccessibilityTableColumn();
+
+ void setParentTable(AccessibilityTable*);
+ virtual AccessibilityObject* parentObject() const { return m_parentTable; }
+ AccessibilityObject* headerObject();
+
+ virtual AccessibilityRole roleValue() const { return ColumnRole; }
+ virtual bool accessibilityIsIgnored() const { return false; }
+ virtual bool isTableColumn() const { return true; }
+
+ void setColumnIndex(int columnIndex) { m_columnIndex = columnIndex; }
+ int columnIndex() const { return m_columnIndex; }
+
+ virtual const AccessibilityChildrenVector& children();
+ virtual void addChildren();
+
+ virtual IntSize size() const;
+ virtual IntRect elementRect() const;
+
+private:
+ AccessibilityTable* m_parentTable;
+ int m_columnIndex;
+ IntRect m_columnRect;
+
+ AccessibilityObject* headerObjectForSection(RenderTableSection*, bool thTagRequired);
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableColumn_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableHeaderContainer.h"
+
+#include "AccessibilityTable.h"
+#include "AXObjectCache.h"
+
+using namespace std;
+
+namespace WebCore {
+
+AccessibilityTableHeaderContainer::AccessibilityTableHeaderContainer()
+ : m_parentTable(0)
+{
+}
+
+AccessibilityTableHeaderContainer::~AccessibilityTableHeaderContainer()
+{
+}
+
+PassRefPtr<AccessibilityTableHeaderContainer> AccessibilityTableHeaderContainer::create()
+{
+ return adoptRef(new AccessibilityTableHeaderContainer());
+}
+
+const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTableHeaderContainer::children()
+{
+ if (!m_haveChildren)
+ addChildren();
+ return m_children;
+}
+
+IntRect AccessibilityTableHeaderContainer::elementRect() const
+{
+ // this will be filled in when addChildren is called
+ return m_headerRect;
+}
+
+IntSize AccessibilityTableHeaderContainer::size() const
+{
+ return elementRect().size();
+}
+
+void AccessibilityTableHeaderContainer::addChildren()
+{
+ ASSERT(!m_haveChildren);
+
+ m_haveChildren = true;
+ if (!m_parentTable || !m_parentTable->isDataTable())
+ return;
+
+ static_cast<AccessibilityTable*>(m_parentTable)->columnHeaders(m_children);
+
+ unsigned length = m_children.size();
+ for (unsigned k = 0; k < length; ++k) {
+ m_headerRect.unite(m_children[k]->elementRect());
+ }
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTableHeaderContainer_h
+#define AccessibilityTableHeaderContainer_h
+
+#include "AccessibilityObject.h"
+#include "AccessibilityTable.h"
+#include "IntRect.h"
+
+namespace WebCore {
+
+class AccessibilityTableHeaderContainer : public AccessibilityObject {
+
+private:
+ AccessibilityTableHeaderContainer();
+public:
+ static PassRefPtr<AccessibilityTableHeaderContainer> create();
+ virtual ~AccessibilityTableHeaderContainer();
+
+ virtual AccessibilityRole roleValue() const { return TableHeaderContainerRole; }
+
+ void setParentTable(AccessibilityTable* table) { m_parentTable = table; }
+ virtual AccessibilityObject* parentObject() const { return m_parentTable; }
+
+ virtual bool accessibilityIsIgnored() const { return false; }
+
+ virtual const AccessibilityChildrenVector& children();
+ virtual void addChildren();
+
+ virtual IntSize size() const;
+ virtual IntRect elementRect() const;
+
+private:
+ AccessibilityTable* m_parentTable;
+ IntRect m_headerRect;
+
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableHeaderContainer_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTableRow.h"
+
+#include "AccessibilityTableCell.h"
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+#include "HTMLTableRowElement.h"
+#include "RenderObject.h"
+#include "RenderTableCell.h"
+#include "RenderTableRow.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AccessibilityTableRow::AccessibilityTableRow(RenderObject* renderer)
+ : AccessibilityRenderObject(renderer)
+{
+}
+
+AccessibilityTableRow::~AccessibilityTableRow()
+{
+}
+
+PassRefPtr<AccessibilityTableRow> AccessibilityTableRow::create(RenderObject* renderer)
+{
+ return adoptRef(new AccessibilityTableRow(renderer));
+}
+
+bool AccessibilityTableRow::accessibilityIsIgnored() const
+{
+ if (!m_renderer)
+ return true;
+
+ AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableRow*>(m_renderer)->table());
+ return renderTable->accessibilityIsIgnored();
+}
+
+AccessibilityObject* AccessibilityTableRow::headerObject()
+{
+ AccessibilityChildrenVector rowChildren = children();
+ if (!rowChildren.size())
+ return 0;
+
+ // check the first element in the row to see if it is a TH element
+ AccessibilityObject* cell = rowChildren[0].get();
+ if (!cell->isTableCell())
+ return 0;
+
+ RenderObject* cellRenderer = static_cast<AccessibilityTableCell*>(cell)->renderer();
+ if (!cellRenderer)
+ return 0;
+
+ Node* cellNode = cellRenderer->element();
+ if (!cellNode || !cellNode->hasTagName(thTag))
+ return 0;
+
+ return cell;
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTableRow_h
+#define AccessibilityTableRow_h
+
+#include "AccessibilityRenderObject.h"
+
+namespace WebCore {
+
+class AccessibilityTableRow : public AccessibilityRenderObject {
+
+private:
+ AccessibilityTableRow(RenderObject*);
+public:
+ static PassRefPtr<AccessibilityTableRow> create(RenderObject*);
+ virtual ~AccessibilityTableRow();
+
+ virtual bool isTableRow() const { return true; };
+ virtual AccessibilityRole roleValue() const { return RowRole; }
+
+ // retrieves the "row" header (a th tag in the rightmost column)
+ AccessibilityObject* headerObject();
+
+ virtual bool accessibilityIsIgnored() const;
+
+ void setRowIndex(int rowIndex) { m_rowIndex = rowIndex; }
+ int rowIndex() const { return m_rowIndex; }
+
+ // allows the table to add other children that may not originate
+ // in the row, but their col/row spans overlap into it
+ void appendChild(AccessibilityObject*);
+
+private:
+ int m_rowIndex;
+};
+
+} // namespace WebCore
+
+#endif // AccessibilityTableRow_h
#import "AXObjectCache.h"
#import "AccessibilityListBox.h"
#import "AccessibilityRenderObject.h"
+#import "AccessibilityTable.h"
+#import "AccessibilityTableCell.h"
+#import "AccessibilityTableRow.h"
+#import "AccessibilityTableColumn.h"
#import "ColorMac.h"
#import "Frame.h"
#import "HTMLAnchorElement.h"
using namespace WebCore;
using namespace HTMLNames;
+// this is SnowLeopard API
+#ifndef NSAccessibilitySelectedCellsAttribute
+#define NSAccessibilitySelectedCellsAttribute @"AXSelectedCells"
+#endif
+
+#ifndef NSAccessibilityVisibleCellsAttribute
+#define NSAccessibilityVisibleCellsAttribute @"AXVisibleCells"
+#endif
+
+#ifndef NSAccessibilityRowHeaderUIElementsAttribute
+#define NSAccessibilityRowHeaderUIElementsAttribute @"AXRowHeaderUIElements"
+#endif
+
+#ifndef NSAccessibilityRowIndexRangeAttribute
+#define NSAccessibilityRowIndexRangeAttribute @"AXRowIndexRange"
+#endif
+
+#ifndef NSAccessibilityColumnIndexRangeAttribute
+#define NSAccessibilityColumnIndexRangeAttribute @"AXColumnIndexRange"
+#endif
+
+#ifndef NSAccessibilityCellForColumnAndRowParameterizedAttribute
+#define NSAccessibilityCellForColumnAndRowParameterizedAttribute @"AXCellForColumnAndRow"
+#endif
+
+#ifndef NSAccessibilityCellRole
+#define NSAccessibilityCellRole @"AXCell"
+#endif
+
@implementation AccessibilityObjectWrapper
#ifndef BUILDING_ON_TIGER
static NSArray* menuItemAttrs = nil;
static NSArray* menuButtonAttrs = nil;
static NSArray* controlAttrs = nil;
+ static NSArray* tableAttrs = nil;
+ static NSArray* tableRowAttrs = nil;
+ static NSArray* tableColAttrs = nil;
+ static NSArray* tableCellAttrs = nil;
NSMutableArray* tempArray;
if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute,
controlAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
-
+ if (tableAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityRowsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
+ [tempArray addObject:NSAccessibilityColumnsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleColumnsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleCellsAttribute];
+ [tempArray addObject:(NSString *)kAXColumnHeaderUIElementsAttribute];
+ [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
+ [tempArray addObject:NSAccessibilityHeaderAttribute];
+ tableAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableRowAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityIndexAttribute];
+ tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableColAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityIndexAttribute];
+ [tempArray addObject:NSAccessibilityHeaderAttribute];
+ [tempArray addObject:NSAccessibilityRowsAttribute];
+ [tempArray addObject:NSAccessibilityVisibleRowsAttribute];
+ tableColAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+ if (tableCellAttrs == nil) {
+ tempArray = [[NSMutableArray alloc] initWithArray:attributes];
+ [tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
+ [tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
+ tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
if (m_object->isPasswordField())
return attributes;
if (m_object->isAnchor() || m_object->isImage())
return anchorAttrs;
+ if (m_object->isDataTable())
+ return tableAttrs;
+ if (m_object->isTableRow())
+ return tableRowAttrs;
+ if (m_object->isTableColumn())
+ return tableColAttrs;
+ if (m_object->isTableCell())
+ return tableCellAttrs;
+
if (m_object->isListBox())
return listBoxAttrs;
{ WebAreaRole, @"AXWebArea" },
{ HeadingRole, @"AXHeading" },
{ ListBoxRole, NSAccessibilityListRole },
- { ListBoxOptionRole, NSAccessibilityStaticTextRole }
+ { ListBoxOptionRole, NSAccessibilityStaticTextRole },
+ // cells exist only in SnowLeopard
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
+ { CellRole, NSAccessibilityGroupRole },
+#else
+ { CellRole, NSAccessibilityCellRole },
+#endif
+ { TableHeaderContainerRole, NSAccessibilityGroupRole }
+
};
AccessibilityRoleMap& roleMap = *new AccessibilityRoleMap;
if ([axRole isEqualToString:NSAccessibilityListRole])
return NSAccessibilityRoleDescription(NSAccessibilityListRole, [self subrole]);
+ if ([axRole isEqualToString:NSAccessibilityTableRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityTableRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityRowRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityRowRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityColumnRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityColumnRole, [self subrole]);
+
+ if ([axRole isEqualToString:NSAccessibilityCellRole])
+ return NSAccessibilityRoleDescription(NSAccessibilityCellRole, [self subrole]);
+
if ([axRole isEqualToString:@"AXWebArea"])
return AXWebAreaText();
return nil;
}
+ if (m_object->isDataTable()) {
+ // TODO: distinguish between visible and non-visible rows
+ if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTable*>(m_object)->rows());
+ }
+ // TODO: distinguish between visible and non-visible columns
+ if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTable*>(m_object)->columns());
+ }
+
+ // HTML tables don't support these
+ if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
+ return nil;
+
+ if ([attributeName isEqualToString:(NSString *)kAXColumnHeaderUIElementsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector columnHeaders;
+ static_cast<AccessibilityTable*>(m_object)->columnHeaders(columnHeaders);
+ return convertToNSArray(columnHeaders);
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
+ AccessibilityObject* headerContainer = static_cast<AccessibilityTable*>(m_object)->headerContainer();
+ if (headerContainer)
+ return headerContainer->wrapper();
+ return nil;
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector rowHeaders;
+ static_cast<AccessibilityTable*>(m_object)->rowHeaders(rowHeaders);
+ return convertToNSArray(rowHeaders);
+ }
+
+ if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute]) {
+ AccessibilityObject::AccessibilityChildrenVector cells;
+ static_cast<AccessibilityTable*>(m_object)->cells(cells);
+ return convertToNSArray(cells);
+ }
+ }
+
+ if (m_object->isTableRow()) {
+ if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
+ return [NSNumber numberWithInt:static_cast<AccessibilityTableRow*>(m_object)->rowIndex()];
+ }
+
+ if (m_object->isTableColumn()) {
+ if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
+ return [NSNumber numberWithInt:static_cast<AccessibilityTableColumn*>(m_object)->columnIndex()];
+
+ // rows attribute for a column is the list of all the elements in that column at each row
+ if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
+ [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
+ return convertToNSArray(static_cast<AccessibilityTableColumn*>(m_object)->children());
+ }
+ if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
+ AccessibilityObject* header = static_cast<AccessibilityTableColumn*>(m_object)->headerObject();
+ if (!header)
+ return nil;
+ return header->wrapper();
+ }
+ }
+
+ if (m_object->isTableCell()) {
+ if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
+ pair<int, int> rowRange;
+ static_cast<AccessibilityTableCell*>(m_object)->rowIndexRange(rowRange);
+ return [NSValue valueWithRange:NSMakeRange(rowRange.first, rowRange.second)];
+ }
+ if ([attributeName isEqualToString:NSAccessibilityColumnIndexRangeAttribute]) {
+ pair<int, int> columnRange;
+ static_cast<AccessibilityTableCell*>(m_object)->columnIndexRange(columnRange);
+ return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
+ }
+ }
+
if (m_object->isListBox() && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
return NSAccessibilityVerticalOrientationValue;
static NSArray* paramAttrs = nil;
static NSArray* textParamAttrs = nil;
+ static NSArray* tableParamAttrs = nil;
if (paramAttrs == nil) {
paramAttrs = [[NSArray alloc] initWithObjects:
@"AXUIElementForTextMarker",
textParamAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
+ if (tableParamAttrs == nil) {
+ NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs];
+ [tempArray addObject:NSAccessibilityCellForColumnAndRowParameterizedAttribute];
+ tableParamAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
if (m_object->isPasswordField())
return [NSArray array];
if (m_object->isTextControl())
return textParamAttrs;
-
+
+ if (m_object->isDataTable())
+ return tableParamAttrs;
+
if (m_object->isMenuRelated())
return nil;
return [NSNumber numberWithInt:length];
}
+ if (m_object->isDataTable()) {
+ if ([attribute isEqualToString:NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
+ if (array == nil || [array count] != 2)
+ return nil;
+ AccessibilityTableCell* cell = static_cast<AccessibilityTable*>(m_object)->cellForColumnAndRow([[array objectAtIndex:0] unsignedIntValue], [[array objectAtIndex:1] unsignedIntValue]);
+ if (!cell)
+ return nil;
+
+ return cell->wrapper();
+ }
+ }
+
if (m_object->isTextControl()) {
if ([attribute isEqualToString: (NSString *)kAXLineForIndexParameterizedAttribute]) {
int lineNumber = m_object->doAXLineForIndex(intNumber);
+2008-08-19 chris fleizach <cfleizach@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Add snowleopard platform in layout tests
+
+ Added support for accessing the attributes of
+ accessibility tables through the accessibility controller
+ in DumpRenderTree
+
+ * DumpRenderTree/AccessibilityUIElement.cpp:
+ (attributesOfColumnHeadersCallback):
+ (attributesOfRowHeadersCallback):
+ (attributesOfColumnsCallback):
+ (attributesOfRowsCallback):
+ (attributesOfVisibleCellsCallback):
+ (attributesOfHeaderCallback):
+ (indexInTableCallback):
+ (rowIndexRangeCallback):
+ (columnIndexRangeCallback):
+ (childAtIndexCallback):
+ (cellForColumnAndRowCallback):
+ (AccessibilityUIElement::getJSClass):
+ * DumpRenderTree/AccessibilityUIElement.h:
+ * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+ (convertNSArrayToVector):
+ (descriptionOfElements):
+ (AccessibilityUIElement::getLinkedUIElements):
+ (AccessibilityUIElement::getChildren):
+ (AccessibilityUIElement::attributesOfLinkedUIElements):
+ (AccessibilityUIElement::attributesOfChildren):
+ (AccessibilityUIElement::attributesOfColumnHeaders):
+ (AccessibilityUIElement::attributesOfRowHeaders):
+ (AccessibilityUIElement::attributesOfColumns):
+ (AccessibilityUIElement::attributesOfRows):
+ (AccessibilityUIElement::attributesOfVisibleCells):
+ (AccessibilityUIElement::attributesOfHeader):
+ (AccessibilityUIElement::indexInTable):
+ (AccessibilityUIElement::rowIndexRange):
+ (AccessibilityUIElement::columnIndexRange):
+ (AccessibilityUIElement::cellForColumnAndRow):
+ * Scripts/run-webkit-tests:
+
2008-08-19 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
return JSValueMakeString(context, parameterizedAttributeNames.get());
}
+static JSValueRef attributesOfColumnHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfColumnHeaders(Adopt, toAXElement(thisObject)->attributesOfColumnHeaders());
+ return JSValueMakeString(context, attributesOfColumnHeaders.get());
+}
+
+static JSValueRef attributesOfRowHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfRowHeaders(Adopt, toAXElement(thisObject)->attributesOfRowHeaders());
+ return JSValueMakeString(context, attributesOfRowHeaders.get());
+}
+
+static JSValueRef attributesOfColumnsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfColumns(Adopt, toAXElement(thisObject)->attributesOfColumns());
+ return JSValueMakeString(context, attributesOfColumns.get());
+}
+
+static JSValueRef attributesOfRowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfRows(Adopt, toAXElement(thisObject)->attributesOfRows());
+ return JSValueMakeString(context, attributesOfRows.get());
+}
+
+static JSValueRef attributesOfVisibleCellsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfVisibleCells(Adopt, toAXElement(thisObject)->attributesOfVisibleCells());
+ return JSValueMakeString(context, attributesOfVisibleCells.get());
+}
+
+static JSValueRef attributesOfHeaderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> attributesOfHeader(Adopt, toAXElement(thisObject)->attributesOfHeader());
+ return JSValueMakeString(context, attributesOfHeader.get());
+}
+
+static JSValueRef indexInTableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ return JSValueMakeNumber(context, toAXElement(thisObject)->indexInTable());
+}
+
+static JSValueRef rowIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> rowIndexRange(Adopt, toAXElement(thisObject)->rowIndexRange());
+ return JSValueMakeString(context, rowIndexRange.get());
+}
+
+static JSValueRef columnIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> columnIndexRange(Adopt, toAXElement(thisObject)->columnIndexRange());
+ return JSValueMakeString(context, columnIndexRange.get());
+}
static JSValueRef lineForIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
if (argumentCount == 1)
indexNumber = JSValueToNumber(context, arguments[0], exception);
- return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(0));
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(indexNumber));
+}
+
+static JSValueRef cellForColumnAndRowCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ unsigned column = 0, row = 0;
+ if (argumentCount == 2) {
+ column = JSValueToNumber(context, arguments[0], exception);
+ row = JSValueToNumber(context, arguments[1], exception);
+ }
+
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->cellForColumnAndRow(column, row));
}
// Static Value Getters
{ "lineForIndex", lineForIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfColumnHeaders", attributesOfColumnHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfRowHeaders", attributesOfRowHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfColumns", attributesOfColumnsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfRows", attributesOfRowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfVisibleCells", attributesOfVisibleCellsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "attributesOfHeader", attributesOfHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "indexInTable", indexInTableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "rowIndexRange", rowIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "columnIndexRange", columnIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "cellForColumnAndRow", cellForColumnAndRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
double minValue();
double maxValue();
int insertionPointLineNumber();
-
+
+ // table specific attributes
+ JSStringRef attributesOfColumnHeaders();
+ JSStringRef attributesOfRowHeaders();
+ JSStringRef attributesOfColumns();
+ JSStringRef attributesOfRows();
+ JSStringRef attributesOfVisibleCells();
+ JSStringRef attributesOfHeader();
+ int indexInTable();
+ JSStringRef rowIndexRange();
+ JSStringRef columnIndexRange();
+
// parameterized attributes
int lineForIndex(int);
JSStringRef boundsForRange(unsigned location, unsigned length);
+ // table specific
+ AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row);
+
private:
static JSClassRef getJSClass();
return JSStringCreateWithCharacters(buffer.data(), buffer.size());
}
+static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector)
+{
+ NSUInteger count = [array count];
+ for (NSUInteger i = 0; i < count; ++i)
+ elementVector.append(AccessibilityUIElement([array objectAtIndex:i]));
+}
+
+static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector)
+{
+ NSMutableString* allElementString = [NSMutableString string];
+ size_t size = elementVector.size();
+ for (size_t i = 0; i < size; ++i) {
+ NSString* attributes = attributesOfElement(elementVector[i].platformUIElement());
+ [allElementString appendFormat:@"%@\n------------\n", attributes];
+ }
+
+ return [allElementString createJSStringRef];
+}
+
void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
{
NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
- NSUInteger count = [linkedElements count];
- for (NSUInteger i = 0; i < count; ++i)
- elementVector.append(AccessibilityUIElement([linkedElements objectAtIndex:i]));
+ convertNSArrayToVector(linkedElements, elementVector);
}
void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector)
{
NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
- NSUInteger count = [children count];
- for (NSUInteger i = 0; i < count; ++i)
- elementVector.append(AccessibilityUIElement([children objectAtIndex:i]));
+ convertNSArrayToVector(children, elementVector);
}
AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
{
Vector<AccessibilityUIElement> linkedElements;
getLinkedUIElements(linkedElements);
-
- NSMutableString* allElementString = [NSMutableString string];
- size_t size = linkedElements.size();
- for (size_t i = 0; i < size; ++i) {
- NSString* attributes = attributesOfElement(linkedElements[i].platformUIElement());
- [allElementString appendFormat:@"%@\n------------\n", attributes];
- }
-
- return [allElementString createJSStringRef];
+ return descriptionOfElements(linkedElements);
}
JSStringRef AccessibilityUIElement::attributesOfChildren()
{
Vector<AccessibilityUIElement> children;
getChildren(children);
-
- NSMutableString* allElementString = [NSMutableString string];
- size_t size = children.size();
- for (size_t i = 0; i < size; ++i) {
- NSString* attributes = attributesOfElement(children[i].platformUIElement());
- [allElementString appendFormat:@"%@\n------------\n", attributes];
- }
-
- return [allElementString createJSStringRef];
+ return descriptionOfElements(children);
}
JSStringRef AccessibilityUIElement::allAttributes()
return [boundsDescription createJSStringRef];
}
+JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
+{
+ // not yet defined in AppKit... odd
+ NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
+ Vector<AccessibilityUIElement> columnHeadersVector;
+ convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
+ return descriptionOfElements(columnHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
+{
+ // this attribute will appear in SnowLeopard
+ NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
+ Vector<AccessibilityUIElement> rowHeadersVector;
+ convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
+ return descriptionOfElements(rowHeadersVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfColumns()
+{
+ NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
+ Vector<AccessibilityUIElement> columnsVector;
+ convertNSArrayToVector(columnsArray, columnsVector);
+ return descriptionOfElements(columnsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfRows()
+{
+ NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
+ Vector<AccessibilityUIElement> rowsVector;
+ convertNSArrayToVector(rowsArray, rowsVector);
+ return descriptionOfElements(rowsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
+{
+ // this attribute will appear in SnowLeopard
+ NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
+ Vector<AccessibilityUIElement> cellsVector;
+ convertNSArrayToVector(cellsArray, cellsVector);
+ return descriptionOfElements(cellsVector);
+}
+
+JSStringRef AccessibilityUIElement::attributesOfHeader()
+{
+ id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
+ if (!headerObject)
+ return [@"" createJSStringRef];
+
+ Vector<AccessibilityUIElement> headerVector;
+ headerVector.append(headerObject);
+ return descriptionOfElements(headerVector);
+}
+
+int AccessibilityUIElement::indexInTable()
+{
+ NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
+ if (!indexNumber)
+ return -1;
+ return [indexNumber intValue];
+}
+
+JSStringRef AccessibilityUIElement::rowIndexRange()
+{
+ // will appear in SnowLeopard
+ NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
+ NSRange range = [indexRange rangeValue];
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+JSStringRef AccessibilityUIElement::columnIndexRange()
+{
+ // will appear in SnowLeopard
+ NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
+ NSRange range = [indexRange rangeValue];
+ NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
+ return [rangeDescription createJSStringRef];
+}
+
+AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
+{
+ // will appear in SnowLeopard
+ NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
+ return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray];
+}
if (isTiger()) {
$platform = "mac-tiger";
-} elsif (isLeopard() || isSnowLeopard()) {
+} elsif (isLeopard()) {
$platform = "mac-leopard";
+} elsif (isSnowLeopard()) {
+ $platform = "mac-snowleopard";
} elsif (isOSX()) {
$platform = "mac";
} elsif (isQt()) {