MediaWiki:Gadget-idle-util.js: Difference between revisions
From Idle Clans wiki
(Created page with "//") |
No edit summary |
||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
// | // 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 || {}); |
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 || {});