From 5d905387b141ee69366e01693a76854520d605e2 Mon Sep 17 00:00:00 2001 From: Nicolas Setton Date: Thu, 19 Jul 2018 03:03:35 -0400 Subject: [PATCH] Revert "Remove static files" These files are needed for the iframe version (for instance for the SPARK Pro page). This reverts commit 60f26a2fd55fef6fa70405103469098f7468ff47. --- README.md | 3 + compile_server/app/static/ace-builds | 1 + compile_server/app/static/common.css | 82 +++ compile_server/app/static/editors.js | 496 ++++++++++++++++++ compile_server/app/static/jquery-3.2.1.min.js | 4 + 5 files changed, 586 insertions(+) create mode 160000 compile_server/app/static/ace-builds create mode 100644 compile_server/app/static/common.css create mode 100644 compile_server/app/static/editors.js create mode 100644 compile_server/app/static/jquery-3.2.1.min.js diff --git a/README.md b/README.md index 1b0cc41..861ecf9 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ pip install -r REQUIREMENTS.txt # This is to initialize the django database ./manage.py migrate +# This is to get the ACE editor +cd compile_server/app/static +git clone https://github.com/ajaxorg/ace-builds.git ``` To enter the environment, to this diff --git a/compile_server/app/static/ace-builds b/compile_server/app/static/ace-builds new file mode 160000 index 0000000..68e40da --- /dev/null +++ b/compile_server/app/static/ace-builds @@ -0,0 +1 @@ +Subproject commit 68e40daf862e2bbad9d9ca76b835f919c6eb8bed diff --git a/compile_server/app/static/common.css b/compile_server/app/static/common.css new file mode 100644 index 0000000..08d1563 --- /dev/null +++ b/compile_server/app/static/common.css @@ -0,0 +1,82 @@ +div.file{ + display: none; +} + +div.editor_container{ + height: 30em; + border: 1px solid #ddd; + border-top: 0px; +} + +div.editor_container.inline{ + height: 20em; + border: 1px solid #ddd; + margin: .5em 0; +} + +div.output_line{ + color: #666; + padding-left:15px; + padding-right:3px; +} + +div.output_msg{ + color: #944; + padding-left:15px; + padding-right:3px; +} + +div.output_msg:hover{ + background-color:#fdd; +} + +div.output_msg_info{ + color: #449; + padding-left:15px; + padding-right:3px; +} + +div.output_msg_info:hover{ + background-color:#ddf; +} + + +div.output_info{ + color: #222; + padding-left:3px; + padding-right:3px; +} + +div.output_error{ + color: #822; + padding-left:3px; + padding-right:3px; +} + +div.output_success{ + color: #070; + padding-left:3px; + padding-right:3px; + font-weight:bold; +} + +div.output_area{ + font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; + margin-top: 10px; + background: #f3f3f3; +} + +div.output_row{ + margin-right: 0px; +} + +div.output_row button{ + margin-right:4px; + margin-top:2px; +} + +.read-only { + background-color: #c0c0c0; + opacity: 0.2; + position: absolute; +} diff --git a/compile_server/app/static/editors.js b/compile_server/app/static/editors.js new file mode 100644 index 0000000..ad5c996 --- /dev/null +++ b/compile_server/app/static/editors.js @@ -0,0 +1,496 @@ +// Log an error message in the output area +function output_error(output_area, message) { + var div = $('
') + div.text(message) + div.appendTo(output_area) +} + +// Reset the buttons on the editors to the "enabled" state +// Reset the count of lines already read to 0 +function reset(container, editors){ + editors.buttons.forEach(function(b){b.disabled = false;}) + container.already_read = 0; +} + +// Process the result of a check +// editors: the editors to decorate +// output_area: the div where the messages should go +// status: the exit status +// message: any message coming back from the application +// TODO: make use of message +function process_check_output(container, editors, output_area, output, status, completed, message) { + // Process the lines + + var read_lines = 0 + + output.forEach(function (l) { + read_lines++ + + // Look for lines that contain an error message + var error_found = false; + var match_found = l.match(/^([a-zA-Z._0-9-]+):(\d+):(\d+):(.+)$/) + if (match_found) { + if (match_found[4].indexOf(" info:") == 0) { + var klass = "output_msg_info"; + } + else { + var klass = "output_msg" + error_found = true; + } + } + else { + var klass = "output_line"; + } + + // Print the line in the output area + var div = $('
') + div.text(l) + div.appendTo(output_area) + + if (match_found != null) { + if (error_found) { + output_area.error_count++ + } + + // Lines that contain a sloc are clickable: + div.on('click', function (x) { + // find the corresponding editor + var basename = match_found[1] + editors.forEach(function (e) { + if (e.basename == basename) { + // Switch to the tab that contains the editor + + // TODO: this is in the case of bootstrap only + // $("#" + e.unique_id + "-tab").tab('show') + + // Jump to the corresponding line + e.gotoLine(parseInt(match_found[2]), + // looks like column numbers are indexed from 0 + parseInt(match_found[3] - 1), + true) + e.focus() + } + }) + }) + } + }) + + // Congratulations! + if (completed) { + reset(container, editors); + + if (status != 0) { + output_error(output_area, "exit status: " + status) + } else if (output_area.error_count == 0) { + var div = $('
') + div.text("Success!") + div.appendTo(output_area) + } else if (output_area.error_count == 1) { + var div = $('
') + div.text("One error.") + div.appendTo(output_area) + } else { + var div = $('
') + div.text(output_area.error_count + " errors.") + div.appendTo(output_area) + } + } + + return read_lines +} + +function get_output_from_identifier(container, editors, output_area, identifier) { + data = { + "identifier": identifier, + "already_read": container.already_read + } + $.ajax({ + url: container.example_server + "/check_output/", + data: JSON.stringify(data), + type: "POST", + dataType: "json", + contentType: 'application/json; charset=UTF-8', + }) + .done(function (json) { + read_lines = process_check_output( + container, + editors, output_area, + json.output_lines, json.status, json.completed, json.message + ) + container.already_read = container.already_read + read_lines + if (!json.completed) { + // We have not finished processing the output: call this again + setTimeout(function () { + get_output_from_identifier(container, editors, output_area, identifier) + }, 250) + } + }) + .fail(function (xhr, status, errorThrown) { + output_error(output_area, "could not download output") + console.log("Error: " + errorThrown); + console.log("Status: " + status); + console.dir(xhr); + }) + .fail(function (json) { + reset(container,editors); + output_error(output_area, json.message) + }) +} + + +// Launch a run on the given example editor +function query_operation_result(container, example_name, editors, output_area, operation_url) { + + files = [] + + // Grab the contents from actual editors + editors.forEach(function (e) { + files.push({ + 'basename': e.basename, + 'contents': e.getValue() + }) + }) + + // Grab the contents from shadow files + if (container.shadow_files){ + container.shadow_files.forEach(function (e){ + files.push({ + 'basename': e.basename, + 'contents': e.contents + }); + }); + } + + data = { + "example_name": example_name, + "files": files, + "main": container.attr("main"), + "extra_args": container.attr("extra_args"), + } + + + // request the examples + $.ajax({ + url: container.example_server + operation_url, + data: JSON.stringify(data), + type: "POST", + dataType: "json", + contentType: 'application/json; charset=UTF-8', + }) + .done(function (json) { + if (json.identifier == "") { + reset(container, editors) + output_error(output_area, json.message) + } else { + get_output_from_identifier(container, editors, output_area, json.identifier) + } + }) + .fail(function (xhr, status, errorThrown) { + // + alert("could not run the example"); + console.log("Error: " + errorThrown); + console.log("Status: " + status); + console.dir(xhr); + }) +} + + +function create_editor(resource, container, content, editors, counter) { + var the_id = "tab_" + container.attr("the_id") + "-" + counter + var div = $('
'); + var editordiv = $('
'); + editordiv.appendTo(div); + div.appendTo(content); + + // ACE editors... + var editor = ace.edit(resource.basename + the_id + '_editor'); + editor.session.setMode("ace/mode/ada"); + + // ... and their contents + editor.setValue(resource.contents); + editor.setShowPrintMargin(false); + editor.gotoLine(1); + editor.initial_contents = resource.contents; + editor.basename = resource.basename; + editor.unique_id = the_id; + + editor.setOptions({ + "highlightActiveLine": false, + }); + + // check if we are overriding db content with inline content + if (container.attr("inline")) { + $(container).children(".resource").each(function () { + if ($(this).attr("region")) { + region = $(this).attr("region"); + + // search editor content for region "region" + beginregion = editor.find("-- #region " + region); + endregion = editor.find("-- #endregion " + region); + + newRange = beginregion.clone(); + newRange.end.row = endregion.end.row; + newRange.end.column = endregion.end.column; + + textReplace = $(this).text().replace(/^\s|\s+$/g, ''); + + editor.getSession().getDocument().replace(newRange, textReplace); + $(this).text(''); + } + else { + // No region: replace the whole editor + editor.initial_contents = $(this).text(); + editor.setValue($(this).text()); + $(this).text(''); + } + }) + } + + // search for remaining region marks and remove + editor.replaceAll("", { + needle: "-- #region (.*)\n", + regExp: true + }); + editor.replaceAll("", { + needle: "-- #endregion (.*)\n", + regExp: true + }); + + // check if container is readonly + if (container.attr("readonly")) { + // remove all read only tags in the editor + editor.replaceAll("", { + needle: "-- (begin|end) readonly", + regExp: true + }); + + editor.setOption("readOnly", true); + } + + // Inline? set the editor to use exactly the vertical space it needs + if (is_inline){ + editor.setOptions({ + maxLines: editor.session.getLength() + }) + } + + // place the cursor at 1,1 + editor.selection.moveTo(0, 0); + + // clear undo stack to avoid undoing everything we just did + editor.getSession().getUndoManager().reset(); + + return editor; +} + +// Fills a
with an editable representation of an example. +// container: the
in question +// example_name: the name of the example to load + +var unique_id = 0 + +function fill_editor_from_contents(container, example_name, example_server, + resources, main) { + + is_inline = container.attr("inline") + + // First create the tabs + + if (!is_inline){ + var ul = $('