Wednesday, October 26, 2011

When HTML table is an accesible table

In addition to previous topic Data vs layout tables another aspect of the issue is when layout-guess computation algorithm is applied for HTML table elements.

Shortly the algorithm starts working if HTML table element has associated table accessible. In particular that means it doesn't run if HTML table is not accessible, i.e. it doesn't have any associated accessible object in the accessible objects hierarchy. This happens if HTML table is
  • not visible (CSS display:none or visibility:hidden styles are applied)
  • not focusable and ARIA role="presentation" is used on it.

Another case is when table element is accessible but it's not a table accessible. From AT perspective the table accessible is an accessible object that exposes a number of table specific interfaces (like IAccessibleTable2 in case of IAccessible2) and has proper accessible roles (like MSAA table or outline roles). So this case is effective (no table accessible is created) when ARIA role used to override native semantics is set on the element, for example role="button". Note, the same time weak ARIA roles like role="banner" don't affect on table semantics and the element gets treated as a table by AT.

In either case HTML table accessibility state affects on its underlying accessible hierarchy. So that if HTML table is not accessible or is not a table accessible then no table structure is exposed, i.e. no rows and no cells.

Also table accessibles may be created for elements different than HTML tables. There are two options to do that:
  • CSS display:table
  • table specific ARIA roles like role="grid" or role="treegrid".
The layout-guess algorithm returns true in former case and false in second case.

Wednesday, October 19, 2011

Data vs layout table

Tables in accessible world may be treated as data or layout table. The data tables are supposed to contain data and user should be able to navigate through its structure and get information like headings. Typical example of data table is grid. Layout tables are supposed for elements arrangement on the screen and structure of these tables is likely ignored by AT.

Firefox provides semi-standard layout-guess object attribute on table accessible to say whether this table is for data or layout. Shortly, this attribute is exposed for layout tables only, for data table it's omitted. This object attribute wasn't adopted by IAccessible2 or ATK specifications yet but there is discussion on IAccessible2 list.

Firefox relies on the following algorithm to detect whether the table is layout or not. The algorithm stops when it hits the item. Note, the algorithm is applicable to accessible HTML tables only (check out when HTML table has no accessible).

Algorithm
  • Table inside editable area is data table always since the table structure is crucial for table editing
  • Table having ARIA table related role is data table (like ARIA grid or treegrid)
  • Table having ARIA landmark role is data table
  • Table having datatable="0" attribute is layout table (Firefox 10)
  • Table created by CSS display style is layout table (Firefox 11)
  • Table having summary attribute or legitimate data table structures is data table; these structures are:
    • caption element
    • col or colgroup elements
    • tfoot or thead elements
    • th elements 
    • header, scrope or abbr attributes on table cell (Firefox 13)
    • abbr element as a single child element of table cell (Firefox 13)
  • Table having nested table is layout table
  • Table having only one row or column is layout table
  • Table having many columns (>= 5) is data table
  • Table having borders around cells is data table
  • Table having differently colored rows is data table
  • Table having many rows (>= 20) is data table
  • Wide table (more than 95% of the document width) is layout table
  • Table having small amount of cells (<= 10) is layout table
  • Table containing embed, object, applet of iframe elements (typical advertisements elements) is layout table
  • Otherwise it's data table

Updated to Firefox 13.

Accessible document handling in Firefox

The accessible document handling is one of tricky parts of accessible Firefox implementation and implicates not evident details. By providing up-to-dated knowledge about this are I hope this information will be interesting for AT developers.

The document accessible is self-contained unit in Firefox and it's mapped into AT APIs by different ways. For example, neither MSAA nor IAccessible2 has similar concept and accessible roles is a primary test used to detect this particular accessible is document accessible. The same time the knowing that this particular accessible is a document accessible having specific document type might be important for AT because it allows to make assumptions about the content and the ways how it should be expose to the user.

Document types

A document accessible may belong to one or more document types. This is mostly terminological split, however documents may be characterized by specific properties depending on type.

Hierarchical and content-dependent types


Tab document
A document accessible created for web page within the browser tab.

On Windows Gecko provides non-standard way to acquire a tab document accessible from any its child accessible object. For that the following GUID:
const GUID SID_IAccessibleContentDocument = {0xa5d8e1f3,0x3571,0x4d8f,0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e}
is used as argument of IServiceProvider::QueryService() method.

Chrome document
A document created for every main Firefox window.

Application document
A document created for any Firefox UI document (also referred as chrome). Note, the application document can be a tab document if it's hosted within a browser tab like add-ons page. In other words, this is either chrome document or tab document.

Dialog document
Different kinds of dialog documents have this type. For example XUL dialog, XUL wizard elements or ARIA dialogs (like role="dialog").

Sub document
A document contained within tab or application document. Sub documents may be nested. For example, documents contained by iframe element accessible objects.

Temporary document
Temporary documents is something we try to avoid but there are few cases when they are created for a short period. The document of this type is replaced by another document shortly.

Native and not native document types


Native document
Native documents are referred to document accessible created for any DOM document. Native document can belong to any of document types listed above.

Not native document
The document accessible can be created when there's no DOM document underneath. It can be done by ARIA like role="dialog" or "document" or "application" placed on HTML element (other than document element or HTML body) or by HTML5 markup like HTML article element. The behavior of such documents may be different from the behavior of native documents since they don't maintain set of features inherent to native documents.

Roles

The document accessible can have one of the following accessible roles:
  • DOCUMENT role
  • APPLICATION role
  • DIALOG role
Exposed role depends on document type. Note that ARIA role can be used to change accessible role.

DOCUMENT role
MSAA / ATK roles: ROLE_SYSTEM_DOCUMENT / ATK_ROLE_DOCUMENT_FRAME.
Primary this role is used for web page documents and for their sub documents.

APPLICATION role
MSAA / ATK roles: ROLE_SYSTEM_APPLICATION / ATK_ROLE_EMBEDDED.
The application role is used for chrome documents when they aren't dialogs. For example, it's used for Firefox UI window, add-ons page or error pages.

DIALOG role
MSAA / ATK roles: ROLE_SYSTEM_DIALOG / ATK_ROLE_DIALOG.
Used for dialog documents.

States

The following states related with document life cycle can be exposed by document accessible.

STALE state
IAccessible2 / ATK states: IA2_STATE_STALE / ATK_STATE_STALE.
The state is exposed when document is not attached to the tree (see Document creation section).

BUSY state
MSAA / ATK states: STATE_SYSTEM_BUSY / ATK_STATE_BUSY.
The state is exposed when document is loading or HTTP request was initiated by user (for example, when clicking on link).

Events

The following events related with document life cycle can be fired.

REORDER event
MSAA event: STATE_SYSTEM_REORDER.
Fired on document container accessible when document accessible is attached to the tree. Target: any document.

LOAD_COMPLETE event
IAcessible2 event / ATK signal: IA2_EVENT_DOCUMENT_LOAD_COMPLETE / "load_complete".
Fired when document is loaded conjointly with its sub documents (the document is referred as completely loaded document). Target: any document, a root of documents loading chain (Firefox 16 and later).

Compatibility.
  • [Firefox 15] target: any native document, a root of documents loading chain. 
  • [Prior to Firefox 15] target: a tab document.

LOAD_STOPPED event
IAcessible2 event / ATK signal: IA2_EVENT_DOCUMENT_LOAD_STOPPED/ "load_stopped".
Fired when document loading is cancelled. Target: any native document, a root of documents loading chain (Firefox 15 and later).

Compatibility. [Prior to Firefox 15] target: a tab document.

RELOAD event
IAcessible2 event / ATK signal: IA2_EVENT_DOCUMENT_RELOAD / "reload".
Fired when the document is about to reload. 'eventFromUserInput' object attribute on document accessible can be used to detect whether the event was caused by user or programmatically. Target: any native document, a root of documents loading chain (Firefox 15 and later).

Compatibility. [Prior to Firefox 15] target: a tab document. 

STATE_CHANGE event
MSAA event / ATK signal: EVENT_OBJECT_STATECHANGE / "state-change".
Fired when documents is completely loaded or loading was cancelled. Fired immediately after LOAD_COMPLETE or LOAD_STOPPED events. Target: any native document, a root of documents loading chain (Firefox 15 and later).

Compatibility. [Prior to Firefox 15] target: a tab document. 

Document creation

A document accessible is created whenever it gains DOM content or the accessible was requested by AT.

The document has STALE state until its initial content is loaded and until the document is attached to the tree. After that the REORDER event on the document container is emitted. In case of document that is a root in hierarchy the REORDER event is fired on application accessible.

The document keeps BUSY state until it gets completely loaded or loading was cancelled. After that the LOAD_COMPLETE or LOAD_STOPPED events are fired.

Children getting

On Windows the document accessible allows to get any child accessible within it by accessible unique ID (refer to IAccessible::accChild). This is quite useful mechanism to get an event target. Note, this works for ARIA documents as well.

Updated to Firefox 16.