1
edit
m (→Example 8) |
(typo on gridcell role) |
||
| (28 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
=Note= | |||
Proposals of this page are obsolete by new IA2 interfaces IAccessibleTable2 and IAccessibleTableCell. | |||
=Summary= | =Summary= | ||
| Line 5: | Line 9: | ||
=Terms= | =Terms= | ||
There is a difference in header term definition between IAccessible2 and markup tables. | There is a difference in header term definition between IAccessible2 and markup tables. IA2 header is a table accessible (i.e. accessible implementing IAccessibleTable interface) with header cell accessibles describing the data cells or in other words rows or columns of the table. However, for example, ARIA header is cell element describing row or column of the table. | ||
Here we will use the header term as an element containing header cells, where header cell is an element describing row or column of the table. This definition is close to IA2 terminology. | Here we will use the header term as an element containing header cells, where header cell is an element describing row or column of the table. This definition is close to IA2 terminology. | ||
| Line 21: | Line 25: | ||
However html:th can be used outside of html:thead or html:tfoot elements and be used to provide heading information as well. HTML 4 specification defines [http://www.w3.org/TR/html401/struct/tables.html#h-11.4.3 algorithm of finding heading information]. | However html:th can be used outside of html:thead or html:tfoot elements and be used to provide heading information as well. HTML 4 specification defines [http://www.w3.org/TR/html401/struct/tables.html#h-11.4.3 algorithm of finding heading information]. | ||
Also HTML specification defines @scope and @headers attributes on cells of the table. Attribute @scope is used to specify | Also HTML specification defines [http://www.w3.org/TR/html401/struct/tables.html#adef-scope @scope] and [http://www.w3.org/TR/html401/struct/tables.html#adef-headers @headers] attributes on cells of the table. Attribute @scope placed on a cell is used to specify set of data cells described by this cell. Also @scope attribute defines if this cell is column or row header cell. Attribute @header used to link the data cell with header cells directly. | ||
===XUL tree and listbox=== | ===XUL tree and listbox=== | ||
| Line 144: | Line 148: | ||
<span role="gridcell"></span> | <span role="gridcell"></span> | ||
<span role="columnheader">John</span> | <span role="columnheader">John</span> | ||
<span | <span role="columnheader">Ivan</span> | ||
</div> | </div> | ||
<div role="row"> | <div role="row"> | ||
<span role="rowheader">Apples</span> | <span role="rowheader">Apples</span> | ||
<span role="gridcell">10</span> | <span role="gridcell">10</span> | ||
<span | <span role="gridcell">12</span> | ||
</div> | </div> | ||
<div role="row"> | <div role="row"> | ||
| Line 484: | Line 488: | ||
</tbody> | </tbody> | ||
</table> | </table> | ||
</pre> | |||
=====Example 9===== | |||
The following example has been introduced on [http://www.w3.org/TR/html401/struct/tables.html#h-11.4.2 w3c]. However adduced HTML markup was adopted from [http://www.oit.umd.edu/WebClinics/tables/21.html here]. | |||
{| border="1" cellpadding=2 cellspacing=3 caption="TRAVEL EXPENSES (actual cost, US$)" | |||
|- | |||
| style="font-weight: bold" | Trip/date | |||
| style="font-weight: bold" | Meals | |||
| style="font-weight: bold" | Room | |||
| style="font-weight: bold" | Trans | |||
| style="font-weight: bold" | Total | |||
|- | |||
| style="font-weight: bold" | San Jose | |||
|- | |||
| 25 Aug 97 | |||
| 37.74 | |||
| 112.00 | |||
| 45.00 | |||
|- | |||
| 26 Aug 97 | |||
| 27.28 | |||
| 112.00 | |||
| 45.00 | |||
|- | |||
| Subtotal | |||
| 65.02 | |||
| 224.00 | |||
| 90.00 | |||
| 379.02 | |||
|- | |||
| style="font-weight: bold" | Seattle | |||
|- | |||
| 27 Aug 97 | |||
| 96.25 | |||
| 109.00 | |||
| 36.00 | |||
|- | |||
| 28 Aug 97 | |||
| 35.00 | |||
| 109.00 | |||
| 36.00 | |||
|- | |||
| Subtotal | |||
| 131.25 | |||
| 218.00 | |||
| 72.00 | |||
| 421.25 | |||
|- | |||
| style="font-weight: bold" | Totals | |||
| 196.27 | |||
| 442.00 | |||
| 162.00 | |||
| 800.27 | |||
|} | |||
<pre> | |||
<table border="1" cellpadding=2 cellspacing=3> | |||
<caption>Travel Expenses (actual cost, US$)</caption> | |||
<thead> | |||
<tr> | |||
<th><p><span id="t1-r1-l1">Trip</span>,<br><span id="t1-r1-l2">date</span></p></th> | |||
<th scope="column">Meals</th> | |||
<th scope="column">Room</th> | |||
<th scope="column" abbr="Transportation">Trans.</th> | |||
<th scope="column">Total</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<th scope="rowgroup" headers="t1-r1-l1">San Jose</th> | |||
</tr> | |||
<tr> | |||
<td scope="row" headers="t1-r1-l2">25 Aug 97</td> | |||
<td>37.74</td> | |||
<td>112.00</td> | |||
<td>45.00</td> | |||
</tr> | |||
<tr> | |||
<td scope="row" headers="t1-r1-l2">26 Aug 97</td> | |||
<td>27.28</td> | |||
<td>112.00</td> | |||
<td>45.00</td> | |||
</tr> | |||
<tr> | |||
<td scope="row">Subtotal</td> | |||
<td>65.02</td> | |||
<td>224.00</td> | |||
<td>90.00</td> | |||
<td>379.02</td> | |||
</tr> | |||
</tbody> | |||
<tbody> | |||
<tr> | |||
<th scope="rowgroup" headers="t1-r1-l1">Seattle</th> | |||
</tr> | |||
<tr> | |||
<td scope="row" headers="t1-r1-l2">27 Aug 97</td> | |||
<td>96.25</td> | |||
<td>109.00</td> | |||
<td>36.00</td> | |||
</tr> | |||
<tr> | |||
<td scope="row" headers="t1-r1-l2"> 28 Aug 97</td> | |||
<td>35.00</td> | |||
<td>109.00</td> | |||
<td>36.00</td> | |||
</tr> | |||
<tr> | |||
<td scope="row">Subtotal</td> | |||
<td>131.25</td> | |||
<td>218.00</td> | |||
<td>72.00</td> | |||
<td>421.25</td> | |||
</tr> | |||
</tbody> | |||
<tbody> | |||
<tr> | |||
<th scope="row">Totals</th> | |||
<td>196.27</td> | |||
<td>442.00</td> | |||
<td>162.00</td> | |||
<td>800.27</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</pre> | </pre> | ||
| Line 505: | Line 640: | ||
===Relations=== | ===Relations=== | ||
The second way is to implement [http://a11y.org/a11yspecs/ia2/docs/html/group__grp_relations.html#g478e78069b9a5439a01943969d1423a7 DESCRIBED_BY] and [http://a11y.org/a11yspecs/ia2/docs/html/group__grp_relations.html#g41a99b1990da6ba8e8c02fbc96a7c58f DESCRIPTION_FOR] accessible relations which link header cells and data cells each other. This way suggests header cell accessibles expose DESCRIPTION_FOR relation with multiple targets pointing to data cells and data cell accessible expose DESCRIPTION_BY relation with multiple targets pointing to header cells. | |||
IAccessible2 provides [http://a11y.org/a11yspecs/ia2/docs/html/interface_i_accessible2.html#967f0dffba760744b5963f42bb7be8ed relations] attribute to get all exposed relations on this accessible. | IAccessible2 provides [http://a11y.org/a11yspecs/ia2/docs/html/interface_i_accessible2.html#967f0dffba760744b5963f42bb7be8ed relations] attribute to get all exposed relations on this accessible. | ||
| Line 515: | Line 652: | ||
</pre> | </pre> | ||
Once you acquired [http://a11y.org/a11yspecs/ia2/docs/html/interface_i_accessible_relation.html IAccessibleRelation] object for the interested accessible relation you can use [http://a11y.org/a11yspecs/ia2/docs/html/interface_i_accessible_relation.html#ceeb5c0c90f8d4a7f167556bec4df682 targets] method to get all accessible targets. | |||
<pre> | <pre> | ||
| Line 524: | Line 661: | ||
</pre> | </pre> | ||
= | =Header Tables approach= | ||
XUL trees and listboxes only have a persistent way to provide header from markup. Persistent way means tree or listbox elements have a table header if and only if header element is provided in markup. HTML tables haven't unique way to provide column header information. Moreover there is no markup for HTML table to provide row header, however html:th elements can be used to create row header visually. And ARIA hasn't markup for headers at all. But AT wants to deal with all tables in unique way. | XUL trees and listboxes only have a persistent way to provide header from markup. Persistent way means tree or listbox elements have a table header if and only if header element is provided in markup. HTML tables haven't unique way to provide column header information. Moreover there is no markup for HTML table to provide row header, however html:th elements can be used to create row header visually. And ARIA hasn't markup for headers at all. But AT wants to deal with all tables in unique way. Here we need to figure our the structure of header tables so that this structure won't be depended on markup used to create a table. | ||
= | ===Header table hierarchy=== | ||
The header table tree should have usual structure for accessible tables. | |||
=====[[#Example_1|Example 1]], [[#Example_2|example 2]] and [[#Example_3|example 3]]===== | |||
These examples expose simple header tables. | |||
Column header table | Column header table exposed as | ||
<pre> | <pre> | ||
table | table | ||
| Line 541: | Line 679: | ||
</pre> | </pre> | ||
Row header table | Row header table exposed as | ||
<pre> | <pre> | ||
table | table | ||
| Line 549: | Line 687: | ||
header_cell | header_cell | ||
</pre> | </pre> | ||
=====[[#Example_4|Example 4]]===== | |||
It exposes more complex header tables. | |||
Column header table tree might be | |||
<pre> | |||
table | |||
row | |||
cell "Animals" colspan="2" | |||
row | |||
cell "Lion" | |||
cell "Triger" | |||
</pre> | |||
Row header table might be | |||
<pre> | |||
table | |||
row | |||
cell "Vegetables" rowspan="2" | |||
cell "Potato" | |||
row | |||
cell "Carrot" | |||
</pre> | |||
=====[[#Example_5|Example 5]]===== | |||
Provides couple of tables where header tables have similar structure with table headers from previous examples. Nothing unpredictable. | |||
=====[[#Example_6|Example 6]]===== | |||
Provides simple row header table. However the way how to expose the column header table might be a trick. | |||
It might be simple column header like | |||
<pre> | |||
table | |||
row | |||
cell "Products" | |||
cell "Downloads number in" | |||
</pre> | |||
but this table loose "2008" and "2009" column header cells and exposed heading information is not complete. If we would try to include "2008" and "2009" header cells into column header table then AT won't have any idea what header cells are used to describe a particular data cell. | |||
One possible approach is IAccessibleTable should expose several header tables like | |||
<pre> | |||
HRESULT getColumnHeaderCount( | |||
[out,retval] long * headerCount) [get] | |||
HRESULT columnHeaderAtIndex( | |||
[in] long headerIndex, | |||
[out] IAccessibleTable **accessibleTable, | |||
[out, retval] long * startingRowIndex) [get] | |||
</pre> | |||
Here we would return three column header tables. If we would add object attribute specifies if cells in the header table are applied locally or affects on whole table then we will address the fact "Products" and "Downloads ..." column header are applied to all data cells, however "2008" and "2009" header cells describing underlying cells only. Any way it's not easy to change IAccessible2 specification. Thus header table approach can't expose tables like this correctly. | |||
=====[[#Example_7|Example 7]] and [[#Example_8|example 8]]===== | |||
Ideally client should provide simple column header table for example 7 because bottom column headers duplicates the top column headers. However column header generated by tfoot element can't be ignored always, example 8 clearly shows this. This tfoot should be result of single-cell row header table. It's not clear how to expose this heading information to AT via header tables like we have in example 6 because "Month" isn't header cell for "Total" row header cell. | |||
=====[[#Example_9|Example 9]]===== | |||
This example is much similar to example 6. It's hard to expose it via table header approach. | |||
===Virtual tree=== | |||
The idea is to expose a virtual tree for header tables, i.e. this tree is not linked with main accessible tree and root of the tree is accessible table for header. | |||
Cell and row elements might be exposed twice as accessible objects (one accessible object is for main accessible tree, another one is virtual header tree). However these twin accessible objects are different. For example, this makes IAccessible navigation methods to work independently, so that if you run through parents of cell from virtual tree then you will achieve header table, if you run up from cell of main tree then you will achieve original table accessible. As well, "table-cell-index" returns index in header table for virtual cell and returns index in main table for normal cell. | Cell and row elements might be exposed twice as accessible objects (one accessible object is for main accessible tree, another one is virtual header tree). However these twin accessible objects are different. For example, this makes IAccessible navigation methods to work independently, so that if you run through parents of cell from virtual tree then you will achieve header table, if you run up from cell of main tree then you will achieve original table accessible. As well, "table-cell-index" returns index in header table for virtual cell and returns index in main table for normal cell. | ||
===State changes=== | |||
If states are changed for the one accessible then states are changed for its twin accessible in another subtree. For example, if you call IAccessibleTable::selectColumn on virtual header table then it selects cells of primary table as well and visa versa. | If states are changed for the one accessible then states are changed for its twin accessible in another subtree. For example, if you call IAccessibleTable::selectColumn on virtual header table then it selects cells of primary table as well and visa versa. | ||
===Events and HitTest=== | ===Events and HitTest=== | ||
Since virtual table header is not linked with main tree then it's impossible to find accessibles of virtual tree by HitTest. As well this is the reason AccessibleObjectFromEvent might not work. So no events should be expected from table header accessible tree. AT can listen original table accessibles on mutation event to requery table header accessible. | Since virtual table header is not linked with main tree then it's impossible to find accessibles of virtual tree by HitTest. As well this is the reason AccessibleObjectFromEvent might not work. So no events should be expected from table header accessible tree. AT can listen original table accessibles on mutation event to requery table header accessible. | ||
=Relations approach= | |||
At the first sight relations approach is more flexible because it should address trick cases of heading usage, especially for the case of HTML tables where @headers attribute is used. Since aria-describedby can be used on data cell to point to non heading information then AT should ignore non header cell accessibles during heading information processing. Also there is one relations approach feature consisted in order of relation targets corresponds to DOM hierarchy, i.e. if heading information doesn't correspond to table cells DOM hierarchy then AT will announce heading wrong. | |||
[[#Example_1|Example 1]]-[[#Example_5|Example 5]] provides expected relation targets. For example, data cell at (row=2, column=2) of [[#Example_4|example 4]] is described by "Vegetable", "Potato" and by "Animals", "Lion". | |||
Another examples are handled in predictable way as well. For example, data cell at (row=6, column=1) of [[#Example_9|example 9]] (cell data is "96.25") is described by "Seattle", "Trip" and "Meals" header cells. | |||
edit