diff options
author | metamuffin <metamuffin@disroot.org> | 2023-08-01 17:25:45 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-08-01 17:25:45 +0200 |
commit | 7b1cb4e58347758cab25b73dc6486f5f90efa6df (patch) | |
tree | aec1c130bdbf576394aeb3b488d8888f31eaa2f2 /frontend | |
parent | 7c933642730dd5b935281f2cc938f2998e3a4114 (diff) | |
download | fastbangs-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.ts | 30 | ||||
-rw-r--r-- | frontend/main.ts | 2 | ||||
-rw-r--r-- | frontend/search.ts | 51 | ||||
-rw-r--r-- | frontend/start.ts | 56 | ||||
-rw-r--r-- | frontend/submit.ts | 9 | ||||
-rw-r--r-- | frontend/ui.ts | 124 |
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 |