59 lines
1.4 KiB
JavaScript
59 lines
1.4 KiB
JavaScript
import { Terminal } from "@xterm/xterm";
|
|
import { FitAddon } from "@xterm/addon-fit";
|
|
|
|
class MyTerminalElement extends HTMLElement {
|
|
|
|
#terminal;
|
|
#fitAddon;
|
|
|
|
#command = "";
|
|
|
|
static #prompt = "$>";
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
this.#terminal = new Terminal({
|
|
cursorBlink: true,
|
|
});
|
|
|
|
this.#fitAddon = new FitAddon();
|
|
this.#terminal.loadAddon(this.#fitAddon);
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.#terminal.open(this);
|
|
this.#fitAddon.fit();
|
|
|
|
this.#terminal.writeln("Hello from xterm.js");
|
|
this.#terminal.write(MyTerminalElement.#prompt);
|
|
|
|
this.#terminal.onData(async data => {
|
|
if (data === '\r') {
|
|
await this.handleCommand();
|
|
this.#terminal.write("\r\n");
|
|
this.#terminal.write(MyTerminalElement.#prompt);
|
|
this.#command = "";
|
|
} else {
|
|
this.#terminal.write(data);
|
|
this.#command += data;
|
|
}
|
|
});
|
|
}
|
|
|
|
async handleCommand() {
|
|
const [command, ...args] = this.#command.split(" ");
|
|
if (command.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const response = await fetch(`/command/${command}`);
|
|
|
|
this.#terminal.write("\r\n");
|
|
this.#terminal.write(await response.text());
|
|
}
|
|
|
|
}
|
|
|
|
customElements.define("my-terminal", MyTerminalElement);
|
|
|