Mozilla Support for Linux/UNIX Assistive Technology Developers

This FAQ explains how makers of Linux- or UNIX- based screen readers, voice dictation packages, onscreen keyboards, magnification software and other assitive technologies can support Gecko-based software. The base of our support for these products is AT-SPI (Assistive Technology Service Provider Interface) and the keyboard API/user interface.

For Firefox and all other Gecko-based products: this documentation only applies to up-to-date builds of Firefox -- currently not an official releases. Grab the current build of Firefox which supports these features

In this document

To Do

Definitions

Here are some basic definitions that you'll need for this document to make sense:

Gecko:
The rendering engine for Firefox, Thunderbird, Nvu, Mozilla Seamonkey and other applications. Gecko is the internal engine that Mozilla uses to render any kind of web content. It supports HTML, XHTML, Cascading Style Sheets (CSS) and the Document Object Model (DOM).
Assistive Technology Service Provider Interface (AT-SPI)
an API devised by Sun Microsystems so that accessibility aids can track what's going on inside the user interface of any software package that supports it. If you seriously need to understand AT-SPI, you'll need to read the docs on gnome.org and play with the available sample apps and code, such as at-poke. Please note that the web docs are sometimes out of date, and the latest AT-SPI is available on CVS.
DOM: Document Object Model
This is the W3C's specification for how web content is exposed to Javascript and other languages. It covers content, style and events. Inside the Gecko process, code has full access to DOM APIs. However, exposing the entire DOM to external software packages is quite involved, partially because changes to the DOM in Firefox must occur on the main thread. We have chosen a subset of readonly methods in the DOM needed for assistive technology vendors. Events such as focus changes must be tracked through AT-SPI events, rather than DOM events.
XUL: eXtensible User-interface Language
The XML-based language used by Firefox and Mozilla to develop the UI. Similar to HTML in that it can be combined with CSS and Javascript to make powerful applications. Contains more desktop-style widgets than HTML and follows a box layout model, rather than being text-flow based.
AJAX: Asynchronous JavaScript And XML
AJAX is a method of building interactive web applications that process user requests, user actions immediately in real time, unlike an HTTP request, during which users must wait for a whole page to reload or for a new page to load. Data is therefore stored and retrieved dynamically much faster.
Roles, states and events:
please read the AT-SPI documentation if you are unfamiliar with these.

AT-SPI tree vs. DOM tree - what's the relation?

The AT-SPI tree and the DOM tree are parallel structures, although the AT-SPI tree is a subset of the DOM tree. QueryInterface() can be used to switch between the interfaces (Accessible, AccessibleText, AccessibleValue, etc.).

What is exposed? Any DOM node that ...

Linix/UNIX Applications Based on the Gecko Layout Engine

Gecko is a rendering engine that Firefox, SeaMonkey, Netscape and yelp use. Gecko can render a variety of content, not just HTML and supports key web standards such as Cascading Style Sheets, Javascript and the W3C DOM. Gecko also handles the users keystrokes and mouse clicks. Gecko is the core architecture that we are adding accessibility to, in order to support basic accessibility in all applications that are based on it.

The Mozilla Gecko engine must be version 1.9 or later to have high quality AT-SPI support, as documented here.

Embedded Clients

Embedded clients use Gecko only in the content window, at the moment for HTML and generic XML only. They typically use standard Windows controls for their user interface -- the area outside of the client content window, plus the context menu.

XUL-Based Clients

XUL-based clients make full use of the Gecko architecture, not only for HTML content, as well as for menus, dialogs and the entire user interface via an XML language called XUL (eXtensible User-interface Language). None of the user interface contains standard Windows controls -- not even the menus! This is done to ensure a common look and feel across all supported platforms, and to allow for different skins (appearances).

Determining if Accessibility is Enabled in a Firefox Installation

See the about:accessibilityenabled Firefox extension.

How to Find the Content Window and Load the Document

In XUL-based clients, screen readers may need to find the content window so that they know where to start grabbing the AT-SPI tree, in order to load the current document into a buffer in their own process.

Use RELATION_EMBEDS on the ROLE_FRAME, which is at the root of each top level window. This will point to the root content accessible(s) for that XUL window.

When you see the content window receive focus, first check the role. If it is a ROLE_DOCUMENT then this should be treated as a document for the default modality of the screen reader. If it is a ROLE_EMBEDDED, ROLE_DIALOG or ROLE_ALERT then stay in focus tracking mode -- there is no need to parse the document. In addition, if it is a ROLE_ALERT, a screen reader should treat it as a message box -- that is, to read the entire contents. These roles can occur on content because of the new Accessible DHTML technology which allows the author to specify the type of document or container.

Gecko also helps determine when to load a new window by firing the following document events: document:load-complete, document:reload and document:load-stopped

 

Supported AT-SPI Interfaces

Interface Supported Notes
Accessible Yes See supported object attributes below
Action Yes All methods
Application Yes All methods
Component Yes All methods
Desktop No
Document Yes All methods?
EditableText Yes All methods
Event Yes See supported events below
Hyperlink Yes Any object embedded in text is considered a hyperlink!
Hypertext Yes Any text with objects embedded in it is considered a hypertext!
Image No ROLE_IMAGE is supported, and is enough
LoginHelper No
Registry No?
Relation Yes See supported relations below
Role Yes See supported roles below
Selection Yes Not yet supported for text
Selector No
State Yes See supported states below
StreamableContent No Could apply to plugins, but probably not objects rendered by Gecko
Table Yes In addition, the object attribute layout-guess=true when Gecko thinks the table is for layout, not for data
Text Yes See supported text attributes below
Value Yes

Supported AT-SPI Roles

The following roles are currently supported:

** XXX Needs updating -- this list is copied from MSAA document ***

XUL: <image>
HTML: <img>

XUL: <label> or <description>
HTML: <label>
DHTML: role="wairole:label"

XUL: <listbox>
HTML: <select size=""> where size > 1 -- STATE_READONLY is off
HTML: <ol> or <ul> -- STATE_READONLY is on
DHTML: role="wairole:list"

XUL: <menuitem>
DHTML: role="wairole:menuitem"

XUL: <tab>
DHTML: role="wairole:tablist"

XUL: <button>
HTML: <input type="button"> or<button>
DHTML: role="wairole:button"

Fires object:state-changed when radiobutton is set/unset

XUL: <separator>
HTML: <hr>
DHTML: role="wairole:separator" XUL: <tooltip> or tooltiptext attribute
Role Supported? Special features
ROLE_INVALID Not a role that can be supported
ROLE_ACCELERATOR_LABEL No
ROLE_ALERT XUL: <browsermessage>
DHTML: xhtml2:role="wairole:alert"
ROLE_ANIMATION No. Animated images use ROLE_GRAPHIC with STATE_ANIMATED.
ROLE_ARROW No
ROLE_CALENDAR No
ROLE_CANVAS No
*** XXX File bug to support for <canvas> ***
ROLE_CHECK_BOX XUL: <checkbox>
HTML: <input type="checkbox">
DHTML: role="wairole:checkbox"
Fires Fires object:state-changed when radiobutton is set/unset when checkbox is toggled
ROLE_CHECK_MENU_ITEM XUL: <menuitem type="checkbox">
DHTML: *** XXX file bug to support via role="wairole:menuitemcheckbox" ***
Supports STATE_CHECKED
ROLE_COLOR_CHOOSER No
ROLE_COLUMN_HEADER XUL: tree column headers
HTML: <th>
DHTML: role="wairole:columnheader"
ROLE_COMBO_BOX XUL: <menulist>
HTML: <select size="1">
DHTML: role="wairole:combobox"
What event do we fire for changes in closed combo box?
ROLE_DATE_EDITOR No
ROLE_DESKTOP_ICON No
ROLE_DESKTOP_FRAME No
Role Supported? Special features
ROLE_DIAL No
ROLE_DIALOG

XUL: <dialog>
DHTML: role="wairole:dialog"

accessible name exposes the <title> of the current dialog
ROLE_DIRECTORY_PANE No
ROLE_DRAWING_AREA No
ROLE_FILE_CHOOSER Supported for native filepicker
ROLE_FILLER No
ROLE_FONT_CHOOSER No
ROLE_FRAME Top level window
ROLE_GLASS_PANE No
ROLE_HTML_CONTAINER No
ROLE_ICON No
ROLE_IMAGE XUL: <image>
HTML: <img>
ROLE_INTERNAL_FRAME No
ROLE_LABEL XUL: <label>
HTML: <label>
DHTML: role="wairole:label"
Supports RELATION_LABEL_FOR (although technically anthing can)
ROLE_LAYERED_PANE No
ROLE_LIST
ROLE_LIST_ITEM XUL: <listitem>
HTML: <li>, <option> or <optgroup>
DHTML: role="wairole:listitem"
Sets STATE_SELECTED if the current listitem is selected.

*** XXX Perhaps should support object attribute "level" when in ROLE_TREE or ROLE_TREE_TABLE, see object attributes section ***
ROLE_MENU XUL: <menuitem> with children
DHTML: role="wairole:menuitem" with child menuitems *** XXX does this work? ***
ROLE_MENU_BAR XUL: <menubar>
DHTML: role="wairole:menubar"
Role Supported? Special features
ROLE_MENU_ITEM
ROLE_OPTION_PANE No
ROLE_PAGE_TAB XUL: <tab>
DHTML: role="wairole:tab"
ROLE_PAGE_TAB_LIST
ROLE_PANEL XUL: <radiogroup>, <groupbox>, <iframe>
HTML: <fieldset>, <frame>, <iframe>
DHTML: role="wairole:group", role="wairole:radiogroup"
ROLE_PASSWORD_TEXT XUL: <textbox type="password">
HTML: <input type="password">
DHTML: role="wairole:secret"
ROLE_POPUP_MENU No, apparently we use ROLE_MENU even for the context menu. XXX *** Is this right? *** Supports Text and EditableText interfaces
ROLE_PROGRESS_BAR XUL: <progressmeter>
DHTML: role="wairole:progressbar"

Fires "object:property-change:accessible-value" when progressbar moves by at least 3%

Supports Value interface

ROLE_PUSH_BUTTON
ROLE_RADIO_BUTTON XUL: <radio>
HTML: <input type="radio">
DHTML: role="wairole:radio"
ROLE_RADIO_MENU_ITEM XUL: <menuitem type="radio">
DHTML: *** XXX file bug to support via role="wairole:menuitemradio" *
Supports STATE_CHECKED
ROLE_ROOT_PANE No
ROLE_ROW_HEADER DHTML: role="wairole:columnheader"
ROLE_SCROLL_BAR Not yet, bug 285167
ROLE_SCROLL_PANE No
Role Supported? Special features
ROLE_SEPARATOR
ROLE_SLIDER XUL:slider should be supported soon via bug 109215
DHTML: role="wairole:slider"
Fires "object:property-change:accessible-value" when slider thumb is moved

Supports Value interface
ROLE_SPIN_BUTTON DHTML: role="wairole:spinbutton" Fires "object:property-change:accessible-value" when changed

Supports Value interface
ROLE_SPLIT_PANE No
ROLE_STATUS_BAR XUL: <statusbar>
ROLE_TABLE HTML: <table>
DHTML: role="wairole:grid"
Supports Table interface
Supports object attribute "layout-guess", see object attributes section
ROLE_TABLE_CELL HTML: <td>
DHTML: role="wairole:gridcell"
*** XXX Perhaps should support object attribute "level" when in ROLE_TREE or ROLE_TREE_TABLE, see object attributes section ***
ROLE_TABLE_COLUMN_HEADER HTML: <th>
DHTML: role="wairole:columnheader" *** XXX Actually, do we use this one or ROLE_COLUMN_HEADER? ***
ROLE_TABLE_ROW_HEADER DHTML: role="wairole:rowheader" *** XXX Actually, do we use this one or ROLE_ROW_HEADER? ***
ROLE_TEAROFF_MENU_ITEM No
ROLE_TERMINAL No
ROLE_TEXT HTML: fallback for display-block styled elements with no known semantic role for the tag
DHTML: role="wairole:description"
XXX *** We are using ROLE_TEXT for DHTML descriptions but ROLE_LABEL for XUL ones, that's inconsistent XXX
Supports Text interface
ROLE_TOGGLE_BUTTON No
ROLE_TOOL_BAR XUL: <toolbar>
DHTML: role="wairole:toolbar"
ROLE_TOOL_TIP
ROLE_TREE No, XXX *** We should use this when there is only 1 column in the tree ***
DHTML: ?
ROLE_TREE_TABLE XUL: <tree>
DHTML: role="wairole:tree" ?
ROLE_UNKNOWN No
ROLE_VIEWPORT No
ROLE_WINDOW No
ROLE_HEADER No
Role Supported? Special features
ROLE_FOOTER No
ROLE_PARAGRAPH HTML: <p>
ROLE_RULER No
ROLE_APPLICATION Root accessible object, parent of top level ROLE_FRAME's
ROLE_AUTOCOMPLETE XUL: <textbox type="autocomplete">
ROLE_EDITBAR No
ROLE_EMBEDDED DHTML: role="wairole:application"
ROLE_ENTRY  XUL: <textbox>
HTML: <input type="text"> or <textarea>
DHTML: role="wairole:textfield" or
role="wairole:textarea"
Supports Text interface
ROLE_CHART No
ROLE_CAPTION HTML: <caption>
ROLE_DOCUMENT_FRAME HTML: <body> without a role on the <html> or <body> element (unless that is wairole:document)
DHTML: role="wairole:document"
Supports Document interface
ROLE_HEADING HTML: <h1>, <h2>, <h3>, <h4>, <h5>, <h6> Supports Text interface

Supports object attribute "level", see object attributes section ***
ROLE_PAGE No
ROLE_SECTION HTML: <div> Supports Text interface
ROLE_FORM HTML: <form> Supports Text interface
ROLE_REDUNDANT_OBJECT No
ROLE_LINK XUL: <label class="text-link">
HTML: <a>, <area>
DHTML: role="wairole:link"
ROLE_INPUT_METHOD_WINDOW No
Role Supported? Special features

Supported AT-SPI States

The following states are currently supported:

State Supported? Where used
STATE_INVALID No Not a usable state -- should not be confused with STATE_INVALID_ENTRY for form controls, which is supported
STATE_ACTIVE Yes Top level window
STATE_ARMED No *** XXX Where should this be supported? Same as MSAA's STATE_HASPOPUP? ***
STATE_BUSY Yes Documents which are loading
STATE_CHECKED Yes Checkboxes as well as checkable menuitems and treeitems
STATE_COLLAPSED Yes Outline items which have children but are not expanded -- always used with STATE_EXPANDABLE
STATE_DEFUNCT Yes Old objects which are no longer available
STATE_EDITABLE Yes Anything that supports the EditableText interface
STATE_ENABLED Yes Form controls
STATE_EXPANDABLE Yes Outline items which have children
STATE_EXPANDED Yes Outline items which are expandable and the children are shown -- always used with STATE_EXPANDABLE
STATE_FOCUSABLE Yes Nearly any element can be focusable
STATE_FOCUSED Yes Only 1 item at a time is ever focused -- always used with STATE_FOCUSABLE
STATE_HAS_TOOLTIP No *** XXX Need to file bug ***
STATE_HORIZONTAL No *** XXX need to file a bug for this and STATE_VERTICAL -- check XUL CSS ***
STATE_ICONIFIED No
STATE_MODAL Yes Modal dialog boxes
STATE_MULTI_LINE Yes ROLE_ENTRY -- always used with STATE_EDITABLE
STATE_MULTISELECTABLE Yes ROLE_TREE, ROLE_LIST, ROLE_TREE_TABLE. Indicates that Enter will insert a new line.
STATE_OPAQUE No
STATE_PRESSED Yes ROLE_BUTTON
STATE_RESIZABLE No
STATE_SELECTABLE Yes ROLE_TREEITEM, ROLE_TABLE_CELL, ROLE_LIST_ITEM
STATE_SELECTED Yes ROLE_TREEITEM, ROLE_TABLE_CELL, ROLE_LIST_ITEM -- always used with STATE_SELETABLE
STATE_SENSITIVE No Where should this be used?
STATE_SHOWING Yes Anything
STATE_SINGLE_LINE Yes ROLE_ENTRY -- always used with STATE_EDITABLE. Indicates that Enter will submit the default button.
STATE_STALE No Where should this be used?
STATE_TRANSIENT Yes Where should this be used?
STATE_VERTICAL No *** XXX need to file a bug for this and STATE_HORIZONTAL -- check XUL CSS ***
STATE_VISIBLE Yes Absence of this state is important on documents, popups and tree items
STATE_MANAGES_DESCENDANTS No Not needed, although potentially useful for trees
STATE_INDETERMINATE No *** XXX File bug to support this based on nsIAccessible::STATE_MIXED. Should work on ROLE_CHECK_BOX, ROLE_TREE_ITEM, ROLE_LIST_ITEM, ROLE_PROGRESS_BAR ***
STATE_REQUIRED Yes XForms form controls, and any element with aaa:required="true"
STATE_TRUNCATED No Where should we use this?
STATE_ANIMATED Yes Animated images.
STATE_INVALID_ENTRY Yes XForms form controls, and any element with aaa:invalid="true"
STATE_SUPPORTS_AUTOCOMPLETION No *** XXX File bug to support this ***
STATE_SELECTABLE_TEXT Yes Anything that supports the Text interface
STATE_IS_DEFAULT Yes Default ROLE_BUTTON's, such as OK in XUL dialogs or Submit in HTML
STATE_VISITED Yes ROLE_LINK

Supported AT-SPI Relations

The following relations are currently supported:

enum {RELATION_LABEL_FOR = 0x1002 };
enum {RELATION_DESCRIPTION_FOR = 0x100f };

These two relations can be used on object to determine what form control is being labelled or desribed.

enum {RELATION_LABELLED_BY = 0x1003 };
enum {RELATION_DESCRIBED_BY = 0x100e };

These two relations are they inverse; they can be used on form controls. If the form control has an accName, you can get the IAccessible that it was labelled by in order to get more formatting information. It is also useful to check for a description.

Note that the label and description relations may be used to prevent redundant information from being presented by the screen reader, since the label and description can occur both on their own, and in the name or description fields of an IAccessible.

enum {RELATION_EMBEDS = 0x1009 };

This relation is used on the root accessible object for a top level Mozilla window, corresponding to what's returned for OBJID_CLIENT for that window. It points to the accessible object corresponding to the root of content in that window. This relation is very useful for finding the content quickly, and will be the proper method for finding content in Firefox 3 and beyond.

enum {RELATION_CONTROLLED_BY = 0x1000 };
enum {RELATION_CONTROLLER_FOR = 0x1001 };

These two relations show what form controls may dynamically change areas of the document, in response to user changes in the form controls themselves. Both controlled_by and controller_for are set in markup from the single dynamic content accessibility dynamic content aaa:controls attribute. The inverse controlled_by relation is automatically calculated.

enum {RELATION_FLOWS_TO = 0x1006 };
enum {RELATION_FLOWS_FROM = 0x1007 };

These two relations allow the reading flow to break out of the normal DOM flow. Both flows_to and flows_from are set in markup from the single dynamic content accessibility aaa:flowsto relation -- the inverse flow_from relation is automatically calculated.

Supported AT-SPI Object Attributes

The following object attributes are currently supported:

Object attribute Applies to (content/UI/any/[role]) Possible values
tag any The actual markup tag used to create this element (also used in XUL)
xml-roles any If a dynamic content accessibility role string is used, it is exposed here. This may provide more information than the AT-SPI role, which is best-fit. In the future, this may be a space or comma delimited list of roles
id any Any value, defined by UI/content developers. Used to indicate a persistant identifier for any object, useful for scripting
layout-guess ROLE_TABLE "true" when Gecko's heuristic determines that it is a table that is probably used for layout, not for table.
Value not set means it is probably a data table.
level ROLE_HEADING The heading level

 

Supported AT-SPI Text Attributes

The following text attributes are currently supported:

Text attribute Possible values
static "true" for list bullet/numbering text or layout-inserted text (such as via CSS pseudo styles :before or :after)

Supported AT-SPI Events

The following events are currently supported:

The document: events are not supported yet but should be soon.

The event object:link-selected is purposely not supported, but focus events are fired on ROLE_LINK objects instead.

AT-SPI Features We Currently Do Not Support

As just stated, the event object::link-selected is purposely not supported, but focus events are fired on ROLE_LINK objects instead.

See Firefox 3 dependencies, and in particular the New ATK blocking bugs.

Known Differences with Other Applications

*** XXX To Be Done ***

Avoiding Memory Leaks

It is the assistive technology's responsibility to watch for events that indicate when windows or content subtrees are being destroyed, and to release all Accessible objects related to that window. In addition, STATE_DEFUNCT is set on objects that should be released by the assistive technology. XXX *** Indicate what events, I think we need to add object:children-changed:foo support ***

To help developers in that regard, there is Memory Leak monitor, a Firefox extension.

Keyboard User Interface and API

Fortunately, Gecko uses the standard keyboard API's for each supported platform.

The Mozilla keyboard shortcuts for content are similar to what is used in other browsers. Here is a list of Firefox keyboard shortcuts.

HTML Examples

Each AT-SPI accessible object is encapsulated in braces ("{}"), and meaningful AT-SPI interfaces and attributes, including specializations, are represented as name/value pairs inside the braces.
For convenience, accessible text is shown merely as 'text="contents of the text"'.
* = Embedded object character (0xfffc), used when no text from the object will be inserted in the parent Hypertext
HTML content HTML source AT-SPI representation

This is a heading

This is a paragraph with an some image image in it.

This is another heading

<h1>This is a heading</h1>
<p>
This is a paragraph with an
<image src="image.gif"
alt="some image"/>
image in it.
</p>
<h2>This is another heading</h2>
{parent Text, role=ROLE_HEADING, objattr="xhtml:tag=h1",
text-attributes="css:font-size=LARGER",
text="This is a heading"}
{parent Hypertext, role=ROLE_PARAGRAPH, attr="xhtml:tag=p"
text="This is a paragraph with an * image in it"}
{child Image, Hyperlink, role=ROLE_IMAGE,
ImageDescription ="some image",
AccessibleName = "" [the HTML title attribute, if present]
hyperlink-range=[28,29]}
{parent Text, role=ROLE_HEADING, objattr="xhtml-role:h2",
text-attributes="css:font-size=LARGE",
text="This is another heading"}

Hey!
Tell me something.

<p>Hey!<br>Tell me something.</p>
{parent Text, role=ROLE_PARAGRAPH, attr="xhtml:tag=p"}
text="Hey!\nTell me something"}
Hey!
Tell me something.
<a href="http://www.google.com">Hey!
<br>Tell me something.</a>
{parent Hyperlink, Text, role=ROLE_LINK
objattr="html:tag=a;link-type=anchor",
text="Hey!\nTell me something",
hyperlink-range=[depends on the containing context],
hyperlink-URI="http://www.google.com",
hyperlink-Object=Text}

Hey


Tell me something

<p>Hey</p><hr/>
<p>Tell me something</p>
{parent1 Text, role=ROLE_PARAGRAPH,
 text="Hey"}
{parent2 role=ROLE_SEPARATOR,
 [note: State doesn't include STATE_VERTICAL,
       to distinguish from vsep]
}
{parent3 Text, role=ROLE_PARAGRAPH, 
 text="Tell me something"}

You are a nice person.

<p>
You <em>are</em> a nice person.
</p>
{parent Text, role=ROLE_PARAGRAPH, attr="html:tag=p", 
 text="You are a nice person",
 attribute run for "are", with objattr="role = html:em", textattr="css:text-style=oblique"}

Here is a bartending site.

<p>
  Here is a
  <a href="http://foo.bar.com">
   bartending site
  </a>
.
</p>
{parent Hypertext, role=ROLE_PARAGRAPH, attr="html:tag=p"
  text="Here is a *.",
  attribute run for "bartending site." with textattr="link=true,    
  css:text-decoration=underline, css:color=(0,0,255)"}
   {child Text,  Hyperlink,
     role=ROLE_LINK, attr="html:tag=a, link-type:anchor",
     text="bartending site",
     hyperlink-indices=[10,11]
     hyperlink-URI="http://foo.bar.com"}

Here is a beer glassbartending site.

<p>
Here is a
<a href="http://foo.bar.com">
<image src="beerglass.GIF"
alt="beer glass"/>
bartending site
</a>
.
</p>
{parent Hypertext, role=ROLE_PARAGRAPH, attr="html:tag=p"
 text="Here is a *."
 attribute run for "bartending site." with textattr="link=true,    
  css:text-decoration=underline, css:color=(0,0,255)"}

   {child Hypertext, Hyperlink,
     role=ROLE_LINK,
     text="*bartending site"
           hypertext-indices=[10,11],
[not sure if we need to dup textattrs here, or add them to defaulttextattrs] ,
     hypertext-URI="http://foo.bar.com"}
         {grandchild Image, Hyperlink
           role=ROLE_IMAGE, attr="html:tag=img, link-type=image"
        AccName/ImageDescription="beer glass",
             hyperlink-indices=[0,1]
        URI="beerglass.GIF"}
[don't know if the URIs should always be fully specified, or if omitting the base URI is OK
At the moment, not planning to do this, instead plan to expose repair text in the name if no alt/title exists ]

Here is a beer glass bartending site .

<p>
Here is a
<image src="beerglass.GIF"
alt="beer glass"/>
<a href="http://foo.bar.com">
bartending site
</a>
.
</p>
{parent Hypertext, role=ROLE_PARAGRAPH, attr="html:tag=p", 
  text="Here is a **."}
   {child Image, Hyperlink,
     role=ROLE_IMAGE, attr="html:tag=img, link-type=image"
     AccName/ImageDescription="beer glass",
     hyperlink-indices=[10,11]
     hyperlink-URI="beerglass.GIF"}
   {child Text, Hyperlink, Action,
    Hypertext, role=ROLE_LINK,
     action-names="activate",
[others?]
     attr="html:tag=a, link-type=anchor"
     text="bartending site",
     textattr=
[as in above examples]
     hypertext-indices=[11,22],
     hypertext-URI="http://foo.bar.com"}

<p>
<IMG SRC="sitemap.gif"
ALT="Site map"
USEMAP="#mymap">
<MAP NAME="mymap" title="site map">
<AREA HREF="1.html" ALT="Bar"
COORDS="5,5,95,195">
<AREA HREF="2.html" ALT="Baz"
COORDS="105,5,195,195">
<AREA HREF="3.html" ALT="Fu"
COORDS="205,5,295,195">
</MAP>
</p>
{parent Hypertext, role=ROLE_PARAGRAPH,
text="*"}
{child Image, Hypertext, text=" ***", Hyperlink,
role=ROLE_IMAGE,
attr="html:tag=map",
ImageBounds=[entire map area]
AccName and ImageDescription="Site map"}
{grandchild Hyperlink, Action,
action-names="click", role=ROLE_LINK,
attr="html:tag=area", hyperlink-URI="1.html", name="Bar"}
{grandchild Hyperlink, Action,
action-names="click", role=ROLE_LINK,
attr="html:tag=area", hyperlink-URI="2.html", name="Baz"}
{grandchild Hyperlink, Action,
action-names="click", role=ROLE_LINK,
attr="html:tag=area", hyperlink-URI="3.html", name="Fu"}
[note that the component bounds of the areas correspond to their rectangular bounding boxes]
  • This is a list item.
  • This is another list item.
<ul>
<li>This is a list item.</li>
<li>This is another list item.</li>
</ul>

{parent Object, role=ROLE_LIST, attr="css:list-style-type=disc"}
{child Text, role=ROLE_LIST_ITEM,
text="This is a list item.", attribute run "static" first 2 chars}
{child Text, role=ROLE_LIST_ITEM,
text="This is another list item.", attribute run "static" first 2 chars}

[Bill: we should be able to support list-style=image, and "list-style-image=URL()", etc. this way.  In the above example, it's not clear whether the bullet should be a unicode char or just omitted and implied by the list style..  my guess is the latter (i.e. bullets don't appear in the text)]
  1. This is a list item.
  2. This is another list item.
<ol>
<li>This is a list item.</li>
<li>This is another list item.</li>
</ol>

{parent Object, role=ROLE_LIST, attr="html:tag=ol, css:list-style-type:decimal"}
{child Text, role=ROLE_LIST_ITEM,
text="1. This is a list item.", attribute run "static" first 3 chars}
{child Text, role=ROLE_LIST_ITEM,
text="2. This is another list item.", attribute run "static" first 3 chars}
  • This is a list item
    • Nested item 1.
    • Nested item 2.
  • This is another list item.
<ul>
<li>
This is a list item.
<ul>
<li>Nested item 1</li>
<li>Nested item 2</li>
</ul>
</li>
<li>This is another list item.</li>
</ul>


{parent Object, role=ROLE_LIST, attr="html:tag=ul, css:list-style-type=disc"}
{child Hypertext, role=ROLE_LIST_ITEM,
text="This is a list item.*"}
{grandchild Object, Hyperlink, role=ROLE_LIST,
attr="html:tag=ul, css:list-style-type=circle, link-type=child",
hyperlink-indices=[20,21],
hyperlink-URI="", [Hmm, degenerate case here...] }
{great-grandchild Text, role=ROLE_LIST_ITEM, attr="html:tag=li"
text="Nested item 1"}
{great-grandchild Text, role=ROLE_LIST_ITEM, attr="html:tag=li"
text="Nested item 2"}
   {child Text, role=ROLE_LIST_ITEM,
text="This is another list item."}


[Note that unlike user interface ROLE_LIST objects, these lists don't
implement Selection, and the list items' StateSets do not include
STATE_SELECTABLE. There is a question here as to whether <ul> and <ol> elements
should always implement Text or not. I think it would be better if they did not, unless they had
non-empty text content, but this may prove impractical.]
<form>
<div>
 <label for="self"/>
Tell me a little more:
</label>
</div>
<div>
<textarea>
I am a monkey with a long
tail. I like to swing from
trees and eat bananas. I've
recently taken up typing
and plan to write my memoirs.
</textarea>
</div>
</form>
{parent Object, role=ROLE_FORM, text=""}
{child1 Object, role=ROLE_SECTION? [or should we use ROLE_PANE?] }
{grandchild Text,
role=ROLE_LABEL,
RELATION_LABEL_FOR=child2,
text="Tell me a little more:"}
{child2 role=ROLE_SECTION?}
{grandchild EditableText,
Relation, StateSet, Action,
ROLE_ENTRY,
text="I am a monkey with ..."},
RELATION_LABELLED_BY=child1,
STATE_MULTILINE,
STATE_REQUIRED allowed}

[ attribute run over the portion of the text scrolled into view?
CONTROLLER_FOR/CONTROLLED_BY for the scrollbar/viewport?
Alternative would be to treat all the text content as though it were visible, but that's no good
for magnifiers and ATs for the mobility-impaired. Probably the textarea needs to be expanded somewhat,
or at least fitted with Actions for scrolling plus text attribution for determining what parts of the text are
currently scrolled into view, without the AT client having to resort to bounds checking in the
"screen review" fashion. This is, however, a general problem with multiline text in viewports.
The relatively new Text getBoundedRanges API reduces the pain somewhat since you can
feed it the Component bounds and it will give you back the visible text.]

Check one or more:

<form aaa:describedby="checkhelp"> 
<p>
<span
x2:tag="wairole:description"
id="checkhelp">
Check one or more:
</span>
<input id="cb1" type="checkbox"/>
<label for="cb1">Red</label>
<input id="cb2" type="checkbox"/>
<label for="cb2">Blue</label>
<input id="cb3" type="checkbox"/>
<label for="cb3">Green</label>
</p>
</form>
{parent Object,
role=ROLE_FORM,
attr="html:tag=form",
RELATION_DESCRIBED_BY=grandchild1,
text="?"}
{child Text,
role=ROLE_PARAGRAPH, attr="html:tag=p", text=""}
{grandchild1 Text,
role=ROLE_LABEL,
RELATION_DESCRIPTION_FOR=parent,
attr="html:tag=wairole:description"}
text="Check one or more:"}
{grandchild2 Action,
StateSet, role=ROLE_CHECK_BOX,
attr="html:tag=input", [and same with other elements, expose html:role]
[note also that these objects do NOT have accessible names, because they are labelled;
accessible-name would presumably come from the HTML title attribute or other attribute.
This is mainly to make it easier for ATs to avoid highly redundant speech in these cases.]
RELATION_LABELLED_BY=grandchild3}
{grandchild3 Text,
role=ROLE_LABEL, text="Red",
RELATION_LABEL_FOR=grandchild2}
{grandchild4 Action,
StateSet, role=ROLE_CHECK_BOX,
RELATION_LABELLED_BY=grandchild5}
{grandchild5 Text,
role=ROLE_LABEL, text="Blue",
RELATION_LABEL_FOR=grandchild4}
{grandchild6 Action,
StateSet, role=ROLE_CHECK_BOX,
RELATION_LABELLED_BY=grandchild7}
{grandchild7 Text,
role=ROLE_LABEL, text="Green",
RELATION_LABEL_FOR=grandchild6}

[RFE: add RELATION_DESCRIBED_BY
and RELATION_DESCRIPTION_FOR to match AT-SPI/DHTML. Also, I thought we had
ROLE_FORM, but it seems not to be there. Did I miss something?]
<form>
<label for="beverage">
Make a selection:
</label>
<select id="beverage">
<option>Water</option>
<option>Wine</option>
<option>Whiskey</option>
</select>
</form>
{parent role=ROLE_FORM?}
{child Text,
role=ROLE_LABEL,
RELATION_LABEL_FOR=child,
text="Make a selection:"}
{child Action,
StateSet, Selection,
attr="html:tag=select",
role=ROLE_COMBO_BOX,
RELATION_LABELLED_BY}
{grandchild,
Text,
  StateSet=...SELECTABLE, SELECTED...,
attr="html:tag=option",
role=ROLE_LIST_ITEM, text="Water"}
{grandchild,
Text,
  StateSet=...SELECTABLE...,
attr="html:tag=option",
role=ROLE_LIST_ITEM, text="Wine"}
{grandchild Text,
StateSet=...SELECTABLE...,
role=ROLE_LIST_ITEM,
attr="html:tag=option",
text="Whiskey"}

[note that because the entry field is not editable, but just displays the current
selection, I think it should not be exposed (especially since it represents a node
which is not present in the HTML DOM. The list items need not implement Action,
since the Selection interface is used by the client to select among them.]

Which sports do you like?

<form>
<label for="sports">
Which sports do you like:
<br>
<select id="sports"
multiple="multiple"
size="3">
<option>
<img src="beerglass.gif"
alt="Beer"/>
Baseball
</option>
<option>Basketball</option>
<option>Football</option>
</select>
</label>
</form>
{parent role=ROLE_FORM?}
{child1 Text,
role=ROLE_LABEL,
RELATION_LABEL_FOR=child2,
text="Which sports do you like:\n*"}
{child2 Object,
accessible-name="sports" [not sure exposing the id is a good idea though],
Selection, Hyperlink,
StateSet=...MULTISELECT...
attr="html:tag=select",
role=ROLE_LIST,
RELATION_LABELLED_BY=child2}
{grandchild1,
HyperText,
  StateSet=...SELECTABLE, SELECTED...,
attr="html:tag=option",
role=ROLE_LIST_ITEM, text="*Baseball"}
{great-grandchild Image, Hyperlink,
role=ROLE_IMAGE,
attr="html:tag=img, link-type=image",
hyperlink-URI="beerglass.gif",
hyperlink-indices=[0,1]}
{grandchild2,
Text,
  StateSet=...SELECTABLE...,
attr="html:tag=option",
role=ROLE_LIST_ITEM, text="Basketball"}
{grandchild3 Text,
StateSet=...SELECTABLE...,
role=ROLE_LIST_ITEM,
attr="html:tag=option",
text="Football"}
To do: HTML table example
To do: DHTML role example

Beyond HTML: Other Types of Web Content

Questions or Comments?

Please discuss accessibility issues on the Mozilla Accessibility mailing list or on the Mozilla Accessibility IRC channel.