XML Formatter QoL improvements (#88)
- Rewritten backend methods for prettifing and minimizing XMLs - Added "Clear" and "Insert default XML" buttons in XML Formatter. - Added place to display error messages in case of any Co-authored-by: Adam Bem <adam.bem@zoho.eu> Reviewed-on: R11/release11-tools-web#88
This commit is contained in:
		@@ -14,7 +14,9 @@ def prettify(source: str) -> str:
 | 
				
			|||||||
        prolog_end = source.find("?>") + 2
 | 
					        prolog_end = source.find("?>") + 2
 | 
				
			||||||
        prolog = source[prolog_start:prolog_end] + "\n"
 | 
					        prolog = source[prolog_start:prolog_end] + "\n"
 | 
				
			||||||
        source = source[prolog_end: ]
 | 
					        source = source[prolog_end: ]
 | 
				
			||||||
    xml = etree.XML(source)
 | 
					    
 | 
				
			||||||
 | 
					    parser = etree.XMLParser(remove_blank_text=True)
 | 
				
			||||||
 | 
					    xml = etree.fromstring(source, parser=parser)
 | 
				
			||||||
    return prolog + etree.tostring(xml, pretty_print=True).decode()
 | 
					    return prolog + etree.tostring(xml, pretty_print=True).decode()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def minimize(source: str) -> str:
 | 
					def minimize(source: str) -> str:
 | 
				
			||||||
@@ -23,18 +25,18 @@ def minimize(source: str) -> str:
 | 
				
			|||||||
    :param source: XML
 | 
					    :param source: XML
 | 
				
			||||||
    :return: minimized XML
 | 
					    :return: minimized XML
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    result = source
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    to_remove = ["   ", "  ", "\t", "\n"]
 | 
					    prolog = ""
 | 
				
			||||||
    to_substitute = [(" <", "<"), ("> ", ">"), ("</ ", "</"), (" >", ">")]
 | 
					    prolog_start = source.find("<?")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for chars in to_remove:
 | 
					    if prolog_start != -1:
 | 
				
			||||||
        result = result.replace(chars, "")
 | 
					        prolog_end = source.find("?>") + 2
 | 
				
			||||||
 | 
					        prolog = source[prolog_start:prolog_end]
 | 
				
			||||||
 | 
					        source = source[prolog_end: ]
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for e in to_substitute:
 | 
					    parser = etree.XMLParser(remove_blank_text=True)
 | 
				
			||||||
        result = result.replace(e[0], e[1])
 | 
					    xml = etree.fromstring(source, parser=parser)
 | 
				
			||||||
    
 | 
					    return prolog + etree.tostring(xml, pretty_print=False).decode()
 | 
				
			||||||
    return result
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def xpath(source: str, xpath: str) -> str:
 | 
					def xpath(source: str, xpath: str) -> str:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -330,8 +330,8 @@
 | 
				
			|||||||
    height: 300px;
 | 
					    height: 300px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.textarea-800 {
 | 
					.textarea-700 {
 | 
				
			||||||
    height: 800px;
 | 
					    height: 700px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.centered-content {
 | 
					.centered-content {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -148,24 +148,32 @@ function performRequest(endpoint, checkXML, checkTransform){
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function performFormatRequest(endpoint, checkXML, sourceId, targetId){
 | 
					function performFormatRequest(endpoint, checkXML, sourceId, targetId){
 | 
				
			||||||
 | 
					    const sourceElement = document.getElementById(sourceId);
 | 
				
			||||||
 | 
					    const targetElement = document.getElementById(targetId);
 | 
				
			||||||
 | 
					    const infoElement = document.getElementById("formatinfo");
 | 
				
			||||||
    const port = 8082;
 | 
					    const port = 8082;
 | 
				
			||||||
    var xmlData = document.getElementById(sourceId).value.trim();
 | 
					    var xmlData = sourceElement.value.trim();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var empty = false;
 | 
					    var empty = false;
 | 
				
			||||||
    if (defaultStrings.includes(xmlData) && checkXML) {
 | 
					    if (defaultStrings.includes(xmlData) && checkXML) {
 | 
				
			||||||
            document.getElementById(sourceId).style.backgroundColor = color_red;
 | 
					            sourceElement.style.backgroundColor = color_red;
 | 
				
			||||||
            xmlData = "";
 | 
					            xmlData = "";
 | 
				
			||||||
            empty = true;
 | 
					            empty = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!empty) {
 | 
					    if (!empty) {
 | 
				
			||||||
        restRequest(port, endpoint, xmlData, "").then(function(result) {
 | 
					        restRequest(port, endpoint, xmlData, "").then(function(result) {
 | 
				
			||||||
 | 
					            console.log(result);
 | 
				
			||||||
            if (result.status == "OK") {
 | 
					            if (result.status == "OK") {
 | 
				
			||||||
                document.getElementById(targetId).value = result.result;
 | 
					                targetElement.value = result.result;
 | 
				
			||||||
                document.getElementById(targetId).style.backgroundColor = null;
 | 
					                targetElement.style.backgroundColor = null;
 | 
				
			||||||
 | 
					                infoElement.innerText = ' Computed'.concat(" in ", result.time, "ms.");
 | 
				
			||||||
 | 
					                infoElement.style.color = "#30aa58";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                document.getElementById(targetId).style.backgroundColor = color_red;
 | 
					                targetElement.style.backgroundColor = color_red;
 | 
				
			||||||
 | 
					                infoElement.innerText = result.result;
 | 
				
			||||||
 | 
					                infoElement.style.color = "#aa3030";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,23 +14,34 @@
 | 
				
			|||||||
        <div id="tool" class="tool rwd-expandable">
 | 
					        <div id="tool" class="tool rwd-expandable">
 | 
				
			||||||
            <div class="tool-context">
 | 
					            <div class="tool-context">
 | 
				
			||||||
                <div class="headline">
 | 
					                <div class="headline">
 | 
				
			||||||
                    <h1>Online XML Formatter <span class="versionInfo"><span class="version-span">v0.21.37 BETA</span></span>
 | 
					                    <h1>Online XML Formatter</h1>
 | 
				
			||||||
                    </h1>
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <select name="processors" id="processors" class="hidden">
 | 
					                <select name="processors" id="processors" class="hidden">
 | 
				
			||||||
                    <option value="libxml">libXML</option>
 | 
					                    <option value="libxml">libXML</option>
 | 
				
			||||||
                </select>
 | 
					                </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <div class="display-space-between">
 | 
				
			||||||
 | 
					                    <div>
 | 
				
			||||||
 | 
					                        <b><span id="formatinfo"></span></b><br>
 | 
				
			||||||
                        <label for="xmlArea"><b>Insert your XML:</b></label>
 | 
					                        <label for="xmlArea"><b>Insert your XML:</b></label>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div>
 | 
				
			||||||
 | 
					                        <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;"
 | 
				
			||||||
 | 
					                            onclick="clearDataField()">Clear</button>
 | 
				
			||||||
 | 
					                        <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;"
 | 
				
			||||||
 | 
					                            onclick="fillDefaultXML(this)">Insert default XML</button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                <textarea id="xmlArea" name="xmlArea" rows="15"
 | 
					                <textarea id="xmlArea" name="xmlArea" rows="15"
 | 
				
			||||||
                    class="textarea-800 bordered-field vertically-resizeable max-width"
 | 
					                    class="textarea-700 bordered-field vertically-resizeable max-width"
 | 
				
			||||||
                    onblur="setDefaultContent(this, 'Insert XML here');"
 | 
					                    onblur="setDefaultContent(this, 'Insert XML here');"
 | 
				
			||||||
                    onfocus="clearDefaultContent(this, 'Insert XML here');"></textarea>
 | 
					                    onfocus="clearDefaultContent(this, 'Insert XML here');"></textarea>
 | 
				
			||||||
                <br><br>
 | 
					                <br><br>
 | 
				
			||||||
                <button id="requestButton" class="max-width block-label action-button active"
 | 
					                <button id="prettifyButton" class="max-width block-label action-button active"
 | 
				
			||||||
                    onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Prettify XML</button>
 | 
					                    onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Prettify XML</button>
 | 
				
			||||||
                <button id="requestButton" class="max-width block-label action-button active"
 | 
					                <button id="minimizeButton" class="max-width block-label action-button active"
 | 
				
			||||||
                    onclick="performFormatRequest('minimizepost', true, 'xmlArea', 'xmlArea')">Minimize XML</button>
 | 
					                    onclick="performFormatRequest('minimizepost', true, 'xmlArea', 'xmlArea')">Minimize XML</button>
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -49,105 +60,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- <script>
 | 
					 | 
				
			||||||
        function getVersion() {
 | 
					 | 
				
			||||||
            return document.getElementById("versions").value;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script> -->
 | 
					 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        function processTooltip() {
 | 
					 | 
				
			||||||
            console.log("processTooltip");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (getProcInfo() == "xalan") {
 | 
					 | 
				
			||||||
                document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0 functions";
 | 
					 | 
				
			||||||
                document.getElementById("processorTooltipInfo").innerText = "Supports XSLT 1.0";
 | 
					 | 
				
			||||||
                hideList(document.getElementsByName("collapse30"));
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0, 2.0 & 3.0 functions";
 | 
					 | 
				
			||||||
                document.getElementById("processorTooltipInfo").innerText = "Supports XSLT up to 3.0";
 | 
					 | 
				
			||||||
                showList(document.getElementsByName("collapse30"));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
    <script>
 | 
					    <script>
 | 
				
			||||||
        function getProcessor() {
 | 
					        function getProcessor() {
 | 
				
			||||||
            return document.getElementById("processors").value;
 | 
					            return "libxml";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    </script>
 | 
					
 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        function getVersion() {
 | 
					        function getVersion() {
 | 
				
			||||||
            if (getProcInfo() == "xalan") {
 | 
					            return "1.0"
 | 
				
			||||||
                return "1.0";
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                return "3.0";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        function getProcInfo() {
 | 
					 | 
				
			||||||
            var processVariables = document.getElementById("processors").value;// + "&version=" + document.getElementById("versions").value;
 | 
					 | 
				
			||||||
            return processVariables;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        var triggerList = document.getElementsByClassName("collapseTrigger");
 | 
					 | 
				
			||||||
        for (i = 0; i < triggerList.length; i++) {
 | 
					 | 
				
			||||||
            console.log("trigger connected");
 | 
					 | 
				
			||||||
            triggerList[i].addEventListener("click", function () {
 | 
					 | 
				
			||||||
                console.log("click");
 | 
					 | 
				
			||||||
                var collapsible = this.parentElement;
 | 
					 | 
				
			||||||
                var collapsibleData = this.nextElementSibling;
 | 
					 | 
				
			||||||
                if (collapsibleData.style.maxHeight > "0px") {
 | 
					 | 
				
			||||||
                    collapsibleData.style.maxHeight = "0px";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    this.classList.toggle("active", false);
 | 
					 | 
				
			||||||
                    if (!this.classList.contains("collapsibleMini")) {
 | 
					 | 
				
			||||||
                        collapsible.classList.toggle("active", false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var subLists1 = collapsibleData.getElementsByClassName("content");
 | 
					 | 
				
			||||||
                    var subLists2 = collapsibleData.getElementsByClassName("active");
 | 
					 | 
				
			||||||
                    for (j = 0; j < subLists1.length; j++) {
 | 
					 | 
				
			||||||
                        subLists1[j].style.maxHeight = "0px";
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    for (j = 0; j < subLists2.length; j++) {
 | 
					 | 
				
			||||||
                        subLists2[j].classList.toggle("active", false);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    collapsibleData.style.maxHeight = (collapsibleData.scrollHeight) + "px";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    this.classList.toggle("active", true);
 | 
					 | 
				
			||||||
                    if (!this.classList.contains("collapsibleMini")) {
 | 
					 | 
				
			||||||
                        collapsible.classList.toggle("active", true);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        var parentContent = this.closest(".content");
 | 
					 | 
				
			||||||
                        parentContent.style.maxHeight = (parentContent.scrollHeight + collapsibleData.scrollHeight) + "px";
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        function init() {
 | 
					        function init() {
 | 
				
			||||||
            //Handle clicks in whole form and set info in tooltip
 | 
					 | 
				
			||||||
            setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here');
 | 
					            setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here');
 | 
				
			||||||
            setDefaultContent(document.getElementById("transformArea"), 'Insert XSD here');
 | 
					 | 
				
			||||||
            console.log("init");
 | 
					 | 
				
			||||||
            // refreshTooltip();
 | 
					 | 
				
			||||||
            processTooltip();
 | 
					 | 
				
			||||||
            tool.addEventListener('click', event => {
 | 
					 | 
				
			||||||
                //Check if script was called from textarea or selector
 | 
					 | 
				
			||||||
                var targetID = event.target.getAttribute('id');
 | 
					 | 
				
			||||||
                if (targetID !== "processors" && targetID !== "xmlArea" && targetID !== "transformArea" && targetID !== "versions") {
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                processTooltip();
 | 
					 | 
				
			||||||
                // console.log("clock");
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    </script>
 | 
					    </script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user