Files
frontend/proxy.html
first@lynx.com 3f1bb80f8f clean up proxy top bar
drop the home button, revert the go-button restyle, add breathing
room between the bar and the recommended sites grid below it
2026-08-24 17:02:06 -04:00

200 lines
6.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-J0Y3T4HN4N"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-J0Y3T4HN4N');
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Selenite",
"alternateName": "selenite.cc",
"url": "https://selenite.cc",
"logo": "https://selenite.cc/favicon.png",
"sameAs": [
"https://github.com/selenite-cc",
"https://youtube.com/@selenitecc",
"https://tiktok.com/@selenitecc",
"https://selenite.cc",
]
}
</script>
<link rel="stylesheet" href="/css/main.css" />
<link rel="stylesheet" href="/css/pages.css" />
<link rel="stylesheet" href="/css/proxy.css" />
<link rel="manifest" href="/manifest.json" />
<title>Selenite</title>
<link rel="icon" href="/favicon.ico" />
<script src="/scram-assets/scramjet.all.js"></script>
<script src="/scram-assets/baremux/index.js"></script>
<script defer>
"use strict";
const swAllowedHostnames = ["localhost", "127.0.0.1"];
async function registerProxySW() {
if (!navigator.serviceWorker) {
throw new Error("your browser doesn't support service workers.");
}
if (location.protocol !== "https:" && !swAllowedHostnames.includes(location.hostname)) {
throw new Error("service workers cannot be registered without https.");
}
const registration = await navigator.serviceWorker.register("/scram-sw.js", { scope: "/scram/" });
const worker = registration.installing || registration.waiting || registration.active;
if (worker && worker.state !== "activated") {
await new Promise((resolve) => {
worker.addEventListener("statechange", () => {
if (worker.state === "activated") resolve();
});
});
}
}
async function renderProxyShortcuts(onSelect) {
const grid = document.getElementById("proxyShortcutsGrid");
if (!grid) return;
try {
const sites = await (await fetch("/resources/proxysites.json")).json();
const fragment = document.createDocumentFragment();
sites.forEach((site) => {
const button = document.createElement("button");
button.type = "button";
button.className = "proxyShortcut";
button.dataset.url = site.url;
const icon = document.createElement("img");
icon.src = site.icon || `https://s2.googleusercontent.com/s2/favicons?domain_url=${encodeURIComponent(site.url)}&sz=256`;
if (site.iconBg) {
icon.style.backgroundColor = site.iconBg;
icon.style.padding = "10px";
icon.style.boxSizing = "border-box";
}
const holder = document.createElement("div");
holder.className = "proxyShortcutHolder";
const title = document.createElement("h1");
title.innerText = site.name;
holder.appendChild(title);
button.appendChild(icon);
button.appendChild(holder);
button.addEventListener("click", () => onSelect(site.url));
fragment.appendChild(button);
});
grid.appendChild(fragment);
} catch {
const shortcuts = document.getElementById("proxyShortcuts");
if (shortcuts) shortcuts.style.display = "none";
}
}
function resolveAddress(input) {
try {
return new URL(input).toString();
} catch { }
try {
const url = new URL(`http://${input}`);
if (url.hostname.includes(".")) return url.toString();
} catch { }
return `https://www.google.com/search?q=${encodeURIComponent(input)}`;
}
document.addEventListener("DOMContentLoaded", () => {
const form = document.getElementById("sj-form");
const address = document.getElementById("sj-address");
const error = document.getElementById("sj-error");
const errorCode = document.getElementById("sj-error-code");
const frameHolder = document.getElementById("proxyFrameHolder");
const { ScramjetController } = $scramjetLoadController();
const scramjet = new ScramjetController({
prefix: "/scram/",
files: {
wasm: "/scram-assets/scramjet.wasm.wasm",
all: "/scram-assets/scramjet.all.js",
sync: "/scram-assets/scramjet.sync.js",
},
});
scramjet.init();
const connection = new BareMux.BareMuxConnection("/scram-assets/baremux/worker.js");
form.addEventListener("submit", async (event) => {
event.preventDefault();
error.textContent = "";
errorCode.textContent = "";
try {
await registerProxySW();
} catch (err) {
error.textContent = "failed to register service worker.";
errorCode.textContent = err.toString();
return;
}
const url = resolveAddress(address.value);
try {
const wispUrl = (location.protocol === "https:" ? "wss" : "ws") + "://" + location.host + "/wisp/";
if ((await connection.getTransport()) !== "/scram-assets/libcurl/index.mjs") {
await connection.setTransport("/scram-assets/libcurl/index.mjs", [{ websocket: wispUrl }]);
}
} catch (err) {
error.textContent = "failed to set up the proxy connection.";
errorCode.textContent = err.toString();
return;
}
frameHolder.innerHTML = "";
const frame = scramjet.createFrame();
frame.frame.id = "sj-frame";
frameHolder.appendChild(frame.frame);
frame.go(url);
});
document.getElementById("proxyFullscreen").addEventListener("click", () => {
const frame = document.getElementById("sj-frame");
if (frame) frame.requestFullscreen();
});
renderProxyShortcuts((url) => {
address.value = url;
form.requestSubmit();
});
});
</script>
</head>
<body>
<div id="proxyBar">
<form id="sj-form">
<input id="sj-address" type="text" placeholder="search or enter a url" autocomplete="off" />
<button type="submit">go</button>
</form>
<img id="proxyFullscreen" src="/img/fullscreen.svg" title="fullscreen" />
</div>
<div id="proxyError">
<p id="sj-error"></p>
<pre id="sj-error-code"></pre>
</div>
<div id="proxyFrameHolder">
<div id="proxyShortcuts">
<p class="filterLabel">recommended sites</p>
<div id="proxyShortcutsGrid"></div>
</div>
</div>
</body>
</html>