garden/themes/cortex/assets/js/page.js
SouthFox 08db36282d
All checks were successful
continuous-integration/drone Build is passing
new init
2023-05-20 19:32:59 +08:00

218 lines
6 KiB
JavaScript

let pages = [window.location.pathname];
let switchDirectionWindowWidth = 900;
let animationLength = 200;
let isso_onload_init = false;
function stackNote(href, level) {
level = Number(level) || pages.length;
uri = URI(window.location);
stacks = [];
if (uri.hasQuery("stack")) {
stacks = uri.query(true).stack;
if (!Array.isArray(stacks)) {
stacks = [stacks];
}
stacks = stacks.slice(0, level - 1);
}
stacks.push(URI(href).suffix("").path());
uri.setQuery("stack", stacks);
old_stacks = stacks.slice(0, level - 1);
state = { stacks: old_stacks, level: level };
window.history.pushState(state, "", uri.href());
}
function unstackNotes(level) {
let container = document.querySelector(".grid");
let children = Array.prototype.slice.call(container.children);
for (let i = level; i < pages.length; i++) {
container.removeChild(children[i]);
destroyPreviews(children[i]);
}
pages = pages.slice(0, level);
}
function fetchNote(href, level, animate = false) {
if (pages.indexOf(URI(href).path()) > -1) return;
isso_del = (pages.length == level);
level = Number(level) || pages.length;
const request = new Request(href);
fetch(request)
.then((response) => response.text())
.then((text) => {
unstackNotes(level);
let container = document.querySelector(".grid");
let fragment = document.createElement("template");
fragment.innerHTML = text;
document.querySelectorAll(".comment").forEach(el => el.remove());
let element = fragment.content.querySelector(".page");
container.appendChild(element);
pages.push(URI(href).path());
setTimeout(
function (element, level) {
element.dataset.level = level + 1;
initializePreviews(element, level + 1);
href = URI(href);
if (href.fragment() !== "") {
document.getElementById(decodeURI(href.fragment())).scrollIntoView();
} else {
element.scrollIntoView();
}
// if (animate) {
// element.animate([{ opacity: 0 }, { opacity: 1 }], animationLength);
// }
if (isso_onload_init) {
window.Isso.init();
window.Isso.fetchComments();
}
if (window.MathJax) {
window.MathJax.typeset();
}
}.bind(null, element, level),
10
);
updateLinkStatuses();
});
}
function updateLinkStatuses() {
links = Array.prototype.slice.call(document.querySelectorAll("a"));
links.forEach(function (link) {
if (pages.indexOf(link.getAttribute("href")) > -1) {
link.classList.add("active");
if (link._tippy) link._tippy.disable();
} else {
link.classList.remove("active");
if (link._tippy) link._tippy.enable();
}
});
}
function destroyPreviews(page) {
links = Array.prototype.slice.call(page.querySelectorAll("a"));
links.forEach(function (link) {
if (link.hasOwnProperty("_tippy")) {
link._tippy.destroy();
}
});
}
let tippyOptions = {
allowHTML: true,
theme: "light",
interactive: true,
interactiveBorder: 10,
delay: 500,
touch: ["hold", 500],
maxWidth: "none",
inlinePositioning: false,
placement: "right",
};
function createPreview(link, html, overrideOptions) {
level = Number(link.dataset.level);
iframe = document.createElement('iframe');
iframe.width = "400px";
iframe.height = "300px";
iframe.srcdoc = html;
tip = tippy(
link,
Object.assign(
{},
tippyOptions,
{
content: iframe.outerHTML
// '<iframe width="400px" height="300px" srcdoc="' +
// escape(html) +
// '"></iframe>',
},
overrideOptions
)
);
}
function initializePreviews(page, level) {
level = level || pages.length;
links = Array.prototype.slice.call(page.querySelectorAll("a:not(.rooter)"));
links.forEach(async function (element) {
var rawHref = element.getAttribute("href");
element.dataset.level = level;
if (rawHref === "") {
rawHref = "/posts/404/"
element.href = "/posts/404/"
}
if (
rawHref &&
!(
rawHref.indexOf("http://") === 0 ||
rawHref.indexOf("https://") === 0 ||
rawHref.indexOf("#") === 0 ||
rawHref.includes("journal/index") ||
rawHref.includes(".pdf") ||
rawHref.includes(".svg")
)
) {
var prefetchLink = element.href;
async function myFetch() {
let response = await fetch(prefetchLink);
let fragment = document.createElement("template");
fragment.innerHTML = await response.text();
let ct = await response.headers.get("content-type");
if (ct.includes("text/html")) {
createPreview(element, fragment.content.querySelector('.content').outerHTML, {
placement:
window.innerWidth > switchDirectionWindowWidth
? "right"
: "top",
});
element.addEventListener("click", function (e) {
if (!e.ctrlKey && !e.metaKey) {
e.preventDefault();
stackNote(element.href, this.dataset.level);
fetchNote(element.href, this.dataset.level, (animate = true));
}
});
};
}
return myFetch();
}
});
}
window.addEventListener("popstate", function (event) {
// TODO: check state and pop pages if possible, rather than reloading.
window.location = window.location; // this reloads the page.
});
window.onload = async function () {
initializePreviews(document.querySelector(".page"));
let stacks = [];
uri = URI(window.location);
if (uri.hasQuery("stack")) {
stacks = uri.query(true).stack;
if (!Array.isArray(stacks)) {
stacks = [stacks];
}
for (let i = 0; i < stacks.length; i++) {
fetchNote(stacks[i], i + 1, (animate = false));
await new Promise(r => setTimeout(r, 1000));
}
window.Isso.init();
window.Isso.fetchComments();
}
isso_onload_init = true;
};