show tiny browser
This commit is contained in:
parent
a87564b082
commit
6fcffc65f9
|
|
@ -4,23 +4,31 @@
|
|||
|
||||
import { $, $$ } from "./dom"
|
||||
import { focusInput } from "./focus"
|
||||
import { scrollback } from "./dom"
|
||||
import { addInput } from "./scrollback"
|
||||
import { randomId } from "../shared/utils"
|
||||
|
||||
const HEIGHT = 540
|
||||
const WIDTH = 960
|
||||
|
||||
const controls = $("browser-controls") as HTMLDivElement
|
||||
const address = $("browser-address") as HTMLSpanElement
|
||||
let iframe: HTMLIFrameElement
|
||||
let iframeWindow: Window
|
||||
let realUrl = ""
|
||||
let showInput = true
|
||||
|
||||
export function isBrowsing(): boolean {
|
||||
return document.querySelector("iframe.browser.active") !== null
|
||||
}
|
||||
|
||||
export function openBrowser(url: string) {
|
||||
export function openBrowser(url: string, openedVia: "click" | "command" = "click") {
|
||||
showInput = openedVia === "click"
|
||||
|
||||
iframe = $$("iframe.browser.active") as HTMLIFrameElement
|
||||
iframeWindow = iframe.contentWindow as Window
|
||||
iframe.src = url
|
||||
iframe.sandbox.add("allow-scripts", "allow-same-origin", "allow-forms")
|
||||
iframe.height = "540"
|
||||
iframe.width = "960"
|
||||
iframe.height = String(HEIGHT)
|
||||
iframe.width = String(WIDTH)
|
||||
iframe.tabIndex = 0
|
||||
|
||||
window.addEventListener("message", handleAppMessage)
|
||||
|
|
@ -35,6 +43,28 @@ export function openBrowser(url: string) {
|
|||
setAddress(url)
|
||||
}
|
||||
|
||||
function closeBrowser() {
|
||||
window.removeEventListener("keydown", handleBrowserKeydown)
|
||||
window.removeEventListener("message", handleAppMessage)
|
||||
controls.removeEventListener("click", handleClick)
|
||||
iframe.removeEventListener("load", handlePageLoad)
|
||||
|
||||
const id = randomId()
|
||||
if (showInput)
|
||||
addInput(id, "browse " + realUrl, "ok")
|
||||
|
||||
iframe.height = String(HEIGHT / 2)
|
||||
iframe.width = String(WIDTH / 2)
|
||||
iframe.style.pointerEvents = "none"
|
||||
iframe.tabIndex = -1
|
||||
iframe.classList.remove("fullscreen", "active")
|
||||
iframe.style.border = "2px solid var(--c64-light-blue)"
|
||||
scrollback.append(iframe)
|
||||
|
||||
controls.style.display = "none"
|
||||
focusInput()
|
||||
}
|
||||
|
||||
function handleAppMessage(event: MessageEvent) {
|
||||
const origin = event.origin
|
||||
if (!origin.includes('localhost') && !origin.match(/\.local$/)) {
|
||||
|
|
@ -74,20 +104,6 @@ function handleAppMessage(event: MessageEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
function closeBrowser() {
|
||||
window.removeEventListener("keydown", handleBrowserKeydown)
|
||||
window.removeEventListener("message", handleAppMessage)
|
||||
controls.removeEventListener("click", handleClick)
|
||||
iframe.removeEventListener("load", handlePageLoad)
|
||||
|
||||
iframe.src = 'about:blank'
|
||||
setTimeout(() => {
|
||||
iframe.remove()
|
||||
controls.style.display = "none"
|
||||
focusInput()
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function handleBrowserKeydown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape" || (e.ctrlKey && e.key === "c")) {
|
||||
e.preventDefault()
|
||||
|
|
@ -123,6 +139,7 @@ function handlePageLoad() {
|
|||
}
|
||||
|
||||
function setAddress(url: string) {
|
||||
realUrl = url
|
||||
address.textContent = url.replace(/https?:\/\//, "")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@
|
|||
// temporary hack for browser commands
|
||||
|
||||
import type { CommandOutput } from "../shared/types"
|
||||
import { openBrowser } from "./browser"
|
||||
import { scrollback, content } from "./dom"
|
||||
import { focusInput } from "./focus"
|
||||
import { resize } from "./resize"
|
||||
import { autoScroll } from "./scrollback"
|
||||
import { sessionId } from "./session"
|
||||
import { send } from "./websocket"
|
||||
import { focusInput } from "./focus"
|
||||
|
||||
export const commands: string[] = []
|
||||
|
||||
export const browserCommands: Record<string, (...args: string[]) => void | Promise<void> | CommandOutput> = {
|
||||
browse: (url: string) => openBrowser(url, "command"),
|
||||
"browser-session": () => sessionId,
|
||||
clear: () => scrollback.innerHTML = "",
|
||||
commands: () => {
|
||||
|
|
@ -27,7 +28,6 @@ export const browserCommands: Record<string, (...args: string[]) => void | Promi
|
|||
content.style.display = ""
|
||||
document.body.dataset.mode = mode
|
||||
resize()
|
||||
autoScroll()
|
||||
focusInput()
|
||||
},
|
||||
reload: () => window.location.reload(),
|
||||
|
|
|
|||
|
|
@ -7,25 +7,26 @@ import { scrollback, cmdInput, $$ } from "./dom"
|
|||
import { randomId } from "../shared/utils"
|
||||
|
||||
type InputStatus = "waiting" | "streaming" | "ok" | "error"
|
||||
const statusColors = {
|
||||
waiting: "yellow",
|
||||
streaming: "purple",
|
||||
ok: "green",
|
||||
error: "red"
|
||||
}
|
||||
|
||||
export function initScrollback() {
|
||||
window.addEventListener("click", handleInputClick)
|
||||
}
|
||||
|
||||
export function autoScroll() {
|
||||
// requestAnimationFrame(() => scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight)
|
||||
// scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight
|
||||
}
|
||||
|
||||
export function insert(node: HTMLElement) {
|
||||
scrollback.append(node)
|
||||
}
|
||||
|
||||
export function addInput(id: string, input: string) {
|
||||
export function addInput(id: string, input: string, status?: InputStatus) {
|
||||
const parent = $$("li.input")
|
||||
const status = $$("span.status.yellow", "•")
|
||||
const statusSpan = $$(`span.status.${statusColors[status || "waiting"]}`, "•")
|
||||
const content = $$("span.content", input)
|
||||
parent.append(status, content)
|
||||
parent.append(statusSpan, content)
|
||||
parent.dataset.id = id
|
||||
|
||||
insert(parent)
|
||||
|
|
@ -36,15 +37,8 @@ export function setStatus(id: string, status: InputStatus) {
|
|||
const statusEl = document.querySelector(`[data-id="${id}"].input .status`)
|
||||
if (!statusEl) return
|
||||
|
||||
const colors = {
|
||||
waiting: "yellow",
|
||||
streaming: "purple",
|
||||
ok: "green",
|
||||
error: "red"
|
||||
}
|
||||
|
||||
statusEl.classList.remove(...Object.values(colors))
|
||||
statusEl.classList.add(colors[status])
|
||||
statusEl.classList.remove(...Object.values(statusColors))
|
||||
statusEl.classList.add(statusColors[status])
|
||||
}
|
||||
|
||||
export function addOutput(id: string, output: CommandOutput) {
|
||||
|
|
@ -65,8 +59,6 @@ export function addOutput(id: string, output: CommandOutput) {
|
|||
} else {
|
||||
insert(item)
|
||||
}
|
||||
|
||||
autoScroll()
|
||||
}
|
||||
|
||||
export function addErrorMessage(message: string) {
|
||||
|
|
@ -87,8 +79,6 @@ export function appendOutput(id: string, output: CommandOutput) {
|
|||
item.innerHTML += content
|
||||
else
|
||||
item.textContent += content
|
||||
|
||||
autoScroll()
|
||||
}
|
||||
|
||||
export function replaceOutput(id: string, output: CommandOutput) {
|
||||
|
|
@ -105,8 +95,6 @@ export function replaceOutput(id: string, output: CommandOutput) {
|
|||
item.innerHTML = content
|
||||
else
|
||||
item.textContent = content
|
||||
|
||||
autoScroll()
|
||||
}
|
||||
|
||||
function processOutput(output: CommandOutput): ["html" | "text", string] {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user