WAY better system for iframe / topbar handling, and topbar url changes when the iframe url does.
This commit is contained in:
parent
2bf4c596d8
commit
3d8cbf3e72
6 changed files with 370 additions and 326 deletions
11
index.js
11
index.js
|
|
@ -30,15 +30,14 @@ const rammerheadScopes = [
|
||||||
"/editsession",
|
"/editsession",
|
||||||
"/needpassword",
|
"/needpassword",
|
||||||
"/syncLocalStorage",
|
"/syncLocalStorage",
|
||||||
"/api/shuffleDict"
|
"/api/shuffleDict",
|
||||||
];
|
];
|
||||||
const rammerheadSession = /^\/[a-z0-9]{32}/;
|
const rammerheadSession = /^\/[a-z0-9]{32}/;
|
||||||
const bare = createBareServer("/bare/");
|
const bare = createBareServer("/bare/");
|
||||||
console.log(chalk.gray("Starting Bare..."));
|
console.log(chalk.gray("Starting Bare..."));
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(compression({ threshold: 0, filter: () => true })
|
app.use(compression({ threshold: 0, filter: () => true }));
|
||||||
);
|
|
||||||
app.use(express.static(path.join(process.cwd(), "static")));
|
app.use(express.static(path.join(process.cwd(), "static")));
|
||||||
app.use(express.static(path.join(process.cwd(), "build")));
|
app.use(express.static(path.join(process.cwd(), "build")));
|
||||||
app.use("/uv/", express.static(uvPath));
|
app.use("/uv/", express.static(uvPath));
|
||||||
|
|
@ -89,10 +88,7 @@ server.on("upgrade", (req, socket, head) => {
|
||||||
|
|
||||||
function shouldRouteRh(req) {
|
function shouldRouteRh(req) {
|
||||||
const url = new URL(req.url, "http://0.0.0.0");
|
const url = new URL(req.url, "http://0.0.0.0");
|
||||||
return (
|
return rammerheadScopes.includes(url.pathname) || rammerheadSession.test(url.pathname);
|
||||||
rammerheadScopes.includes(url.pathname) ||
|
|
||||||
rammerheadSession.test(url.pathname)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function routeRhRequest(req, res) {
|
function routeRhRequest(req, res) {
|
||||||
|
|
@ -103,7 +99,6 @@ function routeRhUpgrade(req, socket, head) {
|
||||||
rh.emit("upgrade", req, socket, head);
|
rh.emit("upgrade", req, socket, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
console.log(chalk.gray("Starting Alu..."));
|
console.log(chalk.gray("Starting Alu..."));
|
||||||
console.log(chalk.green("Alu started successfully!"));
|
console.log(chalk.green("Alu started successfully!"));
|
||||||
server.on("listening", () => {
|
server.on("listening", () => {
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2e6cd673ab519025af951713868860b7895b11b8
|
Subproject commit 11287d0a834c672a55d10164dbfefe9ee1922d3d
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script src="/uv/uv.bundle.js" transition:persist is:inline></script>
|
<script src="/uv/uv.bundle.js" transition:persist is:inline></script>
|
||||||
<script src="/uv.config.js" transition:persist is:inline></script>
|
<script src="/uv.config.js" transition:persist is:inline></script>
|
||||||
<script>
|
<script is:inline>
|
||||||
//@ts-nocheck
|
//@ts-nocheck
|
||||||
let form = document.querySelector("form");
|
let form = document.querySelector("form");
|
||||||
let input = document.querySelector("input");
|
let input = document.querySelector("input");
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url;
|
else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url;
|
||||||
|
|
||||||
let iframe = document.getElementById("proxy-frame");
|
let iframe = document.getElementById("proxy-frame");
|
||||||
|
let topbar = document.getElementById("top-bar");
|
||||||
|
let closeButton = document.getElementById("close-button");
|
||||||
let preference = getProxyPreference();
|
let preference = getProxyPreference();
|
||||||
if (preference === "ultraviolet") {
|
if (preference === "ultraviolet") {
|
||||||
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
|
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
|
||||||
|
|
@ -34,6 +36,8 @@
|
||||||
if (!rammerheadSession) {
|
if (!rammerheadSession) {
|
||||||
let session = await fetch("/newsession");
|
let session = await fetch("/newsession");
|
||||||
let sessionID = await session.text();
|
let sessionID = await session.text();
|
||||||
|
// Disable URL shuffling on rewrite, eventually I'll try and figure out how it works, but for now, it's disabled.
|
||||||
|
await fetch("/editsession?id=" + sessionID + "&enableShuffling=0");
|
||||||
// Now save it in a cookie that expires in 72 hours.
|
// Now save it in a cookie that expires in 72 hours.
|
||||||
document.cookie = `rammerhead-session=${sessionID}; max-age=${60 * 60 * 72}; path=/`;
|
document.cookie = `rammerhead-session=${sessionID}; max-age=${60 * 60 * 72}; path=/`;
|
||||||
}
|
}
|
||||||
|
|
@ -45,46 +49,28 @@
|
||||||
iframe.style.pointerEvents = "auto";
|
iframe.style.pointerEvents = "auto";
|
||||||
iframe.classList.add("proxy-frame");
|
iframe.classList.add("proxy-frame");
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
iframe.addEventListener("load", () => {
|
iframeURLChange(iframe, (newURL) => updateTopbarURL(preference, newURL));
|
||||||
let topBar = document.getElementById("top-bar");
|
const boundIFrameLoad = iframeLoad.bind(null, iframe, loadingContent, topbar, closeButton);
|
||||||
loadingContent.style.opacity = 0;
|
iframe.addEventListener("load", boundIFrameLoad);
|
||||||
topBar.innerHTML = "";
|
|
||||||
topBar.classList.add("top-bar");
|
|
||||||
let closeButton = document.createElement("button");
|
|
||||||
closeButton.classList.add("close-button");
|
|
||||||
closeButton.innerText = "Close";
|
|
||||||
closeButton.addEventListener("click", () => {
|
|
||||||
iframe.style.opacity = 0;
|
|
||||||
topBar.style.opacity = 0;
|
|
||||||
iframe.style.pointerEvents = "none";
|
|
||||||
topBar.style.pointerEvents = "none";
|
|
||||||
setTimeout(() => {
|
|
||||||
iframe.remove();
|
|
||||||
topBar.remove();
|
|
||||||
|
|
||||||
// recreate them
|
function iframeLoad(iframe, loadingContent, topbar, closeButton) {
|
||||||
iframe = document.createElement("iframe");
|
loadingContent.style.opacity = 0;
|
||||||
iframe.id = "proxy-frame";
|
|
||||||
iframe.style.opacity = 0;
|
|
||||||
iframe.style.pointerEvents = "none";
|
|
||||||
topBar = document.createElement("div");
|
|
||||||
topBar.id = "top-bar";
|
|
||||||
topBar.style.opacity = 0;
|
|
||||||
topBar.style.pointerEvents = "none";
|
|
||||||
document.body.appendChild(topBar);
|
|
||||||
document.body.appendChild(iframe);
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
let urlText = document.createElement("p");
|
|
||||||
urlText.classList.add("url-text");
|
|
||||||
urlText.innerText = window.__uv$config.decodeUrl(iframe.src.split(__uv$config.prefix)[1]);
|
|
||||||
iframe.style.opacity = 1;
|
iframe.style.opacity = 1;
|
||||||
topBar.style.opacity = 1;
|
topbar.style.opacity = 1;
|
||||||
topBar.style.pointerEvents = "auto";
|
topbar.style.pointerEvents = "auto";
|
||||||
topBar.appendChild(closeButton);
|
|
||||||
topBar.appendChild(urlText);
|
closeButton.onclick = () => {
|
||||||
document.body.appendChild(topBar);
|
iframe.style.opacity = 0;
|
||||||
});
|
topbar.style.opacity = 0;
|
||||||
|
iframe.style.pointerEvents = "none";
|
||||||
|
topbar.style.pointerEvents = "none";
|
||||||
|
iframe.removeEventListener("load", boundIFrameLoad);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
iframe.src = "about:blank";
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formEventListener(event) {
|
function formEventListener(event) {
|
||||||
|
|
@ -153,4 +139,52 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function iframeURLChange(iframe, callback) {
|
||||||
|
var lastDispatched = null;
|
||||||
|
|
||||||
|
var dispatchChange = function () {
|
||||||
|
var newHref = iframe.contentWindow.location.href;
|
||||||
|
|
||||||
|
if (newHref !== lastDispatched) {
|
||||||
|
callback(newHref);
|
||||||
|
lastDispatched = newHref;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var unloadHandler = function () {
|
||||||
|
// Timeout needed because the URL changes immediately after
|
||||||
|
// the `unload` event is dispatched.
|
||||||
|
setTimeout(dispatchChange, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
function attachUnload() {
|
||||||
|
// Remove the unloadHandler in case it was already attached.
|
||||||
|
// Otherwise, there will be two handlers, which is unnecessary.
|
||||||
|
iframe.contentWindow.removeEventListener("unload", unloadHandler);
|
||||||
|
iframe.contentWindow.addEventListener("unload", unloadHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe.addEventListener("load", function () {
|
||||||
|
attachUnload();
|
||||||
|
|
||||||
|
// Just in case the change wasn't dispatched during the unload event...
|
||||||
|
dispatchChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
attachUnload();
|
||||||
|
}
|
||||||
|
function updateTopbarURL(preference, newURL) {
|
||||||
|
if (newURL === "about:blank") return;
|
||||||
|
let urlText = document.getElementById("url-text");
|
||||||
|
if (urlText) {
|
||||||
|
if (preference === "rammerhead")
|
||||||
|
urlText.innerText = newURL.slice(
|
||||||
|
newURL.indexOf("/" + getCookie("rammerhead-session")) +
|
||||||
|
getCookie("rammerhead-session").length +
|
||||||
|
2
|
||||||
|
);
|
||||||
|
else urlText.innerText = window.__uv$config.decodeUrl(newURL.split(__uv$config.prefix)[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -54,174 +54,214 @@ const t = useTranslations(lang);
|
||||||
// Cleanup event, this should remove all added event listeners to prepare for if the page is visited again.
|
// Cleanup event, this should remove all added event listeners to prepare for if the page is visited again.
|
||||||
window.currentlySelectedTab = "";
|
window.currentlySelectedTab = "";
|
||||||
document.removeEventListener("setting-tabChange", determineListener);
|
document.removeEventListener("setting-tabChange", determineListener);
|
||||||
|
|
||||||
});
|
});
|
||||||
Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
|
Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
|
||||||
let contentToLoad = document.getElementById("content-" + tab.id);
|
let contentToLoad = document.getElementById("content-" + tab.id);
|
||||||
if (contentToLoad) {
|
if (contentToLoad) {
|
||||||
window.loadedContentStorage[tab.id] = contentToLoad.innerHTML;
|
window.loadedContentStorage[tab.id] = contentToLoad.innerHTML;
|
||||||
contentToLoad.remove();
|
contentToLoad.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
tab.addEventListener("click", (event) => {
|
tab.addEventListener("click", (event) => {
|
||||||
loadContent(event.target.id);
|
loadContent(event.target.id);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadContent(tabID) {
|
|
||||||
if (window.currentlySelectedTab == tabID) return;
|
|
||||||
else window.currentlySelectedTab = tabID;
|
|
||||||
let currentContent = document.getElementById("current-content");
|
|
||||||
if (currentContent) {
|
|
||||||
currentContent.style.opacity = "0";
|
|
||||||
setTimeout(() => {
|
|
||||||
currentContent.innerHTML = window.loadedContentStorage[tabID];
|
|
||||||
currentContent.style.opacity = "1";
|
|
||||||
document.dispatchEvent(new CustomEvent("setting-tabChange", { detail: tabID }));
|
|
||||||
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
|
|
||||||
}, 250);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addDropdownListener() {
|
|
||||||
let dropdown_toggles = document.getElementsByClassName("dropdown-toggle");
|
|
||||||
Array.from(dropdown_toggles).forEach((toggle) => {
|
|
||||||
toggle.onclick = function() {
|
|
||||||
closeOtherDropdowns(toggle.id);
|
|
||||||
toggleDropdown(toggle);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleDropdown(toggle) {
|
|
||||||
let dropdown = document.getElementById(toggle.id + "-menu");
|
|
||||||
if (dropdown.style.maxHeight == "0px" || dropdown.style.maxHeight == "") {
|
|
||||||
dropdown.style.maxHeight = dropdown.scrollHeight + "px";
|
|
||||||
toggle.style.borderRadius = "10px 10px 0 0";
|
|
||||||
} else {
|
|
||||||
dropdown.style.maxHeight = "0px";
|
|
||||||
setTimeout(() => {
|
|
||||||
toggle.style.borderRadius = "10px";
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function determineListener(event) {
|
|
||||||
if (event.detail == "setting-tab-proxy") {
|
|
||||||
addDropdownListener();
|
|
||||||
} else if (event.detail == "setting-tab-customization") {
|
|
||||||
addDropdownListener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeOtherDropdowns(dropdownIDToExclude) {
|
|
||||||
let dropdowns = document.getElementsByClassName("dropdown-menu");
|
|
||||||
Array.from(dropdowns).forEach((dropdown) => {
|
|
||||||
dropdown.style.maxHeight = "0px";
|
|
||||||
setTimeout(() => {
|
|
||||||
if (dropdown.id != dropdownIDToExclude + "-menu") {
|
|
||||||
let dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", ""));
|
|
||||||
dropdown_toggle.style.borderRadius = "10px";
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeDropdown(dropdownID) {
|
|
||||||
let dropdown = document.getElementById(dropdownID);
|
|
||||||
if (dropdown) {
|
|
||||||
dropdown.style.maxHeight = "0px";
|
|
||||||
setTimeout(() => {
|
|
||||||
let dropdown_toggle = document.getElementById(dropdownID.replace("-menu", ""));
|
|
||||||
dropdown_toggle.style.borderRadius = "10px";
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocalStorageValue(localStorageItem, dropdownID) {
|
|
||||||
// I was kinda dumb for not doing this earlier.
|
|
||||||
let dropdown = document.getElementById(dropdownID);
|
|
||||||
let dropdownMenu = document.getElementById(dropdownID + "-menu");
|
|
||||||
|
|
||||||
if (dropdown && dropdownMenu) {
|
|
||||||
// Now we find the child that matches localStorageItem.value.
|
|
||||||
let dropdownItem = Array.from(dropdownMenu.children).find((item) => {
|
|
||||||
return JSON.parse(localStorage.getItem(localStorageItem)).value == item.dataset.setting;
|
|
||||||
});
|
});
|
||||||
// Now set the inner text to the name in the dropdownItem.
|
});
|
||||||
return dropdownItem.innerText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applySavedLocalStorage(localStorageItem, dropdownID) {
|
function loadContent(tabID) {
|
||||||
if (localStorage.getItem(localStorageItem)) {
|
if (window.currentlySelectedTab == tabID) return;
|
||||||
let dropdown_toggle = document.getElementById(dropdownID);
|
else window.currentlySelectedTab = tabID;
|
||||||
if (dropdown_toggle) {
|
let currentContent = document.getElementById("current-content");
|
||||||
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID);
|
if (currentContent) {
|
||||||
|
currentContent.style.opacity = "0";
|
||||||
|
setTimeout(() => {
|
||||||
|
currentContent.innerHTML = window.loadedContentStorage[tabID];
|
||||||
|
currentContent.style.opacity = "1";
|
||||||
|
document.dispatchEvent(new CustomEvent("setting-tabChange", { detail: tabID }));
|
||||||
|
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
|
||||||
|
}, 250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function applyDropdownEventListeners(item, dropdownID, localStorageItem, optionalCallback) {
|
function addDropdownListener() {
|
||||||
Array.from(item.children).forEach((item) => {
|
let dropdown_toggles = document.getElementsByClassName("dropdown-toggle");
|
||||||
item.onclick = () => {
|
Array.from(dropdown_toggles).forEach((toggle) => {
|
||||||
let localStorageItemContent = {
|
toggle.onclick = function () {
|
||||||
name: item.innerText,
|
closeOtherDropdowns(toggle.id);
|
||||||
value: item.dataset.setting,
|
toggleDropdown(toggle);
|
||||||
};
|
};
|
||||||
localStorage.setItem(localStorageItem, JSON.stringify(localStorageItemContent));
|
});
|
||||||
applySavedLocalStorage(localStorageItem, dropdownID);
|
}
|
||||||
closeDropdown(item.parentElement.id);
|
|
||||||
if (typeof optionalCallback == "function") {
|
function toggleDropdown(toggle) {
|
||||||
optionalCallback();
|
let dropdown = document.getElementById(toggle.id + "-menu");
|
||||||
|
if (dropdown.style.maxHeight == "0px" || dropdown.style.maxHeight == "") {
|
||||||
|
dropdown.style.maxHeight = dropdown.scrollHeight + "px";
|
||||||
|
toggle.style.borderRadius = "10px 10px 0 0";
|
||||||
|
} else {
|
||||||
|
dropdown.style.maxHeight = "0px";
|
||||||
|
setTimeout(() => {
|
||||||
|
toggle.style.borderRadius = "10px";
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function determineListener(event) {
|
||||||
|
if (event.detail == "setting-tab-proxy") {
|
||||||
|
addDropdownListener();
|
||||||
|
} else if (event.detail == "setting-tab-customization") {
|
||||||
|
addDropdownListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeOtherDropdowns(dropdownIDToExclude) {
|
||||||
|
let dropdowns = document.getElementsByClassName("dropdown-menu");
|
||||||
|
Array.from(dropdowns).forEach((dropdown) => {
|
||||||
|
dropdown.style.maxHeight = "0px";
|
||||||
|
setTimeout(() => {
|
||||||
|
if (dropdown.id != dropdownIDToExclude + "-menu") {
|
||||||
|
let dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", ""));
|
||||||
|
dropdown_toggle.style.borderRadius = "10px";
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDropdown(dropdownID) {
|
||||||
|
let dropdown = document.getElementById(dropdownID);
|
||||||
|
if (dropdown) {
|
||||||
|
dropdown.style.maxHeight = "0px";
|
||||||
|
setTimeout(() => {
|
||||||
|
let dropdown_toggle = document.getElementById(dropdownID.replace("-menu", ""));
|
||||||
|
dropdown_toggle.style.borderRadius = "10px";
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalStorageValue(localStorageItem, dropdownID) {
|
||||||
|
// I was kinda dumb for not doing this earlier.
|
||||||
|
let dropdown = document.getElementById(dropdownID);
|
||||||
|
let dropdownMenu = document.getElementById(dropdownID + "-menu");
|
||||||
|
|
||||||
|
if (dropdown && dropdownMenu) {
|
||||||
|
// Now we find the child that matches localStorageItem.value.
|
||||||
|
let dropdownItem = Array.from(dropdownMenu.children).find((item) => {
|
||||||
|
return JSON.parse(localStorage.getItem(localStorageItem)).value == item.dataset.setting;
|
||||||
|
});
|
||||||
|
// Now set the inner text to the name in the dropdownItem.
|
||||||
|
return dropdownItem.innerText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySavedLocalStorage(localStorageItem, dropdownID) {
|
||||||
|
if (localStorage.getItem(localStorageItem)) {
|
||||||
|
let dropdown_toggle = document.getElementById(dropdownID);
|
||||||
|
if (dropdown_toggle) {
|
||||||
|
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function applyInputListeners(item, localStorageItem) {
|
function applyDropdownEventListeners(item, dropdownID, localStorageItem, optionalCallback) {
|
||||||
item.addEventListener("input", () => {
|
Array.from(item.children).forEach((item) => {
|
||||||
localStorage.setItem(localStorageItem, item.value);
|
item.onclick = () => {
|
||||||
});
|
let localStorageItemContent = {
|
||||||
}
|
name: item.innerText,
|
||||||
|
value: item.dataset.setting,
|
||||||
|
};
|
||||||
|
localStorage.setItem(localStorageItem, JSON.stringify(localStorageItemContent));
|
||||||
|
applySavedLocalStorage(localStorageItem, dropdownID);
|
||||||
|
closeDropdown(item.parentElement.id);
|
||||||
|
if (typeof optionalCallback == "function") {
|
||||||
|
optionalCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("setting-tabChange", determineListener);
|
function applyInputListeners(item, localStorageItem) {
|
||||||
|
item.addEventListener("input", () => {
|
||||||
|
localStorage.setItem(localStorageItem, item.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
loadContent("setting-tab-proxy");
|
document.addEventListener("setting-tabChange", determineListener);
|
||||||
|
|
||||||
function setupCustomizationSettings() {
|
loadContent("setting-tab-proxy");
|
||||||
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
|
|
||||||
applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language");
|
|
||||||
let themeDropdown = document.getElementById("dropdown__selected-theme-menu");
|
|
||||||
let languageDropdown = document.getElementById("dropdown__selected-language-menu");
|
|
||||||
applyDropdownEventListeners(
|
|
||||||
themeDropdown,
|
|
||||||
"dropdown__selected-theme",
|
|
||||||
"alu__selectedTheme",
|
|
||||||
changeTheme
|
|
||||||
);
|
|
||||||
applyDropdownEventListeners(
|
|
||||||
languageDropdown,
|
|
||||||
"dropdown__selected-language",
|
|
||||||
"alu__selectedLanguage",
|
|
||||||
navigateToNewLangaugePage
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupCloakingSettings() {
|
function setupCustomizationSettings() {
|
||||||
Array.from(document.getElementById("cloak-list").children).forEach((cloak) => {
|
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
|
||||||
cloak.addEventListener("click", () => {
|
applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language");
|
||||||
let cloakName = cloak.dataset.cloakName;
|
let themeDropdown = document.getElementById("dropdown__selected-theme-menu");
|
||||||
let cloakIcon = cloak.dataset.cloakIcon;
|
let languageDropdown = document.getElementById("dropdown__selected-language-menu");
|
||||||
|
applyDropdownEventListeners(
|
||||||
|
themeDropdown,
|
||||||
|
"dropdown__selected-theme",
|
||||||
|
"alu__selectedTheme",
|
||||||
|
changeTheme
|
||||||
|
);
|
||||||
|
applyDropdownEventListeners(
|
||||||
|
languageDropdown,
|
||||||
|
"dropdown__selected-language",
|
||||||
|
"alu__selectedLanguage",
|
||||||
|
navigateToNewLangaugePage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupCloakingSettings() {
|
||||||
|
Array.from(document.getElementById("cloak-list").children).forEach((cloak) => {
|
||||||
|
cloak.addEventListener("click", () => {
|
||||||
|
let cloakName = cloak.dataset.cloakName;
|
||||||
|
let cloakIcon = cloak.dataset.cloakIcon;
|
||||||
|
|
||||||
|
let localStorageItem = {
|
||||||
|
name: cloakName,
|
||||||
|
icon: cloakIcon,
|
||||||
|
isCustom: false,
|
||||||
|
};
|
||||||
|
localStorage.setItem("alu__selectedCloak", JSON.stringify(localStorageItem));
|
||||||
|
|
||||||
|
if (cloakName == "None") {
|
||||||
|
localStorage.removeItem("alu__selectedCloak");
|
||||||
|
cloakName = "Settings | Alu";
|
||||||
|
cloakIcon = "/favicon.svg";
|
||||||
|
}
|
||||||
|
let link = document.querySelector("link[rel~='icon']");
|
||||||
|
if (!link) {
|
||||||
|
link = document.createElement("link");
|
||||||
|
link.rel = "icon";
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
link.href = cloakIcon;
|
||||||
|
document.title = cloakName;
|
||||||
|
|
||||||
|
if (!cloak.classList.contains("selected")) {
|
||||||
|
Array.from(document.getElementById("cloak-list").children).forEach((cloak2) => {
|
||||||
|
cloak2.classList.remove("selected");
|
||||||
|
});
|
||||||
|
cloak.classList.add("selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let customNameInput = document.getElementById("cloak-custom-name-input");
|
||||||
|
let customFaviconInput = document.getElementById("cloak-custom-favicon-input");
|
||||||
|
if (localStorage.getItem("alu__selectedCloak")) {
|
||||||
|
let selectedCloak = JSON.parse(localStorage.getItem("alu__selectedCloak"));
|
||||||
|
if (selectedCloak.isCustom) {
|
||||||
|
customNameInput.value = selectedCloak.name;
|
||||||
|
customFaviconInput.value = selectedCloak.icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("cloak-custom-button").addEventListener("click", () => {
|
||||||
|
let cloakName = document.getElementById("cloak-custom-name-input").value;
|
||||||
|
let cloakIcon = document.getElementById("cloak-custom-favicon-input").value;
|
||||||
let localStorageItem = {
|
let localStorageItem = {
|
||||||
name: cloakName,
|
name: cloakName,
|
||||||
icon: cloakIcon,
|
icon: cloakIcon,
|
||||||
isCustom: false,
|
isCustom: true,
|
||||||
};
|
};
|
||||||
localStorage.setItem("alu__selectedCloak", JSON.stringify(localStorageItem));
|
localStorage.setItem("alu__selectedCloak", JSON.stringify(localStorageItem));
|
||||||
|
|
||||||
if (cloakName == "None") {
|
if (cloakName == "None") {
|
||||||
localStorage.removeItem("alu__selectedCloak");
|
localStorage.removeItem("alu__selectedCloak");
|
||||||
cloakName = "Settings | Alu";
|
cloakName = "Settings | Alu";
|
||||||
|
|
@ -235,140 +275,102 @@ const t = useTranslations(lang);
|
||||||
}
|
}
|
||||||
link.href = cloakIcon;
|
link.href = cloakIcon;
|
||||||
document.title = cloakName;
|
document.title = cloakName;
|
||||||
|
|
||||||
if (!cloak.classList.contains("selected")) {
|
|
||||||
Array.from(document.getElementById("cloak-list").children).forEach((cloak2) => {
|
|
||||||
cloak2.classList.remove("selected");
|
|
||||||
});
|
|
||||||
cloak.classList.add("selected");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
let customNameInput = document.getElementById("cloak-custom-name-input");
|
function changeTheme() {
|
||||||
let customFaviconInput = document.getElementById("cloak-custom-favicon-input");
|
let theme = JSON.parse(localStorage.getItem("alu__selectedTheme")).value;
|
||||||
if (localStorage.getItem("alu__selectedCloak")) {
|
if (theme) {
|
||||||
let selectedCloak = JSON.parse(localStorage.getItem("alu__selectedCloak"));
|
document.documentElement.setAttribute("data-theme", theme.toLowerCase());
|
||||||
if (selectedCloak.isCustom) {
|
let footer = document.getElementById("footer");
|
||||||
customNameInput.value = selectedCloak.name;
|
if (footer) {
|
||||||
customFaviconInput.value = selectedCloak.icon;
|
footer.dataset.theme = theme.toLowerCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("cloak-custom-button").addEventListener("click", () => {
|
function setupSettings(event) {
|
||||||
let cloakName = document.getElementById("cloak-custom-name-input").value;
|
if (event.detail == "setting-tab-proxy") {
|
||||||
let cloakIcon = document.getElementById("cloak-custom-favicon-input").value;
|
applySavedLocalStorage("alu__selectedProxy", "dropdown__selected-proxy");
|
||||||
let localStorageItem = {
|
applySavedLocalStorage("alu__search_engine", "dropdown__search-engine");
|
||||||
name: cloakName,
|
applySavedLocalStorage("alu__selectedOpenWith", "dropdown__open-with");
|
||||||
icon: cloakIcon,
|
let selectedProxyDropdown = document.getElementById("dropdown__selected-proxy-menu");
|
||||||
isCustom: true,
|
let searchEngineDropdown = document.getElementById("dropdown__search-engine-menu");
|
||||||
};
|
let openWithDropdown = document.getElementById("dropdown__open-with-menu");
|
||||||
localStorage.setItem("alu__selectedCloak", JSON.stringify(localStorageItem));
|
let bareUrlInput = document.getElementById("bare-url-input");
|
||||||
if (cloakName == "None") {
|
let searxngUrlInput = document.getElementById("searxng-url-input");
|
||||||
localStorage.removeItem("alu__selectedCloak");
|
let savedSearxngUrl = localStorage.getItem("alu__searxngUrl");
|
||||||
cloakName = "Settings | Alu";
|
if (savedSearxngUrl != undefined) {
|
||||||
cloakIcon = "/favicon.svg";
|
if (savedSearxngUrl == "")
|
||||||
|
localStorage.setItem("alu__searxngUrl", "https://searxng.site/");
|
||||||
|
searxngUrlInput.value = localStorage.getItem("alu__searxngUrl");
|
||||||
|
}
|
||||||
|
// Proxy settings
|
||||||
|
applyInputListeners(bareUrlInput, "alu__bareUrl");
|
||||||
|
applyInputListeners(searxngUrlInput, "alu__searxngUrl");
|
||||||
|
applyDropdownEventListeners(
|
||||||
|
searchEngineDropdown,
|
||||||
|
"dropdown__search-engine",
|
||||||
|
"alu__search_engine",
|
||||||
|
checkSearxng
|
||||||
|
);
|
||||||
|
applyDropdownEventListeners(
|
||||||
|
selectedProxyDropdown,
|
||||||
|
"dropdown__selected-proxy",
|
||||||
|
"alu__selectedProxy"
|
||||||
|
);
|
||||||
|
applyDropdownEventListeners(
|
||||||
|
openWithDropdown,
|
||||||
|
"dropdown__open-with",
|
||||||
|
"alu__selectedOpenWith"
|
||||||
|
);
|
||||||
|
if (localStorage.getItem("bareUrl")) {
|
||||||
|
bareUrlInput.value = localStorage.getItem("bareUrl");
|
||||||
|
} else {
|
||||||
|
bareUrlInput.value = "/bare/";
|
||||||
|
}
|
||||||
|
checkSearxng();
|
||||||
|
} else if (event.detail == "setting-tab-customization") {
|
||||||
|
setupCustomizationSettings();
|
||||||
|
} else if (event.detail == "setting-tab-cloaking") {
|
||||||
|
setupCloakingSettings();
|
||||||
}
|
}
|
||||||
let link = document.querySelector("link[rel~='icon']");
|
}
|
||||||
if (!link) {
|
|
||||||
link = document.createElement("link");
|
|
||||||
link.rel = "icon";
|
|
||||||
document.head.appendChild(link);
|
|
||||||
}
|
|
||||||
link.href = cloakIcon;
|
|
||||||
document.title = cloakName;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeTheme() {
|
function checkSearxng() {
|
||||||
let theme = JSON.parse(localStorage.getItem("alu__selectedTheme")).value;
|
// This function checks if the "searxng" option was clicked, display an additional option if so.
|
||||||
if (theme) {
|
if (localStorage.getItem("alu__search_engine")) {
|
||||||
document.documentElement.setAttribute("data-theme", theme.toLowerCase());
|
if (JSON.parse(localStorage.getItem("alu__search_engine")).value.toLowerCase() == "searx") {
|
||||||
let footer = document.getElementById("footer");
|
document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "1";
|
||||||
if (footer) {
|
} else {
|
||||||
footer.dataset.theme = theme.toLowerCase();
|
document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("setting-tabLoad", setupSettings);
|
||||||
|
|
||||||
|
function navigateToNewLangaugePage() {
|
||||||
|
let value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value;
|
||||||
|
let currentLanguage = window.location.pathname.split("/")[1];
|
||||||
|
// Do nothing.. because we're already on the page.
|
||||||
|
if (value == currentLanguage) return;
|
||||||
|
switch (value) {
|
||||||
|
case "en":
|
||||||
|
window.location.href = "/en/settings/";
|
||||||
|
break;
|
||||||
|
case "jp":
|
||||||
|
window.location.href = "/jp/settings/";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
document.addEventListener("astro:after-swap", () => {
|
||||||
function setupSettings(event) {
|
|
||||||
if (event.detail == "setting-tab-proxy") {
|
|
||||||
applySavedLocalStorage("alu__selectedProxy", "dropdown__selected-proxy");
|
|
||||||
applySavedLocalStorage("alu__search_engine", "dropdown__search-engine");
|
|
||||||
applySavedLocalStorage("alu__selectedOpenWith", "dropdown__open-with");
|
|
||||||
let selectedProxyDropdown = document.getElementById("dropdown__selected-proxy-menu");
|
|
||||||
let searchEngineDropdown = document.getElementById("dropdown__search-engine-menu");
|
|
||||||
let openWithDropdown = document.getElementById("dropdown__open-with-menu");
|
|
||||||
let bareUrlInput = document.getElementById("bare-url-input");
|
|
||||||
let searxngUrlInput = document.getElementById("searxng-url-input");
|
|
||||||
let savedSearxngUrl = localStorage.getItem("alu__searxngUrl");
|
|
||||||
if (savedSearxngUrl != undefined) {
|
|
||||||
if (savedSearxngUrl == "") localStorage.setItem("alu__searxngUrl", "https://searxng.site/");
|
|
||||||
searxngUrlInput.value = localStorage.getItem("alu__searxngUrl");
|
|
||||||
}
|
|
||||||
// Proxy settings
|
|
||||||
applyInputListeners(bareUrlInput, "alu__bareUrl");
|
|
||||||
applyInputListeners(searxngUrlInput, "alu__searxngUrl");
|
|
||||||
applyDropdownEventListeners(
|
|
||||||
searchEngineDropdown,
|
|
||||||
"dropdown__search-engine",
|
|
||||||
"alu__search_engine",
|
|
||||||
checkSearxng
|
|
||||||
);
|
|
||||||
applyDropdownEventListeners(
|
|
||||||
selectedProxyDropdown,
|
|
||||||
"dropdown__selected-proxy",
|
|
||||||
"alu__selectedProxy"
|
|
||||||
);
|
|
||||||
applyDropdownEventListeners(openWithDropdown, "dropdown__open-with", "alu__selectedOpenWith");
|
|
||||||
if (localStorage.getItem("bareUrl")) {
|
|
||||||
bareUrlInput.value = localStorage.getItem("bareUrl");
|
|
||||||
} else {
|
|
||||||
bareUrlInput.value = "/bare/";
|
|
||||||
}
|
|
||||||
checkSearxng();
|
|
||||||
} else if (event.detail == "setting-tab-customization") {
|
|
||||||
setupCustomizationSettings();
|
|
||||||
} else if (event.detail == "setting-tab-cloaking") {
|
|
||||||
setupCloakingSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSearxng() {
|
|
||||||
// This function checks if the "searxng" option was clicked, display an additional option if so.
|
|
||||||
if (localStorage.getItem("alu__search_engine")) {
|
|
||||||
if (JSON.parse(localStorage.getItem("alu__search_engine")).value.toLowerCase() == "searx") {
|
|
||||||
document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "1";
|
|
||||||
} else {
|
|
||||||
document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("setting-tabLoad", setupSettings);
|
|
||||||
|
|
||||||
function navigateToNewLangaugePage() {
|
|
||||||
let value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value;
|
|
||||||
let currentLanguage = window.location.pathname.split("/")[1];
|
|
||||||
// Do nothing.. because we're already on the page.
|
|
||||||
if (value == currentLanguage) return;
|
|
||||||
switch (value) {
|
|
||||||
case "en":
|
|
||||||
window.location.href = "/en/settings/";
|
|
||||||
break;
|
|
||||||
case "jp":
|
|
||||||
window.location.href = "/jp/settings/";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.addEventListener('astro:after-swap', () => {
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
settingsLoad();
|
settingsLoad();
|
||||||
}, 300);
|
}, 300);
|
||||||
|
});
|
||||||
})
|
settingsLoad();
|
||||||
settingsLoad()
|
|
||||||
</script>
|
</script>
|
||||||
<style is:global>
|
<style is:global>
|
||||||
.content-hidden {
|
.content-hidden {
|
||||||
|
|
|
||||||
|
|
@ -28,16 +28,25 @@ const { title, optionalPreloads } = Astro.props;
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="title" content="Alu" />
|
<meta name="title" content="Alu" />
|
||||||
<meta name="description" content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization." />
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization."
|
||||||
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://aluu.xyz" />
|
<meta property="og:url" content="https://aluu.xyz" />
|
||||||
<meta property="og:title" content="Alu" />
|
<meta property="og:title" content="Alu" />
|
||||||
<meta property="og:description" content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization." />
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization."
|
||||||
|
/>
|
||||||
<meta property="og:image" content="/logo.png" />
|
<meta property="og:image" content="/logo.png" />
|
||||||
<meta property="twitter:card" content="summary_large_image" />
|
<meta property="twitter:card" content="summary_large_image" />
|
||||||
<meta property="twitter:url" content="https://aluu.xyz" />
|
<meta property="twitter:url" content="https://aluu.xyz" />
|
||||||
<meta property="twitter:title" content="Alu" />
|
<meta property="twitter:title" content="Alu" />
|
||||||
<meta property="twitter:description" content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization." />
|
<meta
|
||||||
|
property="twitter:description"
|
||||||
|
content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization."
|
||||||
|
/>
|
||||||
<meta property="twitter:image" content="/logo.png" />
|
<meta property="twitter:image" content="/logo.png" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
|
@ -166,7 +175,7 @@ const { title, optionalPreloads } = Astro.props;
|
||||||
#proxy-frame {
|
#proxy-frame {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.top-bar {
|
#top-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -179,10 +188,11 @@ const { title, optionalPreloads } = Astro.props;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
transition: opacity 350ms ease-in-out;
|
transition: opacity 250ms ease-in-out;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.close-button {
|
#close-button {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
padding-inline: 40px;
|
padding-inline: 40px;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,12 @@ export function getStaticPaths() {
|
||||||
/>
|
/>
|
||||||
<div id="search-suggestions"></div>
|
<div id="search-suggestions"></div>
|
||||||
<div id="loading-content">Loading...</div>
|
<div id="loading-content">Loading...</div>
|
||||||
<div id="top-bar"></div>
|
|
||||||
<iframe title="proxy-iframe" id="proxy-frame"></iframe>
|
|
||||||
</form>
|
</form>
|
||||||
|
<div id="top-bar">
|
||||||
|
<button id="close-button">Close</button>
|
||||||
|
<span id="url-text"></span>
|
||||||
|
</div>
|
||||||
|
<iframe title="proxy-iframe" id="proxy-frame"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="faq-section">
|
<div class="faq-section">
|
||||||
|
|
@ -44,8 +47,8 @@ export function getStaticPaths() {
|
||||||
<p>
|
<p>
|
||||||
Spreading the word of Alu is a great start, but if you really enjoy Alu, and want private
|
Spreading the word of Alu is a great start, but if you really enjoy Alu, and want private
|
||||||
links, consider supporting me through Patreon! You can support me
|
links, consider supporting me through Patreon! You can support me
|
||||||
<Link href="https://www.patreon.com/wearr/membership" newTab content="Here!" />,
|
<Link href="https://www.patreon.com/wearr/membership" newTab content="Here!" />, thank you
|
||||||
thank you for helping to make Alu great!
|
for helping to make Alu great!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue