Initial commit

This commit is contained in:
ktkk 2025-09-24 10:04:30 +00:00
commit 82d714d8a3
9 changed files with 251 additions and 0 deletions

26
static/index.html Normal file
View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://esm.sh/@xterm/xterm/css/xterm.css" />
<link rel="stylesheet" href="./style.css" />
<title>Document</title>
<script type="importmap">
{
"imports": {
"@xterm/xterm": "https://esm.sh/@xterm/xterm",
"@xterm/addon-fit": "https://esm.sh/@xterm/addon-fit"
}
}
</script>
<script src="./index.js" type="module"></script>
</head>
<body>
<my-terminal></my-terminal>
</body>
</html>

59
static/index.js Normal file
View file

@ -0,0 +1,59 @@
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);

4
static/style.css Normal file
View file

@ -0,0 +1,4 @@
html {
background-color: #000000;
}