var defaultStrings = []; const color_grey = "#6b6b6b"; const color_red = "#ff8f8f"; /** * It clears default content of the element and sets it's color to black. * * @function * @name clearDefaultContent * @kind function * @param {any} element to set * @param {any} text to set * @returns {void} */ function clearDefaultContent(element, text) { if (element.value == text) { element.value = ""; element.style.color = "#000000"; element.style.backgroundColor = "#ffffff"; } } /** * It returns the value of the element with id "processors". * * @function * @name getProcessor * @kind function * @returns {any} */ function getProcessor() { return document.getElementById("processors").value; } /** * It returns the value of the element with id "versions". * * @function * @name getVersion * @kind function * @returns {any} */ function getVersion() { return document.getElementById("versions").value; } /** * It clears all data fields. * * @function * @name clearDataField * @kind function */ function clearDataField() { document.getElementById("xmlArea").value = ""; document.getElementById("xmlArea").style.color = null; document.getElementById("xmlArea").style.backgroundColor = null; document.getElementById("transformArea").value = ""; document.getElementById("transformArea").style.color = null; document.getElementById("transformArea").style.backgroundColor = null; } /** * It fills the XML area with a sample XML. * * @function * @name fillDefaultXML * @kind function * @param {any} element * @returns {void} */ function fillDefaultXML(element) { if (element.classList.contains("active")) { const serverAddress = window.location.protocol + "//" + window.location.hostname + ":8086"; clearDefaultContent(document.getElementById("xmlArea"), "Insert XML here"); fetch(serverAddress + "/assets/samples/sampleXml.xml") .then(response => response.text()) .then((exampleData) => { document.getElementById("xmlArea").value = exampleData; document.getElementById("xmlArea").style.backgroundColor = null; }) } } /** * The `fillDefaultXSLT()` function fetches a default XSLT template from the server and sets the value of the element with id "transformArea" to the fetched template. * * @function * @name fillDefaultXSLT * @kind function * @returns {void} */ function fillDefaultXSLT() { const serverAddress = window.location.protocol + "//" + window.location.hostname + ":8086"; fetch(serverAddress + "/assets/samples/XSLTTemplate.xslt") .then( response => response.text() ) .then( (XSTLTemplate) => { document.getElementById('transformArea').value = XSTLTemplate; } ) } /** * It sets default content for the element an changes it's color to grey * * @function * @name setDefaultContent * @kind function * @param {any} element to set * @param {any} text to set */ function setDefaultContent(element, text) { if (element.value == "") { var id = element.getAttribute('id'); if (!defaultStrings.includes(text)) { defaultStrings.push(text); } if (id == "xmlArea") { element.style.color = color_grey; element.value = text; } if (id == "transformArea") { element.style.color = color_grey; element.value = text; } if (id == "jsonArea") { element.style.color = color_grey; element.value = text; } } } /** * It hides list for specified version of XPath * * @function * @name hideList * @kind function * @param {any} collList class name of list to hide * @returns {void} */ function hideList(collList) { for (i = 0; i < collList.length; i++) { if (collList[i].nextElementSibling !== null) { collList[i].nextElementSibling.style.maxHeight = null; collList[i].nextElementSibling.classList.toggle("collapsibleDataExpanded", false); } collList[i].style.display = 'none'; collList[i].classList.remove("collapsibleActive"); } } /** * It checks if the text is a default text. * * @function * @name checkDefault * @kind function * @param {any} text * @returns {boolean} */ function checkDefault(text) { return defaultStrings.includes(text); } /** * It show list for specified version of XPath * * @function * @name showList * @kind function * @param {any} collList class name of list to hide * @returns {void} */ function showList(collList) { for (i = 0; i < collList.length; i++) { collList[i].style.display = 'block'; } } /** * A function that is used to fold/unfold collapsible elements. * * @function * @name smoothFoldElement * @kind function * @param {any} element * @param {any} toogleState * @param {any} toggleParrent * @returns {void} */ function smoothFoldElement(element, toogleState, toggleParrent) { if (toogleState) { if (toggleParrent) { element.parentElement.style.maxHeight = "0px"; } element.classList.toggle("active", false); var subLists = collapsibleData.getElementsByClassName("collapsibleData"); for (j = 0; j < subLists.length; j++) { subLists[j].style.maxHeight = null; } } else { collapsibleData.parentElement.style.maxHeight = (collapsibleData.parentElement.scrollHeight) + "px"; collapsibleData.classList.toggle("active", true); if (collapsibleData.parentElement.classList.contains("collapsibleData") && collapsibleData.parentElement.classList.contains("active")) { collapsibleData.parentElement.style.maxHeight = (collapsibleData.parentElement.scrollHeight + collapsibleData.scrollHeight) + "px"; } } } /** * Set tooltip info, function is called by onClick handlers * * @function * @name refreshTooltip * @kind function * @returns {void} */ function refreshTooltip() { var resizeList = document.getElementsByClassName("collapsibleData"); document.getElementById("processorTooltipInfo").innerText = procInfo; document.getElementById("xsltelementsheader").innerText = XSLTheader; } /** * A function that performs a request to the server. * * @function * @name performRequest * @kind function * @param {any} endpoint of target service * @param {any} checkXML enable checking for empty XML * @param {any} checkTransform enable checking for empty transform data * @returns {false | undefined} */ function performRequest(endpoint, checkXML, checkTransform) { const sourceId = "xmlArea"; const transformId = "transformArea"; var xmlData = document.getElementById(sourceId).value.trim(); var transformData = document.getElementById(transformId).value.trim(); var port = 8081; if (getProcessor() == "libxml") { port = 8082; } var empty = false; if (defaultStrings.includes(xmlData) && checkXML) { document.getElementById(sourceId).style.backgroundColor = color_red; xmlData = ""; empty = true; } if (defaultStrings.includes(transformData) && checkTransform) { document.getElementById(transformId).style.backgroundColor = color_red; empty = true; } if (!empty) { restRequest(port, endpoint, xmlData, transformData).then(function (result) { document.getElementById("resultArea").value = result.result; document.getElementById("procinfo").innerText = ' Computed using ' + result.processor if (result.type) document.getElementById("procinfo").innerText += ". Returned: " + result.type; else document.getElementById("procinfo").innerText += ". Engine doesn't support return of data types."; if (result.status = "OK") { document.getElementById("procinfo").innerText += " (" + result.time + "ms)"; procinfo.style.color = "#30aa58"; } else { procinfo.style.color = "#aa3030"; } }); } else { document.getElementById("resultArea").value = "No data provided!"; return false; } } /** * Function that prepares data to send and handles response * * @function * @name performFormatRequest * @kind function * @param {any} endpoint of target service * @param {any} checkXML enable checking for empty XML * @param {any} sourceId ID of element to get XML from * @param {any} targetId ID of element to write formatted XML * @returns {void} */ function performFormatRequest(endpoint, checkXML, sourceId, targetId) { const sourceElement = document.getElementById(sourceId); const targetElement = document.getElementById(targetId); const infoElement = document.getElementById("formatinfo"); const port = 8082; var xmlData = sourceElement.value.trim(); var empty = false; if (defaultStrings.includes(xmlData) && checkXML) { sourceElement.style.backgroundColor = color_red; xmlData = ""; empty = true; } if (!empty) { restRequest(port, endpoint, xmlData, "").then(function (result) { if (result.status == "OK") { targetElement.value = result.result; targetElement.style.backgroundColor = null; infoElement.innerText = ' Computed'.concat(" in ", result.time, "ms."); infoElement.style.color = "#30aa58"; } else { targetElement.style.backgroundColor = color_red; infoElement.innerText = result.result; infoElement.style.color = "#aa3030"; } }); } } /** * Form REST request, send and return received data * * @async * @function * @name restRequest * @kind function * @param {any} port of target service * @param {any} endpoint of target service * @param {any} xmlData XML that will be sent * @param {any} transformData data used to transform given XML * @returns {Promise} */ async function restRequest(port, endpoint, xmlData, transformData) { const escapeChar = "specialEscapeChar"; const addr = window.location.protocol + "//" + window.location.hostname + ":" + port + "/" + endpoint; if (defaultStrings.includes(xmlData)) { xmlData = ""; } var jsonData = JSON.stringify({ "data": xmlData, "process": transformData, "processor": getProcessor(), "version": getVersion() }); var init = { headers: new Headers({ }), body: jsonData, // body: data, method: "POST" }; var request = new Request(addr, init); var result = await fetch(request).then(response => { return response.text().then(function (text) { return JSON.parse(text); }); }); return result; }