aboutsummaryrefslogtreecommitdiff
path: root/frontend/query.ts
blob: fc68af9eebdcb51d749fa918aa90cd37eb169ed0 (plain)
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
import { status } from "./ui.ts"

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(engine: string, query: string) {
    const bang_prefix = "!"
    if (query.startsWith(bang_prefix)) {
        const [_engine, ...query_parts] = query.substring(bang_prefix.length).split(" ")
        engine = _engine
        query = query_parts.join(" ")
    }
    const url = await search_url(engine, query)
    if (!url) return status("error", "Invalid search engine.")

    document.title = `${(await bangs)[engine]?.name ?? engine}: ${query}`
    status("success", `Forwarding to ${url}`)
    setTimeout(() => document.location.replace(url), 0)
}

async function search_url(engine: string, query: string) {
    return (await bangs)[engine.toLowerCase()]?.url.replace("{{{s}}}", encodeURIComponent(query).replaceAll("%20", "+"))
}