1616 lines
49 KiB
JavaScript
1616 lines
49 KiB
JavaScript
// src/utils/JavaScriptHelpers.mjs
|
|
function errorCatch(err) {
|
|
if (err.stack) {
|
|
if (err.lineNumber) {
|
|
console.error("ERROR[%s:%s] ", err.name, err.lineNumber, err);
|
|
} else if (err.line) {
|
|
console.error("ERROR[%s:%s] ", err.name, err.line, err);
|
|
} else {
|
|
console.error("ERROR[%s] ", err.name, err);
|
|
}
|
|
} else if (err.number) {
|
|
console.error("ERROR[%s:%s] %s", err.name, err.number, err.message);
|
|
console.error("ERROR[description] %s", err.description);
|
|
} else {
|
|
console.error("ERROR[%s] %s", err.name, err.message);
|
|
}
|
|
}
|
|
function isFunction(name) {
|
|
if (typeof window[name] !== "undefined" && typeof window[name] === "function") {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
function executeFunctionByName(functionName, context) {
|
|
var args = Array.prototype.slice.call(arguments, 2);
|
|
var namespaces = functionName.split(".");
|
|
var func = namespaces.pop();
|
|
if (func == void 0) {
|
|
throw new Error("Cannot get function from namespaces: " + functionName);
|
|
}
|
|
for (var i = 0; i < namespaces.length; i++) {
|
|
context = context[namespaces[i]];
|
|
}
|
|
return context[func].apply(context, args);
|
|
}
|
|
function runFunction(name) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
runFunctionArgsArray(name, args);
|
|
}
|
|
function runFunctionArgsArray(name, args) {
|
|
var fn = window[name];
|
|
if (typeof fn !== "function") {
|
|
return;
|
|
}
|
|
fn.apply(window, args);
|
|
}
|
|
function isObject(val) {
|
|
if (val === null) {
|
|
return false;
|
|
}
|
|
return typeof val === "function" || typeof val === "object";
|
|
}
|
|
function getObjectCount(object) {
|
|
if (!isObject(object)) {
|
|
return -1;
|
|
}
|
|
return Object.keys(object).length;
|
|
}
|
|
function keyInObject(key, object) {
|
|
return objectKeyExists(object, key);
|
|
}
|
|
function objectKeyExists(object, key) {
|
|
return Object.prototype.hasOwnProperty.call(object, key) ? true : false;
|
|
}
|
|
function getKeyByValue(object, value) {
|
|
return Object.keys(object).find((key) => object[key] === value) ?? "";
|
|
}
|
|
function valueInObject(object, value) {
|
|
return objectValueExists(object, value);
|
|
}
|
|
function objectValueExists(object, value) {
|
|
return Object.keys(object).find((key) => object[key] === value) ? true : false;
|
|
}
|
|
function deepCopyFunction(inObject) {
|
|
var outObject, value, key;
|
|
if (typeof inObject !== "object" || inObject === null) {
|
|
return inObject;
|
|
}
|
|
outObject = Array.isArray(inObject) ? [] : {};
|
|
for (key in inObject) {
|
|
value = inObject[key];
|
|
outObject[key] = deepCopyFunction(value);
|
|
}
|
|
return outObject;
|
|
}
|
|
|
|
// src/utils/DomHelpers.mjs
|
|
function loadEl(el_id) {
|
|
let el = document.getElementById(el_id);
|
|
if (el === null) {
|
|
throw new Error("Cannot find: " + el_id);
|
|
}
|
|
return el;
|
|
}
|
|
function pop(theURL, winName, features) {
|
|
let __winName = window.open(theURL, winName, features);
|
|
if (__winName == null) {
|
|
return;
|
|
}
|
|
__winName.focus();
|
|
}
|
|
function expandTA(ta_id) {
|
|
let ta = this.loadEl(ta_id);
|
|
if (ta instanceof HTMLElement && ta.getAttribute("type") !== "textarea") {
|
|
throw new Error("Element is not a textarea: " + ta_id);
|
|
}
|
|
let maxChars = parseInt(ta.getAttribute("cols") ?? "0");
|
|
let ta_value = ta.getAttribute("value");
|
|
let theRows = [];
|
|
if (ta_value != null) {
|
|
theRows = ta_value.split("\n");
|
|
}
|
|
var numNewRows = 0;
|
|
for (var i = 0; i < theRows.length; i++) {
|
|
if (theRows[i].length + 2 > maxChars) {
|
|
numNewRows += Math.ceil((theRows[i].length + 2) / maxChars);
|
|
}
|
|
}
|
|
ta.setAttribute("row", (numNewRows + theRows.length).toString());
|
|
}
|
|
function exists(id) {
|
|
return $("#" + id).length > 0 ? true : false;
|
|
}
|
|
|
|
// src/utils/HtmlElementCreator.mjs
|
|
var HtmlElementCreator = class {
|
|
/**
|
|
* reates object for DOM element creation flow
|
|
* @param {String} tag must set tag (div, span, etc)
|
|
* @param {String} [id=''] optional set for id, if input, select will be used for name
|
|
* @param {String} [content=''] text content inside, is skipped if sub elements exist
|
|
* @param {Array} [css=[]] array for css tags
|
|
* @param {Object} [options={}] anything else (value, placeholder, OnClick, style)
|
|
* @return {Object} created element as an object
|
|
*/
|
|
cel(tag, id = "", content = "", css = [], options = {}) {
|
|
return {
|
|
tag,
|
|
id,
|
|
// override name if set, else id is used. Only for input/button
|
|
name: options.name,
|
|
content,
|
|
css,
|
|
options,
|
|
sub: []
|
|
};
|
|
}
|
|
/**
|
|
* attach a cel created object to another to create a basic DOM tree
|
|
* @param {Object} base object where to attach/search
|
|
* @param {Object} attach the object to be attached
|
|
* @param {String} [id=''] optional id, if given search in base for this id and attach there
|
|
* @return {Object} "none", technically there is no return needed as it is global attach
|
|
*/
|
|
ael(base, attach, id = "") {
|
|
if (id) {
|
|
if (base.id == id) {
|
|
base.sub.push(deepCopyFunction(attach));
|
|
} else {
|
|
if (isObject(base.sub) && base.sub.length > 0) {
|
|
for (var i = 0; i < base.sub.length; i++) {
|
|
this.ael(base.sub[i], attach, id);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
base.sub.push(deepCopyFunction(attach));
|
|
}
|
|
return base;
|
|
}
|
|
/**
|
|
* directly attach n elements to one master base element
|
|
* this type does not support attach with optional id
|
|
* @param {Object} base object to where we attach the elements
|
|
* @param {...Object} attach attach 1..n: attach directly to the base element those attachments
|
|
* @return {Object} "none", technically there is no return needed, global attach
|
|
*/
|
|
aelx(base, ...attach) {
|
|
for (var i = 0; i < attach.length; i++) {
|
|
base.sub.push(deepCopyFunction(attach[i]));
|
|
}
|
|
return base;
|
|
}
|
|
/**
|
|
* same as aelx, but instead of using objects as parameters
|
|
* get an array of objects to attach
|
|
* @param {Object} base object to where we attach the elements
|
|
* @param {Array} attach array of objects to attach
|
|
* @return {Object} "none", technically there is no return needed, global attach
|
|
*/
|
|
aelxar(base, attach) {
|
|
for (var i = 0; i < attach.length; i++) {
|
|
base.sub.push(deepCopyFunction(attach[i]));
|
|
}
|
|
return base;
|
|
}
|
|
/**
|
|
* resets the sub elements of the base element given
|
|
* @param {Object} base cel created element
|
|
* @return {Object} returns reset base element
|
|
*/
|
|
rel(base) {
|
|
base.sub = [];
|
|
return base;
|
|
}
|
|
/**
|
|
* searches and removes style from css array
|
|
* @param {Object} _element element to work one
|
|
* @param {String} css style sheet to remove (name)
|
|
* @return {Object} returns full element
|
|
*/
|
|
rcssel(_element, css) {
|
|
var css_index = _element.css.indexOf(css);
|
|
if (css_index > -1) {
|
|
_element.css.splice(css_index, 1);
|
|
}
|
|
return _element;
|
|
}
|
|
/**
|
|
* adds a new style sheet to the element given
|
|
* @param {Object} _element element to work on
|
|
* @param {String} css style sheet to add (name)
|
|
* @return {Object} returns full element
|
|
*/
|
|
acssel(_element, css) {
|
|
var css_index = _element.css.indexOf(css);
|
|
if (css_index == -1) {
|
|
_element.css.push(css);
|
|
}
|
|
return _element;
|
|
}
|
|
/**
|
|
* removes one css and adds another
|
|
* is a wrapper around rcssel/acssel
|
|
* @param {Object} _element element to work on
|
|
* @param {String} rcss style to remove (name)
|
|
* @param {String} acss style to add (name)
|
|
* @return {Object} returns full element
|
|
*/
|
|
scssel(_element, rcss, acss) {
|
|
this.rcssel(_element, rcss);
|
|
this.acssel(_element, acss);
|
|
return _element;
|
|
}
|
|
/**
|
|
* parses the object tree created with cel/ael and converts it into an HTML string
|
|
* that can be inserted into the page
|
|
* @param {Object} tree object tree with dom element declarations
|
|
* @return {String} HTML string that can be used as innerHTML
|
|
*/
|
|
phfo(tree) {
|
|
let name_elements = [
|
|
"button",
|
|
"fieldset",
|
|
"form",
|
|
"iframe",
|
|
"input",
|
|
"map",
|
|
"meta",
|
|
"object",
|
|
"output",
|
|
"param",
|
|
"select",
|
|
"textarea"
|
|
];
|
|
let skip_options = [
|
|
"id",
|
|
"name",
|
|
"class"
|
|
];
|
|
let no_close = [
|
|
"input",
|
|
"br",
|
|
"img",
|
|
"hr",
|
|
"area",
|
|
"col",
|
|
"keygen",
|
|
"wbr",
|
|
"track",
|
|
"source",
|
|
"param",
|
|
"command",
|
|
// only in header
|
|
"base",
|
|
"meta",
|
|
"link",
|
|
"embed"
|
|
];
|
|
var content = [];
|
|
var line = "<" + tree.tag;
|
|
var i;
|
|
if (tree.id) {
|
|
line += ' id="' + tree.id + '"';
|
|
if (name_elements.includes(tree.tag)) {
|
|
line += ' name="' + (tree.name ? tree.name : tree.id) + '"';
|
|
}
|
|
}
|
|
if (isObject(tree.css) && tree.css.length > 0) {
|
|
line += ' class="';
|
|
for (i = 0; i < tree.css.length; i++) {
|
|
line += tree.css[i] + " ";
|
|
}
|
|
line = line.slice(0, -1);
|
|
line += '"';
|
|
}
|
|
if (isObject(tree.options)) {
|
|
for (const [key, item] of Object.entries(tree.options)) {
|
|
if (!skip_options.includes(key)) {
|
|
line += " " + key + '="' + item + '"';
|
|
}
|
|
}
|
|
}
|
|
line += ">";
|
|
content.push(line);
|
|
if (isObject(tree.sub) && tree.sub.length > 0) {
|
|
if (tree.content) {
|
|
content.push(tree.content);
|
|
}
|
|
for (i = 0; i < tree.sub.length; i++) {
|
|
content.push(this.phfo(tree.sub[i]));
|
|
}
|
|
} else if (tree.content) {
|
|
content.push(tree.content);
|
|
}
|
|
if (!no_close.includes(tree.tag)) {
|
|
content.push("</" + tree.tag + ">");
|
|
}
|
|
return content.join("");
|
|
}
|
|
/**
|
|
* Create HTML elements from array list
|
|
* as a flat element without master object file
|
|
* Is like tree.sub call
|
|
* @param {Array} list Array of cel created objects
|
|
* @return {String} HTML String
|
|
*/
|
|
phfa(list) {
|
|
var content = [];
|
|
for (var i = 0; i < list.length; i++) {
|
|
content.push(this.phfo(list[i]));
|
|
}
|
|
return content.join("");
|
|
}
|
|
};
|
|
|
|
// src/utils/HtmlHelpers.mjs
|
|
var dom = new HtmlElementCreator();
|
|
function escapeHtml(string) {
|
|
return string.replace(/[&<>"'/]/g, function(s) {
|
|
var entityMap = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
'"': """,
|
|
"'": "'",
|
|
"/": "/"
|
|
};
|
|
return entityMap[s];
|
|
});
|
|
}
|
|
function unescapeHtml(string) {
|
|
return string.replace(/&[#\w]+;/g, function(s) {
|
|
var entityMap = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
""": '"',
|
|
"'": "'",
|
|
"/": "/"
|
|
};
|
|
return entityMap[s];
|
|
});
|
|
}
|
|
function html_options(name, data, selected = "", options_only = false, return_string = false, sort = "") {
|
|
return this.html_options_block(
|
|
name,
|
|
data,
|
|
selected,
|
|
0,
|
|
options_only,
|
|
return_string,
|
|
sort
|
|
);
|
|
}
|
|
function html_options_block(name, data, selected = "", multiple = 0, options_only = false, return_string = false, sort = "", onchange = "") {
|
|
var content = [];
|
|
var element_select;
|
|
var select_options = {};
|
|
var element_option;
|
|
var data_list = [];
|
|
var value;
|
|
var options = {};
|
|
if (multiple > 0) {
|
|
select_options.multiple = "";
|
|
if (multiple > 1) {
|
|
select_options.size = multiple;
|
|
}
|
|
}
|
|
if (onchange) {
|
|
select_options.OnChange = onchange;
|
|
}
|
|
element_select = dom.cel("select", name, "", [], select_options);
|
|
if (sort == "keys") {
|
|
data_list = Object.keys(data).sort();
|
|
} else if (sort == "values") {
|
|
data_list = Object.keys(data).sort((a, b) => ("" + data[a]).localeCompare(data[b]));
|
|
} else {
|
|
data_list = Object.keys(data);
|
|
}
|
|
for (const key of data_list) {
|
|
value = data[key];
|
|
options = {
|
|
"label": value,
|
|
"value": key,
|
|
"selected": ""
|
|
};
|
|
if (multiple == 0 && !Array.isArray(selected) && selected == key) {
|
|
options.selected = "";
|
|
}
|
|
if (multiple == 1 && Array.isArray(selected) && selected.indexOf(key) != -1) {
|
|
options.selected = "";
|
|
}
|
|
element_option = dom.cel("option", "", value, [], options);
|
|
dom.ael(element_select, element_option);
|
|
}
|
|
if (!options_only) {
|
|
if (return_string) {
|
|
content.push(dom.phfo(element_select));
|
|
return content.join("");
|
|
} else {
|
|
return element_select;
|
|
}
|
|
} else {
|
|
if (return_string) {
|
|
for (var i = 0; i < element_select.sub.length; i++) {
|
|
content.push(dom.phfo(element_select.sub[i]));
|
|
}
|
|
return content.join("");
|
|
} else {
|
|
return element_select.sub;
|
|
}
|
|
}
|
|
}
|
|
function html_options_refill(name, data, sort = "") {
|
|
var element_option;
|
|
var option_selected;
|
|
var data_list = [];
|
|
var value;
|
|
if (document.getElementById(name)) {
|
|
if (sort == "keys") {
|
|
data_list = Object.keys(data).sort();
|
|
} else if (sort == "values") {
|
|
data_list = Object.keys(data).sort((a, b) => ("" + data[a]).localeCompare(data[b]));
|
|
} else {
|
|
data_list = Object.keys(data);
|
|
}
|
|
[].forEach.call(document.querySelectorAll("#" + name + " :checked"), function(elm) {
|
|
option_selected = elm.value;
|
|
});
|
|
loadEl(name).innerHTML = "";
|
|
for (const key of data_list) {
|
|
value = data[key];
|
|
element_option = document.createElement("option");
|
|
element_option.label = value;
|
|
element_option.value = key;
|
|
element_option.innerHTML = value;
|
|
if (key == option_selected) {
|
|
element_option.selected = true;
|
|
}
|
|
loadEl(name).appendChild(element_option);
|
|
}
|
|
}
|
|
}
|
|
|
|
// src/utils/MathHelpers.mjs
|
|
function dec2hex(dec) {
|
|
return ("0x" + dec.toString(16)).substring(-2);
|
|
}
|
|
function getRandomIntInclusive(min, max) {
|
|
min = Math.ceil(min);
|
|
max = Math.floor(max);
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
}
|
|
function roundPrecision(number, precision) {
|
|
if (isNaN(number) || isNaN(precision)) {
|
|
return number;
|
|
}
|
|
return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);
|
|
}
|
|
|
|
// src/utils/StringHelpers.mjs
|
|
function formatString(string, ...args) {
|
|
return string.replace(/{(\d+)}/g, function(match, number) {
|
|
return typeof args[number] != "undefined" ? args[number] : match;
|
|
});
|
|
}
|
|
function numberWithCommas(number) {
|
|
var parts = number.toString().split(".");
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
return parts.join(".");
|
|
}
|
|
function convertLBtoBR(string) {
|
|
return string.replace(/(?:\r\n|\r|\n)/g, "<br>");
|
|
}
|
|
|
|
// src/utils/DateTimeHelpers.mjs
|
|
function getTimestamp() {
|
|
var date = /* @__PURE__ */ new Date();
|
|
return date.getTime();
|
|
}
|
|
|
|
// src/utils/UniqIdGenerators.mjs
|
|
function generateId(len) {
|
|
var arr = new Uint8Array((len || 40) / 2);
|
|
(window.crypto || // @ts-ignore
|
|
window.msCrypto).getRandomValues(arr);
|
|
return Array.from(arr, self.dec2hex).join("");
|
|
}
|
|
function randomIdF() {
|
|
return Math.random().toString(36).substring(2);
|
|
}
|
|
|
|
// src/utils/ResizingAndMove.mjs
|
|
function getWindowSize() {
|
|
var width, height;
|
|
width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
|
|
height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
|
|
return {
|
|
width,
|
|
height
|
|
};
|
|
}
|
|
function getScrollOffset() {
|
|
var left, top;
|
|
left = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
|
|
top = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
|
|
return {
|
|
left,
|
|
top
|
|
};
|
|
}
|
|
function getScrollOffsetOpener() {
|
|
var left, top;
|
|
left = opener.window.pageXOffset || (opener.document.documentElement.scrollLeft || opener.document.body.scrollLeft);
|
|
top = opener.window.pageYOffset || (opener.document.documentElement.scrollTop || opener.document.body.scrollTop);
|
|
return {
|
|
left,
|
|
top
|
|
};
|
|
}
|
|
function setCenter(id, left, top) {
|
|
var dimensions = {
|
|
height: $("#" + id).height() ?? 0,
|
|
width: $("#" + id).width() ?? 0
|
|
};
|
|
var type = $("#" + id).css("position");
|
|
var viewport = this.getWindowSize();
|
|
var offset = this.getScrollOffset();
|
|
if (left) {
|
|
$("#" + id).css({
|
|
left: viewport.width / 2 - dimensions.width / 2 + offset.left + "px"
|
|
});
|
|
}
|
|
if (top) {
|
|
var top_pos = type == "fixed" ? viewport.height / 2 - dimensions.height / 2 : viewport.height / 2 - dimensions.height / 2 + offset.top;
|
|
$("#" + id).css({
|
|
top: top_pos + "px"
|
|
});
|
|
}
|
|
}
|
|
function goToPos(element, offset = 0, duration = 500, base = "body,html") {
|
|
try {
|
|
let element_offset = $("#" + element).offset();
|
|
if (element_offset == void 0) {
|
|
return;
|
|
}
|
|
if ($("#" + element).length) {
|
|
$(base).animate({
|
|
scrollTop: element_offset.top - offset
|
|
}, duration);
|
|
}
|
|
} catch (err) {
|
|
errorCatch(err);
|
|
}
|
|
}
|
|
function goTo(target) {
|
|
loadEl(target).scrollIntoView({
|
|
behavior: "smooth"
|
|
});
|
|
}
|
|
|
|
// src/utils/FormatBytes.mjs
|
|
function formatBytes(bytes) {
|
|
var i = -1;
|
|
if (typeof bytes === "bigint") {
|
|
bytes = Number(bytes);
|
|
}
|
|
if (isNaN(bytes)) {
|
|
return bytes.toString();
|
|
}
|
|
do {
|
|
bytes = bytes / 1024;
|
|
i++;
|
|
} while (bytes > 99);
|
|
return Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2) + ["kB", "MB", "GB", "TB", "PB", "EB"][i];
|
|
}
|
|
function formatBytesLong(bytes) {
|
|
if (typeof bytes === "bigint") {
|
|
bytes = Number(bytes);
|
|
}
|
|
if (isNaN(bytes)) {
|
|
return bytes.toString();
|
|
}
|
|
let negative = false;
|
|
if (bytes < 0) {
|
|
negative = true;
|
|
bytes *= -1;
|
|
}
|
|
var i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
var sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
return (negative ? "-" : "") + ((bytes / Math.pow(1024, i)).toFixed(2) + " " + sizes[i]).toString();
|
|
}
|
|
function stringByteFormat(bytes, raw = false) {
|
|
if (!(typeof bytes === "string" || bytes instanceof String)) {
|
|
return bytes.toString();
|
|
}
|
|
let valid_units = "bkmgtpezy";
|
|
let regex = /([\d.,]*)\s?(eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i;
|
|
let matches = bytes.match(regex);
|
|
if (matches !== null) {
|
|
let m1 = parseFloat(matches[1].replace(/[^0-9.]/, ""));
|
|
let m2 = matches[2].replace(/[^bkmgtpezy]/i, "").charAt(0).toLowerCase();
|
|
if (m2) {
|
|
bytes = m1 * Math.pow(1024, valid_units.indexOf(m2));
|
|
}
|
|
}
|
|
if (raw) {
|
|
return bytes;
|
|
}
|
|
return Math.round(bytes);
|
|
}
|
|
|
|
// src/utils/UrlParser.mjs
|
|
function parseQueryString(query = "", return_key = "", single = false) {
|
|
return getQueryStringParam(return_key, query, single);
|
|
}
|
|
function getQueryStringParam(search = "", query = "", single = false) {
|
|
if (!query) {
|
|
query = window.location.href;
|
|
}
|
|
const url = new URL(query);
|
|
let param = null;
|
|
if (search) {
|
|
let _params = url.searchParams.getAll(search);
|
|
if (_params.length == 1 || single === true) {
|
|
param = _params[0];
|
|
} else if (_params.length > 1) {
|
|
param = _params;
|
|
}
|
|
} else {
|
|
param = {};
|
|
for (const [key] of url.searchParams.entries()) {
|
|
if (typeof param[key] === "undefined") {
|
|
let _params = url.searchParams.getAll(key);
|
|
param[key] = _params.length < 2 || single === true ? _params[0] : _params;
|
|
}
|
|
}
|
|
}
|
|
return param;
|
|
}
|
|
function hasUrlParameter(key) {
|
|
var urlParams = new URLSearchParams(window.location.search);
|
|
return urlParams.has(key);
|
|
}
|
|
function getUrlParameter(key) {
|
|
var urlParams = new URLSearchParams(window.location.search);
|
|
return urlParams.get(key);
|
|
}
|
|
function updateUrlParameter(key, value, reload = false) {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.set(key, value);
|
|
const newUrl = url.toString();
|
|
window.history.pushState({ path: newUrl }, "", newUrl);
|
|
if (reload) {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
function removeUrlParameter(key, reload = false) {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.delete(key);
|
|
window.history.pushState({}, "", url.toString());
|
|
if (reload) {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
|
|
// src/utils/LoginLogout.mjs
|
|
function loginLogout() {
|
|
const form = document.createElement("form");
|
|
form.method = "post";
|
|
const hiddenField = document.createElement("input");
|
|
hiddenField.type = "hidden";
|
|
hiddenField.name = "login_logout";
|
|
hiddenField.value = "Logout";
|
|
form.appendChild(hiddenField);
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
|
|
// src/utils/ActionIndicatorOverlayBox.mjs
|
|
function actionIndicator(loc, overlay = true) {
|
|
if ($("#indicator").is(":visible")) {
|
|
this.actionIndicatorHide(loc, overlay);
|
|
} else {
|
|
this.actionIndicatorShow(loc, overlay);
|
|
}
|
|
}
|
|
function actionIndicatorShow(loc, overlay = true) {
|
|
if (!$("#indicator").is(":visible")) {
|
|
if (!$("#indicator").hasClass("progress")) {
|
|
$("#indicator").addClass("progress");
|
|
}
|
|
setCenter("indicator", true, true);
|
|
$("#indicator").show();
|
|
}
|
|
if (overlay === true) {
|
|
this.overlayBoxShow();
|
|
}
|
|
}
|
|
function actionIndicatorHide(loc, overlay = true) {
|
|
$("#indicator").hide();
|
|
if (overlay === true) {
|
|
overlayBoxHide();
|
|
}
|
|
}
|
|
function overlayBoxShow() {
|
|
if ($("#overlayBox").is(":visible")) {
|
|
$("#overlayBox").css("zIndex", "100");
|
|
} else {
|
|
$("#overlayBox").show();
|
|
$("#overlayBox").css("zIndex", "98");
|
|
}
|
|
}
|
|
function overlayBoxHide() {
|
|
if (parseInt($("#overlayBox").css("zIndex")) >= 100) {
|
|
$("#overlayBox").css("zIndex", "98");
|
|
} else {
|
|
$("#overlayBox").hide();
|
|
}
|
|
}
|
|
function setOverlayBox() {
|
|
if (!$("#overlayBox").is(":visible")) {
|
|
$("#overlayBox").show();
|
|
}
|
|
}
|
|
function hideOverlayBox() {
|
|
if ($("#overlayBox").is(":visible")) {
|
|
$("#overlayBox").hide();
|
|
}
|
|
}
|
|
function ClearCall() {
|
|
$("#actionBox").html("");
|
|
$("#actionBox").hide();
|
|
$("#overlayBox").hide();
|
|
}
|
|
var ActionIndicatorOverlayBox = class {
|
|
// open overlay boxes counter for z-index
|
|
#GL_OB_S = 100;
|
|
#GL_OB_BASE = 100;
|
|
/**
|
|
* show action indicator
|
|
* - checks if not existing and add
|
|
* - only shows if not visible (else ignore)
|
|
* - overlaybox check is called and shown on a fixzed
|
|
* zIndex of 1000
|
|
* - indicator is page centered
|
|
* @param {String} loc ID string, only used for console log
|
|
*/
|
|
showActionIndicator(loc) {
|
|
if ($("#indicator").length == 0) {
|
|
var el = document.createElement("div");
|
|
el.className = "progress hide";
|
|
el.id = "indicator";
|
|
$("body").append(el);
|
|
} else if (!$("#indicator").hasClass("progress")) {
|
|
$("#indicator").addClass("progress").hide();
|
|
}
|
|
if (!$("#indicator").is(":visible")) {
|
|
this.checkOverlayExists();
|
|
if (!$("#overlayBox").is(":visible")) {
|
|
$("#overlayBox").show();
|
|
}
|
|
$("#overlayBox").css("zIndex", 1e3);
|
|
$("#indicator").show();
|
|
setCenter("indicator", true, true);
|
|
}
|
|
}
|
|
/**
|
|
* hide action indicator, if it is visiable
|
|
* If the global variable GL_OB_S is > GL_OB_BASE then
|
|
* the overlayBox is not hidden but the zIndex
|
|
* is set to this value
|
|
* @param {String} loc ID string, only used for console log
|
|
*/
|
|
hideActionIndicator(loc) {
|
|
if ($("#indicator").is(":visible")) {
|
|
$("#indicator").hide();
|
|
if (this.#GL_OB_S > this.#GL_OB_BASE) {
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_S);
|
|
} else {
|
|
$("#overlayBox").hide();
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_BASE);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* checks if overlayBox exists, if not it is
|
|
* added as hidden item at the body end
|
|
*/
|
|
checkOverlayExists() {
|
|
if ($("#overlayBox").length == 0) {
|
|
var el = document.createElement("div");
|
|
el.className = "overlayBoxElement hide";
|
|
el.id = "overlayBox";
|
|
$("body").append(el);
|
|
}
|
|
}
|
|
/**
|
|
* show overlay box
|
|
* if not visible show and set zIndex to 10 (GL_OB_BASE)
|
|
* if visible, add +1 to the GL_OB_S variable and
|
|
* up zIndex by this value
|
|
*/
|
|
showOverlayBoxLayers(el_id) {
|
|
if (!$("#overlayBox").is(":visible")) {
|
|
$("#overlayBox").show();
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_BASE);
|
|
this.#GL_OB_S = this.#GL_OB_BASE;
|
|
}
|
|
this.#GL_OB_S++;
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_S);
|
|
if (el_id) {
|
|
if ($("#" + el_id).length > 0) {
|
|
$("#" + el_id).css("zIndex", this.#GL_OB_S + 1);
|
|
$("#" + el_id).show();
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* hide overlay box
|
|
* lower GL_OB_S value by -1
|
|
* if we are 10 (GL_OB_BASE) or below hide the overlayIndex
|
|
* and set zIndex and GL_OB_S to 0
|
|
* else just set zIndex to the new GL_OB_S value
|
|
* @param {String} el_id Target to hide layer
|
|
*/
|
|
hideOverlayBoxLayers(el_id = "") {
|
|
this.#GL_OB_S--;
|
|
if (this.#GL_OB_S <= this.#GL_OB_BASE) {
|
|
this.#GL_OB_S = this.#GL_OB_BASE;
|
|
$("#overlayBox").hide();
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_BASE);
|
|
} else {
|
|
$("#overlayBox").css("zIndex", this.#GL_OB_S);
|
|
}
|
|
if (el_id) {
|
|
$("#" + el_id).hide();
|
|
$("#" + el_id).css("zIndex", 0);
|
|
}
|
|
}
|
|
/**
|
|
* only for single action box
|
|
*/
|
|
clearCallActionBox() {
|
|
$("#actionBox").html("");
|
|
$("#actionBox").hide();
|
|
this.hideOverlayBoxLayers();
|
|
}
|
|
};
|
|
|
|
// src/utils/l10nTranslation.mjs
|
|
var l10nTranslation = class {
|
|
#i18n = {};
|
|
constructor(i18n2) {
|
|
this.#i18n = i18n2;
|
|
}
|
|
/**
|
|
* uses the i18n object created in the translation template
|
|
* that is filled from gettext in PHP
|
|
* @param {String} string text to translate
|
|
* @return {String} translated text (based on PHP selected language)
|
|
*/
|
|
__(string) {
|
|
if (typeof this.#i18n !== "undefined" && isObject(this.#i18n) && this.#i18n[string]) {
|
|
return this.#i18n[string];
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/utils/ActionBox.mjs
|
|
var ActionBox = class {
|
|
// open overlay boxes counter for z-index
|
|
zIndex = {
|
|
base: 100,
|
|
max: 110,
|
|
indicator: 0,
|
|
boxes: {},
|
|
active: [],
|
|
top: ""
|
|
};
|
|
// general action box storage
|
|
action_box_storage = {};
|
|
// set to 10 min (*60 for seconds, *1000 for microseconds)
|
|
action_box_cache_timeout = 10 * 60 * 1e3;
|
|
hec;
|
|
l10n;
|
|
/**
|
|
* action box creator
|
|
* @param {Object} hec HtmlElementCreator
|
|
* @param {Object} l10n l10nTranslation
|
|
*/
|
|
constructor(hec2, l10n2) {
|
|
this.hec = hec2;
|
|
this.l10n = l10n2;
|
|
}
|
|
/**
|
|
* Show an action box
|
|
* @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new
|
|
* @param {string} [content=''] content to add to the box
|
|
* @param {array} [action_box_css=[]] additional css elements for the action box
|
|
* @param {number} [override=0] override size adjust
|
|
* @param {number} [content_override=0] override content size adjust
|
|
*/
|
|
showFillActionBox(target_id = "actionBox", content = "", action_box_css = [], override = 0, content_override = 0) {
|
|
this.fillActionBox(target_id, content, action_box_css);
|
|
this.showActionBox(target_id, override, content_override);
|
|
}
|
|
/**
|
|
* Fill action box with content, create it if it does not existgs
|
|
* @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new
|
|
* @param {string} [content=''] content to add to the box
|
|
* @param {array} [action_box_css=[]] additional css elements for the action box
|
|
*/
|
|
fillActionBox(target_id = "actionBox", content = "", action_box_css = []) {
|
|
if (!exists(target_id)) {
|
|
$("#mainContainer").after(
|
|
this.hec.phfo(this.hec.cel("div", target_id, "", ["actionBoxElement", "hide"].concat(action_box_css)))
|
|
);
|
|
}
|
|
$("#" + target_id).html(content);
|
|
}
|
|
/**
|
|
* Adjust the size of the action box
|
|
* @param {string} [target_id='actionBox'] which actionBox to work on
|
|
* @param {number} [override=0] override size adjust
|
|
* @param {number} [content_override=0] override content size adjust
|
|
*/
|
|
adjustActionBox(target_id = "actionBox", override = 0, content_override = 0) {
|
|
this.adjustActionBoxHeight(target_id, override, content_override);
|
|
setCenter(target_id, true, true);
|
|
}
|
|
/**
|
|
* hide any open action boxes and hide overlay
|
|
*/
|
|
hideAllActionBoxes() {
|
|
$('#actionBox, div[id^="actionBox-"].actionBoxElement').hide();
|
|
$("#overlayBox").hide();
|
|
}
|
|
/**
|
|
* hide action box, but do not clear content
|
|
* DEPRECATED
|
|
* @param {string} [target_id='actionBox']
|
|
*/
|
|
hideActionBox(target_id = "actionBox") {
|
|
this.closeActionBoxFloat(target_id, false);
|
|
}
|
|
/**
|
|
* Just show and adjust the box
|
|
* DEPRECAED
|
|
* @param {string} [target_id='actionBox'] which actionBox to work on
|
|
* @param {number} [override=0] override size adjust
|
|
* @param {number} [content_override=0] override content size adjust
|
|
* @param {Boolean} [hide_all=false] if set to true, hide all other action boxes
|
|
*/
|
|
showActionBox(target_id = "actionBox", override = 0, content_override = 0, hide_all = true) {
|
|
this.showActionBoxFloat(target_id, override, content_override, hide_all);
|
|
}
|
|
/**
|
|
* close an action box with default clear content
|
|
* for just hide use hideActionBox
|
|
* DEPRECATED
|
|
* @param {String} [target_id='actionBox'] which action box to close, default is set
|
|
* @param {Boolean} [clean=true] if set to false will not remove html content, just hide
|
|
*/
|
|
closeActionBox(target_id = "actionBox", clean = true) {
|
|
this.closeActionBoxFloat(target_id, clean);
|
|
}
|
|
/**
|
|
* TODO: better stacked action box: OPEN
|
|
* @param {string} [target_id='actionBox'] which actionBox to work on
|
|
* @param {number} [override=0] override size adjust
|
|
* @param {number} [content_override=0] override content size adjust
|
|
* @param {boolean} [hide_all=false] if set to true, hide all other action boxes
|
|
*/
|
|
showActionBoxFloat(target_id = "actionBox", override = 0, content_override = 0, hide_all = false) {
|
|
if (hide_all === true) {
|
|
this.hideAllActionBoxes();
|
|
}
|
|
if (!exists("overlayBox")) {
|
|
$("body").prepend(this.hec.phfo(this.hec.cel("div", "overlayBox", "", ["overlayBoxElement"])));
|
|
$("#overlayBox").css("zIndex", this.zIndex.base);
|
|
}
|
|
$("#overlayBox").show();
|
|
if (!objectKeyExists(this.zIndex.boxes, target_id)) {
|
|
this.zIndex.boxes[target_id] = this.zIndex.max;
|
|
this.zIndex.max += 10;
|
|
} else if (this.zIndex.boxes[target_id] + 10 < this.zIndex.max) {
|
|
this.zIndex.boxes[target_id] = this.zIndex.max;
|
|
this.zIndex.max += 10;
|
|
}
|
|
if (!this.zIndex.indicator) {
|
|
$("#overlayBox").css("zIndex", this.zIndex.boxes[target_id] - 1);
|
|
}
|
|
$("#" + target_id).css("zIndex", this.zIndex.boxes[target_id]).show();
|
|
if (this.zIndex.active.indexOf(target_id) == -1) {
|
|
this.zIndex.active.push(target_id);
|
|
}
|
|
this.zIndex.top = target_id;
|
|
this.adjustActionBox(target_id, override, content_override);
|
|
}
|
|
/**
|
|
* TODO: better stacked action box: CLOSE
|
|
* @param {String} [target_id='actionBox'] which action box to close, default is set
|
|
* @param {Boolean} [clean=true] if set to false will not remove html content, just hide
|
|
*/
|
|
closeActionBoxFloat(target_id = "actionBox", clean = true) {
|
|
if (!exists(target_id)) {
|
|
return;
|
|
}
|
|
if (objectKeyExists(this.action_box_storage, target_id) && clean === true) {
|
|
this.action_box_storage[target_id] = {};
|
|
}
|
|
if (clean === true) {
|
|
$("#" + target_id).html("");
|
|
}
|
|
$("#" + target_id).hide();
|
|
let idx = this.zIndex.active.indexOf(target_id);
|
|
this.zIndex.active.splice(idx, 1);
|
|
let visible_zIndexes = $('#actionBox:visible, div[id^="actionBox-"].actionBoxElement:visible').map((i, el) => ({
|
|
id: el.id,
|
|
zIndex: $("#" + el.id).css("zIndex")
|
|
})).get();
|
|
if (visible_zIndexes.length > 0) {
|
|
let max_zIndex = 0;
|
|
let max_el_id = "";
|
|
for (let zIndex_el of visible_zIndexes) {
|
|
if (parseInt(zIndex_el.zIndex) > max_zIndex) {
|
|
max_zIndex = parseInt(zIndex_el.zIndex);
|
|
max_el_id = zIndex_el.id;
|
|
}
|
|
}
|
|
$("#overlayBox").css("zIndex", max_zIndex - 1);
|
|
this.zIndex.top = max_el_id;
|
|
} else {
|
|
$("#overlayBox").hide();
|
|
}
|
|
}
|
|
/**
|
|
* create a new action box and fill it with basic elements
|
|
* @param {String} [target_id='actionBox']
|
|
* @param {String} [title='']
|
|
* @param {Object} [contents={}]
|
|
* @param {Object} [headers={}]
|
|
* @param {Boolean} [show_close=true]
|
|
* @param {Object} [settings={}] Optional settings, eg style sheets
|
|
*/
|
|
createActionBox(target_id = "actionBox", title = "", contents = {}, headers = {}, settings = {}, show_close = true) {
|
|
if (!objectKeyExists(this.action_box_storage, target_id)) {
|
|
this.action_box_storage[target_id] = {};
|
|
}
|
|
let header_css = [];
|
|
if (objectKeyExists(settings, "header_css")) {
|
|
header_css = settings.header_css;
|
|
}
|
|
let action_box_css = [];
|
|
if (objectKeyExists(settings, "action_box_css")) {
|
|
action_box_css = settings.action_box_css;
|
|
}
|
|
let elements = [];
|
|
elements.push(this.hec.phfo(
|
|
this.hec.aelx(
|
|
this.hec.cel("div", target_id + "_title", "", ["actionBoxTitle", "flx-spbt"].concat(header_css)),
|
|
...show_close === true ? [
|
|
// title
|
|
this.hec.cel("div", "", title, ["fs-b", "w-80"]),
|
|
// close button
|
|
this.hec.aelx(
|
|
this.hec.cel("div", target_id + "_title_close_button", "", ["w-20", "tar"]),
|
|
this.hec.cel(
|
|
"input",
|
|
target_id + "_title_close",
|
|
"",
|
|
["button-close", "fs-s"],
|
|
{
|
|
type: "button",
|
|
value: this.l10n.__("Close"),
|
|
OnClick: "closeActionBox('" + target_id + "', false);"
|
|
}
|
|
)
|
|
)
|
|
] : [
|
|
this.hec.cel("div", "", title, ["fs-b", "w-100"])
|
|
]
|
|
)
|
|
));
|
|
if (getObjectCount(headers) > 0) {
|
|
if (objectKeyExists(headers, "raw_string")) {
|
|
elements.push(headers.raw_string);
|
|
} else {
|
|
elements.push(this.hec.phfo(headers));
|
|
}
|
|
}
|
|
if (getObjectCount(contents) > 0) {
|
|
if (objectKeyExists(contents, "raw_string")) {
|
|
elements.push(contents.raw_string);
|
|
} else {
|
|
elements.push(this.hec.phfo(contents));
|
|
}
|
|
} else {
|
|
elements.push(this.hec.phfo(this.hec.cel("div", target_id + "_content", "", [])));
|
|
}
|
|
elements.push(this.hec.phfo(
|
|
this.hec.aelx(
|
|
this.hec.cel("div", target_id + "_footer", "", ["pd-5", "flx-spbt"]),
|
|
...show_close === true ? [
|
|
// dummy spacer
|
|
this.hec.cel("div", "", "", ["fs-b", "w-80"]),
|
|
// close button
|
|
this.hec.aelx(
|
|
this.hec.cel("div", target_id + "_footer_close_button", "", ["tar", "w-20"]),
|
|
this.hec.cel(
|
|
"input",
|
|
target_id + "_footer_close",
|
|
"",
|
|
["button-close", "fs-s"],
|
|
{
|
|
type: "button",
|
|
value: this.l10n.__("Close"),
|
|
OnClick: "closeActionBox('" + target_id + "', false);"
|
|
}
|
|
)
|
|
)
|
|
] : [
|
|
this.hec.cel("div", "", "", ["fs-b", "w-100"])
|
|
]
|
|
)
|
|
));
|
|
elements.push(this.hec.phfo(this.hec.cel("input", target_id + "-cache_time", "", [], {
|
|
type: "hidden",
|
|
value: Date.now()
|
|
})));
|
|
this.fillActionBox(target_id, elements.join(""), action_box_css);
|
|
}
|
|
/**
|
|
* adjusts the action box height based on content and window height of browser
|
|
* TODO: border on outside/and other margin things need to be added in overall adjustment
|
|
* @param {String} [target_id='actionBox'] target id, if not set, fall back to default
|
|
* @param {Number} [override=0] override value to add to the actionBox height
|
|
* @param {Number} [content_override=0] override the value from _content block if it exists
|
|
*/
|
|
adjustActionBoxHeight(target_id = "actionBox", override = 0, content_override = 0) {
|
|
var new_height = 0;
|
|
var dim = {};
|
|
var abc_dim = {};
|
|
var content_id = "";
|
|
if (isNaN(override)) {
|
|
override = 0;
|
|
}
|
|
if (isNaN(content_override)) {
|
|
content_override = 0;
|
|
}
|
|
switch (target_id) {
|
|
case "actionBox":
|
|
content_id = "action_box";
|
|
break;
|
|
case "actionBoxSub":
|
|
content_id = "action_box_sub";
|
|
break;
|
|
default:
|
|
content_id = target_id;
|
|
break;
|
|
}
|
|
$.each([target_id, content_id + "_content"], function(i, v) {
|
|
$("#" + v).css({
|
|
"height": "",
|
|
"width": ""
|
|
});
|
|
});
|
|
if (exists(content_id + "_title")) {
|
|
dim.height = $("#" + content_id + "_title").outerHeight();
|
|
console.log("Target: %s, Action box Title: %s", target_id, dim.height);
|
|
new_height += dim.height ?? 0;
|
|
}
|
|
if (exists(content_id + "_header")) {
|
|
dim.height = $("#" + content_id + "_header").outerHeight();
|
|
console.log("Target: %s, Action box Header: %s", target_id, dim.height);
|
|
new_height += dim.height ?? 0;
|
|
}
|
|
if (exists(content_id + "_content")) {
|
|
if (content_override > 0) {
|
|
console.log("Target: %s, Action box Content Override: %s", target_id, content_override);
|
|
new_height += content_override;
|
|
} else {
|
|
abc_dim.height = $("#" + content_id + "_content").outerHeight();
|
|
console.log("Target: %s, Action box Content: %s", target_id, abc_dim.height);
|
|
new_height += abc_dim.height ?? 0;
|
|
}
|
|
}
|
|
if (exists(content_id + "_footer")) {
|
|
dim.height = $("#" + content_id + "_footer").outerHeight();
|
|
console.log("Target: %s, Action box Footer: %s", target_id, dim.height);
|
|
new_height += dim.height ?? 0;
|
|
}
|
|
new_height += override;
|
|
var viewport = getWindowSize();
|
|
if (new_height >= viewport.height) {
|
|
if (exists(content_id + "_content")) {
|
|
if (!$("#" + content_id + "_content").hasClass("of-s-y")) {
|
|
$("#" + content_id + "_content").addClass("of-s-y");
|
|
}
|
|
}
|
|
console.log("Target: %s, Viewport: %s, ActionBox (NH): %s, ABcontent: %s, ABouter: %s", target_id, viewport.height, new_height, abc_dim.height, $("#" + target_id).outerHeight());
|
|
var m_height = viewport.height - (new_height - (abc_dim.height ?? 0));
|
|
console.log("Target: %s, New ABcontent: %s", target_id, m_height);
|
|
$("#" + content_id + "_content").css("height", m_height + "px");
|
|
new_height = new_height - (abc_dim.height ?? 0) + m_height;
|
|
console.log("Target: %s, New Hight: %s", target_id, new_height);
|
|
} else {
|
|
if (exists(content_id + "_content")) {
|
|
if ($("#" + content_id + "_content").hasClass("of-s-y")) {
|
|
$("#" + content_id + "_content").removeClass("of-s-y");
|
|
}
|
|
}
|
|
}
|
|
console.log("Target: %s, Action Box new height: %s px (override %s px, content override %s px), window height: %s px, Visible Height: %s px", target_id, new_height, override, content_override, viewport.height, $("#" + content_id).outerHeight());
|
|
$("#" + target_id).css("height", new_height + "px");
|
|
}
|
|
};
|
|
|
|
// src/utils/LoginNavMenu.mjs
|
|
var LoginNavMenu = class {
|
|
hec;
|
|
l10n;
|
|
/**
|
|
* action box creator
|
|
* @param {Object} hec HtmlElementCreator
|
|
* @param {Object} l10n l10nTranslation
|
|
*/
|
|
constructor(hec2, l10n2) {
|
|
this.hec = hec2;
|
|
this.l10n = l10n2;
|
|
}
|
|
/**
|
|
* create login string and logout button elements
|
|
* @param {String} login_string the login string to show on the left
|
|
* @param {String} [header_id='mainHeader'] the target for the main element block
|
|
* if not set mainHeader is assumed
|
|
* this is the target div for the "loginRow"
|
|
*/
|
|
createLoginRow(login_string, header_id = "mainHeader") {
|
|
if (exists(header_id)) {
|
|
if (!exists("loginRow")) {
|
|
$("#" + header_id).html(this.hec.phfo(this.hec.cel("div", "loginRow", "", ["loginRow", "flx-spbt"])));
|
|
}
|
|
$("#loginRow").html(this.hec.phfo(this.hec.cel("div", "loginRow-name", login_string)));
|
|
$("#loginRow").append(this.hec.phfo(this.hec.cel("div", "loginRow-info", "")));
|
|
$("#loginRow").append(this.hec.phfo(
|
|
this.hec.aelx(
|
|
// outer div
|
|
this.hec.cel("div", "loginRow-logout"),
|
|
// inner element
|
|
this.hec.cel("input", "logout", "", [], {
|
|
value: this.l10n.__("Logout"),
|
|
type: "button",
|
|
onClick: "loginLogout()"
|
|
})
|
|
)
|
|
));
|
|
}
|
|
}
|
|
/**
|
|
* create the top nav menu that switches physical between pages
|
|
* (edit access data based)
|
|
* @param {Object} nav_menu the built nav menu with highlight info
|
|
* @param {String} [header_id='mainHeader'] the target for the main element block
|
|
* if not set mainHeader is assumed
|
|
* this is the target div for the "menuRow"
|
|
*/
|
|
createNavMenu(nav_menu, header_id = "mainHeader") {
|
|
if (isObject(nav_menu) && getObjectCount(nav_menu) > 1) {
|
|
if (!exists("menuRow")) {
|
|
$("#" + header_id).html(this.hec.phfo(this.hec.cel("div", "menuRow", "", ["menuRow", "flx-s"])));
|
|
}
|
|
var content = [];
|
|
$.each(nav_menu, function(key, item) {
|
|
if (key != 0) {
|
|
content.push(this.hec.phfo(this.hec.cel("div", "", "·", ["pd-2"])));
|
|
}
|
|
if (item.enabled) {
|
|
if (window.location.href.indexOf(item.url) != -1) {
|
|
item.selected = 1;
|
|
}
|
|
content.push(this.hec.phfo(
|
|
this.hec.aelx(
|
|
this.hec.cel("div"),
|
|
this.hec.cel("a", "", item.name, ["pd-2"].concat(item.selected ? "highlight" : ""), {
|
|
href: item.url
|
|
})
|
|
)
|
|
));
|
|
}
|
|
});
|
|
$("#menuRow").html(content.join(""));
|
|
} else {
|
|
$("#menuRow").hide();
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/utils.mjs
|
|
var aiob = new ActionIndicatorOverlayBox();
|
|
var hec = new HtmlElementCreator();
|
|
var l10n = new l10nTranslation(typeof i18n === "undefined" ? {} : i18n);
|
|
var ab = new ActionBox(hec, l10n);
|
|
var lnm = new LoginNavMenu(hec, l10n);
|
|
if (!String.prototype.format) {
|
|
String.prototype.format = function() {
|
|
console.error("[DEPRECATED] use StringHelpers.formatString");
|
|
return formatString(this, arguments);
|
|
};
|
|
}
|
|
if (Number.prototype.round) {
|
|
Number.prototype.round = function(prec) {
|
|
console.error("[DEPRECATED] use MathHelpers.roundPrecision");
|
|
return roundPrecision(this, prec);
|
|
};
|
|
}
|
|
if (!String.prototype.escapeHTML) {
|
|
String.prototype.escapeHTML = function() {
|
|
console.error("[DEPRECATED] use HtmlHelpers.escapeHtml");
|
|
return escapeHtml(this);
|
|
};
|
|
}
|
|
if (!String.prototype.unescapeHTML) {
|
|
String.prototype.unescapeHTML = function() {
|
|
console.error("[DEPRECATED] use HtmlHelpers.unescapeHtml");
|
|
return unescapeHtml(this);
|
|
};
|
|
}
|
|
function escapeHtml2(string) {
|
|
return escapeHtml(string);
|
|
}
|
|
function roundPrecision2(number, prec) {
|
|
return roundPrecision(number, prec);
|
|
}
|
|
function formatString2(string, ...args) {
|
|
return formatString(string, ...args);
|
|
}
|
|
function unescapeHtml2(string) {
|
|
return unescapeHtml(string);
|
|
}
|
|
function loadEl2(el_id) {
|
|
return loadEl(el_id);
|
|
}
|
|
function pop2(theURL, winName, features) {
|
|
pop(theURL, winName, features);
|
|
}
|
|
function expandTA2(ta_id) {
|
|
expandTA(ta_id);
|
|
}
|
|
function getWindowSize2() {
|
|
return getWindowSize();
|
|
}
|
|
function getScrollOffset2() {
|
|
return getScrollOffset();
|
|
}
|
|
function getScrollOffsetOpener2() {
|
|
return getScrollOffsetOpener();
|
|
}
|
|
function setCenter2(id, left, top) {
|
|
setCenter(id, left, top);
|
|
}
|
|
function goToPos2(element, offset = 0, duration = 500, base = "body,html") {
|
|
goToPos(element, offset, duration, base);
|
|
}
|
|
function goTo2(target) {
|
|
goTo(target);
|
|
}
|
|
function __(string) {
|
|
return l10n.__(string);
|
|
}
|
|
function numberWithCommas2(x) {
|
|
return numberWithCommas(x);
|
|
}
|
|
function convertLBtoBR2(string) {
|
|
return convertLBtoBR(string);
|
|
}
|
|
function getTimestamp2() {
|
|
return getTimestamp();
|
|
}
|
|
function dec2hex2(dec) {
|
|
return dec2hex(dec);
|
|
}
|
|
function generateId2(len) {
|
|
return generateId(len);
|
|
}
|
|
function randomIdF2() {
|
|
return randomIdF();
|
|
}
|
|
function getRandomIntInclusive2(min, max) {
|
|
return getRandomIntInclusive(min, max);
|
|
}
|
|
function isFunction2(name) {
|
|
return isFunction(name);
|
|
}
|
|
function executeFunctionByName2(functionName, context) {
|
|
return executeFunctionByName(functionName, context);
|
|
}
|
|
function isObject2(val) {
|
|
return isObject(val);
|
|
}
|
|
function getObjectCount2(object) {
|
|
return getObjectCount(object);
|
|
}
|
|
function keyInObject2(key, object) {
|
|
return keyInObject(key, object);
|
|
}
|
|
function getKeyByValue2(object, value) {
|
|
return getKeyByValue(object, value);
|
|
}
|
|
function valueInObject2(object, value) {
|
|
return valueInObject(object, value);
|
|
}
|
|
function deepCopyFunction2(inObject) {
|
|
return deepCopyFunction(inObject);
|
|
}
|
|
function exists2(id) {
|
|
return exists(id);
|
|
}
|
|
function formatBytes2(bytes) {
|
|
return formatBytes(bytes);
|
|
}
|
|
function formatBytesLong2(bytes) {
|
|
return formatBytesLong(bytes);
|
|
}
|
|
function stringByteFormat2(bytes) {
|
|
return stringByteFormat(bytes);
|
|
}
|
|
function errorCatch2(err) {
|
|
errorCatch(err);
|
|
}
|
|
function actionIndicator2(loc, overlay = true) {
|
|
actionIndicator(loc, overlay);
|
|
}
|
|
function actionIndicatorShow2(loc, overlay = true) {
|
|
actionIndicatorShow(loc, overlay);
|
|
}
|
|
function actionIndicatorHide2(loc, overlay = true) {
|
|
actionIndicatorHide(loc, overlay);
|
|
}
|
|
function overlayBoxShow2() {
|
|
overlayBoxShow();
|
|
}
|
|
function overlayBoxHide2() {
|
|
overlayBoxHide();
|
|
}
|
|
function setOverlayBox2() {
|
|
setOverlayBox();
|
|
}
|
|
function hideOverlayBox2() {
|
|
hideOverlayBox();
|
|
}
|
|
function ClearCall2() {
|
|
ClearCall();
|
|
}
|
|
function showActionIndicator(loc) {
|
|
aiob.showActionIndicator(loc);
|
|
}
|
|
function hideActionIndicator(loc) {
|
|
aiob.hideActionIndicator(loc);
|
|
}
|
|
function checkOverlayExists() {
|
|
aiob.checkOverlayExists();
|
|
}
|
|
function showOverlayBoxLayers(el_id) {
|
|
aiob.showOverlayBoxLayers(el_id);
|
|
}
|
|
function hideOverlayBoxLayers(el_id = "") {
|
|
aiob.hideOverlayBoxLayers(el_id);
|
|
}
|
|
function clearCallActionBox() {
|
|
aiob.clearCallActionBox();
|
|
}
|
|
function cel(tag, id = "", content = "", css = [], options = {}) {
|
|
return hec.cel(tag, id, content, css, options);
|
|
}
|
|
function ael(base, attach, id = "") {
|
|
return hec.ael(base, attach, id);
|
|
}
|
|
function aelx(base, ...attach) {
|
|
return hec.aelx(base, ...attach);
|
|
}
|
|
function aelxar(base, attach) {
|
|
return hec.aelxar(base, attach);
|
|
}
|
|
function rel(base) {
|
|
return hec.rel(base);
|
|
}
|
|
function rcssel(_element, css) {
|
|
return hec.rcssel(_element, css);
|
|
}
|
|
function acssel(_element, css) {
|
|
return hec.acssel(_element, css);
|
|
}
|
|
function scssel(_element, rcss, acss) {
|
|
hec.scssel(_element, rcss, acss);
|
|
}
|
|
function phfo(tree) {
|
|
return hec.phfo(tree);
|
|
}
|
|
function phfa(list) {
|
|
return hec.phfa(list);
|
|
}
|
|
function html_options2(name, data, selected = "", options_only = false, return_string = false, sort = "") {
|
|
return html_options(name, data, selected, options_only, return_string, sort);
|
|
}
|
|
function html_options_block2(name, data, selected = "", multiple = 0, options_only = false, return_string = false, sort = "", onchange = "") {
|
|
return html_options_block(
|
|
name,
|
|
data,
|
|
selected,
|
|
multiple,
|
|
options_only,
|
|
return_string,
|
|
sort,
|
|
onchange
|
|
);
|
|
}
|
|
function html_options_refill2(name, data, sort = "") {
|
|
html_options_refill(name, data, sort);
|
|
}
|
|
function parseQueryString2(query = "", return_key = "", single = false) {
|
|
return parseQueryString(query, return_key, single);
|
|
}
|
|
function getQueryStringParam2(search = "", query = "", single = false) {
|
|
return getQueryStringParam(search, query, single);
|
|
}
|
|
function updateUrlParameter2(key, value, reload = false) {
|
|
return updateUrlParameter(key, value, reload);
|
|
}
|
|
function removeUrlParameter2(key, reload = false) {
|
|
return removeUrlParameter(key, reload);
|
|
}
|
|
function hasUrlParameter2(key) {
|
|
return hasUrlParameter(key);
|
|
}
|
|
function getUrlParameter2(key) {
|
|
return getUrlParameter(key);
|
|
}
|
|
function loginLogout2() {
|
|
loginLogout();
|
|
}
|
|
function createLoginRow(login_string, header_id = "mainHeader") {
|
|
lnm.createLoginRow(login_string, header_id);
|
|
}
|
|
function createNavMenu(nav_menu, header_id = "mainHeader") {
|
|
lnm.createNavMenu(nav_menu, header_id);
|
|
}
|
|
function showFillActionBox(target_id = "actionBox", content = "", action_box_css = [], override = 0, content_override = 0) {
|
|
ab.showFillActionBox(target_id, content, action_box_css, override, content_override);
|
|
}
|
|
function fillActionBox(target_id = "actionBox", content = "", action_box_css = []) {
|
|
ab.fillActionBox(target_id, content, action_box_css);
|
|
}
|
|
function adjustActionBox(target_id = "actionBox", override = 0, content_override = 0) {
|
|
ab.adjustActionBox(target_id, override, content_override);
|
|
}
|
|
function hideAllActionBoxes() {
|
|
ab.hideAllActionBoxes();
|
|
}
|
|
function hideActionBox(target_id = "actionBox") {
|
|
ab.hideActionBox(target_id);
|
|
}
|
|
function showActionBox(target_id = "actionBox", override = 0, content_override = 0, hide_all = true) {
|
|
ab.showActionBox(target_id, override, content_override, hide_all);
|
|
}
|
|
function closeActionBox(target_id = "actionBox", clean = true) {
|
|
ab.closeActionBox(target_id, clean);
|
|
}
|
|
function showActionBoxFloat(target_id = "actionBox", override = 0, content_override = 0, hide_all = false) {
|
|
ab.showActionBoxFloat(target_id, override, content_override, hide_all);
|
|
}
|
|
function closeActionBoxFloat(target_id = "actionBox", clean = true) {
|
|
ab.closeActionBoxFloat(target_id, clean);
|
|
}
|
|
function createActionBox(target_id = "actionBox", title = "", contents = {}, headers = {}, settings = {}, show_close = true) {
|
|
ab.createActionBox(target_id, title, contents, headers, settings, show_close);
|
|
}
|
|
function adjustActionBoxHeight(target_id = "actionBox", override = 0, content_override = 0) {
|
|
ab.adjustActionBoxHeight(target_id, override, content_override);
|
|
}
|