fix(theme): align reference layouts and restore passing contracts

Align homepage and category discovery, modern widgets, admin controls, quotes, and comments with the reference theme. Remove superseded paths and add rendering and behavior coverage. Update stale asset and finance contracts; all 760 Node tests and 139 widget assertions pass.
This commit is contained in:
kate522 committed 2026-10-29 19:16:03 +08:00
1 parent b520d29368
commit 8aa116ec43
63 files changed
+1985 -2304

No files matched your search

-234
View File
@@ -1,234 +0,0 @@
/**
* AKSRT Archive AJAX Filter
*/
(function () {
"use strict";
function initArchiveFilter(root) {
var scope = root || document;
var bar = scope.querySelector(".archive-filter-bar--ajax[data-ajax-archive]");
if (!bar || bar.dataset.aksrtArchiveInit === "1") return;
bar.dataset.aksrtArchiveInit = "1";
var archiveType = bar.dataset.ajaxArchive || "category";
var termId = parseInt(bar.dataset.termId, 10) || 0;
var wrap = scope.querySelector("[data-ajax-wrap]");
if (!wrap) return;
// 归档面与首页共用同一套骨架契约:.post_ajax_loader + .is-loading,
// 不再使用独立 spinner 遮罩 / opacity 淡出。
var loading = wrap.querySelector(".post_ajax_loader");
var REST_BASE = "/wp-json/aksrt/v1/archive/posts";
var emptyText = archiveType === "tag" ? "该标签下暂无文章" : "该分类下暂无文章";
var state = {
filter_cat: "",
filter_tag: "",
custom: {},
sort: "date",
page: 1
};
var activeCat = bar.querySelector("[data-filter-cat].is-active");
if (activeCat) state.filter_cat = activeCat.dataset.filterCat || "";
var activeTag = bar.querySelector("[data-filter-tag].is-active");
if (activeTag) state.filter_tag = activeTag.dataset.filterTag || "";
var activeSort = bar.querySelector("[data-filter-sort].is-active");
if (activeSort) state.sort = activeSort.dataset.filterSort || "date";
// 自定义高级筛选维度:以当前 URL 参数为准(SSR active 状态与 URL 一致)。
if (bar.querySelector("[data-filter-dim]")) {
new URLSearchParams(window.location.search).forEach(function (value, key) {
if (bar.querySelector('[data-filter-dim="' + key + '"]')) {
state.custom[key] = value;
}
});
}
function buildUrl() {
var params = new URLSearchParams();
params.set("archive_type", archiveType);
params.set("term_id", String(termId));
if (state.filter_cat) params.set("filter_cat", state.filter_cat);
if (state.filter_tag) params.set("filter_tag", state.filter_tag);
if (Object.keys(state.custom).length) params.set("custom_filter", JSON.stringify(state.custom));
params.set("sort", state.sort || "date");
params.set("page", String(state.page));
return REST_BASE + "?" + params.toString();
}
function updateActiveChips() {
bar.querySelectorAll("[data-filter-cat]").forEach(function (el) {
el.classList.toggle("is-active", (el.dataset.filterCat || "") === state.filter_cat);
});
bar.querySelectorAll("[data-filter-tag]").forEach(function (el) {
el.classList.toggle("is-active", (el.dataset.filterTag || "") === state.filter_tag);
});
bar.querySelectorAll("[data-filter-sort]").forEach(function (el) {
el.classList.toggle("is-active", (el.dataset.filterSort || "date") === state.sort);
});
bar.querySelectorAll("[data-filter-dim]").forEach(function (el) {
var current = state.custom[el.dataset.filterDim] || "";
el.classList.toggle("is-active", (el.dataset.filterDimValue || "") !== "" && (el.dataset.filterDimValue || "") === current);
});
}
function showLoading() {
if (loading) loading.classList.add("is-loading");
}
function hideLoading() {
if (loading) loading.classList.remove("is-loading");
}
function rebuildEmptyState() {
var noResults = document.createElement("div");
noResults.className = "no-results content-stream__empty";
noResults.innerHTML = "<p>" + emptyText + "</p>";
wrap.appendChild(noResults);
}
function fetchPosts(pushState) {
showLoading();
fetch(buildUrl(), {
method: "GET",
headers: { Accept: "application/json" },
credentials: "same-origin"
})
.then(function (r) {
if (!r.ok) throw new Error("HTTP " + r.status);
return r.json();
})
.then(function (data) {
hideLoading();
if (data.html !== undefined) {
// 只清真实内容;骨架(.post_ajax_loader)与分页控件保留复用 ——
// 与参考主题 post_ajax success 只 hide 不删的生命周期一致。
var keep = function (node) {
return node === loading ||
node.classList.contains("post_ajax_loader") ||
node.classList.contains("ajax-pag");
};
Array.from(wrap.children).forEach(function (child) {
if (!keep(child)) wrap.removeChild(child);
});
if (data.html) {
var temp = document.createElement("div");
temp.innerHTML = data.html;
while (temp.firstChild) wrap.appendChild(temp.firstChild);
} else {
rebuildEmptyState();
}
// legacy 事件顺序:先 post_ajax.ed,再全局 auto_fun 重扫
wrap.dispatchEvent(new CustomEvent("post_ajax.ed", { bubbles: true }));
if (typeof window.auto_fun === "function") window.auto_fun();
}
if (pushState !== false) {
var url = new URL(window.location.href);
url.searchParams.delete("orderby");
url.searchParams.delete("order");
url.searchParams.delete("paged");
url.searchParams.delete("aksrt_filter_cat");
url.searchParams.delete("aksrt_filter_tag");
bar.querySelectorAll("[data-filter-dim]").forEach(function (el) {
url.searchParams.delete(el.dataset.filterDim);
});
if (state.filter_cat) url.searchParams.set("aksrt_filter_cat", state.filter_cat);
if (state.filter_tag) url.searchParams.set("aksrt_filter_tag", state.filter_tag);
Object.keys(state.custom).forEach(function (key) {
url.searchParams.set(key, state.custom[key]);
});
if (state.sort) url.searchParams.set("orderby", state.sort);
if (state.page > 1) url.searchParams.set("paged", String(state.page));
history.pushState({ aksrtArchive: true, state: Object.assign({}, state) }, "", url.toString());
}
})
.catch(function () {
hideLoading();
});
}
bar.addEventListener("click", function (e) {
var chip = e.target.closest("[data-filter-cat], [data-filter-tag], [data-filter-sort], [data-filter-dim]");
if (!chip) return;
e.preventDefault();
var changed = false;
if (chip.dataset.filterCat !== undefined) {
var newCat = chip.dataset.filterCat;
if (newCat !== state.filter_cat) {
state.filter_cat = newCat;
changed = true;
}
}
if (chip.dataset.filterTag !== undefined) {
var newTag = chip.dataset.filterTag;
if (newTag !== state.filter_tag) {
state.filter_tag = newTag;
changed = true;
}
}
if (chip.dataset.filterSort !== undefined) {
var newSort = chip.dataset.filterSort || "date";
if (newSort !== state.sort) {
state.sort = newSort;
changed = true;
}
}
if (chip.dataset.filterDim !== undefined) {
var dimKey = chip.dataset.filterDim;
var dimValue = chip.dataset.filterDimValue || "";
if (dimValue !== (state.custom[dimKey] || "")) {
if (dimValue === "") {
delete state.custom[dimKey];
} else {
state.custom[dimKey] = dimValue;
}
changed = true;
}
}
if (changed) {
state.page = 1;
updateActiveChips();
fetchPosts(true);
}
});
wrap.addEventListener("click", function (e) {
var pageLink = e.target.closest(".pagination a, .nav-links a, a.page-numbers");
if (!pageLink || !wrap.contains(pageLink)) return;
var href = pageLink.getAttribute("href");
if (!href) return;
var match = href.match(/[?&]paged=(\d+)/);
if (match) {
e.preventDefault();
state.page = parseInt(match[1], 10) || 1;
fetchPosts(true);
}
});
window.addEventListener("popstate", function (e) {
if (e.state && e.state.aksrtArchive) {
state = Object.assign(state, e.state.state);
updateActiveChips();
fetchPosts(false);
}
});
}
function init(root) {
initArchiveFilter(root);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", function () { init(); });
} else {
init();
}
// AJAX 注入新内容后由 auto_fun 重扫(bar 级 data 标记保证幂等)。
if (window.jQuery) {
window.jQuery(document).on("auto_fun", function () { init(); });
}
})();
+1 -1
View File
@@ -510,7 +510,7 @@
showListLoading(commentsArea);
}
function applyCommentOrder(order) {
if (order !== "newest" && order !== "oldest" && order !== "hottest") {
if (order !== "newest" && order !== "hottest") {
order = "newest";
}
renderLoadingState();