Experimental web display
This commit is contained in:
parent
fa889e00d9
commit
68105c49ff
5 changed files with 87 additions and 2 deletions
1
config/bundle.flags
Normal file
1
config/bundle.flags
Normal file
|
@ -0,0 +1 @@
|
|||
--unstable
|
9
mod.ts
9
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<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
1
web-demo/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
textui.js
|
16
web-demo/pre.html
Normal file
16
web-demo/pre.html
Normal 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
62
web.ts
Normal 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 {
|
||||
}
|
Loading…
Reference in a new issue