Справица:Calculator.js
Пређи на навигацију
Пређи на претрагу
(function() {
'use strict';
var OPERATORS = {
'+': function(a, b) {
return a + b;
},
'-': function(a, b) {
return a - b;
},
'*': function(a, b) {
return a * b;
},
'/': function(a, b) {
return a / b;
},
'%': function(a, b) {
return a % b;
},
'^': function(a, b) {
return Math.pow(a, b);
},
'max': Math.max,
'min': Math.min,
'floor': Math.floor,
'ceil': Math.ceil,
'round': Math.round
};
var SINGLE_OPERAND = ['floor', 'ceil', 'round'];
var staticId = 0;
var variables = {};
function resolveVariable(calc, variable) {
if (OPERATORS[variable]) {
// You cannot name a variable the same as an operator.
return null;
}
var num = Number(variable);
if (!Number.isNaN(num)) {
return num;
}
return variables[calc][variable];
}
function updateCalculator($calc, id) {
// TODO: Multiple expressions, which are also variables.
$calc.find('[data-expression]').each(function(_, el) {
var $result = $(el);
var stack = [];
var expression = $result.attr('data-expression').split(' ').reverse();
while (expression.length) {
var item = expression.pop();
if (OPERATORS[item]) {
if (SINGLE_OPERAND.includes(item)) {
stack.push(OPERATORS[item](stack.pop()));
} else {
var arg1 = stack.pop();
var arg2 = stack.pop();
stack.push(OPERATORS[item](arg2, arg1));
}
} else {
stack.push(resolveVariable(id, item));
}
}
var result = stack.pop();
$result.text(result);
var varName = $result.attr('data-variable');
if (varName) {
variables[id][varName] = result;
}
});
}
function changedVariable(event) {
var $var = $(event.target);
var varName = $var.parent().attr('data-variable');
var $calc = $var.closest('.calculator');
var calc = Number($calc.attr('data-id'));
variables[calc][varName] = Number($var.val().trim());
updateCalculator($calc, calc);
}
function hook($content) {
$content.find('.calculator:not(.loaded)').each(function(_, el) {
var $calc = $(el).addClass('loaded');
var id = staticId++;
variables[id] = {};
$calc
.attr('data-id', id)
.find('[data-variable]')
.each(function(__, el2) {
var $var = $(el2);
var varName = $var.attr('data-variable');
var defaultValue = $var.text().trim() || '0';
variables[id][varName] = Number(defaultValue);
if (Number.isNaN(variables[id][varName])) {
variables[id][varName] = 0;
}
if (!$var.attr('data-expression')) {
$var.html($('<input>', {
change: changedVariable,
max: $var.attr('data-max') || '100',
min: $var.attr('data-min') || '0',
step: $var.attr('data-step') || '0.001',
type: 'number',
value: defaultValue
}));
}
});
updateCalculator($calc, id);
});
}
mw.hook('wikipage.content').add(hook);
})();