BLD-533: Improve calculator's tooltip accessibility.
This commit is contained in:
@@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes,
|
||||
in roughly chronological order, most recent first. Add your entries at or near
|
||||
the top. Include a label indicating the component affected.
|
||||
|
||||
Blades: Improve calculator's tooltip accessibility. Add possibility to navigate
|
||||
through the hints via arrow keys. BLD-533.
|
||||
|
||||
LMS: Add feature for providing background grade report generation via Celery
|
||||
instructor task, with reports uploaded to S3. Feature is visible on the beta
|
||||
instructor dashboard. LMS-58
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
<div class="input-wrapper">
|
||||
<input type="text" id="calculator_input" tabindex="-1" />
|
||||
<div class="help-wrapper">
|
||||
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" aria-controls="calculator_input_help" aria-expanded="false" tabindex="-1">Hints</a>
|
||||
<div id="calculator_input_help" class="help" role="tooltip" aria-hidden="true"></div>
|
||||
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" tabindex="-1">Hints</a>
|
||||
<ul id="calculator_input_help" class="help" aria-activedescendant="hint-integers" role="tooltip" aria-hidden="true">
|
||||
<li class="hint-item" id="hint-integers" tabindex="-1"><p><span class="bold">Integers:</span> 2520</p></li>
|
||||
<li class="hint-item" id="hint-decimals" tabindex="-1"><p><span class="bold">Decimals:</span> 3.14 or .98</p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<input id="calculator_button" type="submit" title="Calculate" arial-label="Calculate" value="=" tabindex="-1" />
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
describe 'Calculator', ->
|
||||
|
||||
KEY =
|
||||
TAB : 9
|
||||
ENTER : 13
|
||||
ALT : 18
|
||||
ESC : 27
|
||||
SPACE : 32
|
||||
LEFT : 37
|
||||
UP : 38
|
||||
RIGHT : 39
|
||||
DOWN : 40
|
||||
|
||||
beforeEach ->
|
||||
loadFixtures 'coffee/fixtures/calculator.html'
|
||||
@calculator = new Calculator
|
||||
@@ -9,15 +21,14 @@ describe 'Calculator', ->
|
||||
|
||||
it 'bind the help button', ->
|
||||
# These events are bind by $.hover()
|
||||
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'
|
||||
expect($('#calculator_hint')).toHandle 'mouseover'
|
||||
expect($('#calculator_hint')).toHandle 'mouseout'
|
||||
expect($('#calculator_hint')).toHandle 'keydown'
|
||||
|
||||
it 'prevent default behavior on help button', ->
|
||||
$('div.help-wrapper a').click (e) ->
|
||||
$('#calculator_hint').click (e) ->
|
||||
expect(e.isDefaultPrevented()).toBeTruthy()
|
||||
$('div.help-wrapper a').click()
|
||||
$('#calculator_hint').click()
|
||||
|
||||
it 'bind the calculator submit', ->
|
||||
expect($('form#calculator')).toHandleWith 'submit', @calculator.calculate
|
||||
@@ -51,30 +62,261 @@ describe 'Calculator', ->
|
||||
@calculator.toggle(jQuery.Event("click"))
|
||||
expect($('.calc')).not.toHaveClass('closed')
|
||||
|
||||
describe 'helpShow', ->
|
||||
describe 'showHint', ->
|
||||
it 'show the help overlay', ->
|
||||
@calculator.helpShow()
|
||||
@calculator.showHint()
|
||||
expect($('.help')).toHaveClass('shown')
|
||||
expect($('.help')).toHaveAttr('aria-hidden', 'false')
|
||||
|
||||
describe 'helpHide', ->
|
||||
|
||||
describe 'hideHint', ->
|
||||
it 'show the help overlay', ->
|
||||
@calculator.helpHide()
|
||||
@calculator.hideHint()
|
||||
expect($('.help')).not.toHaveClass('shown')
|
||||
expect($('.help')).toHaveAttr('aria-hidden', 'true')
|
||||
|
||||
describe 'handleKeyDown', ->
|
||||
it 'on pressing Esc the hint becomes hidden', ->
|
||||
@calculator.helpShow()
|
||||
e = jQuery.Event('keydown', { which: 27 } );
|
||||
describe 'handleClickOnDocument', ->
|
||||
it 'on click out of the hint popup it becomes hidden', ->
|
||||
@calculator.showHint()
|
||||
e = jQuery.Event('click');
|
||||
$(document).trigger(e);
|
||||
expect($('.help')).not.toHaveClass 'shown'
|
||||
|
||||
it 'On pressing other buttons the hint continue to show', ->
|
||||
@calculator.helpShow()
|
||||
e = jQuery.Event('keydown', { which: 32 } );
|
||||
$(document).trigger(e);
|
||||
expect($('.help')).toHaveClass 'shown'
|
||||
describe 'selectHint', ->
|
||||
it 'select correct hint item', ->
|
||||
spyOn($.fn, 'focus')
|
||||
element = $('.hint-item').eq(1)
|
||||
@calculator.selectHint(element)
|
||||
|
||||
expect(element.focus).toHaveBeenCalled()
|
||||
expect(@calculator.activeHint).toEqual(element)
|
||||
expect(@calculator.hintPopup).toHaveAttr('aria-activedescendant', element.attr('id'))
|
||||
|
||||
it 'select the first hint if argument element is not passed', ->
|
||||
@calculator.selectHint()
|
||||
expect(@calculator.activeHint.attr('id')).toEqual($('.hint-item').first().attr('id'))
|
||||
|
||||
it 'select the first hint if argument element is empty', ->
|
||||
@calculator.selectHint([])
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').first().attr('id'))
|
||||
|
||||
describe 'prevHint', ->
|
||||
|
||||
it 'Prev hint item is selected', ->
|
||||
@calculator.activeHint = $('.hint-item').eq(1)
|
||||
@calculator.prevHint()
|
||||
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
|
||||
|
||||
it 'Prev hint item is selected', ->
|
||||
@calculator.activeHint = $('.hint-item').eq(1)
|
||||
@calculator.prevHint()
|
||||
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
|
||||
|
||||
it 'if this was the first item, select the last one', ->
|
||||
@calculator.activeHint = $('.hint-item').eq(0)
|
||||
@calculator.prevHint()
|
||||
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
|
||||
|
||||
describe 'nextHint', ->
|
||||
|
||||
it 'Next hint item is selected', ->
|
||||
@calculator.activeHint = $('.hint-item').eq(0)
|
||||
@calculator.nextHint()
|
||||
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
|
||||
|
||||
it 'If this was the last item, select the first one', ->
|
||||
@calculator.activeHint = $('.hint-item').eq(1)
|
||||
@calculator.nextHint()
|
||||
|
||||
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
|
||||
|
||||
describe 'handleKeyDown', ->
|
||||
assertHintIsHidden = (calc, key) ->
|
||||
spyOn(calc, 'hideHint')
|
||||
calc.showHint()
|
||||
e = jQuery.Event('keydown', { keyCode: key });
|
||||
value = calc.handleKeyDown(e)
|
||||
|
||||
expect(calc.hideHint).toHaveBeenCalled
|
||||
expect(value).toBeFalsy()
|
||||
expect(e.isDefaultPrevented()).toBeTruthy()
|
||||
|
||||
assertHintIsVisible = (calc, key) ->
|
||||
spyOn(calc, 'showHint')
|
||||
spyOn($.fn, 'focus')
|
||||
e = jQuery.Event('keydown', { keyCode: key });
|
||||
value = calc.handleKeyDown(e)
|
||||
|
||||
expect(calc.showHint).toHaveBeenCalled
|
||||
expect(value).toBeFalsy()
|
||||
expect(e.isDefaultPrevented()).toBeTruthy()
|
||||
expect(calc.activeHint.focus).toHaveBeenCalled()
|
||||
|
||||
assertNothingHappens = (calc, key) ->
|
||||
spyOn(calc, 'showHint')
|
||||
e = jQuery.Event('keydown', { keyCode: key });
|
||||
value = calc.handleKeyDown(e)
|
||||
|
||||
expect(calc.showHint).not.toHaveBeenCalled
|
||||
expect(value).toBeTruthy()
|
||||
expect(e.isDefaultPrevented()).toBeFalsy()
|
||||
|
||||
it 'hint popup becomes hidden on press ENTER', ->
|
||||
assertHintIsHidden(@calculator, KEY.ENTER)
|
||||
|
||||
it 'hint popup becomes visible on press ENTER', ->
|
||||
assertHintIsVisible(@calculator, KEY.ENTER)
|
||||
|
||||
it 'hint popup becomes hidden on press SPACE', ->
|
||||
assertHintIsHidden(@calculator, KEY.SPACE)
|
||||
|
||||
it 'hint popup becomes visible on press SPACE', ->
|
||||
assertHintIsVisible(@calculator, KEY.SPACE)
|
||||
|
||||
it 'Nothing happens on press ALT', ->
|
||||
assertNothingHappens(@calculator, KEY.ALT)
|
||||
|
||||
it 'Nothing happens on press any other button', ->
|
||||
assertNothingHappens(@calculator, KEY.DOWN)
|
||||
|
||||
describe 'handleKeyDownOnHint', ->
|
||||
it 'Navigation works in proper way', ->
|
||||
calc = @calculator
|
||||
|
||||
eventToShowHint = jQuery.Event('keydown', { keyCode: KEY.ENTER } );
|
||||
$('#calculator_hint').trigger(eventToShowHint);
|
||||
|
||||
spyOn(calc, 'hideHint')
|
||||
spyOn(calc, 'prevHint')
|
||||
spyOn(calc, 'nextHint')
|
||||
spyOn($.fn, 'focus')
|
||||
|
||||
cases =
|
||||
left:
|
||||
event:
|
||||
keyCode: KEY.LEFT
|
||||
shiftKey: false
|
||||
returnedValue: false
|
||||
called:
|
||||
'prevHint': calc
|
||||
isPropagationStopped: true
|
||||
|
||||
leftWithShift:
|
||||
returnedValue: true
|
||||
event:
|
||||
keyCode: KEY.LEFT
|
||||
shiftKey: true
|
||||
not_called:
|
||||
'prevHint': calc
|
||||
|
||||
up:
|
||||
event:
|
||||
keyCode: KEY.UP
|
||||
shiftKey: false
|
||||
returnedValue: false
|
||||
called:
|
||||
'prevHint': calc
|
||||
isPropagationStopped: true
|
||||
|
||||
upWithShift:
|
||||
returnedValue: true
|
||||
event:
|
||||
keyCode: KEY.UP
|
||||
shiftKey: true
|
||||
not_called:
|
||||
'prevHint': calc
|
||||
|
||||
right:
|
||||
event:
|
||||
keyCode: KEY.RIGHT
|
||||
shiftKey: false
|
||||
returnedValue: false
|
||||
called:
|
||||
'nextHint': calc
|
||||
isPropagationStopped: true
|
||||
|
||||
rightWithShift:
|
||||
returnedValue: true
|
||||
event:
|
||||
keyCode: KEY.RIGHT
|
||||
shiftKey: true
|
||||
not_called:
|
||||
'nextHint': calc
|
||||
|
||||
down:
|
||||
event:
|
||||
keyCode: KEY.DOWN
|
||||
shiftKey: false
|
||||
returnedValue: false
|
||||
called:
|
||||
'nextHint': calc
|
||||
isPropagationStopped: true
|
||||
|
||||
downWithShift:
|
||||
returnedValue: true
|
||||
event:
|
||||
keyCode: KEY.DOWN
|
||||
shiftKey: true
|
||||
not_called:
|
||||
'nextHint': calc
|
||||
|
||||
tab:
|
||||
returnedValue: true
|
||||
event:
|
||||
keyCode: KEY.TAB
|
||||
shiftKey: false
|
||||
called:
|
||||
'hideHint': calc
|
||||
|
||||
esc:
|
||||
returnedValue: false
|
||||
event:
|
||||
keyCode: KEY.ESC
|
||||
shiftKey: false
|
||||
called:
|
||||
'hideHint': calc
|
||||
'focus': $.fn
|
||||
isPropagationStopped: true
|
||||
|
||||
alt:
|
||||
returnedValue: true
|
||||
event:
|
||||
which: KEY.ALT
|
||||
not_called:
|
||||
'hideHint': calc
|
||||
'nextHint': calc
|
||||
'prevHint': calc
|
||||
|
||||
$.each(cases, (key, data) ->
|
||||
calc.hideHint.reset()
|
||||
calc.prevHint.reset()
|
||||
calc.nextHint.reset()
|
||||
$.fn.focus.reset()
|
||||
|
||||
e = jQuery.Event('keydown', data.event or {});
|
||||
value = calc.handleKeyDownOnHint(e)
|
||||
|
||||
if data.called
|
||||
$.each(data.called, (method, obj) ->
|
||||
expect(obj[method]).toHaveBeenCalled()
|
||||
)
|
||||
|
||||
if data.not_called
|
||||
$.each(data.not_called, (method, obj) ->
|
||||
expect(obj[method]).not.toHaveBeenCalled()
|
||||
)
|
||||
|
||||
if data.isPropagationStopped
|
||||
expect(e.isPropagationStopped()).toBeTruthy()
|
||||
else
|
||||
expect(e.isPropagationStopped()).toBeFalsy()
|
||||
|
||||
expect(value).toBe(data.returnedValue)
|
||||
)
|
||||
|
||||
describe 'calculate', ->
|
||||
beforeEach ->
|
||||
|
||||
@@ -1,21 +1,48 @@
|
||||
# Keyboard Support
|
||||
|
||||
# If focus is on the hint button:
|
||||
# * Enter: Open or close hint popup. Select last focused hint item if opening
|
||||
# * Space: Open or close hint popup. Select last focused hint item if opening
|
||||
|
||||
# If focus is on a hint item:
|
||||
# * Left arrow: Select previous hint item
|
||||
# * Up arrow: Select previous hint item
|
||||
# * Right arrow: Select next hint item
|
||||
# * Down arrow: Select next hint item
|
||||
|
||||
|
||||
class @Calculator
|
||||
constructor: ->
|
||||
@hintButton = $('#calculator_hint')
|
||||
@hintPopup = $('.help')
|
||||
@hintsList = @hintPopup.find('.hint-item')
|
||||
@selectHint($('#' + @hintPopup.attr('aria-activedescendant')));
|
||||
|
||||
$('.calc').click @toggle
|
||||
$('form#calculator').submit(@calculate).submit (e) ->
|
||||
e.preventDefault()
|
||||
$('div.help-wrapper a')
|
||||
@hintButton
|
||||
.hover(
|
||||
$.proxy(@helpShow, @),
|
||||
$.proxy(@helpHide, @)
|
||||
$.proxy(@showHint, @),
|
||||
$.proxy(@hideHint, @)
|
||||
)
|
||||
.click (e) ->
|
||||
e.preventDefault()
|
||||
.keydown($.proxy(@handleKeyDown, @))
|
||||
.click (e) -> e.preventDefault()
|
||||
|
||||
$(document).keydown $.proxy(@handleKeyDown, @)
|
||||
@hintPopup
|
||||
.keydown($.proxy(@handleKeyDownOnHint, @))
|
||||
|
||||
$('div.help-wrapper')
|
||||
.focusin($.proxy @helpOnFocus, @)
|
||||
.focusout($.proxy @helpOnBlur, @)
|
||||
@handleClickOnDocument = $.proxy(@handleClickOnDocument, @)
|
||||
|
||||
KEY:
|
||||
TAB : 9
|
||||
ENTER : 13
|
||||
ESC : 27
|
||||
SPACE : 32
|
||||
LEFT : 37
|
||||
UP : 38
|
||||
RIGHT : 39
|
||||
DOWN : 40
|
||||
|
||||
toggle: (event) ->
|
||||
event.preventDefault()
|
||||
@@ -49,32 +76,110 @@ class @Calculator
|
||||
|
||||
$calc.toggleClass 'closed'
|
||||
|
||||
helpOnFocus: (e) ->
|
||||
e.preventDefault()
|
||||
@isFocusedHelp = true
|
||||
@helpShow()
|
||||
|
||||
helpOnBlur: (e) ->
|
||||
e.preventDefault()
|
||||
@isFocusedHelp = false
|
||||
@helpHide()
|
||||
|
||||
helpShow: ->
|
||||
$('.help')
|
||||
showHint: ->
|
||||
@hintPopup
|
||||
.addClass('shown')
|
||||
.attr('aria-hidden', false)
|
||||
|
||||
helpHide: ->
|
||||
if not @isFocusedHelp
|
||||
$('.help')
|
||||
.removeClass('shown')
|
||||
.attr('aria-hidden', true)
|
||||
$(document).on('click', @handleClickOnDocument)
|
||||
|
||||
hideHint: ->
|
||||
@hintPopup
|
||||
.removeClass('shown')
|
||||
.attr('aria-hidden', true)
|
||||
|
||||
$(document).off('click', @handleClickOnDocument)
|
||||
|
||||
selectHint: (element) ->
|
||||
if not element or (element and element.length == 0)
|
||||
element = @hintsList.first()
|
||||
|
||||
@activeHint = element;
|
||||
@activeHint.focus();
|
||||
@hintPopup.attr('aria-activedescendant', element.attr('id'));
|
||||
|
||||
prevHint: () ->
|
||||
prev = @activeHint.prev(); # the previous hint
|
||||
# if this was the first item
|
||||
# select the last one in the group.
|
||||
if @activeHint.index() == 0
|
||||
prev = @hintsList.last()
|
||||
# select the previous hint
|
||||
@selectHint(prev)
|
||||
|
||||
nextHint: () ->
|
||||
next = @activeHint.next(); # the next hint
|
||||
# if this was the last item,
|
||||
# select the first one in the group.
|
||||
if @activeHint.index() == @hintsList.length - 1
|
||||
next = @hintsList.first()
|
||||
# give the next hint focus
|
||||
@selectHint(next)
|
||||
|
||||
handleKeyDown: (e) ->
|
||||
ESC = 27
|
||||
if e.which is ESC and $('.help').hasClass 'shown'
|
||||
@isFocusedHelp = false
|
||||
@helpHide()
|
||||
if e.altKey
|
||||
# do nothing
|
||||
return true
|
||||
|
||||
if e.keyCode == @KEY.ENTER or e.keyCode == @KEY.SPACE
|
||||
if @hintPopup.hasClass 'shown'
|
||||
@hideHint()
|
||||
else
|
||||
@showHint()
|
||||
@activeHint.focus()
|
||||
|
||||
e.preventDefault()
|
||||
return false
|
||||
|
||||
# allow the event to propagate
|
||||
return true
|
||||
|
||||
handleKeyDownOnHint: (e) ->
|
||||
if e.altKey
|
||||
# do nothing
|
||||
return true
|
||||
|
||||
switch e.keyCode
|
||||
when @KEY.TAB
|
||||
# hide popup with hints
|
||||
@hideHint()
|
||||
|
||||
when @KEY.ESC
|
||||
# hide popup with hints
|
||||
@hideHint()
|
||||
@hintButton.focus()
|
||||
|
||||
e.stopPropagation()
|
||||
return false
|
||||
|
||||
when @KEY.LEFT, @KEY.UP
|
||||
if e.shiftKey
|
||||
# do nothing
|
||||
return true
|
||||
|
||||
@prevHint()
|
||||
|
||||
e.stopPropagation()
|
||||
return false
|
||||
|
||||
when @KEY.RIGHT, @KEY.DOWN
|
||||
if e.shiftKey
|
||||
# do nothing
|
||||
return true
|
||||
|
||||
@nextHint()
|
||||
|
||||
e.stopPropagation()
|
||||
return false
|
||||
|
||||
# allow the event to propagate
|
||||
return true
|
||||
|
||||
handleClickOnDocument: (e) ->
|
||||
@hideHint()
|
||||
|
||||
# allow the event to propagate
|
||||
return true;
|
||||
|
||||
calculate: ->
|
||||
$.getWithPrefix '/calculate', { equation: $('#calculator_input').val() }, (data) ->
|
||||
|
||||
@@ -112,15 +112,20 @@ div.calc-main {
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
a {
|
||||
#calculator_hint {
|
||||
background: url("../images/info-icon.png") center center no-repeat;
|
||||
height: 35px;
|
||||
@include hide-text;
|
||||
width: 35px;
|
||||
display: block;
|
||||
display: block;
|
||||
|
||||
&:focus {
|
||||
outline: 5px auto #5b9dd9;
|
||||
}
|
||||
}
|
||||
|
||||
.help {
|
||||
@include transition(none);
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 3px #999;
|
||||
@@ -129,11 +134,12 @@ div.calc-main {
|
||||
position: absolute;
|
||||
right: -40px;
|
||||
bottom: 57px;
|
||||
@include transition(none);
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
||||
&.shown {
|
||||
display: block;
|
||||
|
||||
@@ -218,13 +218,14 @@ ${fragment.foot_html()}
|
||||
<input type="text" id="calculator_input" title="${_('Calculator Input Field')}" tabindex="-1" />
|
||||
|
||||
<div class="help-wrapper">
|
||||
<a id="calculator_hint" href="#" role="button" aria-describedby="calculator_input_help" tabindex="-1">${_("Hints")}</a>
|
||||
<div id="calculator_input_help" class="help" role="tooltip" aria-hidden="true">
|
||||
<p><span class="bold">${_("Integers")}:</span> 2520</p>
|
||||
<p><span class="bold">${_("Decimals")}:</span> 3.14 or .98</p>
|
||||
<p><span class="bold">${_("Scientific notation")}:</span> 1.2e-2 (=0.012), -4.4e+5 = -4.4e5 (=-440,000)</p>
|
||||
<p><span class="bold">${_("Appending SI postfixes")}:</span> 2.25k (=2,250)</p>
|
||||
<p><span class="bold">${_("Supported SI postfixes")}:</span></p>
|
||||
<p class="sr" id="hint-instructions">${_('Use the arrow keys to navigate the tips or use the tab key to return to the calculator')}</p>
|
||||
<a id="calculator_hint" href="#" role="button" aria-haspopup="true" tabindex="-1" aria-describedby="hint-instructions">${_("Hints")}</a>
|
||||
<ul id="calculator_input_help" class="help" aria-activedescendant="hint-integers" role="tooltip" aria-hidden="true">
|
||||
<li class="hint-item" id="hint-integers" tabindex="-1"><p><span class="bold">${_("Integers")}:</span> 2520</p></li>
|
||||
<li class="hint-item" id="hint-decimals" tabindex="-1"><p><span class="bold">${_("Decimals")}:</span> 3.14 or .98</p></li>
|
||||
<li class="hint-item" id="hint-scientific-notation" tabindex="-1"><p><span class="bold">${_("Scientific notation")}:</span> 1.2e-2 (=0.012), -4.4e+5 = -4.4e5 (=-440,000)</p></li>
|
||||
<li class="hint-item" id="hint-appending-postfixes" tabindex="-1"><p><span class="bold">${_("Appending SI postfixes")}:</span> 2.25k (=2,250)</p></li>
|
||||
<li class="hint-item" id="hint-supported-postfixes" tabindex="-1"><p><span class="bold">${_("Supported SI postfixes")}:</span></p>
|
||||
<table class="calc-postfixes">
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -279,49 +280,51 @@ ${fragment.foot_html()}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><span class="bold">${_("Operators")}:</span> + - * / ^ and || (${_("parallel resistors function")})</p>
|
||||
<p><span class="bold">${_("Functions")}:</span> sin, cos, tan, sqrt, log10, log2, ln, arccos, arcsin, arctan, abs, fact/factorial</p>
|
||||
<p><span class="bold">${_("Constants")}:</span></p>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>j</td>
|
||||
<td>=</td>
|
||||
<td>sqrt(-1)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>e</td>
|
||||
<td>=</td>
|
||||
<td>${_("Euler's number")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pi</td>
|
||||
<td>=</td>
|
||||
<td>${_("ratio of a circle's circumference to it's diameter")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>k</td>
|
||||
<td>=</td>
|
||||
<td>${_("Boltzmann constant")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>c</td>
|
||||
<td>=</td>
|
||||
<td>${_("speed of light")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>T</td>
|
||||
<td>=</td>
|
||||
<td>${_("freezing point of water in degrees Kelvin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>q</td>
|
||||
<td>=</td>
|
||||
<td>${_("fundamental charge")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</li>
|
||||
<li class="hint-item" id="hint-operators" tabindex="-1"><p><span class="bold">${_("Operators")}:</span> + - * / ^ and || (${_("parallel resistors function")})</p></li>
|
||||
<li class="hint-item" id="hint-functions" tabindex="-1"><p><span class="bold">${_("Functions")}:</span> sin, cos, tan, sqrt, log10, log2, ln, arccos, arcsin, arctan, abs, fact/factorial</p></li>
|
||||
<li class="hint-item" id="hint-constants" tabindex="-1"><p><span class="bold">${_("Constants")}:</span></p>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>j</td>
|
||||
<td>=</td>
|
||||
<td>sqrt(-1)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>e</td>
|
||||
<td>=</td>
|
||||
<td>${_("Euler's number")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pi</td>
|
||||
<td>=</td>
|
||||
<td>${_("ratio of a circle's circumference to it's diameter")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>k</td>
|
||||
<td>=</td>
|
||||
<td>${_("Boltzmann constant")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>c</td>
|
||||
<td>=</td>
|
||||
<td>${_("speed of light")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>T</td>
|
||||
<td>=</td>
|
||||
<td>${_("freezing point of water in degrees Kelvin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>q</td>
|
||||
<td>=</td>
|
||||
<td>${_("fundamental charge")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<input id="calculator_button" type="submit" title="${_('Calculate')}" value="=" aria-label="${_('Calculate')}" value="=" tabindex="-1" />
|
||||
|
||||
Reference in New Issue
Block a user