aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-07-24 22:33:50 +0200
committermetamuffin <metamuffin@disroot.org>2023-07-24 22:33:50 +0200
commit1f639b98e07bcb4f7901e678e670894fbc370d8f (patch)
tree901ea00ec4b9ac090a30738b90662f5bb7d09a46 /frontend
parent5a1201ec1f47b393ce40437bf9b3a478538bac51 (diff)
downloadfastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar
fastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar.bz2
fastbangs-1f639b98e07bcb4f7901e678e670894fbc370d8f.tar.zst
add frontend draft
Diffstat (limited to 'frontend')
-rw-r--r--frontend/index.html12
-rw-r--r--frontend/main.ts83
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", "+"))
+}