aboutsummaryrefslogtreecommitdiff
path: root/frontend/query.ts
blob: e67f09a1e5111ce1f253f02e7de558e0a441c4aa (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(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}`)
    document.location.replace(url)
}

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