aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-08-01 17:25:45 +0200
committermetamuffin <metamuffin@disroot.org>2023-08-01 17:25:45 +0200
commit7b1cb4e58347758cab25b73dc6486f5f90efa6df (patch)
treeaec1c130bdbf576394aeb3b488d8888f31eaa2f2 /frontend
parent7c933642730dd5b935281f2cc938f2998e3a4114 (diff)
downloadfastbangs-7b1cb4e58347758cab25b73dc6486f5f90efa6df.tar
fastbangs-7b1cb4e58347758cab25b73dc6486f5f90efa6df.tar.bz2
fastbangs-7b1cb4e58347758cab25b73dc6486f5f90efa6df.tar.zst
refactor dom interaction with helper function
Diffstat (limited to 'frontend')
-rw-r--r--frontend/helper.ts30
-rw-r--r--frontend/main.ts2
-rw-r--r--frontend/search.ts51
-rw-r--r--frontend/start.ts56
-rw-r--r--frontend/submit.ts9
-rw-r--r--frontend/ui.ts124
6 files changed, 152 insertions, 120 deletions
diff --git a/frontend/helper.ts b/frontend/helper.ts
new file mode 100644
index 0000000..f47d131
--- /dev/null
+++ b/frontend/helper.ts
@@ -0,0 +1,30 @@
+
+
+interface Opts<E> {
+ class?: string[] | string,
+ id?: string,
+ src?: string,
+ for?: string,
+ onclick?: (e: E) => void,
+ onchange?: (e: E) => void,
+}
+
+function apply_opts<E extends HTMLElement>(e: E, o: Opts<E>) {
+ if (o.id) e.id = o.id
+ if (o.onclick) e.onclick = () => o.onclick!(e)
+ if (o.onchange) e.onchange = () => o.onchange!(e)
+ if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for
+ if (typeof o?.class == "string") e.classList.add(o.class)
+ if (typeof o?.class == "object") e.classList.add(...o.class)
+}
+
+export function e<K extends keyof HTMLElementTagNameMap>(name: K, opts: Opts<HTMLElementTagNameMap[K]>, ...children: (HTMLElement | string)[]): HTMLElementTagNameMap[K] {
+ const el = document.createElement(name)
+ apply_opts(el, opts)
+ for (const c of children) {
+ if (typeof c == "string") el.textContent += c;
+ else el.append(c)
+ }
+ return el
+}
+
diff --git a/frontend/main.ts b/frontend/main.ts
index e14ccac..c8f134a 100644
--- a/frontend/main.ts
+++ b/frontend/main.ts
@@ -18,8 +18,6 @@ function process_url() {
add_page_content(engine)
}
bangs.then(bangs => {
- console.log("bop");
-
if (!bangs[engine.toLowerCase()]) {
status("error", "Engine does not exist")
window.location.hash = "#"
diff --git a/frontend/search.ts b/frontend/search.ts
new file mode 100644
index 0000000..0c808db
--- /dev/null
+++ b/frontend/search.ts
@@ -0,0 +1,51 @@
+import { e } from "./helper.ts";
+import { bangs, process_query } from "./query.ts";
+
+export function section_info_search() {
+ return e("section", { class: "info" },
+ e("h2", {}, "Setup"),
+ e("p", {}, "To install this as the default search engine, select \"Add Fastbangs\" in the context-menu of the URL-bar.")
+ )
+}
+
+export function section_search(engine: string) {
+ link_engine(engine)
+
+ const heading = document.createElement("h1")
+ heading.textContent = engine
+ bangs.then(bangs => heading.textContent = bangs[engine]?.name ?? 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 ?? "")
+ })
+
+ return e("section", { class: "search" },
+ heading,
+ e("div", { class: "bar" },
+ input,
+ submit
+ )
+ )
+}
+
+function link_engine(engine: string) {
+ if (document.getElementById("search-link")) {
+ // <link /> is already present, we need reload because browser wont notice otherwise
+ window.location.reload()
+ }
+ const link = document.createElement("link")
+ link.rel = "search"
+ link.id = "search-link"
+ link.type = "application/opensearchdescription+xml"
+ link.href = `/search.xml?default=${encodeURIComponent(engine)}`
+ link.title = `Fastbangs (default engine: ${engine})`
+ document.head.append(link)
+} \ No newline at end of file
diff --git a/frontend/start.ts b/frontend/start.ts
new file mode 100644
index 0000000..1bb1cbb
--- /dev/null
+++ b/frontend/start.ts
@@ -0,0 +1,56 @@
+import { e } from "./helper.ts";
+import { bangs } from "./query.ts";
+import { status } from "./ui.ts"
+
+export function section_info_start() {
+ return e("section", { class: "info" },
+ e("h1", {}, "Fastbangs"),
+ e("p", {}, `
+ This application provides a way to (mostly) locally handle search bangs.
+ First select a default engine to use, then register this page as a search in your browser
+ `)
+ )
+}
+
+export function section_engine_select() {
+ const section = document.createElement("section")
+ section.classList.add("engine-select")
+
+ const select = async (e: string) => {
+ const engine = e.toLowerCase();
+ if (!(await bangs)[engine]) return status("error", `Engine ${JSON.stringify(e)} does not exist.`)
+ window.location.hash = `#${e}`
+ }
+
+ const heading = document.createElement("h2")
+ heading.textContent = "Select a search engine"
+
+ const listing = document.createElement("ul")
+ bangs.then(bangs => {
+ for (const key in bangs) if (bangs[key]!.pinned) {
+ listing.prepend(e("li", { class: "pinned", onclick: () => select(key) }, bangs[key]!.name ?? key))
+ }
+ })
+
+ const input = document.createElement("input")
+ input.type = "input"
+ input.addEventListener("keydown", ev => {
+ if (ev.code == "Enter") select(input.value)
+ })
+
+ const submit = document.createElement("button")
+ submit.textContent = "Select"
+ submit.addEventListener("click", () => select(input.value))
+
+ listing.append(e("li", {},
+ e("label", {}, "Select other engine by bang:"),
+ input,
+ submit
+ ))
+
+ section.append(heading, listing)
+ return e("section", { class: "engine-select" },
+ e("h2", {}, "Select a search engine"),
+ listing
+ )
+}
diff --git a/frontend/submit.ts b/frontend/submit.ts
new file mode 100644
index 0000000..e8f696f
--- /dev/null
+++ b/frontend/submit.ts
@@ -0,0 +1,9 @@
+import { e } from "./helper.ts";
+
+
+export function section_submit() {
+ return e("section", {})
+}
+
+
+
diff --git a/frontend/ui.ts b/frontend/ui.ts
index 8ce34a4..3b223ba 100644
--- a/frontend/ui.ts
+++ b/frontend/ui.ts
@@ -1,125 +1,13 @@
-import { bangs, process_query } from "./query.ts";
+import { section_info_search, section_search } from "./search.ts";
+import { section_engine_select, section_info_start } from "./start.ts";
+import { section_submit } from "./submit.ts";
export function add_page_content(engine?: string) {
//@ts-ignore HTMLCollectionOf is an iterator
for (const e of [...document.getElementsByTagName("section")]) e.remove()
- if (engine) {
- document.body.append(section_search(engine), section_info_search())
- } else {
- document.body.append(section_info_start(), section_engine_select())
- }
-}
-
-function section_search(engine: string) {
- engine = engine.toLowerCase();
- const section = document.createElement("section")
- section.classList.add("search")
-
- if (document.getElementById("search-link")) {
- // <link /> is already present, we need reload because browser wont notice otherwise
- window.location.reload()
- }
- const link = document.createElement("link")
- link.rel = "search"
- link.id = "search-link"
- link.type = "application/opensearchdescription+xml"
- link.href = `/search.xml?default=${encodeURIComponent(engine)}`
- link.title = `Fastbangs (default engine: ${engine})`
- document.head.append(link)
-
- const heading = document.createElement("h1")
- heading.textContent = engine
- bangs.then(bangs => heading.textContent = bangs[engine]?.name ?? 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 search = document.createElement("div")
- search.classList.add("bar")
- search.append(input, submit)
-
- section.append(heading, search)
- return section
-}
-
-function section_engine_select() {
- const section = document.createElement("section")
- section.classList.add("engine-select")
-
- const select = async (e: string) => {
- const engine = e.toLowerCase();
- if (!(await bangs)[engine]) return status("error", `Engine ${JSON.stringify(e)} does not exist.`)
- window.location.hash = `#${e}`
- }
-
- const heading = document.createElement("h2")
- heading.textContent = "Select a search engine"
-
- const listing = document.createElement("ul")
- bangs.then(bangs => {
- for (const key in bangs) if (bangs[key]!.pinned) {
- const li = document.createElement("li")
- li.classList.add("pinned")
- li.textContent = bangs[key]!.name ?? key
- li.onclick = () => select(key)
- listing.prepend(li)
- }
- })
- const other = document.createElement("li")
- const label = document.createElement("label")
- label.textContent = "Select other engine by bang:"
- const input = document.createElement("input")
- input.type = "input"
- input.addEventListener("keydown", ev => {
- if (ev.code == "Enter") select(input.value)
- })
- const submit = document.createElement("button")
- submit.textContent = "Select"
- submit.addEventListener("click", () => select(input.value))
- other.append(label, input, submit)
- listing.append(other)
-
- section.append(heading, listing)
- return section
-}
-
-function section_info_search() {
- const section = document.createElement("section")
- section.classList.add("info")
-
- const heading = document.createElement("h2")
- heading.textContent = "Setup"
-
- const info = document.createElement("p")
- info.textContent = `To install this as the default search engine, select "Add Fastbangs" in the context-menu of the URL-bar.`
-
- section.append(heading, info)
- return section
-}
-
-function section_info_start() {
- const section = document.createElement("section")
- section.classList.add("info")
-
- const heading = document.createElement("h1")
- heading.textContent = "Fastbangs"
-
- const info = document.createElement("p")
- info.textContent = `
- This application provides a way to (mostly) locally handle search bangs.
- First select a default engine to use, then register this page as a search in your browser
- `
- section.append(heading, info)
- return section
+ if (engine == "~submit") document.body.append(section_submit())
+ else if (engine) document.body.append(section_search(engine), section_info_search())
+ else document.body.append(section_info_start(), section_engine_select())
}
let status_el: HTMLElement