Mabinogi World Wiki is brought to you by Coty C., 808idiotz, our other patrons, and contributors like you!!
Want to make the wiki better? Contribute towards getting larger projects done on our Patreon!
MediaWiki:CalcSystem.js
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
function parseAssociation(assoc) { var vars = {}, entries = assoc.split(";"); for(var i=0; i < entries.length; ++i) { var tmp = entries[i].split("="); if(tmp.length < 2) { tmp = entries[i].split(":"); if(tmp.length < 2) break; else if(tmp.length > 2) { tmp[1] = tmp[1].slice(1).join(":") } } vars[tmp[0].trim()] = tmp[1].trim(); } return vars; } function ownScope($elem) { return $elem.parents(".calc-scope")[0]; } function createCalculatorStuff($) { $(".calc-scope").each(function() { var scope = this, $scope = $(this), formulas = {}; // Retrieve formulas $scope.find(".calc-formula").each(function(i) { var $this = $(this); if(ownScope($this) == scope) { var data = $this.text().split(":"); if(data.length < 2) return; data[1] = data.slice(1).join(":"); formulas[data[0]] = Formula(data[0], data[1]); } }); $scope.data("formulas", $.extend( formulas, $($scope.parents(".calc-scope").get().pop()).data("formulas") )); // Parse default values of results. $scope.find(".calc-result").each(function() { var $this = $(this); if(ownScope($this) == scope) { var vars = parseAssociation($this.text()); $this.data("formula", vars.formula); delete vars.formula; $this.data("vars", vars); $this.text(""); $this.removeClass("calc-pre"); } }); // Create variable adjusters in this scope. $scope.find(".calc-var").each(function() { var $this = $(this); if(ownScope($this) == scope) { var type = $this.attr("class").split(" "); for(var i=0; i < type.length; ++i) { if(type[i].substr(0, 10) == "calc-type-") { type = type[i].substr(10).split("-"); break; } } var vars = parseAssociation($this.text()); $this.text(""); $this.removeClass("calc-pre"); $this.data("name", vars.name); delete vars.name; $this.data("vars", vars); if(type[0] in createVar) { createVar[type[0]]($scope, $this, type[1], vars); loadCalcVar($this); } } }); }); $(".calc-scope .calc-var .value").trigger("change").trigger("update"); } Math.float = function(x, d) { var s = x < 1 ? 1 : 0; x = Math.round((x+s) * Math.pow(10, (d || 0))).toString(); var p = x.length - d; return (s ? "0" : x.substr(0, p)) + "." + x.substr(p); } Math.maxn = function(n) { arguments.slice = Array.prototype.slice; return arguments.slice(1).sort(function(a,b){return (a<b?1:(a>b?-1:0))})[n]; } Math.minn = function(n) { arguments.slice = Array.prototype.slice; return arguments.slice(1).sort()[n]; } var MathPropNames = Object.getOwnPropertyNames(Math).sort(function(a,b){return b.length-a.length}); var formula_check = RegExp("^([0-9. +\\-/*()%,?:]+|" + MathPropNames.join("|") + ")+$"); function Formula(name, formula) { var $ = jQuery; return { calc: function($scope, vars) { var f = formula, scope = $scope[0]; function varsInScope() { $this = $(this); if(ownScope($this) == scope) { f = f.replace(new RegExp("\\b" + $this.data("name") + "\\b", "g"), $(this).children(".value").val()); } } $scope.find(".calc-var").each(varsInScope); $parents = $scope.parents(".calc-scope").get(); for(var i=0; i < $parents.length; ++i) { $(scope=$parents[i]).find(".calc-var").each(varsInScope); } for(var x in vars) { f = f.replace(new RegExp("\\b" + x + "\\b", "g"), vars[x]); } if(formula_check.test(f)) { for(var x in MathPropNames) { f = f.replace(new RegExp("(^|[^.])" + MathPropNames[x], "g"), "$1Math." + MathPropNames[x]); } var res; try { res = eval(f); } catch(SyntaxError) { console.log("Syntax error: " + f); return "ERR"; } if(vars.comma) { res = res.toString().split("."); var nc = parseInt(vars.comma); if(nc > 0) { res[0] = res[0].replace(new RegExp("(.)(.)(?=.{" + (nc - 1) + "}(.{" + nc + "})*$)", "g"), '$1,$2'); res = res.join(".") } } return res; } else { return "ERR"; } }, usesVar: function(varname) { return formula.indexOf(varname) != -1; } }; } function loadCalcVar($elem) { if (localStorage) { var val = localStorage.getItem("CalcVar-" + $elem.data("name")) if(val == null) return; var $velem = $elem.children(".value"); if ($velem.prop("tagName") != "SELECT" || $velem.is(':has(option[value="' + val.toString() + '"])')) { $velem.val(val); } } } function saveCalcVar($elem) { if (localStorage) { localStorage.setItem("CalcVar-" + $elem.data("name"), $elem.children(".value").val()); } } function doUpdate($scope, $elem) { return function() { saveCalcVar($elem); $scope.find(".calc-result").each(function() { var $this = jQuery(this), formula = $this.data("formula"), formulas = jQuery(ownScope($this)).data("formulas"); if(formula in formulas && formulas[formula].usesVar($elem.data("name"))) { var tmp = formulas[formula].calc(jQuery(ownScope($this)), $this.data("vars")); $this.text(tmp); if($this.parent().hasClass("calc-type-label")) { $this.siblings("input").val(tmp).change(); } } }); }; } createVar = { prepared: function($scope, $elem) { return $elem.find(".value").change(doUpdate($scope, $elem)); }, input: function($scope, $elem, type, vars) { // type = text|hidden|checked|radio|... var $value; if(["checkbox", "hidden", "number", "radio", "text", "time"].indexOf(type) == -1) type = "text"; $value = jQuery('<input class="value" type="'+type+'" value="' + vars.default +'">').appendTo($elem); if(type == "checkbox" || type == "radio") { var upd = doUpdate($scope, $elem); $value.prop("checked", vars.default); $value.click(function() { $value.val($value.is(":checked")?1:0); upd(); }) } else { $value.change(doUpdate($scope, $elem)); } return $value; }, shiftbox: function($scope, $elem, type, vars) { // type = horz|vert var $ = jQuery, $value; $('<span class="shiftbox-' + type +'1"></span>').appendTo($elem).click(function() { n = parseInt($value.val()) - 1; if ("min" in vars && n < vars.min) n = vars.min; $value.val(n).trigger("change"); }); $value = $('<input class="value shiftbox-' + type + 'box" type="text" value="' + vars.default +'">').appendTo($elem); $value.change(doUpdate($scope, $elem)); $('<span class="shiftbox-' + type +'2"></span>').appendTo($elem).mousedown(function() { n = parseInt($value.val()) + 1; if ("max" in vars && n > vars.max) n = vars.max; $value.val(n).trigger("change"); }); return $value; }, slider: function($scope, $bar, type, vars) { $elem = jQuery('<span class="slider"></span>').append( '<span class="sliderimg"></span><span class="slidertext"></span>' ).appendTo($bar); $elem.addClass("value"); $elem.css("position", "relative"); $elem.data({ "min": vars.min, "max": vars.max, "interval": vars.interval }); $elem.val(vars.default); var intr = $elem.data("interval"); if(typeof(intr) != "undefined") { var idx; if((idx = intr.indexOf(".")) != -1) { $elem.data("precision", intr.length - (idx + 1)); } else { $elem.data("precision", 0); } } else { $elem.data("precision", 3); } setSlider($elem, vars.default); $elem.bind({ "mousedown": beginslide, "mousemove": slide, "mouseup": endslide, "update": doUpdate($scope, $bar) }); jQuery("body").bind({ "mousemove": slide, "mouseup": endslide }); return $elem; }, select: function($scope, $elem, type, vars) { var list = vars.list.split(","), $select = jQuery('<select class="value"></select>').appendTo($elem); $select.change(doUpdate($scope, $elem)); for(var i=0; i < list.length; ++i) { var assoc = list[i].split(":"); if(assoc < 2) break; jQuery('<option value="' + assoc[1] + '"' + ( assoc[1] == vars.default ? ' selected="selected"' : '' ) + '>' + assoc[0] + '</option>').appendTo($select); } return $select; }, label: function($scope, $elem, type, vars) { $value = jQuery('<input type="hidden" class="value" value="'+vars.default+'">').appendTo($elem); $result = jQuery('<span class="calc-result">'+vars.default+'</span>').appendTo($elem); $result.data("formula", vars.formula); delete vars.formula; $result.data("vars", vars); $value.change(doUpdate($scope, $elem)); return $value; } } //// BEGIN SLIDER STUFF //// var $sliding = null; function beginslide(e) { if(!$sliding) { $sliding = jQuery(this); $sliding.data("init", $sliding.val()); var $body = jQuery("body"); $body.data("user-select", [ $body.css("-webkit-user-select"), $body.css("-moz-user-select"), $body.css("user-select") ]); $body.css({ "-webkit-user-select": "none", "-moz-user-select": "none", "user-select": "none" }); } } function slide(e) { if($sliding) { var sliderw = $sliding.children(".sliderimg").width(), barl = $sliding.parent().offset().left, barw = $sliding.parent().width(), rangemin = parseFloat($sliding.data("min")), rangemax = parseFloat($sliding.data("max")); var x = rangemin + ((e.clientX - barl - (sliderw / 2)) / barw * (rangemax - rangemin)); setSlider($sliding, x); } } function endslide(e){ if($sliding){ slide(e); if($sliding.val() != $sliding.data("init")){ $sliding.change(); } $sliding = null; var $body = jQuery("body"); var us = $body.data("user-select"); $body.css({ "-webkit-user-select": us[0], "-moz-user-select": us[1], "user-select": us[0] }); } } function setSlider($slider, pos) { var intr = $slider.data("interval"), rangemin = parseFloat($slider.data("min")), rangemax = parseFloat($slider.data("max")); //Make sure it's locked to an interval value, if there is one if(typeof(intr) != "undefined") { intr = parseFloat(intr); var chk = pos / intr; if(chk != Math.floor(chk)) { pos = Math.round(chk) * intr; } } pos = Math.max(Math.min(pos, rangemax), rangemin); $slider.val(pos) $slider.css("left", ( (pos-rangemin) //Current position, relative to the min value / (rangemax-rangemin) //Value range * ($slider.parent().width() - $slider.children(".sliderimg").width()) ) + "px"); var text = $slider.val().toString(), idx; if((idx = text.indexOf(".")) != -1) { text = text.substr(0, idx + 1 + $slider.data("precision")); } $slider.children(".slidertext").text(text); $slider.trigger("update"); } //// END SLIDER STUFF //// jQuery(createCalculatorStuff);