Accessibility/Comparisons:ATK To UA

From MozillaWiki
Jump to: navigation, search

Discussion with comparison of ATK interfaces to UA

This page attempts to provide an overview of UA, comparing some major interfaces in ATK to UA functionality. I highly recommend to read the introduction to UA before reading this document.

Any developer serious in implementing UA support should always read Apple's official accessibility documentation; this is by no means an end-all be-all document, but can give you an idea about how things work. Feel free to add and edit entries.

Note that this page only is interesting if you're implementing UA support in your application, AT developers use other APIs.

Interfaces

Actions (AtkAction)

There are only three APIs dealing with actions in UA:

accessibilityActionNames 
gives an array of strings telling the available actions that this widget supports.
accessibilityActionDescription 
returns a human-readable (localized) description of a specified action.
accessibilityPerformAction 
performs a specified action.

There are AT APIs for getting a localized name for an action (e.g., what the "AXPress" action would be in human-readable english).

Making a view/widget accessible (AtkComponent)

Ignored nodes

In UA, every widget has to implement a few methods to be made accessible. Those views that are invisible, and uninteresting to the user should implement the accessibilityIsIgnored method to return NO (false).

The ignored objects in the hierarchy are skipped, and the AT will only "see" children, siblings, or parents that are not marked as ignored.

Hit testing

You return the position/size of your widget when the AT asks for the AXSize or AXPosition attributes.

Hit-testing (getting the accessible object at a given point on the screen) is done using the accessibilityHitTest: method, where you want to return the bottom-most widget in your internal hierarchy.

Focus

To get the currently focused widget's accessibility object, accessibilityFocusedUIElement is used, where you need to return the element that is focused.

To set focus, there is the AXFocused attribute that is often settable. To see if a specified attribute is settable, use the accessibilityIsAttributeSettable: and then accessibilitySetValue:forAttribute: to set it.

Traversing the hierarchy

When the AT traverses your hierarchy, it requests the following attributes, that you need to implement in all accessible objects:

AXChildrenAttribute 
will return an array of all accessible children of the widget, skipping any ignored widgets on the way.
AXParentAttribute 
will return the accessible parent of this widget, skipping any ignored widgets on the way.

If an object wants to know its order relative to its siblings, it can ask the parent for the AXChildrenAttribute.

Values in a widget

To get the value of most widgets (barring textviews, and other widgets with very rich content) you simply get the AXValue attribute.

Minimum and maximum values (for e.g., sliders and progressbars) can be returned from the AXMinValue and AXMaxValue attributes.

Relations

There are also attributes for linking a label to its widget, the widget to its label, and the AXLinkedUIElement attribute that can be used to linked elements together than in the interface only are linked visually.

Traversing the DOM (AtkDocument, AtkHypertext)

AtkDocument is ATK's way to expose the DOM to client applications. To my knowledge, this does not (yet) exist in UA, as with many advanced features (particularly those web-specific).

Here are two examples of how WebKit's web view exposes web page content:

text<img/>some text

This is exposed as text, image, text -- all sibling nodes.

<a href="foo.html">bar<img/></a>

The link is exposed as an AXLink, parent of the text and image nodes.

This is one of the areas where it's showing that UA was designed for desktop applications, and not for rich web browsers. Hopefully features features in the future UA will address this kind of gap.

Text editing (AtkEditableText)

Basic

To get/set the value of a text widget you use the AXValueAttribute. There are also some text-specific attributes.

Copying, cutting, pasting etc. are not actions in UA, but the user invokes the menu on the text widget (AXShowMenu action) and then picks the action (copy, paste, cut, etc).

A third-party could of course use standard Cocoa methods on the text widget to let the user perform this in some other way.

Rich text-editing

Rich text-editing is done by querying a text widget for the attributes of specific ranges. For example, you can:

  • Get the bounds of a range
  • Get the styled text of a range (as an NSAttributedText object)
  • Get the range for a line, or an index, or all visible characters

In other words, contrary to ATK, text runs themselves do not contain accessible objects.

Textviews can thus be considered to be "opaque". Their contents can't be traversed like in ATK; instead they are queried for specific ranges or points. This makes it harder to make accessible rich-text editing.

Links (AtkHyperlink)

In UA there's the AXLink role for links (10.4+). Then there's a AXTextLink subrole, and WebKit even defines a custom AXImageMap role for image maps. They also define an AXURL attribute on those links that gives the URL as a string.

For links, the actual linkified object (an image, a text) seems to be a child of an AXLink object in the hierarchy. So some text + an image would be children of the AXLink object.

From WebKit's code, it appears that another extension is an AXVisited attribute that links (and other objects) can have, when they have been visited. (All WebKit extensions can be found here.)

Links usually sport the AXPressAction (just like buttons).

Images (AtkImage)

In UA, images are supposed to have the AXImage role. The position, size, and other data of the actual image is retrievable via the actual NSView in the view hierarchy.

Tables (AtkTable)

The tables in UA are in reality adapted to tables in the user interface. Thus they lack many advanced features. The attributes on the AXTableRole are defined here.

The attributes let an AT traverse a table by:

  • All rows, or all columns
  • Currently visible row(s) or column(s)
  • Currently selected row(s) or column(s)

All of these attributes return arrays of children elements. In the row case, you get an array of all the objects on that row.

To get at a specific cell, it may be possible to just get at the right row, then choose the element depending on which column you want.