Howdy, Stranger!

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

In this Discussion

2024 Participants: Hannah Ackermans * Sara Alsherif * Leonardo Aranda * Brian Arechiga * Jonathan Armoza * Stephanie E. August * Martin Bartelmus * Patsy Baudoin * Liat Berdugo * David Berry * Jason Boyd * Kevin Brock * Evan Buswell * Claire Carroll * John Cayley * Slavica Ceperkovic * Edmond Chang * Sarah Ciston * Lyr Colin * Daniel Cox * Christina Cuneo * Orla Delaney * Pierre Depaz * Ranjodh Singh Dhaliwal * Koundinya Dhulipalla * Samuel DiBella * Craig Dietrich * Quinn Dombrowski * Kevin Driscoll * Lai-Tze Fan * Max Feinstein * Meredith Finkelstein * Leonardo Flores * Cyril Focht * Gwen Foo * Federica Frabetti * Jordan Freitas * Erika FülöP * Sam Goree * Gulsen Guler * Anthony Hay * SHAWNÉ MICHAELAIN HOLLOWAY * Brendan Howell * Minh Hua * Amira Jarmakani * Dennis Jerz * Joey Jones * Ted Kafala * Titaÿna Kauffmann-Will * Darius Kazemi * andrea kim * Joey King * Ryan Leach * cynthia li * Judy Malloy * Zachary Mann * Marian Mazzone * Chris McGuinness * Yasemin Melek * Pablo Miranda Carranza * Jarah Moesch * Matt Nish-Lapidus * Yoehan Oh * Steven Oscherwitz * Stefano Penge * Marta Pérez-Campos * Jan-Christian Petersen * gripp prime * Rita Raley * Nicholas Raphael * Arpita Rathod * Amit Ray * Thorsten Ries * Abby Rinaldi * Mark Sample * Valérie Schafer * Carly Schnitzler * Arthur Schwarz * Lyle Skains * Rory Solomon * Winnie Soon * Harlin/Hayley Steele * Marylyn Tan * Daniel Temkin * Murielle Sandra Tiako Djomatchoua * Anna Tito * Introna Tommie * Fereshteh Toosi * Paige Treebridge * Lee Tusman * Joris J.van Zundert * Annette Vee * Dan Verständig * Yohanna Waliya * Shu Wan * Peggy WEIL * Jacque Wernimont * Katherine Yang * Zach Whalen * Elea Zhong * TengChao Zhou
CCSWG 2024 is coordinated by Lyr Colin (USC), Andrea Kim (USC), Elea Zhong (USC), Zachary Mann (USC), Jeremy Douglass (UCSB), and Mark C. Marino (USC) . Sponsored by the Humanities and Critical Code Studies Lab (USC), and the Digital Arts and Humanities Commons (UCSB).

Code Critique: JS Accessibility Hack

Programming language:

HTML + JavaScript

Code snippet (excerpt of code):

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

Description:

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.)

Explanation:

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 https://uploads.knightlab.com/storymapjs/264d1187a29448e1252d90856e644ca1/history-careers/draft.json: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://gpetruzella.github.io' 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?

Comments

  • 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.