diff options
author | metamuffin <metamuffin@disroot.org> | 2023-07-24 22:33:50 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-07-24 22:33:50 +0200 |
commit | 1f639b98e07bcb4f7901e678e670894fbc370d8f (patch) | |
tree | 901ea00ec4b9ac090a30738b90662f5bb7d09a46 /frontend | |
parent | 5a1201ec1f47b393ce40437bf9b3a478538bac51 (diff) | |
download | fastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar fastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar.bz2 fastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar.zst |
add frontend draft
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/index.html | 12 | ||||
-rw-r--r-- | frontend/main.ts | 83 |
2 files changed, 95 insertions, 0 deletions
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 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <script type="module" src="./bundle.js"></script> + <title>Laufente</title> + </head> + <body> + <noscript>requires javascript</noscript> + </body> +</html> 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 @@ +/// <reference lib="dom" /> + +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 <name>" 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", "+")) +} |