Commit 14c63f0d by polesye

Merge pull request #1315 from edx/anton/fix-caltulator-a11y

Add a11y to the calculator
parents ccd692dd 99c8896c
<ul>
<li class="calc-main">
<a href="#" class="calc">Calculator</a>
<a href="#" class="calc" title="Open Calculator" role="button" aria-controls="calculator_wrapper" aria-expanded="false">Open Calculator</a>
<div id="calculator_wrapper">
<form id="calculator">
<div class="input-wrapper">
<input type="text" id="calculator_input" />
<input type="text" id="calculator_input" tabindex="-1" />
<div class="help-wrapper">
<a href="#">Hints</a>
<dl class="help"></dl>
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" aria-controls="calculator_input_help" aria-expanded="false" tabindex="-1">Hints</a>
<dl id="calculator_input_help" class="help"></dl>
</div>
</div>
<input id="calculator_button" type="submit" value="="/>
<input type="text" id="calculator_output" readonly />
<input id="calculator_button" type="submit" title="Calculate" arial-label="Calculate" value="=" tabindex="-1" />
<input type="text" id="calculator_output" readonly tabindex="-1" />
</form>
</div>
</li>
......
......@@ -9,8 +9,10 @@ describe 'Calculator', ->
it 'bind the help button', ->
# These events are bind by $.hover()
expect($('div.help-wrapper a')).toHandleWith 'mouseover', @calculator.helpToggle
expect($('div.help-wrapper a')).toHandleWith 'mouseout', @calculator.helpToggle
expect($('div.help-wrapper a')).toHandle 'mouseover'
expect($('div.help-wrapper a')).toHandle 'mouseout'
expect($('div.help-wrapper')).toHandle 'focusin'
expect($('div.help-wrapper')).toHandle 'focusout'
it 'prevent default behavior on help button', ->
$('div.help-wrapper a').click (e) ->
......@@ -33,8 +35,8 @@ describe 'Calculator', ->
# Since the focus is called asynchronously, we need to
# wait until focus() is called.
didFocus = false
runs ->
spyOn($.fn, 'focus').andCallFake (elementName) -> didFocus = true
runs ->
spyOn($.fn, 'focus').andCallFake (elementName) -> didFocus = true
@calculator.toggle(jQuery.Event("click"))
waitsFor (-> didFocus), "focus() should have been called on the input", 1000
......@@ -49,12 +51,14 @@ describe 'Calculator', ->
@calculator.toggle(jQuery.Event("click"))
expect($('.calc')).not.toHaveClass('closed')
describe 'helpToggle', ->
it 'toggle the help overlay', ->
@calculator.helpToggle()
describe 'helpShow', ->
it 'show the help overlay', ->
@calculator.helpShow()
expect($('.help')).toHaveClass('shown')
@calculator.helpToggle()
describe 'helpHide', ->
it 'show the help overlay', ->
@calculator.helpHide()
expect($('.help')).not.toHaveClass('shown')
describe 'calculate', ->
......
......@@ -3,26 +3,70 @@ class @Calculator
$('.calc').click @toggle
$('form#calculator').submit(@calculate).submit (e) ->
e.preventDefault()
$('div.help-wrapper a').hover(@helpToggle).click (e) ->
e.preventDefault()
$('div.help-wrapper a')
.hover(
$.proxy(@helpShow, @),
$.proxy(@helpHide, @)
)
.click (e) ->
e.preventDefault()
$('div.help-wrapper')
.focusin($.proxy @helpOnFocus, @)
.focusout($.proxy @helpOnBlur, @)
toggle: (event) ->
event.preventDefault()
$calc = $('.calc')
$calcWrapper = $('#calculator_wrapper')
text = gettext('Open Calculator')
isExpanded = false
$('div.calc-main').toggleClass 'open'
if $('.calc.closed').length
$('.calc').attr 'aria-label', 'Open Calculator'
if $calc.hasClass('closed')
$calcWrapper
.find('input, a, dt, dd')
.attr 'tabindex', -1
else
$('.calc').attr 'aria-label', 'Close Calculator'
text = gettext('Close Calculator')
isExpanded = true
$calcWrapper
.find('input, a, dt, dd')
.attr 'tabindex', 0
# TODO: Investigate why doing this without the timeout causes it to jump
# down to the bottom of the page. I suspect it's because it's putting the
# focus on the text field before it transitions onto the page.
setTimeout (-> $('#calculator_wrapper #calculator_input').focus()), 100
setTimeout (-> $calcWrapper.find('#calculator_input').focus()), 100
$calc
.attr
'title': text
'aria-expanded': isExpanded
.text text
$calc.toggleClass 'closed'
helpOnFocus: (e) ->
e.preventDefault()
@isFocusedHelp = true
@helpShow()
helpOnBlur: (e) ->
e.preventDefault()
@isFocusedHelp = false
@helpHide()
$('.calc').toggleClass 'closed'
helpShow: ->
$('.help').addClass 'shown'
$('#calculator_hint').attr 'aria-expanded', true
helpToggle: ->
$('.help').toggleClass 'shown'
helpHide: ->
if not @isFocusedHelp
$('.help').removeClass 'shown'
$('#calculator_hint').attr 'aria-expanded', false
calculate: ->
$.getWithPrefix '/calculate', { equation: $('#calculator_input').val() }, (data) ->
$('#calculator_output').val(data.result)
$('#calculator_output')
.val(data.result)
.focus()
......@@ -117,6 +117,7 @@ div.calc-main {
height: 35px;
@include hide-text;
width: 35px;
display: block;
}
dl {
......@@ -124,8 +125,6 @@ div.calc-main {
border-radius: 3px;
box-shadow: 0 0 3px #999;
color: #333;
display: none;
line-height: lh();
opacity: 0;
padding: 10px;
position: absolute;
......@@ -133,10 +132,15 @@ div.calc-main {
top: -122px;
@include transition(none);
width: 600px;
height: 0;
overflow: hidden;
pointer-events: none;
&.shown {
display: block;
opacity: 1.0;
height: auto;
opacity: 1;
overflow: visible;
pointer-events: auto;
}
dt {
......
......@@ -208,24 +208,23 @@ ${fragment.foot_html()}
% if course.show_calculator:
<div class="calc-main">
<a aria-label="${_('Open Calculator')}" href="#" class="calc">${_("Calculator")}</a>
<a title="${_('Open Calculator')}" href="#" role="button" aria-controls="calculator_wrapper" aria-expanded="false" class="calc">${_("Open Calculator")}</a>
<div id="calculator_wrapper">
<form id="calculator">
<div class="input-wrapper">
<input type="text" id="calculator_input" title="Calculator Input Field" />
<input type="text" id="calculator_input" title="${_('Calculator Input Field')}" tabindex="-1" />
<div class="help-wrapper">
<a href="#">${_("Hints")}</a>
<dl class="help">
<dt>${_("Suffixes:")}</dt>
<dd> %kMGTcmunp</dd>
<dt>${_("Operations:")}</dt>
<dd>^ * / + - ()</dd>
<dt>${_("Functions:")}</dt>
<dd>sin, cos, tan, sqrt, log10, log2, ln, arccos, arcsin, arctan, abs </dd>
<dt>${_("Constants")}</dt>
<dd>e, pi</dd>
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" aria-controls="calculator_input_help" aria-expanded="false" tabindex="-1">${_("Hints")}</a>
<dl id="calculator_input_help" class="help">
<dt tabindex="-1">${_("Suffixes:")}</dt>
<dd tabindex="-1"> %kMGTcmunp</dd>
<dt tabindex="-1">${_("Operations:")}</dt>
<dd tabindex="-1">^ * / + - ()</dd>
<dt tabindex="-1">${_("Functions:")}</dt>
<dd tabindex="-1">sin, cos, tan, sqrt, log10, log2, ln, arccos, arcsin, arctan, abs </dd>
<dt tabindex="-1">${_("Constants")}</dt>
<dd tabindex="-1">e, pi</dd>
<!-- Students won't know what parallel means at this time. Complex numbers aren't well tested in the courseware, so we would prefer to not expose them. If you read the comments in the source, feel free to use them. If you run into a bug, please let us know. But we can't officially support them right now.
......@@ -233,8 +232,8 @@ ${fragment.foot_html()}
</dl>
</div>
</div>
<input id="calculator_button" type="submit" title="Calculate" value="="/>
<input type="text" id="calculator_output" title="Calculator Output Field" readonly />
<input id="calculator_button" type="submit" title="${_('Calculate')}" value="=" arial-label="${_('Calculate')}" value="=" tabindex="-1" />
<input type="text" id="calculator_output" title="${_('Calculator Output Field')}" readonly tabindex="-1" />
</form>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment