Part 1[]
I thought we'd look at how Accessify Wiki works in several installments. In part 1 we deal with the browser-side or end-user facing components, all written in Javascript. Next time we'll cover the server-side components.
Browser/ client-side components[]
I've represented the browser or client-side components as three concentric rings.
AccessifyHTML.js[]
At the core, we have accessifyhtml5.js, an open-source Javascript library written by Eric Egert with help from the community.
AccessifyHTML5.js can be used standalone as a polyfill. As used in Accessify Wiki, it can also accept a Javascript (strictly a JSON) object "more_fixes", which takes the following form:
more_fixes = {
"CSS Selector": {
"HTML Attribute Name": "Value"
}
}
An example of some fixes in Javascript Object Notation would be:
more_fixes = {
"#site-nav": {
"role": "navigation",
"aria-label": "Main site menu"
}
}
(OK, strictly the "more_fixes =
" part makes this JSON with padding (JSON-P) - let's not quibble.)
This fix could be applied to the following HTML snippet for a site's navigation:
<div id="site-nav">
<a href="/home" >Home</a>
<a href="/about">About us</a>
...
</div>
The only purpose of AccessifyHTML5.js is to add the specified attributes to the selected elements in the HTML structure of the page (the Document Object Model or DOM in the browser), so that end-users and assistive technologies like screen readers can glean more information about the page. It can be thought of as Javascript injection to produce an augmented browsing environment.
The function returns a Javascript object, whose four properties contain arrays of success, warning and error objects, and an object containing the input fixes:
function_return = {
ok: [{
attr: "HTML Attribute",
msg: "Human-readable message",
sel: "CSS selector",
val: "Value"
},
...
],
warn: [],
fail: [],
input: {}
}
For completeness, a full function signature follows.
/**
* @param {object} defaults A Javascript object, or false
* @param {object} more_fixes A Javascript object, or false
* @return {object} A Javascript object
*/
var AccessifyHTML5 = function (defaults, more_fixes) { ... }
Security[]
Note, to prevent attempted security breaches, AccessifyHTML.js only allows certain HTML attributes or properties to be set. So, for example, "role
" and "title
" are allowed, whereas Javascript event handlers like "onclick
" are not allowed. See the code for the full attribute white-list, "ATTR_SECURE
"
Bookmarklet Javascript[]
Having dealt with the inner circle, we come to the middle ring, the bookmarklet Javascript. This can be a standalone bookmarklet, or the "middle layer" of a browser add-on. The bookmarklet Javascript has several purposes:
- It checks browser features and prevents further execution under some circumstances, for example, in an
<iframe>
(to reduce the performance hit for pages with lots iframe-based adverts). Function:browserFeatures()
; - It creates the Accessify Wiki user-interface (UI) element in the bottom-right of the page;
- It determines if there are fixes cached in HTML5 Web Storage (we currently use sessionStorage, plus a time-out);
- If there are it uses AccessifyHTML5.js to apply them straight-away, as described above;
- Otherwise it injects a
<script>
tag into the page to query for fixes on the tools server, based on the URL of the current page; - An example query is: http://accessifywiki--1.appspot.com/fix?url=http://example.org/page;
- And then, if fixes exist it applies them and adds them to Web Storage;
- Finally it updates the UI element with either success, "not found" or "error".
Hmm, an almost complete algorithm. I should probably turn that into a flow diagram or something!
Browser add-on[]
The only purpose of the outer layer of our concentric rings is to package up the 2 inner rings described above into either a user Javascript or browser add-on/ extension.
At present we have only implemented the user-Javascript option. On the plus-side this option is cross-browser - supported on Chrome, Firefox, Safari and Opera (and perhaps on Internet Explorer?) The cross-browser support is gained at a slight cost in installation-time usability, in that you normally need to install a generic browser addon like Greasemonkey to manage the user-Javascript. In time, we will implement one or more browser addons - the initial target will probably be either Internet Explorer or Firefox.
Conclusion part 1[]
So there we have the three browser-side components to deliver accessibility and usability fixes to the end-user in their browser.
In part 2 we'll look at how the server-side components work.