Howdy, Stranger!

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

Accessibility and Custom Audio Files [Sugarcube2]

I'm working on a project to be used by several foreign language teachers. I'm struggling with a technical issue related to two project goals: We want to narrate the entire project so students can hear native speakers, and we also want to make the project accessible to people with disabilities.

I've made the keyboard-accessible, and now I'm working to add the audio. Since 'audio from native speakers' is a project goal, I need to override the default machine-generated speech used by screen reading software. This doesn't seem particularly difficult -- it involves adding
aria-hidden="true"
to the parent tag, then implement a JavaScript listener that will play the appropriate audio file when text element with specific IDs or classes gain focus.

My problem is that I'm having trouble adding a class and/or id to links generated with <<click>>.

I'm using <<click>> because I have a series of objects in each passage. Each object holds a possible responses to a question, number of points for that response, feedback, etc. Each object also includes the file name of the audio for the choice, and the file name for the audio of the feedback. The feedback doesn't show until the user chooses a response.

Greyelf kindly helped me display and randomize these responses:
<<for $i to 0; $i < $choices.length; $i++>>
	<<print "<<click $choices[$i].choice>><<set $j to " + $i + ">><<display \"Choice Logic\">><</click>>">>
<</for>>

(The Choice Logic passage, which isn't part of the problem (I hope!) displays the feedback, takes care of the scoring, etc. I hope to leave it alone as I spent a week getting it to work, and am afraid to change anything!!)

Is there any way to get an ID or class into these links, or should I throw everything out an adopt a different approach?

I thought about using a <span>, but I'd have to make a span get focus, which seems like a bad practice. I also thought about using a paragraph around the choice, but then I'd have to give the paragraph focus to play the sound, then users would have to activate the link inside the paragraph, which seems like poor UI.

Any help or advice appreciated.







Comments

  • Not directly, no. That said, if we're talking about the main passage display area, then it wouldn't be terribly difficult to use a postrender task to modify the <a> elements generated by <<click>>.

    In SugarCube, macros generally denote ownership of generated elements via a class like macro-{name}—specially, macro-click in this case. So, a postrender task could target such elements within the render buffer and modify them as necessary before they're added to the live page. Something like the following should do the job: (goes in Story JavaScript)
    postrender["ariaPostProcessing"] = function (content) {
    	$(".macro-click", content).attr("aria-hidden", true);
    };
    
    That will add aria-hidden="true" to all <<click>> generated links within the main passage display.

    If you need to be more selective in your link targeting, then you'll need something more. For example, to only target <<click>> generated links within certain passages, you could use passage tags (e.g. let's say ariahidden):
    postrender["ariaPostProcessing"] = function (content) {
    	if (tags().contains("ariahidden")) {
    		$(".macro-click", content).attr("aria-hidden", true);
    	}
    };
    
    That will add aria-hidden="true" to all <<click>> generated links within the main passage display for passages tagged with ariahidden.

    Beyond that, there are various ways to be even more selective, if necessary. I can provide examples, if it comes to that.
  • Thank you, I'll play with that. It's a great way to handle the Aria tags, but I think I'll still need a way to tag each of the links the loop generates with a unique id. The ID name (pulled from the response object) would be the name of the sound file (for example, q01-choiceA). I need this so when the link gets focus I can play the file q01-choiceA.mp3.
  • Well, you could do both by wrapping the <<click>> macros with a <span> containing a specific data-* property (e.g. data-xfer) and the properties you wish to transfer to the <<click>> generated <a>. For example:
    <<for $i to 0; $i < $choices.length; $i++>>
    	<<print '<span data-xfer id="' + /* ID_HERE */ + '" aria-hidden="true"><<click $choices[$i].choice>><<set $j to ' + $i + '>><<display "Choice Logic">><</click>></span>'>>
    <</for>>
    
    And the postrender task which looks for the specific constructs and makes the necessary modifications:
    postrender["attr-xfer-post-processing"] = function (content) {
    	$("span[data-xfer]", content).each(function (i, xfer) {
    		var $xfer  = $(xfer);
    		var $click = $xfer.find(">.macro-click");
    		if ($click.length === 0) {
    			return;
    		}
    
    		var id = $xfer.attr("id");
    		if (id) {
    			$xfer.removeAttr("id");
    			$click.attr("id", id);
    		}
    
    		var ah = $xfer.attr("aria-hidden");
    		if (ah) {
    			$click.attr("aria-hidden", ah);
    		}
    
    		$click.insertBefore($xfer);
    		$xfer.remove();
    	});
    };
    
    Once the transfer of properties is complete, it removes the donor <span>, so you're only left with the <a>. You could add a mouseover handler for the audio either as part of the task or as a delegated handler on the document.
  • Wow, that looks perfect!! Thank you! I've never used data-xfer before, and I couldn't find it in the Sugarcube documentation. (I could have missed it, I'm good at that.) Could you point me to a reference so I can learn more?
  • There's nothing inherently special about the data-xfer attribute—I chose that name because it sounded good for this sort of thing. It's simply a data-* attribute (of HTML) which the postrender task keys off to know that it should process that <span> and its child <a class="macro-click">. Basically, it has no special meaning to anything other than the task function shown above.
  • edited December 2015
    Wow, that looks perfect!! Thank you! I've never used data-xfer before, and I couldn't find it in the Sugarcube documentation. (I could have missed it, I'm good at that.) Could you point me to a reference so I can learn more?
    HTML supports adding custom attributes to elements and by convention a custom attribute name starts with "data-", in your specific case TheMadExile added a new custom attribute named "data-xfer" and I would guess he named it thus because it is being used to transfer information between elements.

    edit: looks like we both answered your question at the same time. lol
  • OK, I get it now. Thank you both!
Sign In or Register to comment.