-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
130 lines (124 loc) · 4.02 KB
/
index.html
File metadata and controls
130 lines (124 loc) · 4.02 KB
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Redirecting...</title>
<style>
body {
background: #121212;
color: #555;
font-family: monospace;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
margin: 0;
}
</style>
</head>
<body>
<div id="status"></div>
<script>
// --- CONFIGURATION START ---
const userOptions = {
// Default Bang Selection: URL to use if no bang is entered/found
// "{{{s}}}" represents the query
defaultUrl: "https://google.com/search?q={{{s}}}",
// Quicker Bangs: Define custom bangs, override fetched bangs, or speed up specific bangs.
// NOTE: This is checked before the official bang list, so commonly used bangs can be placed here for even faster resolution.
// Format: "trigger": "url"
quickerBangs: {
"yt": "https://www.youtube.com/results?search_query={{{s}}}",
"g": "https://www.google.com/search?q={{{s}}}",
// "gh": "https://github.com/search?q={{{s}}}",
// "rd": "https://www.reddit.com/search/?q={{{s}}}",
// "local": "http://localhost:8080/search?q={{{s}}}"
}
};
// --- CONFIGURATION END ---
// Register PWA
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
console.log("Registered PWA.");
}
// Fetch from Kagi instead of DDG: More comprehensive list of bangs
const BANGS_URL = "https://raw.githubusercontent.com/kagisearch/bangs/refs/heads/main/data/bangs.json";
async function handleRedirect() {
const params = new URLSearchParams(window.location.search);
const query = params.get('q');
const statusDiv = document.getElementById('status');
if (!query) {
statusDiv.innerText = "Ready. Add ?q=... to URL to search.";
return;
}
statusDiv.innerText = "Processing...";
// Only fetch external bangs if we didn't match a custom bang immediately
let externalBangs = [];
if (needsExternalBangs(query)) {
externalBangs = await getBangs(statusDiv);
}
const finalUrl = resolveUrl(query, externalBangs);
window.location.replace(finalUrl);
}
// Check if we can skip loading the bangs file
function needsExternalBangs(query) {
const match = query.match(/!(\w+)/);
if (!match) return false; // No bang, use default
const trigger = match[1];
return !userOptions.quickerBangs[trigger]; // Return true if NOT in custom bangs
}
async function getBangs(statusDiv) {
const cached = localStorage.getItem('ud_bangs');
const timestamp = localStorage.getItem('ud_time');
const cacheTimeout = 2592000000; // 30 Days
if (cached && timestamp && (Date.now() - timestamp < cacheTimeout)) {
return JSON.parse(cached);
}
statusDiv.innerText = "Updating bang cache...";
try {
const res = await fetch(BANGS_URL);
const text = await res.text();
const json = JSON.parse(text.replace(/^var bangs = /, '').replace(/;$/, ''));
const cleanBangs = json.map(b => ({
t: b.t,
ts: b.ts || [],
u: b.u
}));
localStorage.setItem('ud_bangs', JSON.stringify(cleanBangs));
localStorage.setItem('ud_time', Date.now());
return cleanBangs;
} catch (e) {
console.error("Fetch failed", e);
return [];
}
}
function resolveUrl(query, externalBangs) {
const match = query.match(/!(\w+)/);
// Start with User Default
let url = userOptions.defaultUrl;
let term = query;
if (match) {
const trigger = match[1];
// Check Custom Bangs (Priority & O(1) Speed)
if (userOptions.quickerBangs[trigger]) {
url = userOptions.quickerBangs[trigger];
term = query.replace(`!${trigger}`, '').trim();
}
// Check External Kagi Bangs
else if (externalBangs.length > 0) {
// Check both primary trigger (t) and aliases (ts)
const found = externalBangs.find(b =>
b.t === trigger || (b.ts && b.ts.includes(trigger))
);
if (found) {
url = found.u;
term = query.replace(`!${trigger}`, '').trim();
}
}
}
return url.replace('{{{s}}}', encodeURIComponent(term));
}
handleRedirect();
</script>
</body>
</html>