Files
edx-platform/lms/static/js/calculator.js
Michael Terry a34c8c8233 Drop remaining coffee use
This basically commits the transpiled CoffeeScript JS (with minor
cleanup) and removes coffee build support.

A tiny amount of support for xblocks exists, because external users
may have xblocks with coffee. But no coffee in our tree anyway.
2018-04-13 14:10:40 -04:00

275 lines
7.3 KiB
JavaScript

// Once generated by CoffeeScript 1.9.3, but now lives as pure JS
/* eslint-disable */
/*
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
*/
(function() {
this.Calculator = (function() {
function Calculator() {
this.hintButton = $('#calculator_hint');
this.calcInput = $('#calculator_input');
this.hintPopup = $('.help');
this.hintsList = this.hintPopup.find('.hint-item');
this.selectHint($('#' + this.hintPopup.attr('data-calculator-hint')));
$('.calc').click(this.toggle);
$('form#calculator').submit(this.calculate).submit(function(e) {
return e.preventDefault();
});
this.hintButton.click($.proxy(this.handleClickOnHintButton, this));
this.hintPopup.click($.proxy(this.handleClickOnHintPopup, this));
this.hintPopup.keydown($.proxy(this.handleKeyDownOnHint, this));
$('#calculator_wrapper').keyup($.proxy(this.handleKeyUpOnHint, this));
this.handleClickOnDocument = $.proxy(this.handleClickOnDocument, this);
this.calcInput.focus($.proxy(this.inputClickHandler, this));
}
Calculator.prototype.KEY = {
TAB: 9,
ENTER: 13,
ESC: 27,
SPACE: 32,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
};
Calculator.prototype.toggle = function(event) {
var $calc, $calcWrapper, icon, isExpanded, text;
event.preventDefault();
$calc = $('.calc');
$calcWrapper = $('#calculator_wrapper');
text = gettext('Open Calculator');
isExpanded = false;
icon = 'fa-calculator';
$('.calc-main').toggleClass('open');
if ($calc.hasClass('closed')) {
$calcWrapper.attr('aria-hidden', 'true');
} else {
text = gettext('Close Calculator');
icon = 'fa-close';
isExpanded = true;
$calcWrapper.attr('aria-hidden', 'false');
/*
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((function() {
return $calcWrapper.find('#calculator_input').focus();
}), 100);
}
$calc.attr({
'title': text,
'aria-expanded': isExpanded
}).find('.utility-control-label').text(text);
$calc.find('.icon').removeClass('fa-calculator').removeClass('fa-close').addClass(icon);
return $calc.toggleClass('closed');
};
Calculator.prototype.inputClickHandler = function() {
return $('#calculator_output').removeClass('has-result');
};
Calculator.prototype.showHint = function() {
this.hintPopup.addClass('shown').attr('aria-hidden', false);
$('#calculator_output').removeClass('has-result');
return $(document).on('click', this.handleClickOnDocument);
};
Calculator.prototype.hideHint = function() {
this.hintPopup.removeClass('shown').attr('aria-hidden', true);
$('#calculator_output').removeClass('has-result');
return $(document).off('click', this.handleClickOnDocument);
};
Calculator.prototype.selectHint = function(element) {
if (!element || (element && element.length === 0)) {
element = this.hintsList.first();
}
this.activeHint = element;
this.activeHint.focus();
return this.hintPopup.attr('data-calculator-hint', element.attr('id'));
};
Calculator.prototype.prevHint = function() {
/*
the previous hint
*/
var prev;
prev = this.activeHint.prev();
/*
if this was the first item
select the last one in the group.
*/
if (this.activeHint.index() === 0) {
prev = this.hintsList.last();
}
/*
select the previous hint
*/
return this.selectHint(prev);
};
Calculator.prototype.nextHint = function() {
/*
the next hint
*/
var next;
next = this.activeHint.next();
/*
if this was the last item,
select the first one in the group.
*/
if (this.activeHint.index() === this.hintsList.length - 1) {
next = this.hintsList.first();
}
/*
give the next hint focus
*/
return this.selectHint(next);
};
Calculator.prototype.handleKeyDown = function(e) {
if (e.altKey) {
/*
do nothing
*/
return true;
}
if (e.keyCode === this.KEY.ENTER || e.keyCode === this.KEY.SPACE) {
if (this.hintPopup.hasClass('shown')) {
this.hideHint();
} else {
this.showHint();
this.activeHint.focus();
}
e.preventDefault();
return false;
}
/*
allow the event to propagate
*/
return true;
};
Calculator.prototype.handleKeyDownOnHint = function(e) {
if (e.altKey) {
/*
do nothing
*/
return true;
}
switch (e.keyCode) {
case this.KEY.ESC:
/*
hide popup with hints
*/
this.hideHint();
this.hintButton.focus();
e.stopPropagation();
return false;
case this.KEY.LEFT:
case this.KEY.UP:
if (e.shiftKey) {
/*
do nothing
*/
}
return true;
this.prevHint();
e.stopPropagation();
return false;
case this.KEY.RIGHT:
case this.KEY.DOWN:
if (e.shiftKey) {
/*
do nothing
*/
return true;
}
this.nextHint();
e.stopPropagation();
return false;
}
/*
allow the event to propagate
*/
return true;
};
Calculator.prototype.handleKeyUpOnHint = function(e) {
switch (e.keyCode) {
case this.KEY.TAB:
/*
move focus to hint links and hide hint once focus is out of hint pop up
*/
this.active_element = document.activeElement;
if (!$(this.active_element).parents().is(this.hintPopup)) {
return this.hideHint();
}
}
};
Calculator.prototype.handleClickOnDocument = function(e) {
return this.hideHint();
};
Calculator.prototype.handleClickOnHintButton = function(e) {
e.preventDefault();
e.stopPropagation();
if (this.hintPopup.hasClass('shown')) {
this.hideHint();
return this.hintButton.attr('aria-expanded', false);
} else {
this.showHint();
this.hintButton.attr('aria-expanded', true);
return this.activeHint.focus();
}
};
Calculator.prototype.handleClickOnHintPopup = function(e) {
return e.stopPropagation();
};
Calculator.prototype.calculate = function() {
return $.getWithPrefix('/calculate', {
equation: $('#calculator_input').val()
}, function(data) {
return $('#calculator_output').val(data.result).addClass('has-result').focus();
});
};
return Calculator;
})();
}).call(this);