Screen Reader Detect 1.2

C. Blouch

September 15, 2005

Introduction

JAWS and Window-Eyes are commercial screen reader packages which allow those with visual impairments to hear web pages. The enabling power of these systems can make the difference between the pages being accessible or totally unusable. To avoid putting our members in the dark we need to make sure our pages work well when being used by screen readers through the addition of alt text and other invisible enhancements. Unfortunately there are instances where interactive or dynamic pages can interfere with or outright fail to work when a screen reader is active. In some of these cases no amount of standards adherence or code tweaking will make it work for for all users. A web designer might have been able to adjust things just for screen readers if they had a way to detect whether one was being used, but that was impossible...until now.

What is documented here is a detection package which will tell the page whether a screen reader is running or not.
readme.htmlWhat you are reading right now
detect.htmlA working example
detect.jsThe JS library which makes it go
srdetect.swfFlash movie which gets detection results
srdetect.flaSource actionscript to the Flash movie

Theory of Operation

Macromedia Flash has some ActionScript commands which allow it to discover the presence of a screen reader. The detect.js is included in your page and at the end of the document a function sr_detect_end() is called. This does all the work of embedding the flash movie in the page. Of course it first checks that you have Flash 6 or 7 installed before doing anything. The flash movie then checks for the screen reader and then calls a function in the your page called sr_result() and passes it a '1' or '0' string value. The sr_result() function should then hide the sr_detect DIV so it doesn't interfere with page layouts or get read by the screen reader, if there is one. Next sr_result() can execute any additional javascript you want. This could be commands to switch style sheets, hide or show different DIVs or provide alternate navigation.

Today's screen readers rely on Microsoft Active Acessibility (MSAA) so this is a Windows IE-only solution. The detection process is not needed and should have no effect on other browser/OS platforms.

This screen reader detection process, obviously, relies on the browser being both JavaScript and Flash enabled. If no flash 6 or 7 is detected then we call sr_detect(1) which makes it behave as though a screen reader was detected. Why do we do this? If you have features which ruin the experience for a screen reader user then we want to play it safe and protect those users at the cost of possibly giving a false positive for non-screen reader users. This may seem unfair but with about 97% market penetration for Flash 6 it is a small tradeoff against the possibility of rendering one of our products unusable for a growing class of the AOL audiance.

Integration Steps

There are four easy steps to integrate this detection into a page.
  1. Include the detect.js library.
  2. Call the sr_detect_end() function at the end of the page
  3. Create your sr_result() function to do whatever is desired to improve screen reader operation
  4. Host the detect.swf and detect.js files on your server
If you are already including a .js file into your page, you can save a fetch by adding the contents of detect.js to your existing file. The working example shows all the steps previously described, detects the screen reader and then updates the page to let you know what it found out.

Cross Domain Issues

Because of a bug in the ActionScript getURL method causing animated GIFs to stop rotating in IE6 (bad for ads) we had to revert to using FSCommand to call a VBScript which calls the JavaScript. FSCommand has some cross-domain limitations in that the swf has to be served from the exact same domain as the page including it or the Flash->JS intereface is blocked. If you do need cross domain hosting such as putting the SWF on a CDN, you will need to provide a crossdomain.xml file and host it on the root of your server. For example, you can see the crossdomain.xml for www.aol.com here:

http://www.aol.com/crossdomain.xml

If you are already integrating data driven flash files you may already have a crossdomain.xml file hosted on the root or your server. Just make sure it lists wherever you are pulling in the flash file from. The downside of this is that the crossdomain.xml check only works in Flash7 or higher. If you need to support Flash 6 users you will have to host the srdetect.swf on the same domain as the page using it.

Summary

I hope this library allows you to bring more light into the world of those who must view it through the interface of a screen reader. It can make the difference in not just ease of access, but any access to the pages we present in the products we sell.
Version History
1.2 - 9/15/2005
[Bugifx] - Screen reader detection was causing animated GIFs to stall. Root cause was the use of getURL('javascript:sr_detect(result);'); When This was executed it froze GIFs. Appears to be a bug in IE. Rewrote flash to use fscommand to call a vbscript which in turn calls the sr_detect() function. Rewrote sr_detect_end() to now instantiate the vbscript in addition to the flash object.
[Bugfix] - Detection was becoming unreliable as pages became more complicated, giving many false negative detection scenarios. Rewrote setup process. sr_detect_end() still instantiates the flash object but the flash.swf was rewritten to stop on the first frame. JS library now adds an onload handler to call sr_init after the page is completley loaded. sr_init then checks for flash 6 or higher. Once Flash loading is 100% complete the flash .play() method is invoked which causes the flash to start execution. The Flash movie now waits 1 second, does the screen reader detect and then passes the result to the sr_detect() function.
[Bugfix] - Detection was often failing on the first pageload of a freshly loaded IE. If Flash is present init() now checks the flash .PercentLoaded() to make sure it is 100% done, or waits until it is done before proceeding.
[Change] - Initialization function now called sr_detect_end() and all functions and VARs are prefaced with sr_ to avoid name space collision.
[Change] - sr_result is now expected to be provided by the integrating partner in their page.

1.1 - 8/17/2005
[Bugfix] - When included in non-flash browsers the detect would fail to instantiate leaving ugly junk on the screen. Added detection for flash 6 or 7 before starting Jaws detection.

1.0 - 8/16/2004 - Initial release with no known bugs.