1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import { status } from "./ui.ts"
// TODO embed this information into bangs.js
const ENGINE_PINNED: Set<string> = new Set(["ddg", "ec", "qwl", "sp"])
interface Bangs { [key: string]: { url: string, name?: string, pinned?: boolean } | undefined }
export let bangs: Promise<Bangs>;
export function load_bangs() {
status("info", "Loading bangs...")
bangs = new Promise(r => {
(async () => {
const bangs_res = await fetch("/bangs.json")
if (!bangs_res.ok) return status("error", "could not download bangs.json")
const k: Bangs = await bangs_res.json()
status("info", "Bangs loaded.")
r(Object.fromEntries(Object.entries(k).map(
([key, o]) => [key, {
...o,
pinned: ENGINE_PINNED.has(key)
}]
)) as Bangs)
})()
})
}
export async function process_query(default_engine: string, query: string) {
const bang_prefix = "!"
let url: string | undefined
if (query.startsWith(bang_prefix)) {
const [engine, ...query_parts] = query.substring(bang_prefix.length).split(" ")
url = await search_url(engine, query_parts.join(" "))
} else {
url = await search_url(default_engine, query)
}
if (!url) return status("error", "Invalid search engine.")
status("success", `Forwarding to ${url}`)
setTimeout(() => document.location.href = url!, 0)
}
async function search_url(engine: string, query: string) {
return (await bangs)[engine.toLowerCase()]?.url.replace("{{{s}}}", encodeURIComponent(query).replaceAll("%20", "+"))
}
|