blob: a0f00d2a35cf9ecff5bd4639fe67f99130c8789c [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* HTML: DOM creator class
* args:
* - type: HTML element type (div, table, p etc) to produce
* - params: hash of element params to add (class, style etc)
* - children: optional child or children objects to insert into the new element
* Example:
* div = new HTML('div', {
* class: "footer",
* style: {
* fontWeight: "bold"
* }
#}, "Some text inside a div")
*/
var txt = (msg) => document.createTextNode(msg);
var HTML = (function() {
function HTML(type, params, children) {
/* create the raw element, or clone if passed an existing element */
var child, j, len, val;
if (typeof type === 'object') {
this.element = type.cloneNode();
} else {
this.element = document.createElement(type);
}
/* If params have been passed, set them */
if (isHash(params)) {
for (var key in params) {
val = params[key];
/* Standard string value? */
if (typeof val === "string" || typeof val === 'number') {
this.element.setAttribute(key, val);
} else if (isArray(val)) {
/* Are we passing a list of data to set? concatenate then */
this.element.setAttribute(key, val.join(" "));
} else if (isHash(val)) {
/* Are we trying to set multiple sub elements, like a style? */
for (var subkey in val) {
let subval = val[subkey];
if (!this.element[key]) {
throw "No such attribute, " + key + "!";
}
this.element[key][subkey] = subval;
}
}
}
} else {
if (!children) { children = params } // shortcut!
}
/* If any children have been passed, add them to the element */
if (children) {
/* If string, convert to textNode using txt() */
if (typeof children === "string") {
this.element.inject(txt(children));
} else {
/* If children is an array of elems, iterate and add */
if (isArray(children)) {
for (j = 0, len = children.length; j < len; j++) {
child = children[j];
/* String? Convert via txt() then */
if (typeof child === "string") {
this.element.inject(txt(child));
} else {
/* Plain element, add normally */
this.element.inject(child);
}
}
} else {
/* Just a single element, add it */
this.element.inject(children);
}
}
}
return this.element;
}
return HTML;
})();
/**
* prototype injector for HTML elements:
* Example: mydiv.inject(otherdiv)
*/
HTMLElement.prototype.inject = function(child) {
var item, j, len;
if (isArray(child)) {
for (j = 0, len = child.length; j < len; j++) {
item = child[j];
if (typeof item === 'string') {
item = txt(item);
}
this.appendChild(item);
}
} else {
if (typeof child === 'string') {
child = txt(child);
}
this.appendChild(child);
}
return child;
};
/**
* prototype for emptying an html element
*/
HTMLElement.prototype.empty = function() {
var ndiv;
ndiv = this.cloneNode();
this.parentNode.replaceChild(ndiv, this);
return ndiv;
};
function toggleView(id) {
let obj = document.getElementById(id);
if (obj) {
obj.style.display = (obj.style.display == 'block') ? 'none' : 'block';
}
}
function br() {
return new HTML('br');
}
// construction shortcuts for various elements
let _a = (a,b) => new HTML('a', a,b);
let _b = (a,b) => new HTML('b', a,b);
let _p = (a,b) => new HTML('p', a,b);
let _i = (a,b) => new HTML('i', a, b);
let _div = (a,b) => new HTML('div', a, b);
let _input = (a,b) => new HTML('input', a, b);
let _select = (a,b) => new HTML('select', a, b);
let _option = (a,b) => new HTML('option', a, b);
let _h1 = (a,b) => new HTML('h1', a, b);
let _h2 = (a,b) => new HTML('h2', a, b);
let _h3 = (a,b) => new HTML('h3', a, b);
let _h4 = (a,b) => new HTML('h4', a, b);
let _h5 = (a,b) => new HTML('h5', a, b);
let _kbd = (a,b) => new HTML('kbd', a, b);
let _pre = (a,b) => new HTML('pre', a, b);
let _form = (a,b) => new HTML('form', a, b);
let _hr = (a,b) => new HTML('hr', a, b);
let _span = (a,b) => new HTML('span', a, b);
let _textarea = (a,b) => new HTML('textarea', a, b);
let _get = (a) => document.getElementById(a);
function billitem(a,b,c, total) {
let d = _div({style: {position: 'relative', display: 'block'}});
if (total) { d.style.fontWeight = 'bold'; d.style.borderTop = '2px solid #444'; }
let da = _div({style: {position: 'relative', width: '600px', display: 'inline-block'}}, a);
let db = _div({style: {position: 'relative', width: '60px', display: 'inline-block'}}, b);
let dc = _div({style: {position: 'relative', width: '80px', textAlign: 'right', display: 'inline-block'}}, c);
d.inject(da);
d.inject(db);
d.inject(dc);
return d;
}
// Generic modal function
function modal(title, msg, type, isHTML) {
let modal = document.getElementById('modal');
let text = document.getElementById('modal_text');
if (modal == undefined) {
text = new HTML('p', {id: 'modal_text'}, "");
modal = new HTML('div', { id: 'modal'}, [
new HTML('div', {id: 'modal_content'}, [
new HTML('span', {id: 'modal_close', onclick: 'document.getElementById("modal").style.display = "none";'}, 'X'),
new HTML('h2', {id: 'modal_title'}, title),
new HTML('div', {}, text)
])
]);
document.body.appendChild(modal);
}
if (type) {
modal.setAttribute("class", "modal_" + type);
} else {
modal.setAttribute("class", undefined);
}
modal.style.display = 'block';
document.getElementById('modal_title').innerText = title;
// If we trust HTML, use it. Otherwise only show as textNode.
if (isHTML) {
text.innerHTML = msg;
} else {
msg = (typeof(msg) == "string") ? msg : "An internal browser error occurred.";
msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
text.innerText = msg;
}
}