first commit

This commit is contained in:
Missdrop
2025-07-16 16:30:56 +00:00
commit 7ee33927cb
11326 changed files with 1230901 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
export default function initBookmarkNav() {
const navItems = document.querySelectorAll('.bookmark-nav-item');
const sections = document.querySelectorAll('section[id]');
if (!navItems.length || !sections.length) return;
// Throttle function
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
function setActiveNavItem() {
const fromTop = window.scrollY + 100;
let currentSection = null;
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.offsetHeight;
if (fromTop >= sectionTop && fromTop < sectionTop + sectionHeight) {
currentSection = section;
}
});
navItems.forEach(item => {
item.classList.remove('bg-second-background-color');
if (currentSection && item.getAttribute('data-category') === currentSection.getAttribute('id')) {
item.classList.add('bg-second-background-color');
}
});
}
// // Handle click events on nav items
// navItems.forEach(item => {
// item.addEventListener('click', (e) => {
// e.preventDefault();
// const targetId = item.getAttribute('data-category');
// const targetSection = document.getElementById(targetId);
// if (targetSection) {
// targetSection.scrollIntoView();
// }
// });
// });
// Throttle scroll handler to run at most every 100ms
window.addEventListener('scroll', throttle(setActiveNavItem, 100));
// Initial check
setActiveNavItem();
}
try {
swup.hooks.on("page:view", initBookmarkNav);
} catch (e) {}
document.addEventListener("DOMContentLoaded", initBookmarkNav);

View File

@@ -0,0 +1,53 @@
const toggleStyle = (element, style, firstValue, secondValue) => {
element.style[style] =
element.style[style] === firstValue ? secondValue : firstValue;
};
const setupCategoryList = () => {
const parentElements = Array.from(
document.querySelectorAll(".all-category-list-item"),
).filter((item) =>
item.parentElement.classList.contains("all-category-list"),
);
parentElements.forEach((parentElement) => {
const childElements = parentElement.querySelectorAll(
".all-category-list-child",
);
childElements.forEach((childElement) => {
childElement.style.maxHeight = "0px";
childElement.style.marginTop = "0px";
});
parentElement.addEventListener("click", () => {
const clickedElementTopOffset = parentElement.offsetTop;
childElements.forEach((childElement) => {
toggleStyle(childElement, "maxHeight", "0px", "1000px");
toggleStyle(childElement, "marginTop", "0px", "15px");
});
parentElements.forEach((siblingElement) => {
if (
siblingElement.offsetTop === clickedElementTopOffset &&
siblingElement !== parentElement
) {
const siblingChildElements = siblingElement.querySelectorAll(
".all-category-list-child",
);
siblingChildElements.forEach((siblingChildElement) => {
toggleStyle(siblingChildElement, "maxHeight", "0px", "1000px");
toggleStyle(siblingChildElement, "marginTop", "0px", "15px");
});
}
});
});
});
};
try {
swup.hooks.on("page:view", setupCategoryList);
} catch (e) {
console.error(e);
}
document.addEventListener("DOMContentLoaded", setupCategoryList);

View File

@@ -0,0 +1,25 @@
// Function to format the dates
function formatEssayDates() {
const dateElements = document.querySelectorAll(".essay-date");
if (!dateElements) {
return;
}
dateElements.forEach(function (element) {
const rawDate = element.getAttribute("data-date");
const locale = config.language || "en";
const formattedDate = moment(rawDate).locale(locale).calendar();
element.textContent = formattedDate;
});
}
try {
swup.hooks.on("page:view", formatEssayDates);
} catch (e) {
console.error(e);
}
// Initial call for the first page load
document.addEventListener("DOMContentLoaded", formatEssayDates);

View File

@@ -0,0 +1,22 @@
export default function initLazyLoad() {
const imgs = document.querySelectorAll("img");
const options = {
rootMargin: "0px",
threshold: 0.1,
};
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.getAttribute("data-src");
img.removeAttribute("lazyload");
observer.unobserve(img);
}
});
}, options);
imgs.forEach((img) => {
if (img.hasAttribute("lazyload")) {
observer.observe(img);
}
});
}

View File

@@ -0,0 +1,135 @@
import { navigationState } from "../utils.js";
export const navbarShrink = {
navbarDom: document.querySelector(".navbar-container"),
leftAsideDom: document.querySelector(".page-aside"),
isnavbarShrink: false,
navbarHeight: 0,
init() {
this.navbarHeight = this.navbarDom.getBoundingClientRect().height;
this.shrink();
this.togglenavbarDrawerShow();
this.toggleSubmenu();
window.addEventListener("scroll", () => {
this.shrink();
});
},
shrink() {
const scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
if (!this.isnavbarShrink && scrollTop > this.navbarHeight) {
this.isnavbarShrink = true;
document.body.classList.add("navbar-shrink");
} else if (this.isnavbarShrink && scrollTop <= this.navbarHeight) {
this.isnavbarShrink = false;
document.body.classList.remove("navbar-shrink");
}
},
togglenavbarDrawerShow() {
const domList = [
document.querySelector(".window-mask"),
document.querySelector(".navbar-bar"),
];
if (document.querySelector(".navbar-drawer")) {
domList.push(
...document.querySelectorAll(
".navbar-drawer .drawer-navbar-list .drawer-navbar-item",
),
...document.querySelectorAll(".navbar-drawer .tag-count-item"),
);
}
domList.forEach((v) => {
if (!v.dataset.navbarInitialized) {
v.dataset.navbarInitialized = 1;
v.addEventListener("click", () => {
document.body.classList.toggle("navbar-drawer-show");
});
}
});
const logoTitleDom = document.querySelector(
".navbar-container .navbar-content .logo-title",
);
if (logoTitleDom && !logoTitleDom.dataset.navbarInitialized) {
logoTitleDom.dataset.navbarInitialized = 1;
logoTitleDom.addEventListener("click", () => {
document.body.classList.remove("navbar-drawer-show");
});
}
},
toggleSubmenu() {
const toggleElements = document.querySelectorAll("[navbar-data-toggle]");
toggleElements.forEach((toggle) => {
if (!toggle.dataset.eventListenerAdded) {
toggle.dataset.eventListenerAdded = "true";
toggle.addEventListener("click", function () {
// console.log("click");
const target = document.querySelector(
'[data-target="' + this.getAttribute("navbar-data-toggle") + '"]',
);
const submenuItems = target.children; // Get submenu items
const icon = this.querySelector(".fa-chevron-right");
if (target) {
const isVisible = !target.classList.contains("hidden");
if (icon) {
icon.classList.toggle("icon-rotated", !isVisible);
}
if (isVisible) {
// Animate to hide (reverse stagger effect)
anime({
targets: submenuItems,
opacity: 0,
translateY: -10,
duration: 300,
easing: "easeInQuart",
delay: anime.stagger(80, { start: 20, direction: "reverse" }),
complete: function () {
target.classList.add("hidden");
},
});
} else {
// Animate to show with stagger effect
target.classList.remove("hidden");
anime({
targets: submenuItems,
opacity: [0, 1],
translateY: [10, 0],
duration: 300,
easing: "easeOutQuart",
delay: anime.stagger(80, { start: 20 }),
});
}
}
});
}
});
},
};
try {
swup.hooks.on("page:view", () => {
navbarShrink.init();
navigationState.isNavigating = false;
});
swup.hooks.on("visit:start", () => {
navigationState.isNavigating = true;
document.body.classList.remove("navbar-shrink");
});
} catch (error) {}
document.addEventListener("DOMContentLoaded", () => {
navbarShrink.init();
});

115
public/js/layouts/toc.js Normal file
View File

@@ -0,0 +1,115 @@
/* main function */
import { initTocToggle } from "../tools/tocToggle.js";
import { main } from "../main.js";
export function initTOC() {
const utils = {
navItems: document.querySelectorAll(".post-toc-wrap .post-toc li"),
updateActiveTOCLink() {
if (!Array.isArray(utils.sections)) return;
let index = utils.sections.findIndex((element) => {
return element && element.getBoundingClientRect().top - 100 > 0;
});
if (index === -1) {
index = utils.sections.length - 1;
} else if (index > 0) {
index--;
}
this.activateTOCLink(index);
},
registerTOCScroll() {
utils.sections = [
...document.querySelectorAll(".post-toc li a.nav-link"),
].map((element) => {
const target = document.getElementById(
decodeURI(element.getAttribute("href")).replace("#", ""),
);
return target;
});
},
activateTOCLink(index) {
const target = document.querySelectorAll(".post-toc li a.nav-link")[
index
];
if (!target || target.classList.contains("active-current")) {
return;
}
document.querySelectorAll(".post-toc .active").forEach((element) => {
element.classList.remove("active", "active-current");
});
target.classList.add("active", "active-current");
// Scroll to the active TOC item
const tocElement = document.querySelector(".toc-content-container");
const tocTop = tocElement.getBoundingClientRect().top;
const scrollTopOffset =
tocElement.offsetHeight > window.innerHeight
? (tocElement.offsetHeight - window.innerHeight) / 2
: 0;
const targetTop = target.getBoundingClientRect().top - tocTop;
const viewportHeight = Math.max(
document.documentElement.clientHeight,
window.innerHeight || 0,
);
const distanceToCenter =
targetTop -
viewportHeight / 2 +
target.offsetHeight / 2 -
scrollTopOffset;
const scrollTop = tocElement.scrollTop + distanceToCenter;
tocElement.scrollTo({
top: scrollTop,
behavior: "smooth", // Smooth scroll
});
},
showTOCAside() {
const openHandle = () => {
const styleStatus = main.getStyleStatus();
const key = "isOpenPageAside";
if (styleStatus && styleStatus.hasOwnProperty(key)) {
initTocToggle().pageAsideHandleOfTOC(styleStatus[key]);
} else {
initTocToggle().pageAsideHandleOfTOC(true);
}
};
const initOpenKey = "init_open";
if (theme.articles.toc.hasOwnProperty(initOpenKey)) {
theme.articles.toc[initOpenKey]
? openHandle()
: initTocToggle().pageAsideHandleOfTOC(false);
} else {
openHandle();
}
},
};
if (utils.navItems.length > 0) {
utils.showTOCAside();
utils.registerTOCScroll();
} else {
document
.querySelectorAll(".toc-content-container, .toc-marker")
.forEach((elem) => {
elem.remove();
});
}
return utils;
}
// Event listeners
try {
swup.hooks.on("page:view", () => {
initTOC();
});
} catch (e) {}
document.addEventListener("DOMContentLoaded", initTOC);