From 1f639b98e07bcb4f7901e678e670894fbc370d8f Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 24 Jul 2023 22:33:50 +0200 Subject: add frontend draft --- frontend/index.html | 12 ++++++++ frontend/main.ts | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 frontend/index.html create mode 100644 frontend/main.ts (limited to 'frontend') diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..9a4c5d4 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + + Laufente + + + + + diff --git a/frontend/main.ts b/frontend/main.ts new file mode 100644 index 0000000..7f17fdd --- /dev/null +++ b/frontend/main.ts @@ -0,0 +1,83 @@ +/// + +interface Bangs { [key: string]: string } +let bangs: Bangs = {} +let status_el: HTMLElement + +globalThis.addEventListener("hashchange", () => process_url()) +globalThis.addEventListener("load", async () => { + const bangs_res = await fetch("/bangs.json") + if (!bangs_res.ok) document.writeln("error: could not download bangs.json") + bangs = await bangs_res.json() + process_url() +}) + +function setup_page(engine?: string) { + const section = document.createElement("section") + + if (engine) { + const heading = document.createElement("h1") + heading.textContent = engine + + const input = document.createElement("input") + input.type = "input" + input.addEventListener("keydown", ev => { + if (ev.code == "Enter") process_query(engine, input.value ?? "") + }) + + const submit = document.createElement("button") + submit.textContent = "Search" + submit.addEventListener("click", () => { + process_query(engine, input.value ?? "") + }) + + const info = document.createElement("p") + info.textContent = `To install this as the default search engine, select "Add " in the context-menu of the URL-bar.` + + section.append(heading, input, submit, info) + } else { + const info = document.createElement("p") + info.textContent = `todo` + section.append(info) + } + + status_el = document.createElement("p") + section.append(status_el) + document.body.append(section) +} + + +function status(text: string, color?: string) { + status_el.textContent = text + if (color) status_el.style.color = color +} + +function process_url() { + if (document.location.hash.length != 0) { + const input = document.location.hash.substring(1) + const [default_engine, query_encoded] = input.split("#") + if (!query_encoded) return setup_page(default_engine) + const query = decodeURIComponent(query_encoded) + process_query(default_engine, query) + } else { + setup_page() + } +} + +function process_query(default_engine: string, query: string) { + const bang_prefix = "!" + let url = "" + if (query.startsWith(bang_prefix)) { + const [engine, ...query_parts] = query.substring(bang_prefix.length).split(" ") + url = search_url(engine, query_parts.join(" ")) + } else { + url = search_url(default_engine, query) + } + + status(`Forwarding to ${url}`, "green") + setTimeout(() => document.location.href = url, 0) +} + +function search_url(engine: string, query: string) { + return bangs[engine].replace("{{{s}}}", encodeURIComponent(query).replaceAll("%20", "+")) +} -- cgit v1.2.3-70-g09d2