cli wip
This commit is contained in:
parent
84c182a17d
commit
d80735d120
|
|
@ -13,6 +13,10 @@
|
||||||
font-size: var(--cli-font-size);
|
font-size: var(--cli-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#command-line[data-extended="true"] {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
#command-prompt {
|
#command-prompt {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
|
|
@ -24,14 +28,13 @@
|
||||||
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: var(--cli-spacing-vertical) var(--cli-element-spacing-horizontal);
|
padding: var(--cli-spacing-vertical) var(--cli-element-spacing-horizontal);
|
||||||
min-height: 1.2em;
|
|
||||||
resize: none;
|
resize: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
letter-spacing: inherit;
|
letter-spacing: inherit;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
|
|
||||||
height: var(--cli-height);
|
min-height: var(--cli-height);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
@ -54,13 +57,12 @@
|
||||||
background: transparent;
|
background: transparent;
|
||||||
resize: none;
|
resize: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-height: 1.2em;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
letter-spacing: inherit;
|
letter-spacing: inherit;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
|
|
||||||
height: var(--cli-height);
|
min-height: var(--cli-height);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
////
|
||||||
|
// dom helpers and cached elements
|
||||||
|
//
|
||||||
|
|
||||||
// finds an element by ID
|
// finds an element by ID
|
||||||
export const $ = (id: string): HTMLElement | null =>
|
export const $ = (id: string): HTMLElement | null =>
|
||||||
document.getElementById(id)
|
document.getElementById(id)
|
||||||
|
|
@ -10,4 +14,5 @@ export const $$ = (tag: string, innerHTML = ""): HTMLElement => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// elements we know will be there... right?
|
// elements we know will be there... right?
|
||||||
export const cmdTextbox = document.getElementById("command-textbox")!
|
export const cmdLine = document.getElementById("command-line") as HTMLDivElement
|
||||||
|
export const cmdTextbox = document.getElementById("command-textbox") as HTMLTextAreaElement
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
////
|
||||||
|
// try to keep the command textbox focused at all times
|
||||||
|
//
|
||||||
|
|
||||||
import { cmdTextbox } from "./dom.js"
|
import { cmdTextbox } from "./dom.js"
|
||||||
|
|
||||||
export function initFocus() {
|
export function initFocus() {
|
||||||
|
|
|
||||||
28
src/js/input.ts
Normal file
28
src/js/input.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
////
|
||||||
|
// this file controls the command textbox
|
||||||
|
//
|
||||||
|
|
||||||
|
import { cmdTextbox, cmdLine } from "./dom.js"
|
||||||
|
|
||||||
|
export function initInput() {
|
||||||
|
cmdTextbox.addEventListener("keydown", inputHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputHandler(event: KeyboardEvent) {
|
||||||
|
const target = event.target as HTMLElement
|
||||||
|
if (target?.id !== cmdTextbox.id) return
|
||||||
|
|
||||||
|
console.log(event.key)
|
||||||
|
if (event.key === "Tab") {
|
||||||
|
event.preventDefault()
|
||||||
|
} else if (event.shiftKey && event.key === "Enter") {
|
||||||
|
cmdTextbox.rows += 1
|
||||||
|
cmdLine.dataset.extended = "true"
|
||||||
|
console.log(cmdTextbox.value)
|
||||||
|
} else if (event.key === "Enter") {
|
||||||
|
cmdTextbox.value = ""
|
||||||
|
cmdTextbox.rows = 1
|
||||||
|
cmdLine.dataset.extended = "false"
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import { initResize } from "./resize.js"
|
import { initResize } from "./resize.js"
|
||||||
|
import { initInput } from "./input.js"
|
||||||
import { initFocus } from "./focus.js"
|
import { initFocus } from "./focus.js"
|
||||||
import { startVramCounter } from "./vram.js"
|
import { startVramCounter } from "./vram.js"
|
||||||
import { startConnection } from "./websocket.js"
|
import { startConnection } from "./websocket.js"
|
||||||
|
|
||||||
initFocus()
|
initFocus()
|
||||||
initResize()
|
initResize()
|
||||||
|
initInput()
|
||||||
|
|
||||||
startConnection()
|
startConnection()
|
||||||
startVramCounter()
|
startVramCounter()
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
////
|
||||||
|
// maintain the two video modes: cinema and tall
|
||||||
|
//
|
||||||
|
|
||||||
const content = document.getElementById("content")!
|
const content = document.getElementById("content")!
|
||||||
|
|
||||||
export function initResize() {
|
export function initResize() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
////
|
||||||
// vram
|
// fun vram counter at startup
|
||||||
//
|
//
|
||||||
|
|
||||||
import { $ } from "./dom.js"
|
import { $ } from "./dom.js"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
////
|
||||||
|
// the terminal communicates with the shell via websockets
|
||||||
|
//
|
||||||
|
|
||||||
|
import type { Message } from "../shared/message.js"
|
||||||
|
|
||||||
let ws: WebSocket | null = null
|
let ws: WebSocket | null = null
|
||||||
|
|
||||||
// open our websocket connection
|
// open our websocket connection
|
||||||
|
|
@ -13,8 +19,8 @@ export function startConnection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// send any message
|
// send any message
|
||||||
export function send(obj: any) {
|
export function send(msg: Message) {
|
||||||
ws?.readyState === 1 && ws.send(JSON.stringify(obj))
|
ws?.readyState === 1 && ws.send(JSON.stringify(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
// close it... plz don't do this, though
|
// close it... plz don't do this, though
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,12 @@ app.use("*", async (c, next) => {
|
||||||
console.log(fn(`${c.res.status} ${c.req.method} ${c.req.url} (${end - start}ms)`))
|
console.log(fn(`${c.res.status} ${c.req.method} ${c.req.url} (${end - start}ms)`))
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get("/js/:path{.+}", async c => {
|
app.on("GET", ["/js/:path{.+}", "/shared/:path{.+}"], async c => {
|
||||||
const path = "./src/js/" + c.req.param("path")
|
const path = "./src/" + c.req.path.replace("..", ".")
|
||||||
|
|
||||||
|
// path must end in .js
|
||||||
|
if (!path.endsWith(".js")) return c.text("File not found", 404)
|
||||||
|
|
||||||
const ts = path.replace(".js", ".ts")
|
const ts = path.replace(".js", ".ts")
|
||||||
if (isFile(ts)) {
|
if (isFile(ts)) {
|
||||||
return new Response(await transpile(ts), { headers: { "Content-Type": "text/javascript" } })
|
return new Response(await transpile(ts), { headers: { "Content-Type": "text/javascript" } })
|
||||||
|
|
|
||||||
6
src/shared/message.ts
Normal file
6
src/shared/message.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export type Message = {
|
||||||
|
session: string
|
||||||
|
id: string
|
||||||
|
type: "output"
|
||||||
|
data: any
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user