// 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(""); } 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, "
"); } // 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); }