Showing posts with label firefox-for-AT. Show all posts
Showing posts with label firefox-for-AT. Show all posts

Monday, January 13, 2014

Accessible Mozilla: tech overview of Firefox 26 and Firefox 27

Here's a list of accessibility improvements for assistive technology in Firefox 26 (release) and Firefox 27 (beta).

HTML

HTML label gets a label accessible regardless used CSS styles (see bug), for example,

<label style="display: block; overflow: hidden;">Label</label>

LABEL_FOR relation is exposed on the label accessible implicitly associated with the control (see bug):

<label>Label
  <input>
</label>

MathML

In Firefox 27 we started to create a generic accessible tree for MathML elements, you can read here for details.

Text interface

We've got a bunch of text interface fixes including regression fixes introduced in Firefox 25 timeframe.

Arabic and Herbew character bounds are exposed correctly now (see bug).

XUL link accessible (used by Firefox UI) implements text interface (see bug).

Text selection

We reworked the TEXT_SELECTION_CHANGE eventing. In particular that allowed to fix events in case of selection spanned through several text objects like HTML paragraphs (see bug) and one pretty old Thunderbird bug where caret move events were missed (see bug).

IAccessible2

Firefox 27 has got IAccessible2::relationTargetsOfType (see bug) method from latest IAccessible2 release as well as new CONTAINING_DOCUMENT/TAB_PANE/APPLICATION relations (see bug). Check out this post for summary of IA2 1.3 release changes.

ISimpleDOMNode

ISimpleDOMDocument interface is implemented as tear off in Firefox 27. The change is similar to the one we did a year ago so it shouldn't hurt anybody. Just in case.

Tuesday, November 5, 2013

IAccessible2 relation API

Before IAccessible2 Mozilla practiced all manner of extensions of MSAA. I don't mean I exalt the forethought of MSAA API, I'd rather say this is an example of necessity is the mother of invention. But fortunately MSAA was extensible enough to workaround some lacks of it. Firefox ignored MSAA spec occasionally, implemented tricks and - what a surprise - some of them are in use by modern screen readers nowadays. 

All aforesaid is applicable to accessible relations. MSAA has accNavigate method to navigate the accessibles in tree hierarchy and layout order. Firefox introduced a bunch of extra constants for this method to expose accessible relations. That was a neat approach so that after IAccessible2 invention and implementation the assistive technology wasn't in hurry to switch to the right API. accNavigate was light and simple and had only one disadvantage: it didn't allow you to get multiple targets. IA2 relations in turn didn't have this limitation but API appeared heavy and Firefox implementation was quite slow those days. Firefox 4 implemented a fast version but it didn't change things. That made me think Firefox wasn't a stumbling block here. So

IAccessible2 1.3 refreshed relations API and we've got relationTargetsByType method which allows to get all targets of the given relation type. In other words this is a multiple target version of MSAA accNavigate: plain and simple. The method was implemented in Firefox 27.

I'm curious how fast the assistive technology will pick it up. Otherwise do we need those multiple targets at all?

Thursday, September 5, 2013

Accessible Mozilla: Tech overview of Firefox 25

ARIA


* We don't map aria-atomic:false to accessibility API anymore (see bug). UAIG is flexible on this and allows a fork in implementation: either ignore it or map it. Ignoring seems more reasonable so we did it this way. And here's why. Assistive technology relies on container-atomic object attribute exposed on every child of atomic region. In other words if there's no container-atomic object attribute then the accessible is not contained by atomic region. It's worth to notice it works pretty well if the users deals with nested aria-atomic regions, i.e. when atomic regions contain not atomic areas.

* We've got smarter about accessible tree creation, we started to ignore whitespace accessibles between ARIA grid cells (see bug). These whitespaces can be unintentionally introduced by the author when he creates the web page. They serve the pure layout job like they add some visual space between cells. What's worse any whitespaces are not expected under the grid control hierarchy and thus can confuse the assistive technology.

* ARIA column and row headers are not selectable by default anymore. Technically speaking if you do not specify aria-selected then SELECTABLE state is not exposed (see bug). The idea behind that is ARIA column/row headers are either not interactive at all or they are used to select the whole column/row at once.

* ARIA textbox exposes accessible value constructed from the content beneath the element (see bug).

* ARIA tablist is no longer a live region (see bug). The bug popped up from the wild: the users run into the problem. So we've got the bug fixed and asked for an update to UAIG spec.

* ARIA listbox exposes FOCUSABLE state regardless how it manages its children. That means if the listbox is not DOM focusable and its items are focusable instead (tabindex on items approach) then we enforce FOCUSABLE state on the listbox accessible. The trick is primarily introduced for MSAA environment where screen readers relies on FOCUSABLE state to differentiate HTML:ul from HTML:select since they share same MSAA role (see bug).

* ARIA treegrid like ARIA grid are editable by default now (see bug).

* In some cases we didn't treat 'undefined' value as absent value, for example, ARIA checkbox with aria-checked="undefined" was marked as not checkable. We fixed it.

HTML


longdesc attribute is exposed in Firefox context menu (see bug) as "View description" menu item. Right click on the image having a longdesc allows you to see it in new tab.

Text interface


A major change in this release is ATK and IAccessible text traversal by lines got a new heart. We still observe some problems (and even some serious ones) but definitely it must be a good update.

Events


* We started to fire SELECTION state_change evens on items of selectable widgets like combobox or listbox (see bug). On MSAA level these events are partially duped by selection event but having only it AT had no way to detect which items was deselected.

* We fixed a nasty focus bug observed at google.com start page: we missed the focus event when search textbox is moved through the page (see bug).

* In case of HTML checkbox input we fire state_change event whenever checkbox value is changed (previously we were restricted to user interactions), see bug.

Anything else


* We fixed hit testing for Firefox UI menus and popup (see bug) on Windows. Now each menu and popup hosted in own window returns HWND of that window and when the window receives WM_GET_OBJECT message then it answers it by returning the menu/popup accessible. If you take a hit test on the returned accessible then you get kids of menus/popups.

* We've got rid of XPCOM constant BOUNDARY_ATTRIBUTE_RANGE. It doesn't seem useful and practical.

Wednesday, July 10, 2013

Accessible Mozilla: Tech overview of Firefox 24

Here's a list of Firefox 24 (currently Aurora) improvements for assistive technology.

ARIA


We supported one more way to create hierarchy for ARIA lists and trees (see bug). Now you can do

  <ul role="list">
    <li role="listitem">Item 1
      <ul role="group">
        <li role="listitem">Item 1A</li>
        <li role="listitem">Item 1B</li>
      </ul>
    </li>
    <li role="listitem">Item 2
      <ul role="group">
        <li role="listitem">Item 2A</li>
        <li role="listitem">Item 2B</li>          
      </ul>
    </li>
  </li> 

So following this pattern allows you to get for free the group position for items and relations between them.

It's worth to say that Firefox supports another kind of hierarchy for ARIA trees for a long time:


  <div role="tree">
    <div role="treeitem">Item 1</div>
    <div role="group">
      <div role="treeitem">Item 1A</div>
      <div role="treeitem">Item 1B</div>
    </div>
    <div role="treeitem">Item 2</div>
    <div role="group">
      <div role="treeitem">Item 2A</div>
      <div role="treeitem">Item 2B</div>          
    </div>
  </div> 

Here ARIA group element defines a sub group of items for the item preceding to it.

You can use either hierarchy that suites better for you. Note, second approach doesn't work in case of ARIA lists.

HTML


datalist attribute on the widget makes the accessible object to expose HASPOPUP state in addition to SUPPORTS_AUTOCOMPLETION state we used to have (see bug).

Action interface works on HTML textarea element now.

HTML td elements may be pointed by headers attribute, i.e. HTML td can serve as row/column header. In other words the following pattern is supported:

  <table>
    <tr><td id="juice">Juice</td></tr>
    <tr><td headers="juice">Orange</td></tr>
    <tr><td headers="juice">Apple</td></tr>
  </table>

Moving at the "orange" or "apple" cell by screen reader you will hear that this is orange or apple juice.

Text work


getTextAfterOffset and getTextBeforeOffset methods for word boundaries were improved a bit (see bug and bug). There are still problems left.

IAccessible2


We did first steps on the way to implement new IAccessible2 version released couple months ago. We've got IA2_RELATION_NODE_PARENT_OF relation exposed on ARIA and XUL trees (thanks to Zach who volunteered for this work).

Note, alternatively to IAccessible2 relation interface you can obtain this relation by MSAA IAccessible::accNavigation method using 0x1010 constant. Refer to our source code for all possible values (no docs sorry).

Another bit of IA2 support was IA2_STATE_CHECKABLE (thanks to Marcos A. Di Pietro for the fix). You can see this state on all checkbox-like widgets. Prior to this state the checkable:true object attribute was used for that. Now we expose state and object attribute both.

User interface


Menu items of Firefox UI have correct state now, i.e. no OFFSCREEN state for visible menu items anymore (see bug).

Pinned tabs in Firefox UI expose IA2_STATE_PINNED now.

Thursday, June 13, 2013

Accessible Mozilla: Tech overview of Firefox 23

Here's a list of core accessibility improvements in oncoming Firefox 23 (will be available as beta 24 June).

ARIA


A non standard extension of ARIA was introduced. Now Firefox recognize a "key" ARIA role which is mapped to push button role on IAccessible2/ATK layer. It is supposed to be used for on-screen keyboards and dialpads. AT can use  xml-roles object attribute to pick up that role.

HTML


* A major change of this release is we don't longer create a flat hierarchy for HTML selects (see bug). Say you have a HTML select having optgroup elements like

  <select>
    <option>item
    <optgroup label="group">
      <option>subitem
    </optgroup>
  </select>

then we used to have an accessible hierarchy like:

  combobox - HTML select
   option - HTML option (item)
   heading - HTML optgroup
   option- HTML option (subitem)

Firefox 23 exposes the following hierarchy:

  combobox - HTML select
   option - HTML option (item)
   grouping - HTML optgroup
     option - HTML option (subitem)


* Another change is HTML5 input@type=range is now accessible. It's exposed as a slider role and implements the value interface, i.e. you can obtain min, max and current values and step. Also it fires value change events.

Nasty bugs


A bug where JAWS lost the virtual buffer was fixed. The patch was back ported to Firefox 22 and Firefox 21.

Another bug was that we lost inactive document occasionally. So if the user didn't interact with the document and the document wasn't self updated via JavaScript then it could be not accessible for screen readers (see bug).

ISimpleDOM support


Yet another ISimpleDOM interface (ISimpleDOMText) was tear offed as continuation of this work.

Other bug fixes


* A selection bug where we wrongly claimed that unfocused text area has a selection was fixed.

* We don't prune children anymore for number of roles like text entry, menu items and etc if they have complex trees. In other words, if for example a text entry has anything else than a plain text then you will see that in hierarchy (see bug). So if you do

  <div role="textbox"><span role="button"></span></div>

then you will get a button inside the text entry.

Tuesday, May 21, 2013

IAccessible2. New features and performance.

After months of long discussions the IAccessible2 group released 1.3 version. It was probably most disputable release after the initial shipping. A number of assistive technology vendors requested a number of changes for better integration with the browser. So it took a time to find a common multiplier for all ideas.

So updated IAccessible2 API require some engineering love and thus it will be implemented in Firefox by parts. It'd be helpful to know which features are most crucial and needed for you as AT developer so we can give them a priority. To let us know please leave a comment in the bug or just ping me saying that. Alternatively you can vote for or comment right into the interesting bug (see sections below).

Roles


IA2_ROLE_COMPLEMENTARY_CONTENT is supposed for HTML5 aside element and WAI ARIA complementray role (see Mozilla bug).

States


A new IA2_STATE_PINNED state will be exposed on pinned tabs in Firefox UI (see Mozilla bug).

Technically speaking IA2_STATE_CHECKABLE was introduced in place of hacks used to workaround a lack of this state. For example Firefox exposes checkable object attribute (IAccessible2 hack) and STATE_SYSTEM_MARQUEED (pure MSAA approach). See Mozilla bug.

Relations


There is a bunch of new relations introduced to simplify a navigation through the hierarchy. Now you can quickly move to

Note, IServiceProvider is an alternative to described relations (strictly speaking a subsest of described relations). See Mozilla bug.

Also now you can get a next and previous elements in tab order (IA2_RELATION_NEXT_TABBABLE and IA2_RELATION_PREVIOUS_TABBABLE). It's useful for AT that implement own in-page navigation (see Mozilla bug).

New IA2_RELATION_NODE_PARENT_OF is a dual relation to IA2_RELATION_NODE_CHILD_OF. It's useful to get all logical children of the accessible (as you know a logical parent-child relation may be different from parent-child relation defined by accessible tree). Example is aria-owns (like aria-owns tree) and flat structured hierarchies like XUL tree (used for message list in Thunderbird) or ARIA tree where the hierarchy is supplied by aria-level like:

  <ul role="tree">
    <li role="treeitem" aria-level="1">Item 1</li>
    <li role="treeitem" aria-level="2">Item 1.1</li>
  </ul>

See Mozilla bug.

 

IAccessibleDocument


IAccessibleDocument is a new interface that allows you to get an anchor target, i.e. an element that the page was scrolled to after the page was loaded. Also an object of this interface is returned by relations like IA2_RELATION_CONTAINING_DOCUMENT and IA2_RELATION_CONTAINING_WINDOW. See Mozilla bug.

 

Manage the media content


The idea was to manage the media content by accessible actions (IA2 group got parsimonious for a new interface so the existing mechanism was reused).

If a screen reader starts, say, a subtitled video then it invokes IA2_ACTION_OPEN action. The browsers plays a portion of subtitled video and stops it until a screen reader invokes IA2_ACTION_COMPLETE action. This action is used to notify the browser that screen reader consumed the portion of played video subtitles, for example, it finished reading of them. If screen reader is no longer interesting to manage the media playback then it invokes IA2_ACTION_CLOSE action.

If more than one AT tries to manage the same media (i.e. AT that invoked 'open' action) then the browser holds on the video playback until all AT invoke 'complete' action. See Mozilla bug.

Performance


After IAccessible2 implementation by Firefox and AT it got clear that IAccessible2 API can be improved in certain ways to make the intercommunication between the browser and AT faster. So number of changes was introduced for performance matter.

Object attribute by name


Now you can obtain object attributes by name rather than get them all together and then parse the string (see Mozilla bug).

Relation by type


Now you have a method to get relation targets by type. You don't need to get all relations when you need a single one (see Mozilla bug).

Accessible containing the caret


You have a fast way to get a text accessible containing a caret in the subtree and the caret offset in  the text accessible. Previously the algorithm to find an accessible containing the caret failed on some cases. The idea of that approach was that a screen reader should crawl down the hierarchy asking for caret position until it reaches a deepest text accessible having the caret. It failed if you meet non text accessible on the way. As a workaround the screen readers navigated children. While the workaround worked well but it was really slow (see Mozilla bug).

Text attributes


The change is similar to object attributes. A light alternative to the method used to get all text attributes was added.  Now you can specify a string filter and get attributes you need (see Mozilla bug).

Get all hyperlinks


Usually AT needs all hyperlinks at once. Getting them one by one is unperformant (especially for out of process AT) and requires a cache implementation on the browser side. So a new method to get all hyperlinks has been introduced (see Mozilla bug).

Wednesday, May 15, 2013

Accessible Mozilla: Tech overview of Firefox 22

Firefox 22 reached beta status (it will be released June 24). It's time to list accessibility improvements we made for this version.

ARIA


ARIA role="note" doesn't allow name from subtree (bug) anymore. The bug caused JAWS, for example, to announce role="note" content twice.

HTML


* HTML radio group position doesn't count hidden radio elements (bug). So if the page contains hidden input@type="radio" then a screen reader doesn't take them into account announcing the number of radios.

* HTML input@type="file" changed its hierachy. Now it contains a push button and a label. Be careful if you have dependences on this hierarchy (see bug).

* HTML5 header and footer has changed their mapping according to HTML spec:
footer element that is not a descendant of an article or section element. contentinfo role;

header element that is not a descendant of an article or section element.  banner role.

XUL


XUL label@value element now implements text interface (partially). You can obtain a text between offsets but you can't get it by words for example (refer to bug). XUL label is used wide in Firefox user interface (for example, in Options dialog). Let us know if you have problems with new implementation.

ATK


RELATION_NODE_PARENT_OF has been implemented. It's exposed for aria-owns markup and XUL trees (used in Thunderbird and Firefox bookmarks).

Text interface


As I wrote before we started text interface reimplementation. Firefox 22 got improved getTextAt and getTextBefore offsets at word boundaries. Note, in case of getTextAt we had to mimic WebKit behavior rather than follow the ATK spec to keep Orca working.

Attention. It might be important


* Document load event may be fired a bit later than we used to do that, it will be fired right after all events contained in the queue at the time when document got loaded (see bug).

* IServiceProvider interface is implemented as a tear off (bug).

Wednesday, April 10, 2013

Accessible text support in Firefox

So getting back shortly after ATK text insight to share our plans about text support in Firefox. In fact we started the work already and couple patches were landed into Firefox 22 (currently in Aurora stage). The primary work is targeted to Firefox 23 and Firefox 24.

We need to know if the changes we introduce deliver any problems for screen readers. Recently we figured out that we broke Orca. We cherished our bugs through years and probably screen readers learned how to live with them. Putting a screen reader into fresh water might make it feel bad. I guess that's what happens with Orca.

So it's worth to give the assistive technology and the users a notice and ask them to keep eyes open. And of course be ready to report bugs against us.

 

An overview


The text problem is wide and consists of several parts (or has several layers like ogres or onions).

Caret navigation


Caret navigation in Firefox is not good in general. The behavior is inconsistent and
accidental. From time to time I observe weirdness myself writing a next blog post. The caret may move somewhere I didn't want to or it may hang somewhere in the text and I need to use mouse to move it. I don't exclude a possibility that Google Blogger product "helps" the Firefox but I don't recall any web app for rich text editing running really smooth in Firefox. If you deal with lists, tables or control elements then as a rule you should be ready to surprises.

We can't bypass a caret navigation problems, for example, recently I fixed one bug but it's likely we won't pay much attention until UIA text implementation.

ATK and IAccessible2 text


These interfaces are very similar. IA2 interface is simplified (I'd say a human friendly) version of ATK. Actually this is a reason that these interfaces have shared implementation in Firefox. We have a *lot* of bugs related to this implementation.

UIA text


UIA has a different concept of accessible text support and likely requires a separate implementation. We don't have immediate plans on it.

 

Technical part


In short our plans is ATK/IAccessible2 text bugs. On technical layer the work is scoped by following items:

* Fix ATK/IAccessible2 getTextAt/Before/After method logic. Check out our understanding of ATK text to make sure our understanding is the same with yours one.
* Fix soft line breaks problem. Currently start and end of lines produced by soft line break share the same offset. So we never know which line we should return when that offset is given.
* Do not use embedded characters for inline elements.

Please keep your eyes open and let us know if you observe a problem when reading the text in your favorite screen reader.

Wednesday, March 27, 2013

Accessible Mozilla: Tech overview of Firefox 21

Next week Firefox 21 reaches a beta status so it's time to list accessibility related changes we introduced for assistive technology. This release we were focused on under-the-hood improvements and ARIA bugs. Let's start.

ARIA


* We pick up accessible value of ARIA combobox in name computation. An example:

  <label for="test">Flash the screen 
    <div role="combobox">
      <div role="textbox"></div>
      <ul role="listbox" style="list-style-type:none;">
        <li role="option">1</li>
        <li role="option" aria-selected="true">2</li>
        <li role="option">3</li>
      </ul>
    </div>
    times.
  </label> 

In this case accessible name of the label is "Flash the screen 2 times" (refer to bug).

* ARIA grid has editable state by default. ARIA grid editable or readonly states (a case of aria-readonly attribute usage) are inherited by grid cells until aria-readonly attribute on a gridcell overrides it (see bug).

* We no longer expose hidden:false object attribute for aria-hidden="false" because ARIA group members concluded that aria-hidden mirrors CSS display:none (check out the bug for details). In particular this means

  <div aria-hidden="true">
    <input aria-hidden="false">
  </div>

HTML input element is still ARIA hidden.

Sure the author doesn't have any single reason to use aria-hidden="false" in his web app but you know people do crazy things every time. If we exposed it then it could be confusing for screen readers (if they wouldn't know that "false" value is an author error of course). However you may ask why ARIA spec doesn't like to treat "false" value as "true" value like it does for any other error value. It's less work for browsers, no burden for AT. You see that wouldn't bad. I do not know. Go ask your dad.

* We supported ARIA based text attributes. Now you can use aria-invalid="grammar" to mark that your text has a grammatical error. From AT perspective it means that we expose invalid:grammar text attribute.

Unfortunately ARIA spec doesn't look perfect about defining the aria-invalid. For example, it doesn't allow a list of values

  <p aria-invalid="spelling,grammar">my wrong text</p>

and it says nothing about aria-invalid inheritance which would allow you to do a trick

  <p aria-invalid="spelling">
    <span aria-invalid="grammar">my wrong text</span>
  </p>

to say that your text is misspelled and has grammatical error. Also it doesn't say how the browser should resolve collisions between aria-invalid and native spelling support which is also mapped into invalid text attribute.

HTML


* HTML5 main element was implemented. It's exposed as xml-roles:main object attribute on accessibility layer.

* We sorted out name computation for HTML input buttons:
  • HTML input@type="button", @type="submit", type="reset" gets name from:
    • @value attribute
    • @title attribute 
  • HTML input@type="image" gets name from:
    • @alt attribute
    • @value attribute
    • @title attribute
  • HTML input@type="image" having no valid @src attribute gets name from:
    • @alt attribute
    • @value attribute
    • "Submit Query" - a visible label of the button

Everything else


* We did one more fix in our name computation algorithm and now we don't jam together a plain text and name coming from a control element. For example:

  <label>foo<input type="text" value="bar">baz</label>

The accessible name of the label is "foo bar baz". Visually "foo" and "baz" are separated from HTML input, thus we wrap the control's name by spaces when we compute the label name.

* We learned how to coalesce state change events so you should get only one event when the object changes its state fast enough, for example, it may happen during document loading when state busy of a document accessible is switched quickly.

* You can use magic offsets now to get text attributes.

Monday, February 11, 2013

Accessible Mozilla: Tech overview of Firefox 20

In short, what's new in upcoming Firefox 20.

You might need to know


During a document loading we may create a temporary document (about:blank) for a short time and then create the requested document. The temporary document is a normal document and behaves as any other document (in particular we fire document load complete event on it). But since it doesn't exist for a long time then it shouldn't get a focus (at least there's no percedence). If the temporary document existence is likely a problem for your application then please contact us.

Apparently this behavior was introduced in Firefox 20, at least that's the first time when we caught it (refer to bug for details).

ARIA


ARIA role combobox exposes an accessible value computed from the content of selected item.

<div role="combobox">
  <div role="textbox"></div>
  <div role="listbox">
    <div role="option">1</div>
    <div role="option" aria-selected="true">2</div>
    <div role="option">3</div>
  </div>
</div>
 
In this example the accessible value of combobox equals "2". I'm not sure whether this feature has any good effect on ARIA evolution in the web since underlying textbox and listbox are supposed to handle all user input. It was done rather for consistence between HTML and ARIA widgets (see bug).

HTML


We started to build context dependent trees in more cases (refer to bug for details). In particular we don't create list item accessibles for HTML li, dl and etc if they are children of presentational list. For example:

<ul role="presentation">
  <li>item</li>
</ul>

We don't create an accessible for HTML li element in this case.

Also we reject to create HTML table cells if they don't have a table row as a parent. This behavior caused a certain problem. I hope we will be able to backport the fix into Firefox 20.

SVG


We introduced basic SVG accessibility. SVG graphic elements like circle or rect are mapped to accessibility API as graphic role accessibles (see bug). Accessible name and description for these elements are computed from child SVG desc and title elements (see bug for more info).

XUL


We stopped to create accessibles for XUL deck element itself and its child elements if they don't belong to the selected panel. Basically we rolled back to the behavior we had prior Firefox 16. We did that because we were reported that the behavior can be a problem for existing code. In particular, it didn't make a good job for AddBlock+ and JAWS users (see bug).

ISimpleDOMNode


As I wrote before ISimpleDOMNode was implemented as tear off. Let us know if this hits you.

Bug fixes


Windowless/inaccessible plugins don't expose NULL child in MSAA tree anymore (see bug).

Also we fixed an intermittent bug that made us to ignore ARIA role on the body of the document (see bug).

We fixed the case when caret offset was misreported.

Friday, December 7, 2012

IServiceProvider implementation in Firefox

In Firefox every MSAA accessible object implements IServiceProvider interface which is used to obtain different accessible objects that are in connection to the given one. The idea of IServiceProvider is quite close to IAccessible2/ATK relation concept but it operates on different set of relation types. It has IServiceProvider::QueryService method which is defined as:

  HRESULT QueryService(
      REFGUID guidService,
      REFIID riid,
      void **ppv
  );

guidService identifies the accessible object you need, riid is an interface the object should be queried to.

In Firefox we support the following guid services:

IID_IAccessibleApplication  to get an IAccessible2 application accessible implementing IAccessibleApplication interface.

SID_IAccessibleContentDocument = { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} } a Firefox specific service used to get a tab document the accessible object belongs to.

IID_IAccessibleEx used to obtain UIA IRawElementProviderSimple instance. It works under "accessibility.uia.enable" preference.

Also we support IID_ISimpleDOMNode, IID_IAccessible and IID_IAccessible2 as guid services but they are basically query interfaces and they return the same object as query interface does.

Note, all said above works in Firefox 16 and later. Prior to Firefox 16 we used to have a different logic that allowed tricks like

  accessible->QueryService(IID_IAccessible2,
                           IID_IApplicationAccessible,
                           (void**)&appAcc);

to get an application accessible. It's not possible anymore. Please double check your code if you rely on IServiceProvider::QueryService.

Monday, December 3, 2012

ISimpleDOM support

As you probably know Firefox implements ISimpleDOM interfaces to provide a MS COM access to DOM in the browser. IE maintains similar interfaces. In accessibility world they were used to workaround lacks of MSAA API. Early days screen readers didn't have a choice how to make the browser accessible and they were DOM based.

Years later after IAccessible2 and UIA appeared the ISimpleDOM interfaces got obsolete. A bright demo of this statement is the NVDA screen reader which doesn't rely on ISimpleDOM at all and works nicely with Firefox. Nonetheless periodically I hear that ISimpleDOM is still very useful for AT. As a rule this opinion comes from proprietary screen reader vendors so I don't really aware of details. We trust them and we continue to support ISimpleDOM. However we don't recommend anyone to use ISimpleDOM.

We consider ISimpleDOM as optional API and thus we think that our support of it shouldn't affect on AT software that don't rely on ISimpleDOM. As a first part of this idea the ISimpleDOMNode interface was implemented as a tear off. That means whenever you query ISimpleDOMNode interface you always get a new instance implementing this interface. That allows us to save 4 bytes per accessible object and that was good for memory usage. The change was landed on Firefox 20.

We didn't find any problems during testing stage but if you would like to give it a spin, please try a nightly build. Especially it makes sense if you are developer of AT software relying on ISimpleDOM. Please let us know if you have concerns.

Sunday, December 2, 2012

Accessible Mozilla: Tech overview of Firefox 19

ARIA


ARIA spec enriched by test suite so lately we've got reported a lot about ARIA problems in Firefox. On that wave we improved a little bit our ARIA support. You can check out this wiki to see how we do on ARIA test suite failures.

* ARIA role="rowgroup" is a strong role now, in other words it overrides native role, and it is mapped as grouping role into accessibility APIs (ATK_ROLE_PANEL on ATK, NSAccessibilityGroupRole on OS X, ROLE_SYSTEM_GROUPING on MSAA/IA2). See bug for details.

* When ARIA role="tab" gets selected within containing role="tablist" then selection event (EVENT_SELECTION on MSAA / "selection_changed" on ATK) is fired on the tablist, see bug for more info.

* Inherited role="presentation" is now ignored if the element has global ARIA attribute or relation. For example:

  <table role="presentation">
    <tr>
      <td aria-hidden="true" id="cell">cell1</td>
      <td aria-labelledby="cell1">cell2</td>
      <td>cell3</td>
    </tr>
  </table> 

HTML td elements "cell1" and "cell2" have both a generic accessible, "cell3" is not accessible (its text leaf it is of course). See bug for more info.

* ARIA menu item containing a sub menu (i.e. having aria-haspopup attribute) is exposed as ATK_ROLE_MENU on Linux, see bug for more info.

* Previously we rejected to use values of ARIA slider, spinbutton and scrollbar in name computation. For example:

  <input id="input">
  <label for="input">
    foo <span role="slider" aria-valuetext="middle"> foo</span>
  </label>

Expected name for "input" accessible is "foo middle foo". Refer to bug for more info.

Attributes


* A document accessible picks up object attributes from container (like iframe element) provided by ARIA markup only. Previously we used to propagate object attributes like "class", "id" or "xml-roles" to the document. That didn't make huge sense but it's behavioral change and you might want to be aware of it. See bug for more info.

* New "explicit-name" object attribute was introduced as a part of ongoing IAccessible2 1.3 spec. This attribute is exposed with "true" value when the author specified accessible name explicitly (for example, by HTML label element). Otherwise this attribute is omitted (for example, when name is computed from subtree like in case of <button>press me</button> or there's no accessible name at all like <p>it's a paragraph</p>). See bug for more info.

Roles


A document accessible doesn't inherit ARIA role from container anymore. This behavior was introduced a long time ago to let the author to change a role of 3d party ARIA widget. This approach added certain problems for web developers:
  • If the author applies a navigation landmark on the iframe then Firefox copies it over the role of the child document.
  • If the author has actually set a role on the child document contained within the iframe and the author had applied a role to it (such as role="application") it will be overridden.
So behavior opposite to what we do is wanted actually. Also we didn't have a good idea whether our behavior is used anywhere on the web, thus we decided to change. Refer to bug for more info.

States


If XUL deck panel is not selected then all its children expose invisible state (instead offscreen state as we used to do). The problem has been seen in Firefox "About dialog" where hidden elements used for different update statuses of the browser had offscreen state and that made them discoverable for screen reader users. This was regression from Firefox 18 (note, the fix was backported to Firefox 18). See bug for details.

Events


* HTML5 progress element is a subject of value change events now, similar to ARIA progressbar role (thanks to James Kitchener for fixing this one). See bug for more info.

* When the user clicks a link then state_change event for traversed state (ATK_STATE_VISITED on ATK,  STATE_SYSTEM_TRAVERSED on MSAA) is fired on the link accessible. See bug for more info.

* When the user clicks a link to download a file then we used to fire state_change event for busy:true state (ATK_STATE_BUSY on ATK, STATE_SYSTEM_BUSY on MSAA) on document accessible but we never fired concomitant state_change event for busy:false state. The issue was fixed. Refer to bug for details.

Zoom level


Finally all zoom level work was finished in Firefox 19. Before that we didn't respected a zoom level in accessibility APIs implementation, for example, methods operating on coordinates and size didn't take into account whether the web page was zoomed or not. That made us, for example, to return a wrong accessible in hit testing. Primarily it was a problem for screen magnifiers and it was pulled from Firefox 4 times. Refer to bug for more info.

Random notes


We dropped obsolete xlink support on HTML elements. Previously we used to expose them as accessible actions. Generic Xlink support has gone in Firefox for years ago so we just dropped a vain baggage (see bug for more info).

Thursday, October 11, 2012

Firefox 16 - 18: what's new for AT developers

This summer wasn't super plenteous for features interesting for assistive technology developers. Firefox 17 was nearly barren in this sense. Thus here's a list of changes introduced in Firefox 16, Firefox 17 and Firefox 18.

ARIA

(Firefox 16) ARIA documents are now subject of document loaded event. If the author does something like:

  <div id="dialog" role="dialog" style="display: none;">A message</div>
  document.getElementById("dialog").style.display = "block";

then LOAD_COMPLETE event is fired after the dialog appears (refer to document handling in Firefox for details).

(Firefox 17) We sorted out stuff related with vertical and horizontal states.  Previously we could expose these states on the same accessible the same time regardless the value of aria-orientation attribute or expose them on elements that orientation is not applied to. Also ARIA role="scrollbar" got vertical state as default value.

(Firefox 18) If ARIA grid contains role="rowgroup" then IAccessibleTable interface went crazy, i.e. row/col/cell indexes coherence was broken.

(Firefox 18) aria-activedescendant behavior was corrected a bit. We have supported the case the spec says about: "Authors MAY use the aria-activedescendant attribute on the focused descendant of a composite widget; for example, on a textbox descendant of a combo box." This is an example these words are applicable to.

  <div id="combobox" role="combobox">
    <input id="combobox_entry" />
    <ul>
      <li id="combobox_option1" role="option">option1</li>
      <li id="combobox_option2" role="option">option2</li>
    </ul>
  </div>

If the input has DOM focus and the author changes the aria-activedescendant attribute on combobox element to point a combobox option then that combobox option gets the focus.

(Firefox 18) If ARIA role="presentation" is used on the element having ARIA global attributes or referred by ARIA relation then role="presentation" is ignored as it wasn't there. The behavior is similar if the element is focusable.

HTML

(Firefox 16) HTML5 article element is a subject of 'article' xml-roles object attribute.

Also we fixed few edge cases. Btw, they all were caught in the wild.

(Firefox 18) We didn't create a listitem accessible for HTML li element in some cases like:

  <ul id="list7">
    <li id="l7_li1" style="display:inline-block;">Oranges</li>
    <li id="l7_li2" style="display:inline; float: right;">Apples</li>
  </ul>


(Firefox 18) Table related styles used outside the table context prevented to create a correct accessible. For example,

  <h1 style="display: table-cell;">a header</h1>

didn't have a heading accessible.

States

(Firefox 18) Finally we sorted out invisible/offscreen states and the implementation corresponds to what I wrote before.

(Firefox 18) Some offscreen accessible didn't expose the offscreen state. You could see this bug at ai squared site.

Text attributes

(Firefox 16) auto-generated text attribute is supported now (refer to IAccessible2 spec). It's get exposed for auto generated CSS content (:after and :before pseudo elements) and HTML list bullets. Note, we don't expose the auto-generated object attribute anymore.

XPCOM

(Firefox 16) defaultKeyBinding attribute and getKeyBindings method of nsIAccessible interface was replaced on single accessKey attribute. Gecko always exposed either an access key (alt + letter) and/or keyboard shortcut (ctrl + letter). An ability to return many keybindings was never used.

Friday, June 8, 2012

Firefox 15: what's new for AT developers

Firefox 15 is in aurora channel now. This release doesn't have a lot of features interesting for AT developers. Primarily we were focused on under the hood work. But none the less.

ARIA

As you know some ARIA state and properties are exposed via accessible object attributes. Basically ARIA attribute is mapped to accessible object attribute when there's no proper mapping to accessibility API, for example, in case of aria-sort attribute. As consequence this is applicable for any unknown ARIA attribute. Thus if you have something like:
  <div aria-myownproperty="myvalue"></div>
then Firefox exposes "myownproperty:myvalue" object attribute.

Whenever the ARIA attribute value is changed Firefox should fire IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED event. Prior Firefox 15 the event was missed in some cases.

HTML

The bug when row accessible of the table (ATK_ROLE_LIST_ITEM / ROLE_SYSTEM_ROW) wasn't created for layout tables was fixed. Example:
  <div style="display: table;">
    <div style="display: table-row;">
      <div style="display: table-cell;">cell</div>
    </div>
  </div>
Thanks to MichaƂ Frontczak for this contribution.

Events

The major change that may affect on ATs is we started to fire document loading events on iframe documents. Prior to Firefox 15 they were restricted to tab documents. So if you, for example, change @src attribute on HTML iframe element then it causes LOAD_COMPLETE event on the document accessible loaded into the iframe. The same time if loading document contains sub documents (for example, a tab page containing iframe elements) then there's only one event fired on the document, in other words, document loading events are fired on root of the documents loading chain. Refer here for more information.

Correctness and performance

Finally the list bullet accessible boundaries bug was fixed. Also we fixed a regression that IAccessible2 state defunt wasn't exposed on defunct accessible.

Bunch of performance bugs were fixed. Overall performance was improved. Thanks to Mark Cappela and others for this good work. Also we made accessible states computation noticeable faster. This should make the screen reader user experience a little bit smoother.

XPCOM

A quick update on XPCOM support for those who use it in Firefox add-ons. We introdroduced new roles for HTML definition elements
  • dl element: nsIAccessibleRole.ROLE_DEFINITION_LIST
  • dt element: nsIAccessibleRole.ROLE_TERM
  • dd element: nsIAccessibleRole.ROLE_DEFINITION
Also nsIAccessible.numAction attribute was renamed to nsIAccessible.actionCount for consistence with other interfaces.

Friday, May 11, 2012

Firefox 14: what's new for AT developers

Firefox 14 is in aurora channel and 5 June it's becoming a beta. We did a bunch of improvements and changes in accessibility support.

ARIA

ARIA role="note" is mapped into IA2_ROLE_NOTE role.  ARIA role="form" is mapped to IA2_ROLE_FORM / ATK_ROLE_FORM role. Also xml-roles:note and xml-roles:form object attributes are exposed respectively.

ARIA aria-describedby attribute used on HTML image element and pointing to HTML a element makes the image accessible to expose showlongdesc action. This action opens an URL provided by @href attribute on HTML a element in a new window. Take a look at example:
  <a id="a" href="http://www.mozilla.org">a link</a>
  <img aria-describedby="a" src="mozlizzard.png">

HTML

HTML section element accessible has IA2_ROLE_SECTION / ATK_ROLE_SECTION role and exposes xml-roles:region object attribute what makes it similar to ARIA role="region".

HTML sup and sub elements are exposed as text-position text attribute. Say you have:
  <div>x<sub>i</sub><sup>2</sup></div>
which looks like xi2. In this case you get default text attributes at range (0, 1) for HTML div accessible, text-position:sub at (1, 2) range and text-position:super at (2, 3) range.

HTML button having aria-pressed="true" attribute has IA2_ROLE_TOGGLE_BUTTON / ATK_ROLE_TOGGLE_BUTTON role.

States

Editable text fields always expose IA2_STATE_EDITABLE / ATK_STATE_EDITABLE state not depending on whether text field is readonly or disabled.

Undertemined HTML progress element and ARIA role="progressbar" expose STATE_SYSTEM_INDETERMINATE / ATK_STATE_INDETERMINATE state. Here are examples of indeterminate progressmeters:
  <progress></progress>
  <div aria="progressbar"></div>

Correctness and consistence

Image map accessible tree is properly updated when image map is changed. So whenever you add or remove HTML area element to/from related HTML map or change @name attribute on HTML map the image map accessible picks up the changes.

XUL listbox accessible tree is updated correctly when list items are inserted or removed. The issue affected on Thuderbird UI and Firefox profile manager dialog. I'm happy that finally this problem was fixed.

event-from-input:true object attribute is exposed on event target accessible if it's a child of the focused editable area. In general this is not correct but it's a good approximation to desired behavior. So for example, if value of the focused editable area is changed by script then we still report event-from-input:true and that's wrong of course.

We report the value of tag object attribute in lowercase always. We do that for consistence with other markup languages like XUL, XHTML or SVG. Also tag object attribute is not exposed when it's not applicable, for example, it's not used anymore for bullet accessible of list item. These changes shouldn't introduce problems for ATs but you should be aware of them just in case.

In MSAA/IAccessible2 layer when accessible is defunct then any method called on it returns CO_E_OBJECTNOTCONNECTED now.

XPCOM interfaces

nsIAccessible::innerHTML attribute was removed. It dupes the HTML element interface capabilities so it doesn't make sense to maintain accessibility version of it.

XUL/XBL

ARIA relation attributes used on XBL bound element are allowed to point to XBL anonymous content. You can do:

  <bindings xmlns="http://www.mozilla.org/xbl">
    <binding id="custombutton">
      <content aria-labelledby="button.label" role="button">
        <label xmlns="http://www.w3.org/1999/xhtml" anonid="button.label">
          anon label
        </label>
      </content>
    </binding>
  </bindings>

  <div id="button" style="-moz-binding: url('#custombutton');"></div>

In this case the button accessible picks up the name from anonymous label element.