From 68105c49ffadd52379f50e39a3f15a568e92dc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sat, 6 Mar 2021 01:02:04 +0200 Subject: [PATCH] Experimental web display --- config/bundle.flags | 1 + mod.ts | 9 +++++-- web-demo/.gitignore | 1 + web-demo/pre.html | 16 ++++++++++++ web.ts | 62 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 config/bundle.flags create mode 100644 web-demo/.gitignore create mode 100644 web-demo/pre.html create mode 100644 web.ts diff --git a/config/bundle.flags b/config/bundle.flags new file mode 100644 index 0000000..418455f --- /dev/null +++ b/config/bundle.flags @@ -0,0 +1 @@ +--unstable \ No newline at end of file diff --git a/mod.ts b/mod.ts index 8f74894..ed1a25b 100644 --- a/mod.ts +++ b/mod.ts @@ -2,11 +2,13 @@ import { AnsiTerminalDisplay } from "./ansi.ts"; import { UIConfig } from "./config.ts"; import { Display } from "./display.ts"; import { TextUI } from "./ui.ts"; +import { PreTerminalDisplay } from "./web.ts"; export { TextUI } from "./ui.ts"; export const UI_DISPLAY_TYPES = { autodetect: undefined, ansi: AnsiTerminalDisplay, + web_pre: PreTerminalDisplay, dummy: Display, } as const; @@ -15,8 +17,11 @@ export async function createTextUI( display_type: keyof typeof UI_DISPLAY_TYPES = "autodetect", ): Promise { if (display_type == "autodetect") { - // TODO detect platform - display_type = "ansi"; + if (typeof (window as any).document != "undefined") { + display_type = "web_pre"; + } else { + display_type = "ansi"; + } } var display = new UI_DISPLAY_TYPES[display_type](); diff --git a/web-demo/.gitignore b/web-demo/.gitignore new file mode 100644 index 0000000..a00eb62 --- /dev/null +++ b/web-demo/.gitignore @@ -0,0 +1 @@ +textui.js \ No newline at end of file diff --git a/web-demo/pre.html b/web-demo/pre.html new file mode 100644 index 0000000..da526af --- /dev/null +++ b/web-demo/pre.html @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web.ts b/web.ts new file mode 100644 index 0000000..b80da7d --- /dev/null +++ b/web.ts @@ -0,0 +1,62 @@ +import { BufferLocation, BufferSize, Char, Color } from "./base.ts"; +import { Display } from "./display.ts"; + +/** + * Base for all web-based terminal displays + */ +class WebDisplay implements Display { + readonly document = (window as any).document; + + async getSize(): Promise { + return { w: 40, h: 20 }; + } + + async setupPalette(colors: readonly Color[]): Promise { + return []; + } + + async clear(): Promise { + } + + async setCursorVisibility(visible: boolean): Promise { + } + + async setChar(at: BufferLocation, char: Char): Promise { + } + + async getKeyStrokes(): Promise { + return []; + } +} + +/** + * Basic terminal display using a single "pre" tag + */ +export class PreTerminalDisplay extends WebDisplay { + element: any; + + async clear(): Promise { + if (!this.element) { + this.element = this.document.createElement("pre"); + this.document.body.appendChild(this.element); + } + + const { w, h } = await this.getSize(); + const line = Array(w).fill(" ").join(""); + this.element.textContent = Array(h).fill(line).join("\n"); + } + + async setChar(at: BufferLocation, char: Char): Promise { + const { w, h } = await this.getSize(); + const offset = at.y * (w + 1) + at.x; + const text = this.element.textContent; + this.element.textContent = text.slice(0, offset) + char.ch + + text.slice(offset + 1); + } +} + +/** + * DOM terminal display, using one div per char + */ +export class DOMTerminalDisplay extends WebDisplay { +}