diff --git a/src/web/Manager.js b/src/web/Manager.js index 270e68f8..4b89942a 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -142,7 +142,7 @@ Manager.prototype.initialiseEventListeners = function() { document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter)); document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter)); this.addMultiEventListener("#input-text", "mousedown dblclick select", this.highlighter.inputMousedown, this.highlighter); - document.querySelector("#input-file .close").addEventListener("click", this.input.closeFile.bind(this.input)); + document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input)); // Output document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); @@ -159,6 +159,8 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output); this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); + this.addDynamicListener("#output-file-slice", "click", this.output.displayFile, this.output); + document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output)); // Options document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index d8d028d0..93cc351b 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -17,7 +17,7 @@ const OutputWaiter = function(app, manager) { this.app = app; this.manager = manager; - this.file = null; + this.dishBuffer = null; }; @@ -37,8 +37,9 @@ OutputWaiter.prototype.get = function() { * @param {string|ArrayBuffer} data - The output string/HTML/ArrayBuffer * @param {string} type - The data type of the output * @param {number} duration - The length of time (ms) it took to generate the output + * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer */ -OutputWaiter.prototype.set = function(data, type, duration) { +OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { const outputText = document.getElementById("output-text"); const outputHtml = document.getElementById("output-html"); const outputFile = document.getElementById("output-file"); @@ -46,7 +47,7 @@ OutputWaiter.prototype.set = function(data, type, duration) { const inputHighlighter = document.getElementById("input-highlighter"); let scriptElements, lines, length; - this.closeFile(); + if (!preserveBuffer) this.closeFile(); switch (type) { case "html": @@ -80,7 +81,7 @@ OutputWaiter.prototype.set = function(data, type, duration) { outputHtml.innerHTML = ""; length = data.byteLength; - this.setFile(new File([data], "output.dat")); + this.setFile(data); break; case "string": default: @@ -106,10 +107,11 @@ OutputWaiter.prototype.set = function(data, type, duration) { /** * Shows file details. * - * @param {File} file + * @param {ArrayBuffer} buf */ -OutputWaiter.prototype.setFile = function(file) { - this.file = file; +OutputWaiter.prototype.setFile = function(buf) { + this.dishBuffer = buf; + const file = new File([buf], "output.dat"); // Display file overlay in output area with details const fileOverlay = document.getElementById("output-file"), @@ -124,7 +126,7 @@ OutputWaiter.prototype.setFile = function(file) { * Removes the output file and nulls its memory. */ OutputWaiter.prototype.closeFile = function() { - this.file = null; + this.dishBuffer = null; document.getElementById("output-file").style.display = "none"; }; @@ -134,8 +136,40 @@ OutputWaiter.prototype.closeFile = function() { */ OutputWaiter.prototype.downloadFile = function() { const filename = window.prompt("Please enter a filename:", "download.dat"); + const file = new File([this.dishBuffer], filename); - if (filename) FileSaver.saveAs(this.file, filename, false); + if (filename) FileSaver.saveAs(file, filename, false); +}; + + +/** + * Handler for file display events. + */ +OutputWaiter.prototype.displayFile = function() { + const startTime = new Date().getTime(), + showFileOverlay = document.getElementById("show-file-overlay"), + sliceFromEl = document.getElementById("output-file-slice-from"), + sliceToEl = document.getElementById("output-file-slice-to"), + sliceFrom = parseInt(sliceFromEl.value, 10), + sliceTo = parseInt(sliceToEl.value, 10), + str = Utils.arrayBufferToStr(this.dishBuffer.slice(sliceFrom, sliceTo)); + + showFileOverlay.style.display = "block"; + this.set(str, "string", new Date().getTime() - startTime, true); +}; + + +/** + * Handler for show file overlay events. + * + * @param {Event} e + */ +OutputWaiter.prototype.showFileOverlayClick = function(e) { + const outputFile = document.getElementById("output-file"), + showFileOverlay = e.target; + + outputFile.style.display = "block"; + showFileOverlay.style.display = "none"; }; @@ -198,8 +232,8 @@ OutputWaiter.prototype.adjustWidth = function() { * Saves the current output to a file. */ OutputWaiter.prototype.saveClick = function() { - if (!this.file) { - this.file = new File([new Uint8Array(Utils.strToCharcode(this.app.dishStr))], ""); + if (!this.dishBuffer) { + this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.app.dishStr)).buffer; } this.downloadFile(); }; @@ -227,7 +261,7 @@ OutputWaiter.prototype.copyClick = function() { let success = false; try { textarea.select(); - success = document.execCommand("copy"); + success = textarea.value && document.execCommand("copy"); } catch (err) { success = false; } diff --git a/src/web/html/index.html b/src/web/html/index.html index cd690869..a132aebd 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -184,7 +184,7 @@
- +
Name:
@@ -216,15 +216,22 @@
+
- +
Size:
-
- Display in output
- Options for how much to display + +
+ + + + +
to
+ +
diff --git a/src/web/static/images/file-128x128.png b/src/web/static/images/file-128x128.png new file mode 100644 index 00000000..005c504d Binary files /dev/null and b/src/web/static/images/file-128x128.png differ diff --git a/src/web/static/images/file-32x32.png b/src/web/static/images/file-32x32.png new file mode 100644 index 00000000..884bf485 Binary files /dev/null and b/src/web/static/images/file-32x32.png differ diff --git a/src/web/stylesheets/components/_pane.css b/src/web/stylesheets/components/_pane.css index f69984b4..fb8f309b 100644 --- a/src/web/stylesheets/components/_pane.css +++ b/src/web/stylesheets/components/_pane.css @@ -50,8 +50,10 @@ .card>img { float: left; - width: 150px; - height: 150px; + width: 128px; + height: 128px; + margin-left: 10px; + margin-top: 11px; } .card-body .close { @@ -68,4 +70,14 @@ overflow: hidden; text-overflow: ellipsis; user-select: text; -} \ No newline at end of file +} + +.card-body>.btn { + margin-bottom: 15px; + margin-top: 5px; +} + +.card input[type=number] { + padding-right: 6px; + padding-left: 6px; +} diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 519b81fc..370c2235 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -88,6 +88,14 @@ display: none; } +#show-file-overlay { + position: absolute; + right: 15px; + top: 15px; + cursor: pointer; + display: none; +} + .io-btn-group { float: right; margin-top: -4px; diff --git a/src/web/stylesheets/utils/_overrides.css b/src/web/stylesheets/utils/_overrides.css index 36069cd5..23f83bd8 100755 --- a/src/web/stylesheets/utils/_overrides.css +++ b/src/web/stylesheets/utils/_overrides.css @@ -64,7 +64,8 @@ a:focus { .alert, .modal-content, .tooltip-inner, -.dropdown-menu { +.dropdown-menu, +.input-group-addon { border-radius: 0 !important; } @@ -187,6 +188,15 @@ optgroup { color: var(--primary-font-colour); } +.input-group-addon:not(:first-child):not(:last-child) { + border-left: 0; + border-right: 0; +} + +.input-group-btn:first-child>.btn { + border-right: 0; +} + /* Bootstrap-switch */