Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Participants: Ben Allen * Stephanie August * Damon Loren Baker * Theo Ellin Ballew * Ivette Bayo Urban * John Bell * Paisley Benaza * Kathi Berens * David Berry * Sayan Bhattacharyya * Christina Boyles * Gregory Bringman * André Brock * Ron Burkey * Evan Buswell * Sarah Ciston * Eileen Clancy * Tara Conley * Krystal Cooper * Ranjodh Dhaliwal * Anthony Di Franco * Craig Dietrich * Jeremy Douglass * Kevin Driscoll * William Dyson * Brandee Easter * Martin Erwig * Schuyler Esprit * Max Feinstein * Todd Furmanski * Geoffrey Gimse * Erin Glass * Rochelle Gold * Catherine Griffiths * Ben Grosser * Fox Harrell * Sydette Harry * Brendan Howell * Nazua Idris * Jessica Johnson * Waliya Yohanna Joseph * Ted Kafala * Dorothy Kim * Corinna Kirsch * Steve Klabnik * Shelly Knotts * Peter Kudenov * Fidelia Lam * Liz Losh * Thor Magnusson * Jim Malazita * Judy Malloy * Zach Mann * Mark Marino * Lauren McCarthy * Irma McClaurin * Patrick McDonnell * Tara McPherson * Todd Milstein * Nick Montfort * Mark Neal * Safiya Noble * Keith O'Hara * David Ogborn * Allison Parrish * Ali Pearl * Gerol Petruzella * Andrew Pilsch * Samuel Pizelo * Jessica Pressman * Helen Pritchard * Daniel Punday * Kristopher Purzycki * Harvey Quamen * Amit Ray * Margaret Rhee * Lisa Rhody * Scott Richmond * Teddy Roland * Jamal Russell * Anastasia Salter * Mark Sample * Evan Schauer * Ari Schlesinger * Mehdy Sedaghat Payam * Ash Smith * Winnie Soon * Glen Southergill * Mel Stanfill * Samara Hayley Steele * Nikki Stevens * Tonia Sutherland * Miriam Sweeney * Ezra Teboul * Daniel Temkin * Dennis Tenen * Marilyn M. Thomas-Houston * Elizabeth Timbs * Giuseppe Torre * Rebecca Uliasz * Annette Vee * Sneha Veeragoudar * Ashleigh Wade * Kurt James Werner * Jacque Wernimont * Zach Whalen * Roger Whitson * Roger Whitson * Michael Widner * Jody Zellen * Kai Zhang
Coordinated by Mark Marino (USC), Jeremy Douglass (UCSB), Catherine Griffiths (USC), Ali Rachel Pearl (USC), and Teddy Roland (UCSB). Sponsored by the Humanities and Critical Code Studies Lab (USC), and the Digital Arts and Humanities Commons (UCSB).

Code Critique: JS Accessibility Hack

edited January 24 in Code Critiques

Programming language:

HTML + JavaScript

Code snippet (excerpt of code):

Examples below; you can find the entire script on my github.


I'm presenting a bit of simple HTML/JS. Essentially, it carries out the following sequence of steps:

  1. presents a clickable link for the user to generate an accessible <table> containing the data in an otherwise non-accessible media object embedded on the page. On click, the JavaScript...
  2. generates the URI of the JSON data which underlie the media;
  3. assigns the JSON data to a variable;
  4. uses a series of 'replace' operations to edit the content of the variable;
  5. displays the variable content as an accessible <table> element on the original webpage. (the code for this last bit is courtesy of Afshin Mehrabani via GitHub.)


The code was born out of creative tension. StoryMapJS is a project of Knight Lab at Northwestern University, which develops open-source tools for storytelling. Their tools provide engaging and interactive ways to understand data visually in narrative context. As with many media-centric tools, though, StoryMapsJS is optimized for sighted users; navigating a StoryMapJS object using NVDA is an exercise in confusion. I wanted to create a lightweight user-side bit of code that would programmatically offer the user access to the same data used in the visual map, but in a standard HTML table, providing structural context which screen readers can parse effectively for the listener.

As I developed and deployed the code, I began realizing that there were some curious ways the requirements of the code structure and syntax expressed values relevant to the presumed audience. One significant context was in step 4 above, i.e., the 'replace' operations for content editing. The raw JSON data, if presented in a table, would be hardly more intelligible, aurally, than the original media. Thus, as code author, I was immediately making choices of exclusion, based on the aural clarity of how the data would be presented. For example, here's one line:

var obj = obj.replace(/zoomify|location|head|storymap|media|text|attribution|call_to_action|true|false|slides|date|caption|credit|type|overview|line|osm|zoom|map_as_image|map_subdomains|map_|,|url|::|\/\/|[{\[\]}_\"]/gim , "");

As you'll probably intuit, most of these terms to be 'replaced' (with nothing) are headers. Rather than just leaving them alone, or formatting them to be more readable as needed (e.g converting "call_to_action" to "call to action"), I made the choice that these category signifiers were both extraneous - the data themselves were intelligible - and obscurantist - the value of any meaning they conveyed would be outweighed by their "cluttering up" the aural space of the information. The last several terms to be replaced represent the special and escape characters which, if left alone, would obscure meaning and/or produce oddities in formatting once the string is converted to an HTML <table> element.

A second example of how the actual writing of the code was shaped by authorial consideration of the audience: the line below formats the string as a colon-separated array. This is not the most typical choice; but I made it responding to my perception of the most likely ways the typical creators of StoryMapJS items would enter readable text. A StoryMapJS object is based on a Google Sheet, and includes fields for narrative descriptions, captions, etc. The script needed to take into account the fact that the string it's meant to format will include characters, including punctuation with special meaning in code, which have different meaning in context of human-read content, and so which must be in a sense "escaped." The second line, below, is an illustrative example of a consequence of this choice: adding a colon into a string for the sole purpose of signalling a table break.

var jsonarray = obj.split(":");

obj = obj.replace(/image url/gim , "New Slide:image url");

A final, and rather significant, consideration arose at the testing stage. The script relies upon the XMLHttpRequest object to get access to the original JSON data underlying the media object. Security protections against malicious code restrict the remote use of XMLHttpRequest. Interestingly, the relevant policy is implemented in slightly different ways by the different major browsers; and so, while the script works as intended in Firefox and Edge, Chrome and Safari block its execution on security grounds. It can be enabled if the admin of the target server enables a certain header (see below); but of course this is often not a realistic option, and essentially places the agency for "allowing" the implementation of an accessibility solution in the control of the server admin, rather than the end user.

Chrome console error message blocking data access: "Failed to load No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '' is therefore not allowed access."

Discussion questions:

  1. How much of code writing rests on a model of constraint, either presumed or explicit? Particularly in conversations of user experience and design, how often does the end user perceive "all" the information contained in the source database, and how do those choices get made for the "generic" end user? for specific end users?

  2. How does such a constraint model influence a code author's perception of power imbalances in relation to the end user, particularly in context of the idealism of "open"?

  3. The nexus of accessibility, agency, and security seems a powerful convergence of considerations for a code writer. Given that the rhetoric of security tends to set safety and agency as mutually constraining elements, are there parameters of code work which tacitly weigh against accessible coding?


  • One thing your critique and the questions has me thinking about is this talk by Jacob Thornton (who co-created the extremely popular CSS framework Bootstrap about some of the problems associated with CSS as a concept.

    The thing that I think is especially relevant to your second question is the early discussion of Richard Stallman and the different early models for what was "open" on the web. To save anyone who's interested from watching a 42-minute video, the point is that in the early days of HTML, when it was first becoming apparent that people might want to change the font on their websites (gasp), there was a discussion at the W3C about who should have control: the content provider, the browser provider, or the user.

    As the talk kind of lays out, all three ideas conform to the idea of an open web. The W3C, with the release of the CSS spec, eventually sided with content providers, figuring that the ability to style one's content in any fashion embodied the open web. But Stallman was, and still is, an advocate for the user having final authority, with the idea that each of us could have our particular and particularly detailed stylesheet that styles the web how we want it. This is another definition of "open."

    So, all of that is to say, with regards to CORS and XMLHttpRequest, the onus of being "open" is on the content provider (again) and not on the user, so while we have an "open web" of accessible APIs (which is why StoryMapJS is so cool), it's only "open" at the behest of a particular segment of web users, as you draw out.

    All of this is to say that there's an interesting way to think about a constraint on application design emerging from human language itself, a particular definition of "open" (that was chosen and baked into the web's architecture) that out-competed other, different definitions of "open."

Sign In or Register to comment.