diff options
Diffstat (limited to 'web/js/nms-ui-boxes.js')
-rw-r--r-- | web/js/nms-ui-boxes.js | 512 |
1 files changed, 257 insertions, 255 deletions
diff --git a/web/js/nms-ui-boxes.js b/web/js/nms-ui-boxes.js index ee4dc98..6a89fcd 100644 --- a/web/js/nms-ui-boxes.js +++ b/web/js/nms-ui-boxes.js @@ -5,10 +5,10 @@ * The idea is to retain the ability to fiddle with html, but solve common * problems such as "I need to show a box that looks good" and "I need to * update the content of this field in this box when something happens". - * + * * Seeing as how it's 2019, I figured I'd try to use this whole "class" * thing :D - * + * * Eventually, everything in nms-info-box.js should use this, but more over, * if a need to write some code that needs a UI element arises, the general * problem should be solved here, while the implementation: elsewhere. @@ -20,221 +20,220 @@ */ class nmsBox { - constructor(type,settings = null) { - this.type = type; - this._boxes = [] - this.html = document.createElement(type); - this.html.nmsBox = this; - if (settings) { - this.applySettings(settings); - } - } - get value() { - var values = []; - for (var x in this._boxes) { - var tmp = this._boxes[x].value; - if (tmp != undefined && !((tmp instanceof Array) && tmp.length == 0)) { - values.push(tmp) - } - } - return values; - } + constructor(type, settings = null) { + this.type = type; + this._boxes = []; + this.html = document.createElement(type); + this.html.nmsBox = this; + if (settings) { + this.applySettings(settings); + } + } + get value() { + var values = []; + for (var x in this._boxes) { + var tmp = this._boxes[x].value; + if (tmp != undefined && !(tmp instanceof Array && tmp.length == 0)) { + values.push(tmp); + } + } + return values; + } - applySettings(settings) { - /* - * This really should go deeper, but the problem is that - * I'm lazy. You can't just use Object.assign() either because - * stuff like html.style isn't just any element and we want - * to be able to do html:{style:{display:"none"}} instead - * of html:{style:new (style object thing with display:none)} - * - * So far this works. - * - * Note that this breaks forr classList: This is because - * classList is just an accessor for className, so you - * should set className instead initially. - */ - if (settings.html) { - for (var x in settings.html) { - if(settings.html[x] instanceof Object) { - Object.assign(this.html[x],settings.html[x]) - } else { - this.html[x] = settings.html[x]; - } - } - } - } - /* Should rename these to push() and unshift(), really, to be - * more consistent. - */ - add(box) { - this._boxes.push(box); - box.attach(this.html) - box.show() - } - insert(box) { - this._boxes.unshift(box) - box.attach(this.html) - box.show(true,-1) - } - - /* This is provided so as to allow attaching to non-nmsBox-objects. - * E.g.: attach the root to a HTML element directly. - * If you just use foo = document.getElement..., - * foo.appendChild(box.html), then .hide() will work fine, - * but there's no way to do .show() afterwards. - * - * Be aware: - * - we want to AVOID the child knowing too much about the parent - * - HTML elements can only ever be part of a single parent - * element. This means that it is safe to attach(root1), .show(), - * atach(root2), show() ... The DOM object wil be removed from root1. - * - Due to the above, we should probably actually adress that, since - * there are valid reasons for showing the same nmsBox twice (e.g.: - * showing a list of tons of stuff, and also a "top 5") - */ - attach(root) { - if (!(root instanceof HTMLElement)) { - root = document.getElementById(root) - } - console.assert(root instanceof HTMLElement) - this._root = root; - } - show(show = true,where=1) { - if (!show) { - this.hide() - return - } - if (this._root instanceof HTMLElement) { - if (where>0) { - this._root.appendChild(this.html); - } else { - this._root.insertBefore(this.html,this._root.firstElementChild) - } - } - } - _remove(source,box) { - source.html.removeChild(box.html) - if (box._root == source) { - box._root = undefined; - } - var x = source._boxes.indexOf(box) - delete source._boxes[x] - } - _includes(source,box) { - if (source._boxes.indexOf(box) >= 0) { - return true; - } else { - return false; - } - } - /* - * This redirect is to make it easier for subclasses that - * override add() to make it eaiser to add logical - * childs, e.g. adding to a table really adds to ._tbody, - * not the true top-element of the table. - */ - remove(box) { - this._remove(this,box) - } - includes(box) { - return this._includes(this,box); - } - hide() { - if (this.html.parentElement instanceof HTMLElement) { - this.html.parentElement.removeChild(this.html); - } - } - destroy() { - this.hide() - for (var i in this._boxes) { - var x = this._boxes[i]; - x.hide() - x.destroy() - delete this._boxes[i] - } - delete this.html; - delete this; - } - update() { - for (var x in this._boxes) { - this._boxes[x].update(); - } - } -}; + applySettings(settings) { + /* + * This really should go deeper, but the problem is that + * I'm lazy. You can't just use Object.assign() either because + * stuff like html.style isn't just any element and we want + * to be able to do html:{style:{display:"none"}} instead + * of html:{style:new (style object thing with display:none)} + * + * So far this works. + * + * Note that this breaks forr classList: This is because + * classList is just an accessor for className, so you + * should set className instead initially. + */ + if (settings.html) { + for (var x in settings.html) { + if (settings.html[x] instanceof Object) { + Object.assign(this.html[x], settings.html[x]); + } else { + this.html[x] = settings.html[x]; + } + } + } + } + /* Should rename these to push() and unshift(), really, to be + * more consistent. + */ + add(box) { + this._boxes.push(box); + box.attach(this.html); + box.show(); + } + insert(box) { + this._boxes.unshift(box); + box.attach(this.html); + box.show(true, -1); + } + /* This is provided so as to allow attaching to non-nmsBox-objects. + * E.g.: attach the root to a HTML element directly. + * If you just use foo = document.getElement..., + * foo.appendChild(box.html), then .hide() will work fine, + * but there's no way to do .show() afterwards. + * + * Be aware: + * - we want to AVOID the child knowing too much about the parent + * - HTML elements can only ever be part of a single parent + * element. This means that it is safe to attach(root1), .show(), + * atach(root2), show() ... The DOM object wil be removed from root1. + * - Due to the above, we should probably actually adress that, since + * there are valid reasons for showing the same nmsBox twice (e.g.: + * showing a list of tons of stuff, and also a "top 5") + */ + attach(root) { + if (!(root instanceof HTMLElement)) { + root = document.getElementById(root); + } + console.assert(root instanceof HTMLElement); + this._root = root; + } + show(show = true, where = 1) { + if (!show) { + this.hide(); + return; + } + if (this._root instanceof HTMLElement) { + if (where > 0) { + this._root.appendChild(this.html); + } else { + this._root.insertBefore(this.html, this._root.firstElementChild); + } + } + } + _remove(source, box) { + source.html.removeChild(box.html); + if (box._root == source) { + box._root = undefined; + } + var x = source._boxes.indexOf(box); + delete source._boxes[x]; + } + _includes(source, box) { + if (source._boxes.indexOf(box) >= 0) { + return true; + } else { + return false; + } + } + /* + * This redirect is to make it easier for subclasses that + * override add() to make it eaiser to add logical + * childs, e.g. adding to a table really adds to ._tbody, + * not the true top-element of the table. + */ + remove(box) { + this._remove(this, box); + } + includes(box) { + return this._includes(this, box); + } + hide() { + if (this.html.parentElement instanceof HTMLElement) { + this.html.parentElement.removeChild(this.html); + } + } + destroy() { + this.hide(); + for (var i in this._boxes) { + var x = this._boxes[i]; + x.hide(); + x.destroy(); + delete this._boxes[i]; + } + delete this.html; + delete this; + } + update() { + for (var x in this._boxes) { + this._boxes[x].update(); + } + } +} class nmsString extends nmsBox { - constructor(content,type) { - type = type ? type : "p"; - super(type,{ html: { textContent: content }}) - } - set value(input) { - this.html.textContent = input; - } - get value() { - return this.html.textContent; - } + constructor(content, type) { + type = type ? type : "p"; + super(type, { html: { textContent: content } }); + } + set value(input) { + this.html.textContent = input; + } + get value() { + return this.html.textContent; + } } class nmsButton extends nmsBox { - constructor(text,type = "btn-default") { - super("button",{html:{textContent:text,className:"btn "+type,type:"button"}}) - } + constructor(text, type = "btn-default") { + super("button", { + html: { textContent: text, className: "btn " + type, type: "button" }, + }); + } } /* * A general-purpose table. It can be created in one go, or - * as-you-go. + * as-you-go. */ class nmsTable extends nmsBox { - constructor(content, caption) { - super("table",{html:{className:"table table-condensed"}}); - if (caption != undefined) { - var cap = new nmsBox("caption"); - cap.html.textContent = caption; - super.add(cap); - } - this._tbody = new nmsBox("tbody"); - super.add(this._tbody); - for (var v in content) { - this.add(content[v]); - } - } - remove(box) { - this._remove(this._tbody,box) - } - includes(box) { - return this._tbody.includes(box) - } - _makeBox(content) { - if (content instanceof nmsBox) { - return content; - } - var tr; - var td1; - var td2; - tr = new nmsBox("tr"); - for (var x in content) { - var td = new nmsBox("td"); - var child = content[x]; - if (child instanceof nmsBox) { - td.add(child); - } else { - td.add(new nmsString(child)); - } - tr.add(td); - } - return tr; - } - /* Can take either a single nmsBox-object that will be added as-is, - * or an array of items that will be added as individual cells - */ - add(content) { - this._tbody.add(this._makeBox(content)); - } - insert(box) { - this._tbody.insert(this._makeBox(box)); - } + constructor(content, caption) { + super("table", { html: { className: "table table-sm table-transparent" } }); + if (caption != undefined) { + var cap = new nmsBox("caption"); + cap.html.textContent = caption; + super.add(cap); + } + this._tbody = new nmsBox("tbody"); + super.add(this._tbody); + for (var v in content) { + this.add(content[v]); + } + } + remove(box) { + this._remove(this._tbody, box); + } + includes(box) { + return this._tbody.includes(box); + } + _makeBox(content) { + if (content instanceof nmsBox) { + return content; + } + var tr; + tr = new nmsBox("tr"); + for (var x in content) { + var td = new nmsBox("td"); + var child = content[x]; + if (child instanceof nmsBox) { + td.add(child); + } else { + td.add(new nmsString(child)); + } + tr.add(td); + } + return tr; + } + /* Can take either a single nmsBox-object that will be added as-is, + * or an array of items that will be added as individual cells + */ + add(content) { + this._tbody.add(this._makeBox(content)); + } + insert(box) { + this._tbody.insert(this._makeBox(box)); + } } /* @@ -245,54 +244,57 @@ class nmsTable extends nmsBox { * myThing.add(nmsString("whatever")) * myThing.title = "blah...." */ -class nmsPanel extends nmsBox{ - constructor(title){ - super("div",{html:{style:{gridColumn: 2}}}); - this._topBox = new nmsBox("div",{ html: { className: "panel panel-default"}}); - this._body = new nmsBox("div",{html:{className: "panel-body"}}); - this.nav = new nmsBox("div",{html:{className: "panel-body"}}); - this._topBox.add(this.makeHeading(title)); - this._topBox.add(this.nav); - this._topBox.add(this._body); - super.add(this._topBox); - } - attach(root = document.getElementById("genericPanelContainer")) { - try { - var x = parseInt(root.lastElementChild.style.gridColumnStart); - this.html.style.gridColumnStart = x+1; - } catch(e) { - } - super.attach(root) - } - show() { - if (!this._root) { - this.attach() - } - super.show() - } - /* Mainly just to make the constructor more readable. */ - makeHeading(title) { - var titleObject = new nmsBox("div",{html:{className: "panel-heading"}}); - this._titleText = new nmsBox("h4",{html:{textContent: title}}); - var closeButton = new nmsBox("button"); - closeButton.html.className = "close"; - closeButton.panel = this; - closeButton.html.onclick = function() { - this.nmsBox.panel.destroy(); - } - closeButton.html.style = "float: right;"; - closeButton.add(new nmsString("X","span")); - titleObject.add(closeButton); - titleObject.add(this._titleText); - return titleObject; - } - add(item) { - this._body.add(item) - } - set title(input) { - this._titleText.html.textContent = input; - } - get title() { - this._titleText.html.textContent; - } +class nmsPanel extends nmsBox { + constructor(title) { + super("div", { html: { style: { gridColumn: 2 } } }); + this._topBox = new nmsBox("div", { + html: { className: "panel panel-default" }, + }); + this._body = new nmsBox("div", { html: { className: "panel-body" } }); + this.nav = new nmsBox("div", { html: { className: "panel-body" } }); + this._topBox.add(this.makeHeading(title)); + this._topBox.add(this.nav); + this._topBox.add(this._body); + super.add(this._topBox); + } + attach(root = document.getElementById("genericPanelContainer")) { + try { + var x = parseInt(root.lastElementChild.style.gridColumnStart); + this.html.style.gridColumnStart = x + 1; + } catch (e) {} + super.attach(root); + } + show() { + if (!this._root) { + this.attach(); + } + super.show(); + } + /* Mainly just to make the constructor more readable. */ + makeHeading(title) { + var titleObject = new nmsBox("div", { + html: { className: "panel-heading" }, + }); + this._titleText = new nmsBox("h4", { html: { textContent: title } }); + var closeButton = new nmsBox("button"); + closeButton.html.className = "close"; + closeButton.panel = this; + closeButton.html.onclick = function () { + this.nmsBox.panel.destroy(); + }; + closeButton.html.style = "float: right;"; + closeButton.add(new nmsString("X", "span")); + titleObject.add(closeButton); + titleObject.add(this._titleText); + return titleObject; + } + add(item) { + this._body.add(item); + } + set title(input) { + this._titleText.html.textContent = input; + } + get title() { + this._titleText.html.textContent; + } } |