MediaWiki:Gadget-idle-util.js: Difference between revisions
From Idle Clans wiki
No edit summary |
No edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 94: | Line 94: | ||
* @param {number} number | * @param {number} number | ||
* The number to format. | * The number to format. | ||
* @param {number} decimals | * @param {number} [decimals] | ||
* The number of decimals to display. | * The number of decimals to display. | ||
* | * | ||
Line 103: | Line 103: | ||
decimals = decimals || 2; | decimals = decimals || 2; | ||
return new Intl.NumberFormat('en-US', { maximumFractionDigits: decimals }).format(number); | return new Intl.NumberFormat('en-US', { maximumFractionDigits: decimals }).format(number); | ||
}, | |||
number: { | |||
/** | |||
* Round the given value to the specified number of decimals using | |||
* bankers rounding. | |||
* | |||
* This is mainly used by calculators to ensure the values are the | |||
* same as the game (C# uses bankers rounding by default). | |||
* | |||
* @param {number} value | |||
* The value to round. | |||
* @param {number} decimals | |||
* The maximum number of decimals to display. | |||
* | |||
* @returns {number} | |||
* The rounded value. | |||
*/ | |||
bankersRound: function(value, decimals) { | |||
value = parseFloat(value.toFixed(6)); // Try to fix floating point errors. | |||
decimals = decimals || 2; // Default to 2 decimal places. | |||
var x = value * Math.pow(10, decimals); | |||
var r = Math.round(x); | |||
var br = Math.abs(x) % 1 === 0.5 ? (r % 2 === 0 ? r : r-1) : r; | |||
return br / Math.pow(10, decimals); | |||
}, | |||
/** | |||
* Round the given value to the specified number of decimals, removing | |||
* any trailing zeros if necessary. | |||
* | |||
* @param {number} value | |||
* The value to round. | |||
* @param {number} decimals | |||
* The maximum number of decimals to display. | |||
* | |||
* @returns {number} | |||
* The rounded value. | |||
*/ | |||
toFixedSmall: function(value, decimals) { | |||
return parseFloat(value.toFixed(decimals)); | |||
} | |||
}, | }, | ||
Latest revision as of 07:23, 11 June 2024
// REQUIRES oojs-ui-widgets ;(function($, mw, idleClans) { idleClans.util = { /** * If we should print debug information to the console. */ DEBUG: false, /** * Send a debug message to the console. * * @param {...*} arguments * The arguments to log. */ debug: function() { if (!this.DEBUG) return; var args = Array.prototype.slice.call(arguments); console.log.apply(console, ["DEBUG:"].concat(args)); }, /** * The gemstone prefixes for each tier. */ GEMSTONE_PREFIXES: [ "Normal", "Refined", "Great", "Elite", "Superior", "Outstanding", "Godlike" ], /** * Get the refined name for the given name and tier. * * If the tier is out of bounds, an error is logged and the name is * returned with an error prefix. * * @param {string} name * The name to prepend the prefix to. * @param {number} tier * The tier of the gemstone. * * @returns {string} * The refined name. */ getRefinedName: function(name, tier) { if (tier < 0 || tier >= this.GEMSTONE_PREFIXES.length) { mw.error("getRefinedName: Tier out of bounds (" + tier + ", " + this.GEMSTONE_PREFIXES.length + ")"); return "Err " + name; } return this.GEMSTONE_PREFIXES[tier] + " " + name; }, // utils.tierify(["House", "Mansion", "Castle"]); // utils.tierify([function(i) { return NAMES[i]; }, 10]); /** * Tierify the given supplier, adding "T1", "T2", etc. to the names. * * @param {[function(number): string, number]|string[]} supplier * Either a tuple containing a function and a number, or an array * of names to tierify. If a tuple is provided, the function will * be used to supply the names based on the index, with the number * specifying how many tiers to create. * @param {string[]|string} [prepend] * Optionally, an array of names to prepend to the tier array. * @param {string[]|string} [append] * Optionally, an array of names to append to the tier array. */ tierify: function(supplier, prepend, append) { prepend = prepend || []; append = append || []; if (!Array.isArray(prepend)) prepend = [prepend]; if (!Array.isArray(append)) append = [append]; // Get the names from the supplier. var names = supplier; if (typeof supplier[0] === 'function') { names = []; var nameSupplier = supplier[0]; var tierCount = supplier[1]; for (var i = 0; i < tierCount; i++) names.push(nameSupplier(i)); } // Tierify the names. var tiered = names.map(function(name, index) { return "(T" + (index + 1) + ") " + name; }); // Add the prepended and appended names. return prepend.concat(tiered, append); }, /** * Format the given number with commas. * * @param {number} number * The number to format. * @param {number} [decimals] * The number of decimals to display. * * @returns {string} * The formatted number. */ formatNumber: function(number, decimals) { decimals = decimals || 2; return new Intl.NumberFormat('en-US', { maximumFractionDigits: decimals }).format(number); }, number: { /** * Round the given value to the specified number of decimals using * bankers rounding. * * This is mainly used by calculators to ensure the values are the * same as the game (C# uses bankers rounding by default). * * @param {number} value * The value to round. * @param {number} decimals * The maximum number of decimals to display. * * @returns {number} * The rounded value. */ bankersRound: function(value, decimals) { value = parseFloat(value.toFixed(6)); // Try to fix floating point errors. decimals = decimals || 2; // Default to 2 decimal places. var x = value * Math.pow(10, decimals); var r = Math.round(x); var br = Math.abs(x) % 1 === 0.5 ? (r % 2 === 0 ? r : r-1) : r; return br / Math.pow(10, decimals); }, /** * Round the given value to the specified number of decimals, removing * any trailing zeros if necessary. * * @param {number} value * The value to round. * @param {number} decimals * The maximum number of decimals to display. * * @returns {number} * The rounded value. */ toFixedSmall: function(value, decimals) { return parseFloat(value.toFixed(decimals)); } }, ui: { /** * Create a dropdown widget with the given items and optionally the * selected item. * * @param {(string|{label:string,header:boolean=,disabled:boolean=,hidden:boolean=})[]} items * The items to display in the dropdown widget. * @param {number} [selected] * Optionally, the index of the selected item. * @param {string} [label] * Optionally, the label for the dropdown widget. * * @returns {OO.ui.DropdownWidget} * The dropdown widget. */ dropdown: function(items, selected, label) { var currentIndex = 0; var dropdown = new OO.ui.DropdownWidget({ label: label, menu: { items: items.map(function (item, index) { if (typeof item === 'string') return new OO.ui.MenuOptionWidget({ data: currentIndex++, label: item }); var label = item.label || "Unknown"; var header = item.header || false; var disabled = item.disabled || false; var hidden = item.hidden || false; if (header) { label = $("<div style='text-align:center'>" + label + "</div>"); return new OO.ui.MenuSectionOptionWidget( { label: label } ); } if (!hidden) return new OO.ui.MenuOptionWidget({ data: currentIndex++, label: label, disabled: disabled }); return new OO.ui.MenuOptionWidget({ data: currentIndex++, label: label, disabled: disabled, invisibleLabel: hidden, $element: $("<div style='display:none'></div>") }); }) } }); // We need to override the "below" key to have value "below". // If we don't then it might go above the dropdown and hide // items behind the navbar. OO.ui.MenuSelectWidget.static.flippedPositions = { below: 'below', above: 'below', top: 'bottom', bottom: 'top' }; if (selected !== undefined && typeof selected === 'number') { if (selected < 0 || selected >= items.length) mw.error("UI.dropdown: Selected index out of bounds (" + selected + ", " + items.length + ")"); else dropdown.getMenu().selectItemByData(selected); } return dropdown; }, /** * Create a button widget with the given label and flags. * * @param {string} [label] * Optionally, the label for the button. * @param {string[]} [flags] * Optionally, the flags for the button. * * @returns {OO.ui.ButtonWidget} * The button widget. */ button: function(label, flags) { label = label || "Button"; flags = flags || []; return new OO.ui.ButtonWidget({ label: label, flags: flags }); }, /** * Create a button input widget with the given label and flags. * * @param {string} [label] * Optionally, the label for the button. * @param {string[]} [flags] * Optionally, the flags for the button. * * @returns {OO.ui.ButtonInputWidget} * The button input widget. */ buttonInput: function(label, flags) { label = label || "Button"; flags = flags || []; return new OO.ui.ButtonInputWidget({ label: label, flags: flags }); }, /** * Create a checkbox widget with an optional label and selected * state. * * @param {boolean} [selected] * Optionally, whether the checkbox is selected. * @param {string} [label] * Optionally, the label for the checkbox. * * @returns {OO.ui.CheckboxInputWidget|OO.ui.FieldLayout} * The checkbox widget, or a field layout with the checkbox * and the label. */ checkbox: function(selected, label) { var checkbox = new OO.ui.CheckboxInputWidget({ selected: selected }); if (label !== undefined && typeof label === 'string') { return new OO.ui.FieldLayout(checkbox, { label: label, align: 'inline' }); } return checkbox; }, /** * Create a toggle switch widget with an optional initial state. * * @param {boolean} [switched] * Optionally, whether the switch is on. * * @returns {OO.ui.ToggleSwitchWidget} * The toggle switch widget. */ switch: function(switched) { switched = switched || false; return new OO.ui.ToggleSwitchWidget({ value: switched }); } } } })(window.jQuery, window.mw, window.idleClans = window.idleClans || {});