1
0
forked from sent/waves
waves/public/assets/g/mario/References/ItemsHoldr-0.2.1.js
2025-04-09 17:11:14 -05:00

671 lines
26 KiB
JavaScript

var ItemsHoldr;
(function (ItemsHoldr_1) {
"use strict";
/**
* Storage container for a single ItemsHoldr value. The value may have triggers
* assigned to value, modularity, and other triggers, as well as an HTML element.
*/
var ItemValue = (function () {
/**
* Creates a new ItemValue with the given key and settings. Defaults are given
* to the value via proliferate before the settings.
*
* @constructor
* @param ItemsHolder The container for this value.
* @param key The key to reference this new ItemValue by.
* @param settings Any optional custom settings.
*/
function ItemValue(ItemsHolder, key, settings) {
if (settings === void 0) { settings = {}; }
this.ItemsHolder = ItemsHolder;
ItemsHolder.proliferate(this, ItemsHolder.getDefaults());
ItemsHolder.proliferate(this, settings);
this.key = key;
if (!this.hasOwnProperty("value")) {
this.value = this.valueDefault;
}
if (this.hasElement) {
this.element = ItemsHolder.createElement(this.elementTag || "div", {
className: ItemsHolder.getPrefix() + "_value " + key
});
this.element.appendChild(ItemsHolder.createElement("div", {
"textContent": key
}));
this.element.appendChild(ItemsHolder.createElement("div", {
"textContent": this.value
}));
}
if (this.storeLocally) {
// If there exists an old version of this property, get it
if (ItemsHolder.getLocalStorage().hasOwnProperty(ItemsHolder.getPrefix() + key)) {
this.value = this.retrieveLocalStorage();
}
else {
// Otherwise save the new version to memory
this.updateLocalStorage();
}
}
}
/**
* @returns The value being stored, with a transformGet applied if one exists.
*/
ItemValue.prototype.getValue = function () {
if (this.transformGet) {
return this.transformGet(this.value);
}
return this.value;
};
/**
* Sets the value being stored, with a is a transformSet applied if one exists.
* Any attached triggers to the new value will be called.
*
* @param value The desired value to now store.
*/
ItemValue.prototype.setValue = function (value) {
if (this.transformSet) {
this.value = this.transformSet(value);
}
else {
this.value = value;
}
this.update();
};
/**
* General update Function to be run whenever the internal value is changed.
* It runs all the trigger, modular, etc. checks, updates the HTML element
* if there is one, and updates localStorage if needed.
*/
ItemValue.prototype.update = function () {
// Mins and maxes must be obeyed before any other considerations
if (this.hasOwnProperty("minimum") && Number(this.value) <= Number(this.minimum)) {
this.value = this.minimum;
if (this.onMinimum) {
this.onMinimum.apply(this, this.ItemsHolder.getCallbackArgs());
}
}
else if (this.hasOwnProperty("maximum") && Number(this.value) <= Number(this.maximum)) {
this.value = this.maximum;
if (this.onMaximum) {
this.onMaximum.apply(this, this.ItemsHolder.getCallbackArgs());
}
}
if (this.modularity) {
this.checkModularity();
}
if (this.triggers) {
this.checkTriggers();
}
if (this.hasElement) {
this.updateElement();
}
if (this.storeLocally) {
this.updateLocalStorage();
}
};
/**
* Stores a ItemValue's value in localStorage under the prefix plus its key.
*
* @param {Boolean} [overrideAutoSave] Whether the policy on saving should
* be ignored (so saving happens
* regardless). By default, false.
*/
ItemValue.prototype.updateLocalStorage = function (overrideAutoSave) {
if (overrideAutoSave || this.ItemsHolder.getAutoSave()) {
this.ItemsHolder.getLocalStorage()[this.ItemsHolder.getPrefix() + this.key] = JSON.stringify(this.value);
}
};
/**
* Checks if the current value should trigger a callback, and if so calls it.
*/
ItemValue.prototype.checkTriggers = function () {
if (this.triggers.hasOwnProperty(this.value)) {
this.triggers[this.value].apply(this, this.ItemsHolder.getCallbackArgs());
}
};
/**
* Checks if the current value is greater than the modularity (assuming
* modular is a non-zero Numbers), and if so, continuously reduces value and
* calls this.onModular.
*/
ItemValue.prototype.checkModularity = function () {
if (this.value.constructor !== Number || !this.modularity) {
return;
}
while (this.value >= this.modularity) {
this.value = Math.max(0, this.value - this.modularity);
if (this.onModular) {
this.onModular.apply(this, this.ItemsHolder.getCallbackArgs());
}
}
};
/**
* Updates the ItemValue's element's second child to be the ItemValue's value.
*/
ItemValue.prototype.updateElement = function () {
if (this.ItemsHolder.hasDisplayChange(this.value)) {
this.element.children[1].textContent = this.ItemsHolder.getDisplayChange(this.value);
}
else {
this.element.children[1].textContent = this.value;
}
};
/**
* Retrieves a ItemValue's value from localStorage, making sure not to try to
* JSON.parse an undefined or null value.
*
* @returns {Mixed}
*/
ItemValue.prototype.retrieveLocalStorage = function () {
var value = localStorage.getItem(this.ItemsHolder.getPrefix() + this.key);
if (value === "undefined") {
return undefined;
}
if (value.constructor !== String) {
return value;
}
return JSON.parse(value);
};
return ItemValue;
})();
ItemsHoldr_1.ItemValue = ItemValue;
/**
* A versatile container to store and manipulate values in localStorage, and
* optionally keep an updated HTML container showing these values.
*/
var ItemsHoldr = (function () {
/**
* Initializes a new instance of the ItemsHoldr class.
*
* @param settings Any optional custom settings.
*/
function ItemsHoldr(settings) {
if (settings === void 0) { settings = {}; }
var key;
this.prefix = settings.prefix || "";
this.autoSave = settings.autoSave;
this.callbackArgs = settings.callbackArgs || [];
this.allowNewItems = settings.allowNewItems === undefined
? true : settings.allowNewItems;
if (settings.localStorage) {
this.localStorage = settings.localStorage;
}
else if (typeof localStorage === "undefined") {
this.localStorage = this.createPlaceholderStorage();
}
else {
this.localStorage = localStorage;
}
this.defaults = settings.defaults || {};
this.displayChanges = settings.displayChanges || {};
this.items = {};
if (settings.values) {
this.itemKeys = Object.keys(settings.values);
for (key in settings.values) {
if (settings.values.hasOwnProperty(key)) {
this.addItem(key, settings.values[key]);
}
}
}
else {
this.itemKeys = [];
}
if (settings.doMakeContainer) {
this.containersArguments = settings.containersArguments || [
["div", {
"className": this.prefix + "_container"
}]
];
this.container = this.makeContainer(settings.containersArguments);
}
}
/* Simple gets
*/
/**
*
*/
ItemsHoldr.prototype.key = function (index) {
return this.itemKeys[index];
};
/**
* @returns The values contained within, keyed by their keys.
*/
ItemsHoldr.prototype.getValues = function () {
return this.items;
};
/**
* @returns {Mixed} Default attributes for values.
*/
ItemsHoldr.prototype.getDefaults = function () {
return this.defaults;
};
/**
* @returns A reference to localStorage or a replacment object.
*/
ItemsHoldr.prototype.getLocalStorage = function () {
return this.localStorage;
};
/**
* @returns Whether this should save changes to localStorage automatically.
*/
ItemsHoldr.prototype.getAutoSave = function () {
return this.autoSave;
};
/**
* @returns The prefix to store thigns under in localStorage.
*/
ItemsHoldr.prototype.getPrefix = function () {
return this.prefix;
};
/**
* @returns The container HTML element, if it exists.
*/
ItemsHoldr.prototype.getContainer = function () {
return this.container;
};
/**
* @returns createElement arguments for HTML containers, outside-to-inside.
*/
ItemsHoldr.prototype.getContainersArguments = function () {
return this.containersArguments;
};
/**
* @returns Any hard-coded changes to element content.
*/
ItemsHoldr.prototype.getDisplayChanges = function () {
return this.displayChanges;
};
/**
* @returns Arguments to be passed to triggered event callbacks.
*/
ItemsHoldr.prototype.getCallbackArgs = function () {
return this.callbackArgs;
};
/* Retrieval
*/
/**
* @returns String keys for each of the stored ItemValues.
*/
ItemsHoldr.prototype.getKeys = function () {
return Object.keys(this.items);
};
/**
* @param key The key for a known value.
* @returns The known value of a key, assuming that key exists.
*/
ItemsHoldr.prototype.getItem = function (key) {
this.checkExistence(key);
return this.items[key].getValue();
};
/**
* @param key The key for a known value.
* @returns The settings for that particular key.
*/
ItemsHoldr.prototype.getObject = function (key) {
return this.items[key];
};
/**
* @param key The key for a potentially known value.
* @returns Whether there is a value under that key.
*/
ItemsHoldr.prototype.hasKey = function (key) {
return this.items.hasOwnProperty(key);
};
/**
* @returns A mapping of key names to the actual values of all objects being stored.
*/
ItemsHoldr.prototype.exportItems = function () {
var output = {}, i;
for (i in this.items) {
if (this.items.hasOwnProperty(i)) {
output[i] = this.items[i].getValue();
}
}
return output;
};
/* ItemValues
*/
/**
* Adds a new key & value pair to by linking to a newly created ItemValue.
*
* @param key The key to reference by new ItemValue by.
* @param settings The settings for the new ItemValue.
* @returns The newly created ItemValue.
*/
ItemsHoldr.prototype.addItem = function (key, settings) {
if (settings === void 0) { settings = {}; }
this.items[key] = new ItemValue(this, key, settings);
this.itemKeys.push(key);
return this.items[key];
};
/**
* Clears a value from the listing, and removes its element from the
* container (if they both exist).
*
* @param key The key of the element to remove.
*/
ItemsHoldr.prototype.removeItem = function (key) {
if (!this.items.hasOwnProperty(key)) {
return;
}
if (this.container && this.items[key].hasElement) {
this.container.removeChild(this.items[key].element);
}
this.itemKeys.splice(this.itemKeys.indexOf(key), 1);
delete this.items[key];
};
/**
* Completely clears all values from the ItemsHoldr, removing their
* elements from the container (if they both exist) as well.
*/
ItemsHoldr.prototype.clear = function () {
var i;
if (this.container) {
for (i in this.items) {
if (this.items[i].hasElement) {
this.container.removeChild(this.items[i].element);
}
}
}
this.items = {};
this.itemKeys = [];
};
/**
* Sets the value for the ItemValue under the given key, then updates the ItemValue
* (including the ItemValue's element and localStorage, if needed).
*
* @param key The key of the ItemValue.
* @param value The new value for the ItemValue.
*/
ItemsHoldr.prototype.setItem = function (key, value) {
this.checkExistence(key);
this.items[key].setValue(value);
};
/**
* Increases the value for the ItemValue under the given key, via addition for
* Numbers or concatenation for Strings.
*
* @param key The key of the ItemValue.
* @param amount The amount to increase by (by default, 1).
*/
ItemsHoldr.prototype.increase = function (key, amount) {
if (amount === void 0) { amount = 1; }
this.checkExistence(key);
var value = this.items[key].getValue();
value += amount;
this.items[key].setValue(value);
};
/**
* Increases the value for the ItemValue under the given key, via addition for
* Numbers or concatenation for Strings.
*
* @param key The key of the ItemValue.
* @param amount The amount to increase by (by default, 1).
*/
ItemsHoldr.prototype.decrease = function (key, amount) {
if (amount === void 0) { amount = 1; }
this.checkExistence(key);
var value = this.items[key].getValue();
value -= amount;
this.items[key].setValue(value);
};
/**
* Toggles whether a value is true or false.
*
* @param key The key of the ItemValue.
*/
ItemsHoldr.prototype.toggle = function (key) {
this.checkExistence(key);
var value = this.items[key].getValue();
value = value ? false : true;
this.items[key].setValue(value);
};
/**
* Ensures a key exists in values. If it doesn't, and new values are
* allowed, it creates it; otherwise, it throws an Error.
*
* @param key
*/
ItemsHoldr.prototype.checkExistence = function (key) {
if (!this.items.hasOwnProperty(key)) {
if (this.allowNewItems) {
this.addItem(key);
}
else {
throw new Error("Unknown key given to ItemsHoldr: '" + key + "'.");
}
}
};
/**
* Manually saves an item's value to localStorage, ignoring the autoSave flag.
*
* @param key The key of the item to save.
*/
ItemsHoldr.prototype.saveItem = function (key) {
if (!this.items.hasOwnProperty(key)) {
throw new Error("Unknown key given to ItemsHoldr: '" + key + "'.");
}
this.items[key].updateLocalStorage(true);
};
/**
* Manually saves all values to localStorage, ignoring the autoSave flag.
*/
ItemsHoldr.prototype.saveAll = function () {
var key;
for (key in this.items) {
if (this.items.hasOwnProperty(key)) {
this.items[key].updateLocalStorage(true);
}
}
};
/* HTML helpers
*/
/**
* Hides the container Element by setting its visibility to hidden.
*/
ItemsHoldr.prototype.hideContainer = function () {
this.container.style.visibility = "hidden";
};
/**
* Shows the container Element by setting its visibility to visible.
*/
ItemsHoldr.prototype.displayContainer = function () {
this.container.style.visibility = "visible";
};
/**
* Creates the container Element, which contains a child for each ItemValue that
* specifies hasElement to be true.
*
* @param containers An Array representing the Element to be created and the
* children between it and the contained ItemValues.
* Each contained Object has a String tag name as its
* first member, followed by any number of Objects to apply
* via createElement.
* @returns A newly created Element that can be used as a container.
*/
ItemsHoldr.prototype.makeContainer = function (containers) {
var output = this.createElement.apply(this, containers[0]), current = output, child, key, i;
for (i = 1; i < containers.length; ++i) {
child = this.createElement.apply(this, containers[i]);
current.appendChild(child);
current = child;
}
for (key in this.items) {
if (this.items[key].hasElement) {
child.appendChild(this.items[key].element);
}
}
return output;
};
/**
* @returns Whether displayChanges has an entry for a particular value.
*/
ItemsHoldr.prototype.hasDisplayChange = function (value) {
return this.displayChanges.hasOwnProperty(value);
};
/**
* @returns The displayChanges entry for a particular value.
*/
ItemsHoldr.prototype.getDisplayChange = function (value) {
return this.displayChanges[value];
};
/* Utilities
*/
/**
* Creates a new HTMLElement of the given type. For each Object given as
* arguments after, each member is proliferated onto the element.
*
* @param tag The type of the HTMLElement (by default, "div").
* @param args Any number of Objects to be proliferated onto the
* new HTMLElement.
* @returns A newly created HTMLElement of the given tag.
*/
ItemsHoldr.prototype.createElement = function (tag) {
if (tag === void 0) { tag = "div"; }
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var element = document.createElement(tag), i;
// For each provided object, add those settings to the element
for (i = 0; i < args.length; i += 1) {
this.proliferateElement(element, args[i]);
}
return element;
};
/**
* Proliferates all members of the donor to the recipient recursively, as
* a deep copy.
*
* @param recipient An object receiving the donor's members.
* @param donor An object whose members are copied to recipient.
* @param noOverride If recipient properties may be overriden (by
* default, false).
* @returns The recipient, which should have the donor proliferated onto it.
*/
ItemsHoldr.prototype.proliferate = function (recipient, donor, noOverride) {
var setting, i;
// For each attribute of the donor:
for (i in donor) {
if (donor.hasOwnProperty(i)) {
// If noOverride, don't override already existing properties
if (noOverride && recipient.hasOwnProperty(i)) {
continue;
}
// If it's an object, recurse on a new version of it
setting = donor[i];
if (typeof setting === "object") {
if (!recipient.hasOwnProperty(i)) {
recipient[i] = new setting.constructor();
}
this.proliferate(recipient[i], setting, noOverride);
}
else {
// Regular primitives are easy to copy otherwise
recipient[i] = setting;
}
}
}
return recipient;
};
/**
* Identical to proliferate, but tailored for HTML elements because many
* element attributes don't play nicely with JavaScript Array standards.
* Looking at you, HTMLCollection!
*
* @param recipient An HTMLElement receiving the donor's members.
* @param donor An object whose members are copied to recipient.
* @param noOverride If recipient properties may be overriden (by
* default, false).
* @returns The recipient, which should have the donor proliferated onto it.
*/
ItemsHoldr.prototype.proliferateElement = function (recipient, donor, noOverride) {
var setting, i, j;
// For each attribute of the donor:
for (i in donor) {
if (donor.hasOwnProperty(i)) {
// If noOverride, don't override already existing properties
if (noOverride && recipient.hasOwnProperty(i)) {
continue;
}
setting = donor[i];
// Special cases for HTML elements
switch (i) {
// Children: just append all of them directly
case "children":
if (typeof (setting) !== "undefined") {
for (j = 0; j < setting.length; j += 1) {
recipient.appendChild(setting[j]);
}
}
break;
// Style: proliferate (instead of making a new Object)
case "style":
this.proliferate(recipient[i], setting);
break;
// By default, use the normal proliferate logic
default:
// If it's an object, recurse on a new version of it
if (typeof setting === "object") {
if (!recipient.hasOwnProperty(i)) {
recipient[i] = new setting.constructor();
}
this.proliferate(recipient[i], setting, noOverride);
}
else {
// Regular primitives are easy to copy otherwise
recipient[i] = setting;
}
break;
}
}
}
return recipient;
};
/**
* Creates an Object that can be used to create a new LocalStorage
* replacement, if the JavaScript environment doesn't have one.
*
* @returns {Object}
*/
ItemsHoldr.prototype.createPlaceholderStorage = function () {
var i, output = {
"keys": [],
"getItem": function (key) {
return this.localStorage[key];
},
"setItem": function (key, value) {
this.localStorage[key] = value;
},
"clear": function () {
for (i in this) {
if (this.hasOwnProperty(i)) {
delete this[i];
}
}
},
"removeItem": function (key) {
delete this[key];
},
"key": function (index) {
return this.keys[index];
}
};
Object.defineProperties(output, {
"length": {
"get": function () {
return output.keys.length;
}
},
"remainingSpace": {
"get": function () {
return 9001; // Is there a way to calculate this?
}
}
});
return output;
};
return ItemsHoldr;
})();
ItemsHoldr_1.ItemsHoldr = ItemsHoldr;
})(ItemsHoldr || (ItemsHoldr = {}));