From 1f02b11c7463a7b7dddd9c942bfaa32ac31ec306 Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Wed, 13 Apr 2022 22:16:46 +0200 Subject: [PATCH] fix(#700): fix terminal emulator on mobile --- .../javascript/WebTerminal/HtmlTerminal.css | 16 ++++-- .../javascript/WebTerminal/HtmlTerminal.js | 53 +++++++------------ .../javascript/WebTerminal/terminal.html | 2 +- 00_Common/javascript/common.mjs | 6 ++- index.html | 2 +- 5 files changed, 37 insertions(+), 42 deletions(-) diff --git a/00_Common/javascript/WebTerminal/HtmlTerminal.css b/00_Common/javascript/WebTerminal/HtmlTerminal.css index 0150bb9a..eaeea966 100644 --- a/00_Common/javascript/WebTerminal/HtmlTerminal.css +++ b/00_Common/javascript/WebTerminal/HtmlTerminal.css @@ -17,7 +17,7 @@ overflow-y: scroll; width: 100%; - max-width: 60rem; + max-width: 640px; margin: 0 auto; } @@ -32,10 +32,7 @@ padding: 0; } -/* The "terminal" has one "prompt" element. - * This prompt is not any kind of input, but just a simple - * with an id "prompt" and a - */ +/* The "terminal" has one "prompt" input-element. */ @keyframes prompt-blink { 100% { opacity: 0; @@ -57,6 +54,15 @@ width: 0.75rem; opacity: 1; } +.terminal input#prompt { + text-transform: uppercase; + background: none; + border: none; + outline: none; + caret-color: var(--text); + color: var(--text); + font: var(--terminal-font); +} /* Terminal scrollbar */ diff --git a/00_Common/javascript/WebTerminal/HtmlTerminal.js b/00_Common/javascript/WebTerminal/HtmlTerminal.js index c8d529d9..a2aa2365 100644 --- a/00_Common/javascript/WebTerminal/HtmlTerminal.js +++ b/00_Common/javascript/WebTerminal/HtmlTerminal.js @@ -26,7 +26,7 @@ class HtmlTerminal { * @private * @type {HTMLElement} */ - #$prompt = undefined; + #$prompt; /** * Constructor @@ -45,13 +45,18 @@ class HtmlTerminal { this.$output.classList.add('terminal'); // Create a prompt element. - // This element gets added if input is needed - this.#$prompt = document.createElement("span"); + // This element gets added if input is needed. + this.#$prompt = document.createElement("input"); this.#$prompt.setAttribute("id", "prompt"); - this.#$prompt.innerText = ""; + this.#$prompt.setAttribute("type", "text"); + this.#$prompt.setAttribute("length", "50"); + this.#$prompt.addEventListener("keydown", this.#handleKey.bind(this)); - //TODO: this handler shouls be only on the propt element and only active if cursor is visible - document.addEventListener("keyup", this.#handleKey.bind(this)); + // Force focus on the promt on each click. + // This is needed for mobile support. + document.body.addEventListener('click', () => { + this.#$prompt.focus(); + }); } /** @@ -77,37 +82,16 @@ class HtmlTerminal { * @param {*} e */ #handleKey(e) { - // if no input-callback is defined + // if no input-callback is defined just return if (!this.#inputCallback) { return; } - if (e.keyCode === 13 /* ENTER */) { - // create a new line with the text input and remove the prompt - const text = this.#$prompt.innerText; - this.write(text + "\n"); - this.#$prompt.innerText = ""; + if (e.keyCode == 13) { + const text = this.#$prompt.value; + this.#$prompt.value = ''; this.#$prompt.remove(); - - // return the inputed text - this.#inputCallback(text); - - // remove the callback and the key handler - this.#inputCallback = undefined; - } else if (e.keyCode === 8 /* BACKSPACE */) { - this.#$prompt.innerText = this.#$prompt.innerText.slice(0, -1); - } else if ( - e.keyCode == 16 // "Shift" - || e.keyCode == 17 // "Control" - || e.keyCode == 20 // "CapsLock" - || !e.key.match(/^[a-z0-9!"ยง#$%&'()*+,.\/:;<=>?@\[\] ^_`{|}~-]$/i) - ) { - // ignore non-visible characters - return e; - } else { - this.#$prompt.innerHtml = ''; - const key = e.shiftKey ? e.key.toUpperCase() : e.key; - this.#$prompt.innerText = this.#$prompt.innerText + key; + this.#inputCallback(text + '\n'); } } @@ -122,7 +106,7 @@ class HtmlTerminal { } /** - * TODO: + * Create a new div and add html content. * * @public * @param {*} htmlContent @@ -189,7 +173,8 @@ class HtmlTerminal { */ input(callback) { // show prompt with a blinking prompt - this.$output.appendChild(this.#$prompt); this.#inputCallback = callback; + this.$output.appendChild(this.#$prompt); + this.#$prompt.focus(); } } diff --git a/00_Common/javascript/WebTerminal/terminal.html b/00_Common/javascript/WebTerminal/terminal.html index d9fab1d6..ae68bedb 100644 --- a/00_Common/javascript/WebTerminal/terminal.html +++ b/00_Common/javascript/WebTerminal/terminal.html @@ -1,7 +1,7 @@ Minimal node.js terminal - + BASIC Computer Games

BASIC Computer Games

\ No newline at end of file +BASIC Computer Games

BASIC Computer Games

\ No newline at end of file