diff --git a/src/web/InputWaiter.mjs b/src/web/InputWaiter.mjs index fa1b53e5..a459f27a 100755 --- a/src/web/InputWaiter.mjs +++ b/src/web/InputWaiter.mjs @@ -41,18 +41,25 @@ class InputWaiter { 145, //Scroll ]; - this.loaderWorker = null; - this.fileBuffer = null; + this.loaderWorkers = {}; + this.fileBuffers = {}; + this.inputs = {}; } /** - * Gets the user's input from the input textarea. + * Gets the user's input from the active input textarea. * * @returns {string} */ get() { - return this.fileBuffer || document.getElementById("input-text").value; + const textArea = document.getElementById("input-text"); + const value = textArea.value; + const inputNum = this.getActiveTab(); + if (this.fileBuffers[inputNum] && this.fileBuffers[inputNum].fileBuffer) { + return this.fileBuffers[inputNum].fileBuffer; + } + return value; } @@ -66,17 +73,21 @@ class InputWaiter { */ set(input, silent=false) { const inputText = document.getElementById("input-text"); + const inputNum = this.getActiveTab(); if (input instanceof File) { this.setFile(input); inputText.value = ""; this.setInputInfo(input.size, null); + this.displayTabInfo(input); } else { inputText.value = input; - this.closeFile(); + this.inputs[inputNum] = input; + this.closeFile(inputNum); if (!silent) window.dispatchEvent(this.manager.statechange); const lines = input.length < (this.app.options.ioDisplayThreshold * 1024) ? input.count("\n") + 1 : null; this.setInputInfo(input.length, lines); + this.displayTabInfo(input); } } @@ -88,18 +99,17 @@ class InputWaiter { */ setFile(file) { // Display file overlay in input area with details - const fileOverlay = document.getElementById("input-file"), - fileName = document.getElementById("input-file-name"), - fileSize = document.getElementById("input-file-size"), - fileType = document.getElementById("input-file-type"), - fileLoaded = document.getElementById("input-file-loaded"); + const inputNum = this.getActiveTab(); - this.fileBuffer = new ArrayBuffer(); - fileOverlay.style.display = "block"; - fileName.textContent = file.name; - fileSize.textContent = file.size.toLocaleString() + " bytes"; - fileType.textContent = file.type || "unknown"; - fileLoaded.textContent = "0%"; + this.fileBuffers[inputNum] = { + fileBuffer: new ArrayBuffer(), + name: file.name, + size: file.size.toLocaleString(), + type: file.type || "unknown", + loaded: "0%" + }; + + this.setFileInfo(this.fileBuffers[inputNum]); } @@ -122,6 +132,26 @@ class InputWaiter { } document.getElementById("input-info").innerHTML = msg; + + } + + /** + * Displays information about the input file. + * + * @param fileObj + */ + setFileInfo(fileObj) { + const fileOverlay = document.getElementById("input-file"), + fileName = document.getElementById("input-file-name"), + fileSize = document.getElementById("input-file-size"), + fileType = document.getElementById("input-file-type"), + fileLoaded = document.getElementById("input-file-loaded"); + + fileOverlay.style.display = "block"; + fileName.textContent = fileObj.name; + fileSize.textContent = fileObj.size + " bytes"; + fileType.textContent = fileObj.type; + fileLoaded.textContent = fileObj.loaded; } @@ -134,20 +164,23 @@ class InputWaiter { */ inputChange(e) { // Ignore this function if the input is a File - if (this.fileBuffer) return; + const inputNum = this.getActiveTab(); + if (this.fileBuffers[inputNum]) return; // Remove highlighting from input and output panes as the offsets might be different now - this.manager.highlighter.removeHighlights(); + // this.manager.highlighter.removeHighlights(); // Reset recipe progress as any previous processing will be redundant now this.app.progress = 0; // Update the input metadata info const inputText = this.get(); + this.inputs[inputNum] = inputText; const lines = inputText.length < (this.app.options.ioDisplayThreshold * 1024) ? inputText.count("\n") + 1 : null; this.setInputInfo(inputText.length, lines); + this.displayTabInfo(inputText); if (e && this.badKeys.indexOf(e.keyCode) < 0) { // Fire the statechange event as the input has been modified @@ -178,7 +211,7 @@ class InputWaiter { this.loaderWorker = new LoaderWorker(); this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); - this.loaderWorker.postMessage({"file": file}); + this.loaderWorker.postMessage({"file": file, "inputNum": this.getActiveTab()}); this.set(file); return false; } @@ -211,8 +244,7 @@ class InputWaiter { inputDragleave(e) { e.stopPropagation(); e.preventDefault(); - document.getElementById("input-text").classList.remove("dropping-file"); - document.getElementById("input-file").classList.remove("dropping-file"); + e.target.closest("#input-text,#input-file").classList.remove("dropping-file"); } @@ -230,20 +262,24 @@ class InputWaiter { e.stopPropagation(); e.preventDefault(); - const file = e.dataTransfer.files[0]; const text = e.dataTransfer.getData("Text"); - document.getElementById("input-text").classList.remove("dropping-file"); - document.getElementById("input-file").classList.remove("dropping-file"); + e.target.closest("#input-text,#input-file").classList.remove("dropping-file"); if (text) { - this.closeFile(); + this.closeFile(this.getActiveTab()); this.set(text); return; } - if (file) { - this.loadFile(file); + if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { + for (let i = 0; i < e.dataTransfer.files.length; i++) { + const file = e.dataTransfer.files[i]; + if (i !== 0) { + this.addTab(); + } + this.loadFile(file, this.getActiveTab()); + } } } @@ -255,8 +291,15 @@ class InputWaiter { */ inputOpen(e) { e.preventDefault(); - const file = e.srcElement.files[0]; - this.loadFile(file); + + // TODO : CHANGE THIS TO HANDLE MULTIPLE FILES + for (let i = 0; i < e.srcElement.files.length; i++) { + const file = e.srcElement.files[i]; + if (i !== 0) { + this.addTab(); + } + this.loadFile(file, this.getActiveTab()); + } } @@ -267,9 +310,17 @@ class InputWaiter { */ handleLoaderMessage(e) { const r = e.data; + let inputNum; + const tabNum = this.getActiveTab(); + if (r.hasOwnProperty("inputNum")) { + inputNum = r.inputNum; + } if (r.hasOwnProperty("progress")) { - const fileLoaded = document.getElementById("input-file-loaded"); - fileLoaded.textContent = r.progress + "%"; + this.fileBuffers[inputNum].loaded = r.progress + "%"; + if (tabNum === inputNum) { + const fileLoaded = document.getElementById("input-file-loaded"); + fileLoaded.textContent = r.progress + "%"; + } } if (r.hasOwnProperty("error")) { @@ -278,7 +329,7 @@ class InputWaiter { if (r.hasOwnProperty("fileBuffer")) { log.debug("Input file loaded"); - this.fileBuffer = r.fileBuffer; + this.fileBuffers[inputNum].fileBuffer = r.fileBuffer; this.displayFilePreview(); window.dispatchEvent(this.manager.statechange); } @@ -289,13 +340,14 @@ class InputWaiter { * Shows a chunk of the file in the input behind the file overlay. */ displayFilePreview() { + const inputNum = this.getActiveTab(); const inputText = document.getElementById("input-text"), - fileSlice = this.fileBuffer.slice(0, 4096); + fileSlice = this.fileBuffers[inputNum].fileBuffer.slice(0, 4096); inputText.style.overflow = "hidden"; inputText.classList.add("blur"); inputText.value = Utils.printable(Utils.arrayBufferToStr(fileSlice)); - if (this.fileBuffer.byteLength > 4096) { + if (this.fileBuffers[inputNum].fileBuffer.byteLength > 4096) { inputText.value += "[truncated]..."; } } @@ -304,9 +356,9 @@ class InputWaiter { /** * Handler for file close events. */ - closeFile() { - if (this.loaderWorker) this.loaderWorker.terminate(); - this.fileBuffer = null; + closeFile(inputNum) { + if (this.loaderWorkers[inputNum]) this.loaderWorkers[inputNum].terminate(); + delete this.fileBuffers[inputNum]; document.getElementById("input-file").style.display = "none"; const inputText = document.getElementById("input-text"); inputText.style.overflow = "auto"; @@ -318,18 +370,18 @@ class InputWaiter { * Loads a file into the input. * * @param {File} file + * @param {string} inputNum */ - loadFile(file) { - if (file) { - this.closeFile(); - this.loaderWorker = new LoaderWorker(); - this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); - this.loaderWorker.postMessage({"file": file}); + loadFile(file, inputNum) { + if (file && inputNum) { + this.closeFile(inputNum); + this.loaderWorkers[inputNum] = new LoaderWorker(); + this.loaderWorkers[inputNum].addEventListener("message", this.handleLoaderMessage.bind(this)); + this.loaderWorkers[inputNum].postMessage({"file": file, "inputNum": inputNum}); this.set(file); } } - /** * Handler for clear IO events. * Resets the input, output and info areas. @@ -337,7 +389,7 @@ class InputWaiter { * @fires Manager#statechange */ clearIoClick() { - this.closeFile(); + this.closeFile(this.getActiveTab()); this.manager.output.closeFile(); this.manager.highlighter.removeHighlights(); document.getElementById("input-text").value = ""; @@ -350,10 +402,38 @@ class InputWaiter { } /** - * Handler for adding a new input tab. + * Handler for clear all IO events. + * Resets the input, output and info areas. * + * @fires Manager#statechange */ - addTab() { + clearAllIoClick() { + // TODO: Close all tabs here + const tabs = document.getElementById("input-tabs").getElementsByTagName("li"); + for (let i = tabs.length - 1; i >= 0; i--) { + const tabItem = tabs.item(i); + this.closeFile(this.getActiveTab(tabItem.id.replace("input-tab-", ""))); + this.removeTab(tabItem); + } + this.manager.output.closeFile(); + // this.manager.highlighter.removeHighlights(); + const inputNum = this.getActiveTab(); + document.getElementById(`input-tab-${inputNum}`).firstElementChild.innerText = "New Tab"; + document.getElementById("input-text").value = ""; + document.getElementById("output-text").value = ""; + document.getElementById("input-info").innerHTML = ""; + document.getElementById("output-info").innerHTML = ""; + document.getElementById("input-selection-info").innerHTML = ""; + document.getElementById("output-selection-info").innerHTML = ""; + window.dispatchEvent(this.manager.statechange); + } + + /** + * Function to create a new tab + * + * @param {boolean} changeTab + */ + addTab(changeTab = true) { const tabWrapper = document.getElementById("input-tabs"); const tabsList = tabWrapper.children[0]; const lastTabNum = tabsList.lastElementChild.id.replace("input-tab-", ""); @@ -361,21 +441,17 @@ class InputWaiter { tabWrapper.style.display = "block"; - // Resize highlighter - // document.getElementById("input-highlighter").style.height = "calc(100% - var(--tab-height) - var(--title-height))"; + document.getElementById("input-wrapper").style.height = "calc(100% - var(--tab-height) - var(--title-height))"; + document.getElementById("input-file").style.height = "calc(100% - var(--tab-height) - var(--title-height))"; - const activeTabElements = document.getElementsByClassName("active-input-tab"); - for (let i = 0; i < activeTabElements.length; i++) { - activeTabElements.item(i).classList.remove("active-input-tab"); - } + this.inputs[newTabNum.toString()] = ""; const newTab = document.createElement("li"); newTab.id = `input-tab-${newTabNum}`; - newTab.classList.add("active-input-tab"); const newTabContent = document.createElement("div"); newTabContent.classList.add("input-tab-content"); - newTabContent.innerText = `Tab ${newTabNum}`; + newTabContent.innerText = "New Tab"; const newTabCloseBtn = document.createElement("button"); newTabCloseBtn.className = "btn btn-primary bmd-btn-icon btn-close-tab"; @@ -391,72 +467,50 @@ class InputWaiter { tabsList.appendChild(newTab); - const multiWrapper = document.getElementById("multi-input-wrapper"); - - const activeAreaElements = document.getElementsByClassName("active-input-area"); - for (let i = 0; i < activeAreaElements.length; i++) { - activeAreaElements.item(i).classList.remove("active-input-area"); + if (changeTab) { + this.changeTab(newTabContent); } + } - const newTextAreaWrapper = document.createElement("div"); - newTextAreaWrapper.className = "textarea-wrapper no-select input-wrapper active-input-area"; - newTextAreaWrapper.id = `tab-input-area-${newTabNum}`; + /** + * Function to remove a tab + * + * @param {Element} tabLiItem + */ + removeTab(tabLiItem) { + const tabList= tabLiItem.parentElement; + if (tabList.children.length > 1) { + if (tabLiItem.classList.contains("active-input-tab")) { + if (tabLiItem.previousElementSibling) { + this.changeTab(tabLiItem.previousElementSibling.firstElementChild); - const newTextArea = document.createElement("textarea"); - newTextArea.id = `input-text-${newTabNum}`; - newTextArea.spellcheck = "false"; - newTextArea.classList.add("input-text"); + window.dispatchEvent(this.manager.statechange); + } else if (tabLiItem.nextElementSibling) { + this.changeTab(tabLiItem.nextElementSibling.firstElementChild); - const newFileArea = document.createElement("div"); - newFileArea.id = `input-file-${newTabNum}`; - newFileArea.classList.add("input-file"); + window.dispatchEvent(this.manager.statechange); + } + } + const tabNum = tabLiItem.id.replace("input-tab-", ""); - const newFileOverlay = document.createElement("div"); - newFileOverlay.classList.add("file-overlay"); + delete this.fileBuffers[tabNum]; + delete this.inputs[tabNum]; - const newFileWrapper = document.createElement("div"); - newFileWrapper.style.position = "relative"; - newFileWrapper.style.height = "100%"; + tabList.removeChild(tabLiItem); + } else { + const tabNum = tabLiItem.id.replace("input-tab-", ""); + delete this.fileBuffers[tabNum]; + this.inputs[tabNum] = ""; + document.getElementById("input-text").value = ""; + tabLiItem.firstElementChild.innerText = "New Tab"; + } + if (tabList.children.length === 1) { + document.getElementById("input-tabs").style.display = "none"; - const newFileCard = document.createElement("div"); - newFileCard.className = "io-card card"; + document.getElementById("input-wrapper").style.height = "calc(100% - var(--title-height))"; + document.getElementById("input-file").style.height = "calc(100% - var(--title-height))"; - const newFileThumb = document.createElement("img"); - newFileThumb["aria-hidden"] = "true"; - newFileThumb.src = require("./static/images/file-128x128.png"); - newFileThumb.alt = "File icon"; - newFileThumb.id = `input-file-thumbnail-${newTabNum}`; - - const newFileCardBody = document.createElement("div"); - newFileCardBody.class = "card-body"; - - const newFileCloseButton = document.createElement("button"); - newFileCloseButton.type = "button"; - newFileCloseButton.class = "close"; - newFileCloseButton.id = `input-file-close-${newTabNum}`; - newFileCloseButton.innerHTML = "×"; - - newFileCardBody.appendChild(newFileCloseButton); - - const cardInfo = ` - Name:
- Size:
- Type:
- Loaded: `; - - newFileCardBody.innerHTML = newFileCardBody.innerHTML + cardInfo; - - newFileCard.appendChild(newFileThumb); - newFileCard.appendChild(newFileCardBody); - newFileWrapper.appendChild(newFileCard); - newFileArea.appendChild(newFileOverlay); - newFileArea.appendChild(newFileWrapper); - - newTextAreaWrapper.appendChild(newTextArea); - newTextAreaWrapper.appendChild(newFileArea); - multiWrapper.appendChild(newTextAreaWrapper); - - // file inputs! + } } /** @@ -464,72 +518,97 @@ class InputWaiter { * * @param {event} mouseEvent */ - removeTab(mouseEvent) { - if (!mouseEvent.path) { + removeTabClick(mouseEvent) { + if (!mouseEvent.srcElement) { return; } - const closeBtn = mouseEvent.path[1]; - const liItem = closeBtn.parentElement; - const tabList = liItem.parentElement; - if (tabList.children.length > 1) { - if (liItem.classList.contains("active-input-tab")) { - // If current tab is active, change the active tab and input to another tab - let newActiveAreaId; - if (liItem.previousElementSibling) { - liItem.previousElementSibling.classList.add("active-input-tab"); - const newActiveTabNum = liItem.previousElementSibling.id.replace("input-tab-", ""); - newActiveAreaId = `tab-input-area-${newActiveTabNum}`; - } else if (liItem.nextElementSibling) { - liItem.nextElementSibling.classList.add("active-input-tab"); - const newActiveTabNum = liItem.nextElementSibling.id.replace("input-tab-", ""); - newActiveAreaId = `tab-input-area-${newActiveTabNum}`; - } + this.removeTab(mouseEvent.srcElement.parentElement.parentElement); - if (newActiveAreaId) { - document.getElementById(newActiveAreaId).classList.add("active-input-area"); - } - } - const tabNum = liItem.id.replace("input-tab-", ""); - const multiInputArea = document.getElementById("multi-input-wrapper"); - const inputAreaId = `tab-input-area-${tabNum}`; - const inputArea = document.getElementById(inputAreaId); - - tabList.removeChild(liItem); - multiInputArea.removeChild(inputArea); - } - if (tabList.children.length === 1) { - document.getElementById("input-tabs").style.display = "none"; - // document.getElementById("input-highlighter").style.height = "calc(100% - var(--title-height))"; - } } /** - * Handler for changing tabs + * Change the active tab to tabElement + * + * @param {Element} tabElement The tab element to change to + */ + changeTab(tabElement) { + const liItem = tabElement.parentElement; + const newTabNum = liItem.id.replace("input-tab-", ""); + const currentTabNum = this.getActiveTab(); + const inputText = document.getElementById("input-text"); + + document.getElementById(`input-tab-${currentTabNum}`).classList.remove("active-input-tab"); + liItem.classList.add("active-input-tab"); + + this.inputs[currentTabNum] = inputText.value; + + if (this.fileBuffers[newTabNum]) { + const fileObj = this.fileBuffers[newTabNum]; + this.setInputInfo(fileObj.size, 1); + this.setFileInfo(fileObj); + this.displayFilePreview(); + } else { + inputText.value = this.inputs[newTabNum]; + inputText.style.overflow = "auto"; + inputText.classList.remove("blur"); + + this.inputChange(null); + document.getElementById("input-file").style.display = "none"; + } + + window.dispatchEvent(this.manager.statechange); + + } + + /** + * Handler for changing tabs event * * @param {event} mouseEvent */ - changeTab(mouseEvent) { - if (!mouseEvent.path) { + changeTabClick(mouseEvent) { + if (!mouseEvent.srcElement) { return; } - const tabContent = mouseEvent.path[0]; - const liItem = tabContent.parentElement; - const tabNum = liItem.id.replace("input-tab-", ""); + this.changeTab(mouseEvent.srcElement); - const activeTabsList = document.getElementsByClassName("active-input-tab"); - for (let i = 0; i < activeTabsList.length; i++) { - activeTabsList.item(i).classList.remove("active-input-tab"); + } + + /** + * Display input information in the tab header + * + * @param {string|File} input + */ + displayTabInfo(input) { + const activeTabs = document.getElementsByClassName("active-input-tab"); + if (activeTabs.length > 0) { + const activeTabContent = activeTabs.item(0).getElementsByClassName("input-tab-content")[0]; + if (input instanceof File) { + activeTabContent.innerText = input.name; + } else { + if (input.length > 0) { + activeTabContent.innerText = input.slice(0, 100); + } else { + activeTabContent.innerText = "New Tab"; + } + } } - const activeAreaList = document.getElementsByClassName("active-input-area"); - for (let i = 0; i < activeAreaList.length; i++) { - activeAreaList.item(i).classList.remove("active-input-area"); + } + + /** + * Gets the number of the current active tab + * + * @returns {string} + */ + getActiveTab() { + const activeTabs = document.getElementsByClassName("active-input-tab"); + if (activeTabs.length > 0) { + const activeTab = activeTabs.item(0); + const activeTabNum = activeTab.id.replace("input-tab-", ""); + return activeTabNum; + } else { + throw "Could not find an active tab"; } - liItem.classList.add("active-input-tab"); - - const newActiveAreaId = `tab-input-area-${tabNum}`; - document.getElementById(newActiveAreaId).classList.add("active-input-area"); - } } diff --git a/src/web/LoaderWorker.js b/src/web/LoaderWorker.js index 076e0e7d..7e7d1c3e 100755 --- a/src/web/LoaderWorker.js +++ b/src/web/LoaderWorker.js @@ -12,8 +12,10 @@ */ self.addEventListener("message", function(e) { const r = e.data; - if (r.hasOwnProperty("file")) { - self.loadFile(r.file); + if (r.hasOwnProperty("file") && (r.hasOwnProperty("inputNum"))) { + self.loadFile(r.file, r.inputNum); + } else if (r.hasOwnProperty("file")) { + self.loadFile(r.file, ""); } }); @@ -22,8 +24,9 @@ self.addEventListener("message", function(e) { * Loads a file object into an ArrayBuffer, then transfers it back to the parent thread. * * @param {File} file + * @param {string} inputNum */ -self.loadFile = function(file) { +self.loadFile = function(file, inputNum) { const reader = new FileReader(); const data = new Uint8Array(file.size); let offset = 0; @@ -31,11 +34,11 @@ self.loadFile = function(file) { const seek = function() { if (offset >= file.size) { - self.postMessage({"progress": 100}); - self.postMessage({"fileBuffer": data.buffer}, [data.buffer]); + self.postMessage({"progress": 100, "inputNum": inputNum}); + self.postMessage({"fileBuffer": data.buffer, "inputNum": inputNum}, [data.buffer]); return; } - self.postMessage({"progress": Math.round(offset / file.size * 100)}); + self.postMessage({"progress": Math.round(offset / file.size * 100), "inputNum": inputNum}); const slice = file.slice(offset, offset + CHUNK_SIZE); reader.readAsArrayBuffer(slice); }; diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index 572e9c32..eb7e7eea 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -142,22 +142,22 @@ class Manager { this.addDynamicListener("textarea.arg", "drop", this.recipe.textArgDrop, this.recipe); // Input - // this.addMultiEventListener("#input-text", "keyup", this.input.inputChange, this.input); - // this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input); + this.addMultiEventListener("#input-text", "keyup", this.input.inputChange, this.input); + this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input); document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app)); - document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input)); + document.getElementById("clr-io").addEventListener("click", this.input.clearAllIoClick.bind(this.input)); this.addListeners("#open-file", "change", this.input.inputOpen, this.input); - // this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input); - // this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input); - // this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input); + this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input); + this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input); + this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input); // document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter)); // 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.clearIoClick.bind(this.input)); - document.getElementById("btn-new-tab").addEventListener("click", this.input.addTab); - this.addDynamicListener("#input-tabs ul li .btn-close-tab i", "click", this.input.removeTab, this.input); - this.addDynamicListener("#input-tabs ul li .input-tab-content", "click", this.input.changeTab, this.input); + document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input)); + document.getElementById("btn-new-tab").addEventListener("click", this.input.addTab.bind(this.input)); + this.addDynamicListener("#input-tabs ul li .btn-close-tab i", "click", this.input.removeTabClick, this.input); + this.addDynamicListener("#input-tabs ul li .input-tab-content", "click", this.input.changeTabClick, this.input); // Output document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); diff --git a/src/web/html/index.html b/src/web/html/index.html index 4c92a1ec..a70a3d3f 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -234,7 +234,7 @@ - - - -
-
- -
-
-
-
- -
- - Name:
- Size:
- Type:
- Loaded: -
+ +
+
+ +
+
+
+
+ +
+ + Name:
+ Size:
+ Type:
+ Loaded:
diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index d5e5bc3d..77f11403 100755 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -6,7 +6,7 @@ * @license Apache-2.0 */ -.input-text, +#input-text, #output-text, #output-html { position: relative; @@ -30,12 +30,6 @@ -moz-padding-start: 1px; /* Fixes bug in Firefox */ } -#multi-input-wrapper { - display: flex; - flex-direction: column; - height: calc(100% - var(--title-height)); -} - #input-tabs ul { list-style: none; background-color: var(--title-background-colour); @@ -69,16 +63,21 @@ .active-input-tab { font-weight: bold; + background-color: var(--primary-background-colour); } .input-tab-content { width: 100%; + max-width: 100%; padding-left: 5px; padding-right: 5px; padding-top: 10px; padding-bottom: 10px; height: var(--tab-height); vertical-align: middle; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .btn-close-tab { @@ -89,7 +88,7 @@ .textarea-wrapper { width: 100%; - height: 100%; + height: calc(100% - var(--title-height)); box-sizing: border-box; overflow: hidden; pointer-events: auto; @@ -102,21 +101,13 @@ color: var(--fixed-width-font-colour); } -.input-wrapper { - display: none; -} - -.active-input-area { - display: inline-block; -} - #input-highlighter, #output-highlighter { position: absolute; left: 0; - bottom: 0; + top: 0; width: 100%; - height: calc(100% - var(--title-height)); + height: 100%; padding: 3px; margin: 0; overflow: hidden; @@ -167,13 +158,13 @@ transition: all 0.5s ease; } -.input-file, +#input-file, #output-file { position: absolute; left: 0; bottom: 0; width: 100%; - height: calc(100% - var(--tab-height) - var(--title-height)); + height: calc(100% - var(--title-height)); display: none; } @@ -213,7 +204,6 @@ .dropping-file { border: 5px dashed var(--drop-file-border-colour) !important; - margin: -5px; } #stale-indicator {