mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-28 00:47:33 +01:00
720478377f
The UI of a single Hacknet Node now only takes up ~50% of the screen. This allows two nodes to be displayed per "row" when the screen is wide enough. Also repositioned the buttons for the nodes so they are inline with the information each updates. This visual correlation lets us reduce the text that needs to be in each button. Also reduced the amount of DOM that needs to be continuously garbage collected by updating specific text rather than throwing out entire HTML elements.
279 lines
9.7 KiB
JavaScript
279 lines
9.7 KiB
JavaScript
//General helper functions
|
|
import {isString} from "./StringHelperFunctions.js";
|
|
import {dialogBoxCreate} from "./DialogBox.js";
|
|
|
|
//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;
|
|
}
|
|
|
|
function clearObject(obj) {
|
|
for (var key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
delete obj[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adds a random offset to a number within a certain percentage
|
|
//e.g. addOffset(100, 5) will return anything from 95 to 105.
|
|
//The percentage argument must be between 0 and 100;
|
|
function addOffset(n, percentage) {
|
|
if (percentage < 0 || percentage > 100) {return n;}
|
|
|
|
var offset = n * (percentage / 100);
|
|
|
|
return n + ((Math.random() * (2 * offset)) - offset);
|
|
}
|
|
|
|
//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);
|
|
return newElem;
|
|
}
|
|
|
|
//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;
|
|
}
|
|
|
|
//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);
|
|
}
|
|
|
|
function removeElement(elem) {
|
|
if (elem == null || !(elem instanceof Element)) {return;}
|
|
while(elem.firstChild) {elem.removeChild(elem.firstChild);}
|
|
elem.parentNode.removeChild(elem);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
function createElement(type, params={}) {
|
|
var el = document.createElement(type);
|
|
if (params.id) {el.id = params.id;}
|
|
if (params.class) {el.className = params.class;}
|
|
if (params.name) {el.name = params.name;}
|
|
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;}
|
|
if (params.marginLeft) {el.style.marginLeft = params.marginLeft;}
|
|
if (params.marginTop) {el.style.marginTop = params.marginTop;}
|
|
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;}
|
|
if (params.fontSize) {el.style.fontSize = params.fontSize;}
|
|
if (params.whiteSpace) {el.style.whiteSpace = params.whiteSpace;}
|
|
if (params.width) {el.style.width = params.width;}
|
|
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;}
|
|
if (params.tooltip && params.tooltip !== "") {
|
|
el.className += " tooltip";
|
|
el.appendChild(createElement("span", {
|
|
class:"tooltiptext",
|
|
innerHTML:params.tooltip
|
|
}));
|
|
} else if (params.tooltipleft) {
|
|
el.className += " tooltip";
|
|
el.appendChild(createElement("span", {
|
|
class:"tooltiptextleft",
|
|
innerHTML:params.tooltipleft
|
|
}));
|
|
}
|
|
if (params.href) {el.href = params.href;}
|
|
if (params.target) {el.target = params.target;}
|
|
if (params.tabIndex) {el.tabIndex = params.tabIndex;}
|
|
if (params.clickListener) {
|
|
el.addEventListener("click", params.clickListener);
|
|
}
|
|
if (params.inputListener) {
|
|
el.addEventListener("input", params.inputListener);
|
|
}
|
|
if (params.changeListener) {
|
|
el.addEventListener("change", params.changeListener);
|
|
}
|
|
if (params.onkeyup) {
|
|
el.addEventListener("keyup", params.onkeyup);
|
|
}
|
|
if (params.onfocus) {
|
|
el.addEventListener("focus", params.onfocus);
|
|
}
|
|
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",
|
|
id:id + "-content",
|
|
});
|
|
|
|
for (var i = 0; i < elems.length; ++i) {
|
|
content.appendChild(elems[i]);
|
|
}
|
|
container.appendChild(content);
|
|
document.getElementById("entire-game-container").appendChild(container);
|
|
return container;
|
|
}
|
|
|
|
//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";
|
|
}
|
|
}
|
|
return [li, hdr, panel];
|
|
}
|
|
|
|
//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"));
|
|
}
|
|
}
|
|
|
|
function clearSelector(selector) {
|
|
for (var i = selector.options.length - 1; i >= 0; --i) {
|
|
selector.remove(i);
|
|
}
|
|
}
|
|
|
|
function getRandomInt(min, max) {
|
|
if (min > max) {return getRandomInt(max, min);}
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
}
|
|
|
|
//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;
|
|
}
|
|
|
|
for (var i = 0; i < a1.length; ++i) {
|
|
if (a1[i] != a2[i]) {return false;}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function printArray(a) {
|
|
return "[" + a.join(", ") + "]";
|
|
}
|
|
|
|
//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;
|
|
}
|
|
|
|
function exceptionAlert(e) {
|
|
dialogBoxCreate("Caught an exception: " + e + "<br><br>" +
|
|
"Filename: " + e.fileName + "<br><br>" +
|
|
"Line Number: " + e.lineNumber + "<br><br>" +
|
|
"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");
|
|
}
|
|
|
|
/*Creates a graphical "progress bar"
|
|
* e.g.: [||||---------------]
|
|
* params:
|
|
* @totalTicks - Total number of ticks in progress bar. Preferably a factor of 100
|
|
* @progress - Current progress, taken as a decimal (i.e. 0.6 to represent 60%)
|
|
*/
|
|
function createProgressBarText(params={}) {
|
|
//Default values
|
|
var totalTicks = (params.totalTicks == null ? 20 : params.totalTicks);
|
|
var progress = (params.progress == null ? 0 : params.progress);
|
|
|
|
var percentPerTick = 1 / totalTicks;
|
|
var numTicks = Math.floor(progress / percentPerTick);
|
|
var numDashes = totalTicks - numTicks;
|
|
return "[" + Array(numTicks+1).join("|") + Array(numDashes+1).join("-") + "]";
|
|
}
|
|
|
|
export {sizeOfObject, clearObject, addOffset, clearEventListeners, getRandomInt,
|
|
compareArrays, printArray, powerOfTwo, clearEventListenersEl,
|
|
removeElementById, removeElement, createElement, createAccordionElement,
|
|
appendLineBreaks,
|
|
removeChildrenFromElement, createPopup, clearSelector, exceptionAlert,
|
|
createProgressBarText, getElementById};
|