mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
fix html terminal to support linebreaks inside lines
This commit is contained in:
@@ -96,9 +96,18 @@ class HtmlTerminal {
|
||||
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 = '';
|
||||
this.#$prompt.innerText = this.#$prompt.innerText + e.key;
|
||||
const key = e.shiftKey ? e.key.toUpperCase() : e.key;
|
||||
this.#$prompt.innerText = this.#$prompt.innerText + key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,27 +144,23 @@ class HtmlTerminal {
|
||||
* @param {string} text
|
||||
*/
|
||||
write(text) {
|
||||
if (text.match(/^\n*$/)) {
|
||||
// empty new line
|
||||
text.match(/\n/g).forEach(() => {
|
||||
const $br = document.createElement("br");
|
||||
this.$output.appendChild($br);
|
||||
});
|
||||
} else if (text && text.length && text.includes("\n")) {
|
||||
if (!text || text.length <= 0) {
|
||||
// empty line
|
||||
this.$output.appendChild(document.createElement("br"));
|
||||
} else if (text.endsWith("\n")) {
|
||||
// single line with linebrank
|
||||
const $lineNode = this.#newLine(text);
|
||||
this.$output.appendChild(this.#newLine(text));
|
||||
this.$output.appendChild(document.createElement("br"));
|
||||
} else if (text.includes("\n")) {
|
||||
// multible lines
|
||||
const lines = text.split("\n");
|
||||
lines.forEach((line) => {
|
||||
if (line.length === 0 || line.match(/^\s*$/)) {
|
||||
this.$output.appendChild(document.createElement("br"));
|
||||
} else {
|
||||
const $lineNode = this.#newLine(line);
|
||||
this.$output.appendChild($lineNode);
|
||||
//this.$node.appendChild(document.createElement("br"));
|
||||
}
|
||||
this.write(line);
|
||||
});
|
||||
} else if (text && text.length) {
|
||||
// simple line
|
||||
const $lineNode = this.#newLine(text);
|
||||
this.$output.appendChild($lineNode);
|
||||
} else {
|
||||
// single line
|
||||
this.$output.appendChild(this.#newLine(text));
|
||||
}
|
||||
|
||||
// scroll to the buttom of the page
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
import { print, println, tab, input } from '../common.mjs';
|
||||
|
||||
async function main() {
|
||||
println(tab(20), "Minimal node.js terminal 2");
|
||||
println("");
|
||||
println(tab(30), "Minimal node.js terminal emulator");
|
||||
println();
|
||||
println(tab(0), "tab 0");
|
||||
println(tab(5), "tab 5");
|
||||
println(tab(10), "tab 10");
|
||||
println(tab(15), "tab 15");
|
||||
println(tab(20), "tab 20");
|
||||
println(tab(25), "tab 25");
|
||||
println("");
|
||||
println("1234567890", " ", "ABCDEFGHIJKLMNOPRSTUVWXYZ");
|
||||
println("");
|
||||
println();
|
||||
println("1234567890", " _ ", "ABCDEFGHIJKLMNOPRSTUVWXYZ");
|
||||
println();
|
||||
print("\nHallo"); print(" "); print("Welt!\n");
|
||||
println("");
|
||||
print("Line 1\nLine 2\nLine 3\nLine 4");
|
||||
println("");
|
||||
println("Line 1\nLine 2\nLine 3\nLine 4");
|
||||
println("----------------------------------------------");
|
||||
|
||||
const value = await input("input");
|
||||
println(`input value was "${value}"`);
|
||||
|
||||
@@ -1,21 +1,67 @@
|
||||
|
||||
/**
|
||||
* Print multible strings to the terminal.
|
||||
* Strings get concatinated (add together) without any space betweent them.
|
||||
* There will be no newline at the end!
|
||||
* If you want a linebrak at the end use `println`.
|
||||
*
|
||||
* This function is normally used if you want to put something on the screen
|
||||
* and later add some content to the same line.
|
||||
* For normal output (similar to `console.log`) use `println`!
|
||||
*
|
||||
* @param {...string} messages - the strings to print to the terminal.
|
||||
*/
|
||||
export function print(...messages) {
|
||||
process.stdout.write(messages.join(""));
|
||||
process.stdout.write(messages.join(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multible strings as a new line to the terminal.
|
||||
* Strings get concatinated (add together) without any space betweent them.
|
||||
* There will be a newline at the end!
|
||||
* If you want the terminal to stay active on the current line use `print`.
|
||||
*
|
||||
* @param {...any} messages - the strings to print to the terminal.
|
||||
*/
|
||||
export function println(...messages) {
|
||||
process.stdout.write(messages.join("") + "\n");
|
||||
process.stdout.write(messages.join("") + "\n");
|
||||
}
|
||||
|
||||
export function tab(count) {
|
||||
return " ".repeat(count);
|
||||
/**
|
||||
* Create an empty string with a given length
|
||||
*
|
||||
* @param {number} length - the length of the string in space-characters.
|
||||
* @returns {string} returns a string containing only ampty spaces with a length of `count`.
|
||||
*/
|
||||
export function tab(length) {
|
||||
return " ".repeat(length);
|
||||
}
|
||||
|
||||
export async function input(message = "") {
|
||||
process.stdout.write(message + ' ');
|
||||
return new Promise(resolve => {
|
||||
process.stdin.on('data', (input) => {
|
||||
resolve(input.toString().replace('\n', ''));
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Read input from the keyboard and return it as a string.
|
||||
* TODO: to would be very helpfull to only allow a certain class of input (numbers, letters)
|
||||
* TODO: also we could convert all inputs to uppercase (where it makes sence).
|
||||
*
|
||||
* @param {string=''} message - a message or question to print befor the input.
|
||||
* @returns {Promise<string>} - returns the entered text as a string
|
||||
* @async
|
||||
*/
|
||||
export async function input(message = '') {
|
||||
/* First we need to print the mesage
|
||||
* We append a space by default to seperate the message from the imput.
|
||||
* TODO: If the message already contains a space at the end this is not needed! */
|
||||
process.stdout.write(message + ' ');
|
||||
|
||||
return new Promise(resolve => {
|
||||
process.stdin.on('data', (input) => {
|
||||
/* onData returns a Buffer.
|
||||
* First we need to convert it into a string. */
|
||||
const data = input.toString();
|
||||
|
||||
/* The result fo onData is a string ending with an `\n`.
|
||||
* We just need the actual content so let's remove the newline at the end: */
|
||||
const content = data[data.length] === '\n' ? data.slice(0, -1) : data;
|
||||
|
||||
resolve(content);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user