2025-07-08 13:35:23 -04:00
|
|
|
if (!globalThis.TETRATTO_LINK_HANDLER_CTX) {
|
|
|
|
globalThis.TETRATTO_LINK_HANDLER_CTX = "embed";
|
|
|
|
}
|
|
|
|
|
|
|
|
// create little link preview box
|
|
|
|
function create_link_preview() {
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW = document.createElement("div");
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.position = "fixed";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.bottom = "0.5rem";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.left = "0.5rem";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.background = "#323232";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.color = "#ffffff";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.borderRadius = "4px";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.padding = "0.25rem 0.5rem";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.style.display = "none";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.id = "tetratto_link_preview";
|
|
|
|
globalThis.TETRATTO_LINK_PREVIEW.setAttribute(
|
|
|
|
"data-turbo-permanent",
|
|
|
|
"true",
|
|
|
|
);
|
|
|
|
document.body.appendChild(globalThis.TETRATTO_LINK_PREVIEW);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Clean up all "atto://" links on the page.
|
|
|
|
function fix_atto_links() {
|
|
|
|
setTimeout(() => {
|
|
|
|
if (!document.getElementById("tetratto_link_preview")) {
|
|
|
|
create_link_preview();
|
|
|
|
}
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
if (TETRATTO_LINK_HANDLER_CTX === "embed") {
|
|
|
|
// relative links for embeds
|
|
|
|
const path = window.location.pathname.slice("/api/v1/net/".length);
|
|
|
|
|
|
|
|
function fix_element(
|
|
|
|
selector = "a",
|
|
|
|
property = "href",
|
|
|
|
relative = true,
|
|
|
|
) {
|
|
|
|
for (const y of Array.from(document.querySelectorAll(selector))) {
|
|
|
|
if (!y[property].startsWith(window.location.origin)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
let x = new URL(y[property]).pathname;
|
|
|
|
|
|
|
|
if (!x.includes(".html")) {
|
|
|
|
x = `${x}/index.html`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (relative) {
|
|
|
|
y[property] =
|
|
|
|
`atto://${path.replace("atto://", "").split("/")[0]}${x}`;
|
|
|
|
} else {
|
|
|
|
y[property] =
|
2025-07-08 17:38:24 -04:00
|
|
|
`/api/v1/net/${path.replace("atto://", "").split("/")[0]}${x}`;
|
2025-07-08 13:35:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fix_element("a", "href", true);
|
|
|
|
fix_element("link", "href", false);
|
|
|
|
fix_element("script", "src", false);
|
|
|
|
|
|
|
|
// send message
|
|
|
|
window.top.postMessage(
|
|
|
|
JSON.stringify({
|
|
|
|
t: true,
|
|
|
|
event: "change_url",
|
|
|
|
target: window.location.href,
|
|
|
|
}),
|
|
|
|
"*",
|
|
|
|
);
|
|
|
|
|
|
|
|
// handle messages
|
|
|
|
window.addEventListener("message", (e) => {
|
|
|
|
if (typeof e.data !== "string") {
|
|
|
|
console.log("refuse message (bad type)");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = JSON.parse(e.data);
|
|
|
|
|
|
|
|
if (!data.t) {
|
|
|
|
console.log("refuse message (not for tetratto)");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("received message");
|
|
|
|
|
|
|
|
if (data.event === "back") {
|
|
|
|
window.history.back();
|
|
|
|
} else if (data.event === "forward") {
|
|
|
|
window.history.forward();
|
|
|
|
} else if (data.event === "reload") {
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const anchor of Array.from(document.querySelectorAll("a"))) {
|
|
|
|
if (
|
|
|
|
!anchor.href.startsWith("atto://") ||
|
|
|
|
anchor.getAttribute("data-checked") === "true"
|
|
|
|
) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const href = structuredClone(anchor.href);
|
|
|
|
|
|
|
|
anchor.addEventListener("click", () => {
|
|
|
|
if (TETRATTO_LINK_HANDLER_CTX === "net") {
|
|
|
|
window.location.href = `/net/${href.replace("atto://", "")}`;
|
|
|
|
} else {
|
|
|
|
window.location.href = `/api/v1/net/${href}`;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
anchor.addEventListener("mouseenter", () => {
|
|
|
|
TETRATTO_LINK_PREVIEW.innerText = href;
|
|
|
|
TETRATTO_LINK_PREVIEW.style.display = "block";
|
|
|
|
});
|
|
|
|
|
|
|
|
anchor.addEventListener("mouseleave", () => {
|
|
|
|
TETRATTO_LINK_PREVIEW.style.display = "none";
|
|
|
|
});
|
|
|
|
|
|
|
|
anchor.removeAttribute("href");
|
|
|
|
anchor.style.cursor = "pointer";
|
|
|
|
anchor.setAttribute("data-checked", "true");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fix_atto_links();
|
|
|
|
create_link_preview();
|