Experimental web display

This commit is contained in:
Michaël Lemaire 2021-03-06 01:02:04 +02:00
parent fa889e00d9
commit 68105c49ff
5 changed files with 87 additions and 2 deletions

1
config/bundle.flags Normal file
View file

@ -0,0 +1 @@
--unstable

9
mod.ts
View file

@ -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<TextUI> {
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]();

1
web-demo/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
textui.js

16
web-demo/pre.html Normal file
View file

@ -0,0 +1,16 @@
<html>
<head>
<meta charset="utf-8">
<script type="module">
import { createTextUI } from "./textui.js";
const ui = await createTextUI();
ui.drawing.color(2, 0).text("hello", { x: 10, y: 3 });
ui.drawing.color(0, 1).text("world", { x: 10, y: 5 });
await ui.loop();
</script>
</head>
<body></body>
</html>

62
web.ts Normal file
View file

@ -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<BufferSize> {
return { w: 40, h: 20 };
}
async setupPalette(colors: readonly Color[]): Promise<readonly Color[]> {
return [];
}
async clear(): Promise<void> {
}
async setCursorVisibility(visible: boolean): Promise<void> {
}
async setChar(at: BufferLocation, char: Char): Promise<void> {
}
async getKeyStrokes(): Promise<string[]> {
return [];
}
}
/**
* Basic terminal display using a single "pre" tag
*/
export class PreTerminalDisplay extends WebDisplay {
element: any;
async clear(): Promise<void> {
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<void> {
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 {
}