diff --git a/CHANGELOG.md b/CHANGELOG.md index fde6b8fb755fc8f8818bd1d7afd8474c18873ebf..28fdb59c94469b05ada76e904b72e56b92413f64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added (for new features, dependecies etc.) +* `ext_sss_markdown` module for pretty display of server-side scripting stdout. + See module docstring for more information. * `ext_trigger_crawler_form` module which generates a form for triggering the crawler. See module docstring for more info. * Support for deeply nested selectors in SELECT queries. diff --git a/build.properties.d/00_default.properties b/build.properties.d/00_default.properties index da4c8d0035970069b6762206477ae3b250b521c7..23b1e9ff929b030750f6cab0014f22cd0d6b7cf4 100644 --- a/build.properties.d/00_default.properties +++ b/build.properties.d/00_default.properties @@ -39,10 +39,11 @@ # overridden in the makefile in any case. ############################################################################## -# Modules enabled by default +# Modules enabled/disabled by default ############################################################################## BUILD_MODULE_EXT_PREVIEW=ENABLED BUILD_MODULE_EXT_RESOLVE_REFERENCES=ENABLED +BUILD_MODULE_EXT_SSS_MARKDOWN=DISABLED BUILD_MODULE_EXT_TRIGGER_CRAWLER_FORM=DISABLED ############################################################################## diff --git a/src/core/js/ext_sss_markdown.js b/src/core/js/ext_sss_markdown.js new file mode 100644 index 0000000000000000000000000000000000000000..21c7d3261faeb7052dbe8aa0b9fba29d88ed56d9 --- /dev/null +++ b/src/core/js/ext_sss_markdown.js @@ -0,0 +1,55 @@ +/** + * @module ext_sss_markdown + * @version 0.1 + * + * Transforms the STDOUT of server-side scripting responses from plain text to + * HTML. The STDOUT is interpreted as Markdown. + * + * Module has to be enabled via setting the build property + * `BUILD_MODULE_EXT_SSS_MARKDOWN=ENABLED`. + */ +var ext_sss_markdown = function() { + + var logger = log.getLogger("ext_sss_markdown"); + + var init = function() { + logger.trace("enter init"); + const stdout_container = $("#caosdb-stdout"); + if (stdout_container.length == 0) { + // nothing to do + return; + } + + // get text content of the STDOUT container + const text = stdout_container[0].textContent; + logger.debug("transform", text); + // interpret as markdown. + const html = markdown.textToHtml(text); + + // a little styling + stdout_container.css({padding: 10}); + + // replace plain markdown text with formatted html + stdout_container.empty(); + stdout_container.append(html); + + // hide error output container if the STDERR was empty. + var errortext = $("#caosdb-stderr").text(); + if (errortext.length == 0) { + $("#caosdb-container-stderr").hide(); + } + } + + return { + init: init, + logger: logger, + }; + +}(); + + +$(document).ready(function() { + if ("${BUILD_MODULE_EXT_SSS_MARKDOWN}" == "ENABLED") { + caosdb_modules.register(ext_sss_markdown); + } +}); diff --git a/src/core/xsl/main.xsl b/src/core/xsl/main.xsl index 52e5b4249fa85479efc69bd7d8c63de80fbb2631..d4ec6cda7bd9fee3f3e65bee6564de71fc7e49d4 100644 --- a/src/core/xsl/main.xsl +++ b/src/core/xsl/main.xsl @@ -240,6 +240,11 @@ <xsl:value-of select="concat($basepath,'webinterface/${BUILD_NUMBER}/js/ext_revisions.js')"/> </xsl:attribute> </xsl:element> + <xsl:element name="script"> + <xsl:attribute name="src"> + <xsl:value-of select="concat($basepath,'webinterface/${BUILD_NUMBER}/js/ext_sss_markdown.js')"/> + </xsl:attribute> + </xsl:element> <xsl:element name="script"> <xsl:attribute name="src"> <xsl:value-of select="concat($basepath,'webinterface/${BUILD_NUMBER}/js/ext_trigger_crawler_form.js')"/> diff --git a/test/core/index.html b/test/core/index.html index ab65f0d9546c671ad55485a187154d7a165f3e5c..50d8cbef8003d6fb9ab383f94405bcfa07270774 100644 --- a/test/core/index.html +++ b/test/core/index.html @@ -67,6 +67,7 @@ <script src="js/ext_bottom_line.js"></script> <script src="js/ext_revisions.js"></script> <script src="js/autocomplete.js"></script> + <script src="js/ext_sss_markdown.js"></script> <script src="js/ext_trigger_crawler_form.js"></script> <!--EXTENSIONS--> <script src="js/modules/webcaosdb.js.js"></script> @@ -86,6 +87,7 @@ <script src="js/modules/ext_bottom_line.js.js"></script> <script src="js/modules/ext_revisions.js.js"></script> <script src="js/modules/autocomplete.js.js"></script> + <script src="js/modules/ext_sss_markdown.js.js"></script> <script src="js/modules/ext_trigger_crawler_form.js.js"></script> </body> </html> diff --git a/test/core/js/modules/ext_sss_markdown.js.js b/test/core/js/modules/ext_sss_markdown.js.js new file mode 100644 index 0000000000000000000000000000000000000000..07199e869f56c7042a78dba6938de55e4a36e727 --- /dev/null +++ b/test/core/js/modules/ext_sss_markdown.js.js @@ -0,0 +1,77 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * ** end header + */ + + +/* MODULE ext_sss_markdown */ +QUnit.module("ext_sss_markdown", { + before: function (assert) { + markdown.init(); + ext_sss_markdown.logger.setLevel("trace"); + + const qunit_obj = this; + const done = assert.async(); + + // load test case + $.ajax({ + cache: true, + dataType: 'xml', + url: "xml/test_sss_output.xml", + }).done(function(data, textStatus, jdXHR) { + // append the test case to the QUnit module object. + qunit_obj.testCase1 = data; + }).always(function() { + done(); + }); + }, + after: function (assert) { + // clean up + $("#caosdb-stdout").remove(); + } +}); + + +QUnit.test("availability", function(assert) { + assert.ok(ext_sss_markdown, "available"); +}); + +QUnit.test("test case 1", function(assert) { + // setup + const testCase1 = this.testCase1; + const plainStdout = testCase1.evaluate("/Response/script/stdout", testCase1, null, XPathResult.STRING_TYPE, null).stringValue; + + const stdout = $('<div id="caosdb-stdout"/>').text(plainStdout); + $("body").append(stdout); + + assert.equal($("#caosdb-stdout").length, 1); + assert.equal($("#caosdb-stdout div.alert").length, 0, "no bootstrap alert"); + assert.equal($("#caosdb-stdout p").length, 0, "no html paragraphs"); + assert.equal($("#caosdb-stdout").text(), plainStdout, "only plain text"); + + ext_sss_markdown.init(); + + assert.equal($("#caosdb-stdout p").length, 3, "3 html paragraphs transformed"); + assert.equal($("#caosdb-stdout code").length, 1, "html code tag transformed"); + assert.equal($("#caosdb-stdout div.alert").text(), + "this is a bootstrap alert", "bootstrap alert transformed"); + +}); diff --git a/test/core/xml/test_sss_output.xml b/test/core/xml/test_sss_output.xml new file mode 100644 index 0000000000000000000000000000000000000000..6fad9d3edcc3436b32c0efc2a015fe5ce60a29df --- /dev/null +++ b/test/core/xml/test_sss_output.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="../webcaosdb.xsl"?> +<Response> + <script code="0"> + <stdout>here are new lines and stuff + +<code>this is a code environment</code> + + +<div class="alert alert-info">this is a bootstrap alert</div> + +last line ---</stdout> + </script> +</Response>