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.
275 lines
7.3 KiB
JavaScript
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);
|