Wednesday, October 19, 2011

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.

No comments:

Post a Comment

Post a Comment