2017-04-19 21:19:33 +02:00
|
|
|
//General helper functions
|
2018-06-22 23:30:24 +02:00
|
|
|
import {isString} from "./StringHelperFunctions";
|
2018-06-26 18:34:11 +02:00
|
|
|
import {dialogBoxCreate} from "./DialogBox";
|
2017-04-19 21:19:33 +02:00
|
|
|
|
|
|
|
//Returns the size (number of keys) of an object
|
|
|
|
function sizeOfObject(obj) {
|
|
|
|
var size = 0, key;
|
|
|
|
for (key in obj) {
|
|
|
|
if (obj.hasOwnProperty(key)) size++;
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2018-05-02 19:38:11 +02:00
|
|
|
function clearObject(obj) {
|
|
|
|
for (var key in obj) {
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
|
|
delete obj[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-19 21:19:33 +02:00
|
|
|
//Adds a random offset to a number within a certain percentage
|
2017-08-30 19:44:29 +02:00
|
|
|
//e.g. addOffset(100, 5) will return anything from 95 to 105.
|
2017-04-19 21:19:33 +02:00
|
|
|
//The percentage argument must be between 0 and 100;
|
|
|
|
function addOffset(n, percentage) {
|
2018-03-28 18:35:34 +02:00
|
|
|
if (percentage < 0 || percentage > 100) {return n;}
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2017-04-19 21:19:33 +02:00
|
|
|
var offset = n * (percentage / 100);
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
return n + ((Math.random() * (2 * offset)) - offset);
|
2017-05-05 23:27:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//Given an element by its Id(usually an 'a' element), removes all event listeners
|
|
|
|
//from that element by cloning and replacing. Then returns the new cloned element
|
|
|
|
function clearEventListeners(elemId) {
|
|
|
|
var elem = document.getElementById(elemId);
|
|
|
|
if (elem == null) {console.log("ERR: Could not find element for: " + elemId); return null;}
|
|
|
|
var newElem = elem.cloneNode(true);
|
|
|
|
elem.parentNode.replaceChild(newElem, elem);
|
2017-05-06 08:24:01 +02:00
|
|
|
return newElem;
|
2017-06-02 06:15:45 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 23:27:31 +02:00
|
|
|
//Same as clearEventListeners except it takes a DOM element object rather than an ID
|
|
|
|
function clearEventListenersEl(el) {
|
|
|
|
if (el == null) {console.log("ERR: element passed into clearEventListenersEl is null"); return null;}
|
|
|
|
var newElem = el.cloneNode(true);
|
|
|
|
el.parentNode.replaceChild(newElem, el);
|
|
|
|
return newElem;
|
|
|
|
}
|
|
|
|
|
2017-11-02 22:47:09 +01:00
|
|
|
//Given its id, this function removes an element AND its children
|
|
|
|
function removeElementById(id) {
|
|
|
|
var elem = document.getElementById(id);
|
|
|
|
if (elem == null) {return;}
|
|
|
|
while(elem.firstChild) {elem.removeChild(elem.firstChild);}
|
|
|
|
elem.parentNode.removeChild(elem);
|
|
|
|
}
|
|
|
|
|
2018-02-09 22:11:43 +01:00
|
|
|
function removeElement(elem) {
|
2018-05-02 19:38:11 +02:00
|
|
|
if (elem == null || !(elem instanceof Element)) {return;}
|
2018-02-09 22:11:43 +01:00
|
|
|
while(elem.firstChild) {elem.removeChild(elem.firstChild);}
|
|
|
|
elem.parentNode.removeChild(elem);
|
|
|
|
}
|
|
|
|
|
2017-12-02 04:50:08 +01:00
|
|
|
function removeChildrenFromElement(el) {
|
|
|
|
if (isString(el)) {
|
|
|
|
el = document.getElementById(el);
|
|
|
|
}
|
|
|
|
if (el == null) {return;}
|
|
|
|
if (el instanceof Element) {
|
|
|
|
while(el.firstChild) {
|
|
|
|
el.removeChild(el.firstChild);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-05 19:19:33 +02:00
|
|
|
/**
|
|
|
|
* Returns a reference to the first object with the specified value of the ID or NAME attribute, throwing an error if it is unable to find it.
|
|
|
|
* @param {string} elementId The HTML ID to retrieve the element by.
|
|
|
|
* @returns {HTMLElement} The single element.
|
|
|
|
* @throws {Error} When the 'idString' cannot be found.
|
|
|
|
*/
|
|
|
|
function getElementById(elementId) {
|
|
|
|
var el = document.getElementById(elementId);
|
|
|
|
if (el == null) {
|
|
|
|
throw new Error("Unable to find element with id '" + elementId + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
return el;
|
|
|
|
}
|
|
|
|
|
2018-03-03 22:05:33 +01:00
|
|
|
function createElement(type, params={}) {
|
2017-12-02 04:50:08 +01:00
|
|
|
var el = document.createElement(type);
|
|
|
|
if (params.id) {el.id = params.id;}
|
|
|
|
if (params.class) {el.className = params.class;}
|
2018-05-02 19:38:11 +02:00
|
|
|
if (params.name) {el.name = params.name;}
|
2017-12-02 04:50:08 +01:00
|
|
|
if (params.innerHTML) {el.innerHTML = params.innerHTML;}
|
|
|
|
if (params.innerText) {el.innerText = params.innerText;}
|
|
|
|
if (params.value) {el.value = params.value;}
|
|
|
|
if (params.text) {el.text = params.text;}
|
|
|
|
if (params.display) {el.style.display = params.display;}
|
|
|
|
if (params.visibility) {el.style.visibility = params.visibility;}
|
|
|
|
if (params.margin) {el.style.margin = params.margin;}
|
2018-01-20 05:47:57 +01:00
|
|
|
if (params.marginLeft) {el.style.marginLeft = params.marginLeft;}
|
2018-01-27 07:52:39 +01:00
|
|
|
if (params.marginTop) {el.style.marginTop = params.marginTop;}
|
2017-12-02 04:50:08 +01:00
|
|
|
if (params.padding) {el.style.padding = params.padding;}
|
|
|
|
if (params.color) {el.style.color = params.color;}
|
|
|
|
if (params.border) {el.style.border = params.border;}
|
|
|
|
if (params.float) {el.style.cssFloat = params.float;}
|
2018-01-20 05:47:57 +01:00
|
|
|
if (params.fontSize) {el.style.fontSize = params.fontSize;}
|
2018-03-12 20:39:04 +01:00
|
|
|
if (params.whiteSpace) {el.style.whiteSpace = params.whiteSpace;}
|
2018-01-20 05:47:57 +01:00
|
|
|
if (params.width) {el.style.width = params.width;}
|
2017-12-02 04:50:08 +01:00
|
|
|
if (params.backgroundColor) {
|
|
|
|
el.style.backgroundColor = params.backgroundColor
|
|
|
|
}
|
|
|
|
if (params.position) {el.style.position = params.position;}
|
|
|
|
if (params.type) {el.type = params.type;}
|
|
|
|
if (params.checked) {el.checked = params.checked;}
|
|
|
|
if (params.for) {el.htmlFor = params.for;}
|
|
|
|
if (params.pattern) {el.pattern = params.pattern;}
|
|
|
|
if (params.maxLength) {el.maxLength = params.maxLength;}
|
|
|
|
if (params.placeholder) {el.placeholder = params.placeholder;}
|
2018-05-02 19:38:11 +02:00
|
|
|
if (params.tooltip && params.tooltip !== "") {
|
2017-12-02 04:50:08 +01:00
|
|
|
el.className += " tooltip";
|
|
|
|
el.appendChild(createElement("span", {
|
|
|
|
class:"tooltiptext",
|
|
|
|
innerHTML:params.tooltip
|
|
|
|
}));
|
2018-02-24 23:55:06 +01:00
|
|
|
} else if (params.tooltipleft) {
|
|
|
|
el.className += " tooltip";
|
|
|
|
el.appendChild(createElement("span", {
|
|
|
|
class:"tooltiptextleft",
|
|
|
|
innerHTML:params.tooltipleft
|
|
|
|
}));
|
2017-12-02 04:50:08 +01:00
|
|
|
}
|
2018-01-27 07:52:39 +01:00
|
|
|
if (params.href) {el.href = params.href;}
|
|
|
|
if (params.target) {el.target = params.target;}
|
2018-05-02 19:38:11 +02:00
|
|
|
if (params.tabIndex) {el.tabIndex = params.tabIndex;}
|
2017-12-02 04:50:08 +01:00
|
|
|
if (params.clickListener) {
|
|
|
|
el.addEventListener("click", params.clickListener);
|
|
|
|
}
|
|
|
|
if (params.inputListener) {
|
|
|
|
el.addEventListener("input", params.inputListener);
|
|
|
|
}
|
|
|
|
if (params.changeListener) {
|
|
|
|
el.addEventListener("change", params.changeListener);
|
|
|
|
}
|
2018-02-09 22:11:43 +01:00
|
|
|
if (params.onkeyup) {
|
|
|
|
el.addEventListener("keyup", params.onkeyup);
|
|
|
|
}
|
2018-05-02 19:38:11 +02:00
|
|
|
if (params.onfocus) {
|
|
|
|
el.addEventListener("focus", params.onfocus);
|
|
|
|
}
|
2017-12-02 04:50:08 +01:00
|
|
|
return el;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createPopup(id, elems) {
|
|
|
|
var container = createElement("div", {
|
|
|
|
class:"popup-box-container",
|
|
|
|
id:id,
|
|
|
|
display:"block"
|
|
|
|
}),
|
|
|
|
content = createElement("div", {
|
|
|
|
class:"popup-box-content",
|
2018-02-15 05:26:43 +01:00
|
|
|
id:id + "-content",
|
2017-12-02 04:50:08 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
for (var i = 0; i < elems.length; ++i) {
|
|
|
|
content.appendChild(elems[i]);
|
|
|
|
}
|
|
|
|
container.appendChild(content);
|
|
|
|
document.getElementById("entire-game-container").appendChild(container);
|
2018-02-15 05:26:43 +01:00
|
|
|
return container;
|
2017-12-02 04:50:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//Creates both the header and panel element of an accordion and sets the click handler
|
|
|
|
function createAccordionElement(params) {
|
|
|
|
var li = document.createElement("li"),
|
|
|
|
hdr = document.createElement("button"),
|
|
|
|
panel = document.createElement("div");
|
|
|
|
hdr.classList.add("accordion-header");
|
|
|
|
panel.classList.add("accordion-panel");
|
|
|
|
|
|
|
|
if (params.id) {
|
|
|
|
hdr.id = params.id + "-hdr";
|
|
|
|
panel.id = params.id + "-panel";
|
|
|
|
}
|
|
|
|
if (params.hdrText) {hdr.innerHTML = params.hdrText;}
|
|
|
|
if (params.panelText) {panel.innerHTML = params.panelText;}
|
|
|
|
li.appendChild(hdr);
|
|
|
|
li.appendChild(panel);
|
|
|
|
//Click handler
|
|
|
|
hdr.onclick = function() {
|
|
|
|
this.classList.toggle("active");
|
|
|
|
var tmpPanel = this.nextElementSibling;
|
|
|
|
if (tmpPanel.style.display === "block") {
|
|
|
|
tmpPanel.style.display = "none";
|
|
|
|
} else {
|
|
|
|
tmpPanel.style.display = "block";
|
|
|
|
}
|
|
|
|
}
|
2018-02-09 22:11:43 +01:00
|
|
|
return [li, hdr, panel];
|
2017-12-02 04:50:08 +01:00
|
|
|
}
|
|
|
|
|
2018-05-02 19:38:11 +02:00
|
|
|
//Appends n line breaks (as children) to the Element el
|
|
|
|
function appendLineBreaks(el, n) {
|
|
|
|
for (var i = 0; i < n; ++i) {
|
|
|
|
el.appendChild(createElement("br"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-02 04:50:08 +01:00
|
|
|
function clearSelector(selector) {
|
|
|
|
for (var i = selector.options.length - 1; i >= 0; --i) {
|
|
|
|
selector.remove(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-02 06:15:45 +02:00
|
|
|
function getRandomInt(min, max) {
|
2017-06-19 16:54:11 +02:00
|
|
|
if (min > max) {return getRandomInt(max, min);}
|
2017-06-02 06:15:45 +02:00
|
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//Returns true if all elements are equal, and false otherwise
|
|
|
|
//Assumes both arguments are arrays and that there are no nested arrays
|
|
|
|
function compareArrays(a1, a2) {
|
|
|
|
if (a1.length != a2.length) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2017-06-17 04:53:57 +02:00
|
|
|
for (var i = 0; i < a1.length; ++i) {
|
|
|
|
if (a1[i] != a2[i]) {return false;}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function printArray(a) {
|
|
|
|
return "[" + a.join(", ") + "]";
|
2017-07-13 18:54:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//Returns bool indicating whether or not its a power of 2
|
|
|
|
function powerOfTwo(n) {
|
|
|
|
if (isNaN(n)) {return false;}
|
|
|
|
return n && (n & (n-1)) === 0;
|
2017-08-30 19:44:29 +02:00
|
|
|
}
|
|
|
|
|
2018-07-03 05:35:12 +02:00
|
|
|
//Rounds a number to two decimal places
|
|
|
|
function roundToTwo(n) {
|
|
|
|
return +(Math.round(n + "e+2") + "e-2");
|
|
|
|
}
|
|
|
|
|
2018-03-27 02:46:21 +02:00
|
|
|
function exceptionAlert(e) {
|
|
|
|
dialogBoxCreate("Caught an exception: " + e + "<br><br>" +
|
2018-05-02 19:38:11 +02:00
|
|
|
"Filename: " + e.fileName + "<br><br>" +
|
|
|
|
"Line Number: " + e.lineNumber + "<br><br>" +
|
2018-03-27 02:46:21 +02:00
|
|
|
"This is a bug, please report to game developer with this " +
|
|
|
|
"message as well as details about how to reproduce the bug.<br><br>" +
|
|
|
|
"If you want to be safe, I suggest refreshing the game WITHOUT saving so that your " +
|
|
|
|
"safe doesn't get corrupted");
|
|
|
|
}
|
|
|
|
|
2018-07-03 05:35:12 +02:00
|
|
|
export {sizeOfObject,
|
|
|
|
clearObject,
|
|
|
|
addOffset,
|
|
|
|
clearEventListeners,
|
|
|
|
getRandomInt,
|
|
|
|
compareArrays,
|
|
|
|
printArray,
|
|
|
|
powerOfTwo,
|
|
|
|
roundToTwo,
|
|
|
|
clearEventListenersEl,
|
|
|
|
removeElementById,
|
|
|
|
removeElement,
|
|
|
|
createElement,
|
|
|
|
createAccordionElement,
|
2018-05-02 19:38:11 +02:00
|
|
|
appendLineBreaks,
|
2018-07-03 05:35:12 +02:00
|
|
|
removeChildrenFromElement,
|
|
|
|
createPopup,
|
|
|
|
clearSelector,
|
|
|
|
exceptionAlert,
|
|
|
|
getElementById};
|