101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { bangs } from "./bang";
|
|
import "./global.css";
|
|
|
|
function noSearchDefaultPageRender() {
|
|
const currentUrl = window.location.href.replace(/\/+$/, "");
|
|
const app = document.querySelector<HTMLDivElement>("#app")!;
|
|
app.innerHTML = `
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh;">
|
|
<div class="content-container">
|
|
<h1>Und*ck</h1>
|
|
<p>DuckDuckGo's bang redirects are too slow. Add the following URL as a custom search engine to your browser. Enables <a href="https://duckduckgo.com/bangs" target="_blank">all of DuckDuckGo's bangs.</a></p>
|
|
<div class="url-container">
|
|
<input
|
|
type="text"
|
|
class="url-input"
|
|
value="${currentUrl}?q=%s"
|
|
readonly
|
|
/>
|
|
<button class="copy-button">
|
|
<p>Copy</p>
|
|
</button>
|
|
</div>
|
|
<details style="margin-top: 16px;">
|
|
<summary>Demo search</summary>
|
|
<p>Added so that some browsers treat this page as a search engine</p>
|
|
<form class="url-container">
|
|
<input
|
|
type="text"
|
|
name="q"
|
|
class="url-input"
|
|
placeholder="doom on typescript types !yt"
|
|
role="searchbox"
|
|
/>
|
|
<button type="submit" class="copy-button">
|
|
<p>Search</p>
|
|
</button>
|
|
</form>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
<footer class="footer">
|
|
<a href="https://github.com/troylusty/unduck" target="_blank">github</a>
|
|
•
|
|
forked from
|
|
<a href="https://github.com/t3dotgg/unduck" target="_blank">t3dotgg/unduck</a>
|
|
</footer>
|
|
</div>
|
|
`;
|
|
|
|
const copyButton = app.querySelector<HTMLButtonElement>(".copy-button")!;
|
|
const copyIcon = copyButton.querySelector("p")!;
|
|
const urlInput = app.querySelector<HTMLInputElement>(".url-input")!;
|
|
|
|
copyButton.addEventListener("click", async () => {
|
|
await navigator.clipboard.writeText(urlInput.value);
|
|
copyIcon.textContent = "Copied";
|
|
|
|
setTimeout(() => {
|
|
copyIcon.textContent = "Copy";
|
|
}, 2000);
|
|
});
|
|
}
|
|
|
|
const LS_DEFAULT_BANG = localStorage.getItem("default-bang") ?? "ddg";
|
|
const defaultBang = bangs.find((b) => b.t === LS_DEFAULT_BANG);
|
|
|
|
function getBangredirectUrl() {
|
|
const url = new URL(window.location.href);
|
|
const query = url.searchParams.get("q")?.trim() ?? "";
|
|
if (!query) {
|
|
noSearchDefaultPageRender();
|
|
return null;
|
|
}
|
|
|
|
const match = query.match(/!(\S+)/i);
|
|
|
|
const bangCandidate = match?.[1]?.toLowerCase();
|
|
const selectedBang = bangs.find((b) => b.t === bangCandidate) ?? defaultBang;
|
|
|
|
// Remove the first bang from the query
|
|
const cleanQuery = query.replace(/!\S+\s*/i, "").trim();
|
|
|
|
// Format of the url is:
|
|
// https://www.google.com/search?q={{{s}}}
|
|
const searchUrl = selectedBang?.u.replace(
|
|
"{{{s}}}",
|
|
// Replace %2F with / to fix formats like "!ghr+t3dotgg/unduck"
|
|
encodeURIComponent(cleanQuery).replace(/%2F/g, "/"),
|
|
);
|
|
if (!searchUrl) return null;
|
|
|
|
return searchUrl;
|
|
}
|
|
|
|
function doRedirect() {
|
|
const searchUrl = getBangredirectUrl();
|
|
if (!searchUrl) return;
|
|
window.location.replace(searchUrl);
|
|
}
|
|
|
|
doRedirect();
|