From c0c83c5cdc22f97f4b3146b23fee1f7a7d1d096b Mon Sep 17 00:00:00 2001 From: j433866 Date: Fri, 22 Mar 2019 15:10:19 +0000 Subject: [PATCH] Stores inputs in memory instead of in textareas. Allow selecting multiple files. Allow drag and dropping multiple files. Clear all IO button will close all tabs. Will now spawn multiple loaderworkers simultaneously. Improve tab logic to break less and work in Firefox. --- src/web/InputWaiter.mjs | 407 +++++++++++++++++------------ src/web/LoaderWorker.js | 15 +- src/web/Manager.mjs | 20 +- src/web/html/index.html | 56 ++-- src/web/stylesheets/layout/_io.css | 32 +-- 5 files changed, 300 insertions(+), 230 deletions(-) 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 {