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.

Thursday, March 29, 2012

New contributors, welcome on board!

I remember that couple years ago I answered some Mozilla questionnaire and one of questions was "how many new contributors were involved into your project this year". That time I answered "none". Now I can say times were changed. Mozilla started the active engagement work and of course it brought a positive effect to Mozilla accessibility story.

I was the first one from accessibility team who volunteered to find good first bugs for new contributors and do mentoring. Now everyone from accessibility team joined. And I can say you why.
  • It's really fun because you talk to new people who is passionate about open web, accessibility and Mozilla.
  • You acquire new experience working closely with contributors having different styles and another way of thinking.
  • New contributors do amazing work! Over the past three months about 150 bugs were fixed in accessibility module, over 30 bugs were fixed by new contributors.
As you can see results are very exiting.

Ok. What if you think Mozilla is cool or if you are passionate about accessibility. Then it's time to join!

If you are a hacker then you can start hacking on Firefox accessibility easily. Here are simple steps:
Well, if you want to try something else outside the accessibility then there's a nice tool to find mentored bugs. Or if you are unsure about code hacking this time then check out how else you can get involved.

Interested? Do you want to change the web? Then welcome on board! It's really fun!

Thursday, March 22, 2012

Firefox 13 for AT developers

Several days ago Firefox 13 entered into aurora channel. No active development on it anymore so it's time to give it a try.

Firefox 13 looks much more interesting from AT perspective than Firefox 12. Let's run through the changes.

HTML

We implemented the canvas fallback content accessibility.

Table data vs layout algorithm was enriched by extending the list of legitimate data table structures. So if @headers, @scope and @abbr attributes are specified on HTML table cell or the table cell contains HTML abbr element as a single child element then the table is treated as data table. Thanks to our new contributor Mark Capella who implemented this.

ARIA

As you probably know that ARIA doesn't provide a way to expose accessible actions on ARIA widgets and therefore Firefox makes a guess about actions depending on ARIA role. This release got a fix for role="button" which is exposed with press action now.

We dropped ARIA role="label" support which was removed from the spec.

ARIA role="listitem" doesn't longer support aria-selected and aria-checked. ARIA role="combobox" doesn't allow aria-valuemin/aria-valuemax attributes that were maintained by mistake I believe over certain period. 

Text attributes

In Firefox 13 the font-family text attribute represents the actual used font. Previously the value was exactly the same what the user specified by CSS font-family property. Note, the range still might be not correct on case by case basis, for example, when font-family is changed within a single text node.

New text-underline-color and text-line-through-color text attributes were implemented. Check out IAccessible2 spec for details.

The text-position text attribute is restricted to spec allowed values: baseline, super and sub. Other enum values of CSS vertical-align used to expose this text attribute are ignored.

Object attributes

Now we expose D2D object attribute on Windows. If hardware acceleration is turned on then you can see D2D:true object attribute on application accessible.

We expose margin-left/right/top/bottom object attributes. Thanks to Mark Capella who volunteered to fix this issue.

Work in progress and randoms

Got more progress on OS X accessibility. Probably not a giant step but no doubts we moving forward. Not a part of default build still.

We addressed few issues with text interface like wrong behavior of caretOffset. We fixed some regressions in hit testing and accessible coordinates for zoomed pages. Fixed a major issue when we missed parts of accessible tree under certain circumstances. The patch was back ported to Firefox 12.

On ATK the application accessible object name is a real application name. Prior this fix it was application brand name. To make things clear we expose now 'Firefox' not 'Nightly', for example, in case of nightly Firefox build. That was done because ATK doesn't have an option to expose application name the way as IAccessible2 does and AT had hard times to figure out that the running nightly Firefox is Firefox actually.

Virtual cursor

Last but not least. At XPCOM level we introduced traversal API and virtual cursor support. That's a major step on the way to make screen readers running in the browser. Now you can manage the virtual cursor from JS. This is pure API thing, i.e. the virtual cursor doesn't have any visual presentation so as Firefox add-on developer you should take care about this. This work was influenced by Firefox accessibility on Android. Anyway this item deserves own post so no many details here.

Thursday, March 1, 2012

Windows 8 Narrator on the web

I should notice I'm not a screen reader user and therefore my front-end observations might be not complete or not accurate. Please correct me if I say something wrong.

Windows 8 beta is out. I saw a bunch of posts saying that Microsoft improved accessibility support, in particular that Narrator was greatly refined over previous versions including outstanding performance in IE. So I wanted to play with Narrator and see how it works in Firefox.

The background of the interest is sort of pragmatic. I'm curious whether the market share of screen readers can be shifted after Windows 8 release. The rationally is simple. If some OS provides a set of built-in applications then the user gets all-in-one solution. And if those applications are good enough then many users don't need anything else. So I wasn't going to do any truth worth research but I wanted to see myself how the things look.

On Windows Mozilla bets on IAccessible2, an open standard developed by number of companies including both AT client vendors (screen readers, screen magnifiers etc) and AT server vendors. I don't think this is going to change but if Firefox wasn't nice on Narrator and if Narrator takes a certain percent of the market share then we at Mozilla can't leave this unaddressed.

This time I didn't pay an attention to touch-based accessibility features despite this is definitely a crucial part for mobile web. But this is certainly big area deserving own topic. I focused on how Narrator is doing on the web in classical desktop case.

Narrator

The first noticeable thing is Narrator highlights traversed objects similar to what Voice Over does. This should be a neat feature for teaching and training. I liked the help dialog to see command shortcuts which is good for newbies. Another interesting feature the Narrator allows to bring a dialog containing the list of available actions on the current object and the user can pick up the one to invoke.

Narrator is fast, at least I didn't noticed any lags when I navigated the web. Moreover I've got an impression that sometimes it's faster than NVDA (both on IE and Firefox).

It provides hierarchical virtual cursor: arrow keys allows you to move into container, navigate through siblings within a container and move outside a container. It seems that the implementation is quite plain, it just moves the virtual cursor through accessible tree. You may consider this as a benefit since often this allows you to skip easily a large portions of the page. However taking into account that containers aren't provided by any good description then this is rather useless feature, at least until the user learns the hierarchy for each web site he visits. To Narrator credit I must say it announces the amount of items within certain containers.

On the other hand the web pages and especially web applications have quite complicated trees and that makes navigation not trivial. I'm not experienced user but I feel like NVDA approach is nicer. Narrator approach sounded for me like it's more suitable for tree inspection for debugging proposes rather than for document navigation in the wild.

I looked how Narrator goes with some applications like GMail. I was able to navigate the whole GMail, however sometimes the virtual cursor reached a certain point and didn't move further. I was forced to use tab to skip this place. Also I wasn't able to locate some menus of menu buttons. I think this is because these menus weren't in hierarchy of the button. So you might want to blame Gmail.

Narrator allows to navigate the text, provides commands to traverse the page by paragraphs and supports table navigation but I didn't make it to do more complicated structural navigation like navigation by headings, links etc. It doesn't sound like Narrator has it.

MSAA / UIA / IAccessible2

Windows 8 makes some work to map MSAA to UIA and that allows Narrator to work with MSAA applications. That makes Firefox accessible in principle. For example, you can navigate the web pages and do basic interaction with control elements like open a link, click a button etc. But MSAA accessibility is quite restricted.

Narrator allows the user to navigate by paragraphs, lines, words and characters. It provides some support of text attributes. None of these features work in Firefox. When the document is loaded then Narrator starts reading it. Again not in Firefox.

In summary Firefox doesn't look cool in Narrator. It's sort of expected because Firefox doesn't implement UIA.

I didn't really believe that Microsoft will bridge IAccessible2 to UIA but I hoped. That would allow a number of applications like Eclipse, Open Office or Firefox to work great for Narrator users. Sometimes dreams may not come true.

Wednesday, February 29, 2012

How I booked the flight or the curse of cancel button

Recently I booked the flight for me and my family. After some search I stopped at Rossiya airlines (Saint-Petersburg's airlines). It was new airlines for me but they offered the best option.

So I started booking and somewhere in the middle I decided to use another bank card. I pressed cancel button (instead the pay button) and it says the payment failed. No option to retry.

I tried to dial the call-center of Rossiya airlines, several times, but no any luck to ring till the bell is answered. So I wrote them email and in few minutes I got an answer:
Unfortunately you can't pay by bank card online if you rejected to do that once. But you can pay in our office, choose another payment type or book another flight.
Sure I tried to book the flight again but the price surprised me. It wasn't the best option anymore. So I decided to pay existing one and since another payment type usually assumes a noticeable fee then I said:
Ok. What is address of your office in my city.
They said:
Unfortunately we don't have offices in your city. You can try to pay by VTB-24 ATM or in VTB-24 bank office.
I asked about the fee. They said no fee. Ok, nice.

I located VTB-24 ATM near of my house and tried to pay. When I typed the payment info then the ATM said that it can't process this request. I thought maybe VTB-24 ATM can vary, thus I checked Rossiya airlines web site which ATM can be used to make this payment. Next day I tried another VTB-24 ATM. This time when I specified all payment info it said "the feature is not implemented". The farther into the forest the thicker the trees I thought.

So I came to the office of VTB-24 bank to make a payment. They said I can't pay by my bank card. Of course if that was a bank card of their bank then I could do that but otherwise they can't help me and they need a cash. So I moved to ATM of my bank and got that cache, got back to that office and oh happiness I did that.

Say me what a heck I pressed that cancel button.

Friday, February 24, 2012

Firefox 12 for AT developers

Firefox 12 is still on aurora channel and expected to enter into beta stage at 13 March. It doesn't have much "front-end" features but there's couple ones that might be interesting for AT developers. We did some under the hood work and crash fixes. Also we improved Mac accessibility support but it's still not a part of the default build.

ARIA support gained some sugar for multi-selectable widgets like ARIA list and tree. Now the selected state is exposed on list options and tree items by default, i.e. until aria-selected="false" is specified. This prevents screen readers like JAWS and NVDA to say "unselected" for many ARIA widgets on the web when the user traverse through their items. So a bit of sugar to keep users less annoyed.

We fixed NAVRELATION_EMBEDS MSAA relation on Firefox application accessible (ROLE_SYSTEM_APPLICATION/IA2_ROLE_FRAME). It failed to return a selected tab document accessible under certain circumstances, for example, when Firebug is installed.

Invisible and offscreen states

The most important change is we altered a logic how we expose MSAA INVISIBLE and OFFSCREEN states and ATK VISIBLE and SHOWING states. Let's do some background on this.

ATK VISIBLE means visible or the user can make it visible. ATK SHOWING means visible, i.e. on the screen. See the post  for the reference.

MSAA expectations are different. INVISIBLE means not visible on the screen (in either case), OFFSCREEN means it's not visible on the screen but the user can make it visible. See the post for the reference.

So based on that we'd need to do the following:
  • on the screen
    • MSAA: no INVISIBLE & no OFFSCREEN
    • ATK: VISIBLE & SHOWING
  • not on the screen
    • MSAA: INVISIBLE & OFFSCREEN
    • ATK: VISIBLE & no SHOWING
  • hidden accessible
    • MSAA: INVISIBLE & no OFFSCREEN
    • ATK: no VISIBLE & no SHOWING

However Firefox didn't expose hidden accessible this way on MSAA so we decided to not fix this and keep the logic closer to ATK spec:
  • on the screen
    • MSAA: no INVISIBLE & no OFFSCREEN
    • ATK: VISIBLE & SHOWING
  • not on the screen
    • MSAA: no INVISIBLE & OFFSCREEN
    • ATK: VISIBLE & no SHOWING
  • hidden accessible
    • MSAA: INVISIBLE & no OFFSCREEN
    • ATK: no VISIBLE & no SHOWING

Also we started to treat accessibles from the background as offscreen (previously they were exposed as invisible). The reason of doing this is usually ATs ignore invisible accessibles but they are interested in changes happening in background tab.

If you need more information on this then please refer to the bug to read discussion.

Monday, February 20, 2012

aria-hidden and role="presentation"

John Foliot pinged me about his blog post devoted to ARIA techniques used to hide the content from assistive technologies. Since I don't have straight answer then I decided to put my thoughts here.

presentation role
ARIA role="presentation" technique is intended to hide an element from AT users. A classical example is presentational images. If you place role="presentation" on the image then it gets removed from accessible tree. Also this technique can be used to remove HTML table semantics, i.e. if role="presentation" is specified on HTML table then table structure is not exposed.

ARIA role="presentation" is completely ignored if it's used on focusable element. That means the element isn't removed from accessible tree and its native semantic is exposed. For example, if you put this role on HTML button then it's revealed as normal HTML button to AT. This is reasonable because if the user focuses the button then focus doesn't get lost and screen reader announces something meaningful.

aria-hidden
The most noticeable difference from role="presentation" is aria-hidden affects on whole subtree. John gave a good use case: hide excess links from screen reader users. A common pattern is a clickable image inside HTML:a element. ARIA spec confirms this saying "Authors MAY, with caution, use aria-hidden to hide visibly rendered content from assistive technologies only if the act of hiding this content is intended to improve the experience for users of assistive technologies by removing redundant or extraneous content."

I should notice that ARIA is not designed to change visual presentation and affect on behavior. Thus if this is an ordinal link then no ARIA technique can be used to hide it from screen reader user since this contradicts to ARIA design. But if the author puts @tabindex="-1" on the link to make it unfocusable then aria-hidden looks like a proper way to achieve desired result.

Technical side
ARIA implementation guide allows to remove elements with aria-hidden from accessible tree but it doesn't require that. Also it states "If the object is in the accessibility tree, map all attributes as normal. In addition, expose object attribute hidden:true". Additionally it points that if the aria-hidden attribute is changed then the browser should emit attribute_changed event (in case of IAccessible2). That's exactly what Firefox does.

So Firefox does a minimal implementation of aria-hidden allowing a screen reader to do what it thinks it should. That means each screen readers should invent a wheel and actually that what happens (or doesn't) - check this table to see how Firefox is different depending on screen reader running.

Implementation of aria-hidden both on browser side and screen reader side is not straightforward. For example if some element having aria-hidden contains a focusable element then its *whole* subtree can't be ignored. At the first glance reasonable solution would be if the browser doesn't create an accessible for each element in subtree until the element is focusable, in other words it treats aria-hidden as role="presentation" was specified on each node in subtree. Otherwise AT needs to crawl the accessible tree to check if there's an element with aria-hidden in ancestor chain. The current Firefox implementation forces AT to do that.

Things to think about.
If the browser doesn't create an accessible for aria-hidden subtree then there is a black box having certain dimensions on the screen. Thus if the user investigates the page layout by mouse then screen reader says nothing when the mouse pointer is above that black box but if the user clicks at this area then he gets unexpected behavior.

On the other hand some screen magnifiers use dimensions of accessible objects for page zooming. No accessible then zoom is likely broken.

So at the second glance I think aria-hidden shouldn't change the tree at all. Instead the browser should expose hidden:true object attribute on every accessible from the subtree of aria-hidden element. That allows AT to decide whether they want to ignore the accessible or not and prevents AT to crawl the accessible hierarchy.

I'd say this rule should be applicable to role="presentation" as well. So if the user explorers the page by mouse then screen reader can say this is presentational image but exclude it from keyboard navigation.