diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 604b7b8c..fec3b9be 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -407,6 +407,7 @@ class Utils { */ static strToArrayBuffer(str) { log.debug("Converting string to array buffer"); + if (!str) return new ArrayBuffer; const arr = new Uint8Array(str.length); let i = str.length, b; while (i--) { @@ -434,6 +435,7 @@ class Utils { */ static strToUtf8ArrayBuffer(str) { log.debug("Converting string to UTF8 array buffer"); + if (!str) return new ArrayBuffer; const utf8Str = utf8.encode(str); if (str.length !== utf8Str.length) { @@ -464,6 +466,7 @@ class Utils { */ static strToByteArray(str) { log.debug("Converting string to byte array"); + if (!str) return []; const byteArray = new Array(str.length); let i = str.length, b; while (i--) { @@ -491,6 +494,7 @@ class Utils { */ static strToUtf8ByteArray(str) { log.debug("Converting string to UTF8 byte array"); + if (!str) return []; const utf8Str = utf8.encode(str); if (str.length !== utf8Str.length) { @@ -520,6 +524,7 @@ class Utils { */ static strToCharcode(str) { log.debug("Converting string to charcode"); + if (!str) return []; const charcode = []; for (let i = 0; i < str.length; i++) { @@ -555,6 +560,7 @@ class Utils { */ static byteArrayToUtf8(byteArray) { log.debug("Converting byte array to UTF8"); + if (!byteArray || !byteArray.length) return ""; const str = Utils.byteArrayToChars(byteArray); try { const utf8Str = utf8.decode(str); @@ -588,7 +594,7 @@ class Utils { */ static byteArrayToChars(byteArray) { log.debug("Converting byte array to chars"); - if (!byteArray) return ""; + if (!byteArray || !byteArray.length) return ""; let str = ""; // String concatenation appears to be faster than an array join for (let i = 0; i < byteArray.length;) { @@ -611,6 +617,7 @@ class Utils { */ static arrayBufferToStr(arrayBuffer, utf8=true) { log.debug("Converting array buffer to str"); + if (!arrayBuffer || !arrayBuffer.byteLength) return ""; const arr = new Uint8Array(arrayBuffer); return utf8 ? Utils.byteArrayToUtf8(arr) : Utils.byteArrayToChars(arr); } diff --git a/src/web/waiters/InputWaiter.mjs b/src/web/waiters/InputWaiter.mjs index 000940a4..86ad9873 100644 --- a/src/web/waiters/InputWaiter.mjs +++ b/src/web/waiters/InputWaiter.mjs @@ -997,7 +997,6 @@ class InputWaiter { this.setupInputWorker(); this.manager.worker.setupChefWorker(); this.addInput(true); - this.bakeAll(); // Fire the statechange event as the input has been modified window.dispatchEvent(this.manager.statechange); diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index f0b03d72..a247375e 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -49,6 +49,8 @@ class OutputWaiter { html: "", changed: false }; + // Hold a copy of the currently displayed output so that we don't have to update it unnecessarily + this.currentOutputCache = null; this.outputChrEnc = 0; this.initEditor(); @@ -170,9 +172,26 @@ class OutputWaiter { /** * Sets the value of the current output - * @param {string} data + * @param {string|ArrayBuffer} data */ setOutput(data) { + // Don't do anything if the output hasn't changed + if (data === this.currentOutputCache) return; + this.currentOutputCache = data; + + // If data is an ArrayBuffer, convert to a string in the correct character encoding + if (data instanceof ArrayBuffer) { + if (this.outputChrEnc === 0) { + data = Utils.arrayBufferToStr(data); + } else { + try { + data = cptable.utils.decode(this.outputChrEnc, new Uint8Array(data)); + } catch (err) { + data = err; + } + } + } + // Turn drawSelection back on this.outputEditorView.dispatch({ effects: this.outputEditorConf.drawSelection.reconfigure( @@ -508,28 +527,7 @@ class OutputWaiter { this.setHTMLOutput(output.data.result); break; - case "ArrayBuffer": { - this.outputTextEl.style.display = "block"; - outputFile.style.display = "none"; - - this.clearHTMLOutput(); - - let outputVal = ""; - if (this.outputChrEnc === 0) { - outputVal = Utils.arrayBufferToStr(output.data.result); - } else { - try { - outputVal = cptable.utils.decode(this.outputChrEnc, new Uint8Array(output.data.result)); - } catch (err) { - outputVal = err; - } - } - - this.setOutput(outputVal); - - // this.setFile(await this.getDishBuffer(output.data.dish), activeTab); - break; - } + case "ArrayBuffer": case "string": default: this.outputTextEl.style.display = "block"; @@ -1136,7 +1134,8 @@ class OutputWaiter { * @param {number} inputNum */ async displayTabInfo(inputNum) { - if (!this.outputExists(inputNum)) return; + // Don't display anything if there are no, or only one, tabs + if (!this.outputExists(inputNum) || Object.keys(this.outputs).length <= 1) return; const dish = this.getOutputDish(inputNum); let tabStr = "";