135 lines
4.4 KiB
JavaScript
135 lines
4.4 KiB
JavaScript
(function () {
|
|
var root = document.documentElement;
|
|
var body = document.body;
|
|
var storageKey = "ghost-thred-theme";
|
|
|
|
function setTheme(theme) {
|
|
body.classList.toggle("theme-dark", theme === "dark");
|
|
localStorage.setItem(storageKey, theme);
|
|
}
|
|
|
|
var savedTheme = localStorage.getItem(storageKey);
|
|
if (savedTheme) {
|
|
setTheme(savedTheme);
|
|
}
|
|
|
|
document.querySelectorAll("[data-theme-toggle]").forEach(function (button) {
|
|
button.addEventListener("click", function () {
|
|
setTheme(body.classList.contains("theme-dark") ? "light" : "dark");
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll("[data-accordion]").forEach(function (button) {
|
|
button.addEventListener("click", function () {
|
|
var section = button.parentElement;
|
|
section.classList.toggle("is-open");
|
|
});
|
|
});
|
|
|
|
var tabRoot = document.querySelector("[data-tabs]");
|
|
if (tabRoot) {
|
|
var triggers = tabRoot.querySelectorAll("[data-tab-trigger]");
|
|
var panels = tabRoot.querySelectorAll("[data-tab-panel]");
|
|
|
|
triggers.forEach(function (trigger) {
|
|
trigger.addEventListener("click", function () {
|
|
var target = trigger.getAttribute("data-tab-trigger");
|
|
|
|
triggers.forEach(function (item) {
|
|
item.classList.toggle("is-active", item === trigger);
|
|
});
|
|
|
|
panels.forEach(function (panel) {
|
|
panel.classList.toggle("is-active", panel.getAttribute("data-tab-panel") === target);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
var searchModal = document.querySelector("[data-search-modal]");
|
|
var searchInput = document.querySelector("[data-search-input]");
|
|
var searchResults = document.querySelector("[data-search-results]");
|
|
|
|
function getSearchItems() {
|
|
var items = [];
|
|
|
|
document.querySelectorAll(".post-card h2 a, .recommended-list a, .category-chip, .author-list__item").forEach(function (link) {
|
|
items.push({
|
|
title: (link.textContent || "").trim(),
|
|
url: link.getAttribute("href") || "#"
|
|
});
|
|
});
|
|
|
|
return items.filter(function (item, index, array) {
|
|
return item.title && array.findIndex(function (candidate) {
|
|
return candidate.title === item.title && candidate.url === item.url;
|
|
}) === index;
|
|
});
|
|
}
|
|
|
|
function renderSearchResults(keyword) {
|
|
var normalized = keyword.trim().toLowerCase();
|
|
if (!normalized) {
|
|
searchResults.innerHTML = '<p class="search-modal__hint">Start typing to filter visible posts, tags, and authors in the current page.</p>';
|
|
return;
|
|
}
|
|
|
|
var items = getSearchItems().filter(function (item) {
|
|
return item.title.toLowerCase().indexOf(normalized) !== -1;
|
|
});
|
|
|
|
if (!items.length) {
|
|
searchResults.innerHTML = '<p class="search-empty">No matching items in the current view.</p>';
|
|
return;
|
|
}
|
|
|
|
searchResults.innerHTML = items.map(function (item) {
|
|
return '<a class="search-result" href="' + item.url + '">' + item.title + "</a>";
|
|
}).join("");
|
|
}
|
|
|
|
function toggleSearch(open) {
|
|
if (!searchModal) {
|
|
return;
|
|
}
|
|
|
|
searchModal.hidden = !open;
|
|
body.style.overflow = open ? "hidden" : "";
|
|
|
|
if (open && searchInput) {
|
|
window.setTimeout(function () {
|
|
searchInput.focus();
|
|
}, 10);
|
|
}
|
|
}
|
|
|
|
document.querySelectorAll("[data-search-open]").forEach(function (button) {
|
|
button.addEventListener("click", function () {
|
|
toggleSearch(true);
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll("[data-search-close]").forEach(function (button) {
|
|
button.addEventListener("click", function () {
|
|
toggleSearch(false);
|
|
});
|
|
});
|
|
|
|
if (searchInput) {
|
|
searchInput.addEventListener("input", function (event) {
|
|
renderSearchResults(event.target.value);
|
|
});
|
|
}
|
|
|
|
document.addEventListener("keydown", function (event) {
|
|
if (event.key === "/" && !/input|textarea/i.test(document.activeElement.tagName)) {
|
|
event.preventDefault();
|
|
toggleSearch(true);
|
|
}
|
|
|
|
if (event.key === "Escape") {
|
|
toggleSearch(false);
|
|
}
|
|
});
|
|
})();
|