feat(comments): 评论区按 Zibll 1:1 全量复刻

- 评论项/表单/工具栏/筛选/分页/空状态 DOM 全部替换为 zibll 原始类名
  (li.comment、comt-main、comt-meta、list-inline、dropup 工具栏、
  theme-pagination/pagenav、post_ajax_loader 骨架等)
- 移植 zibll main.css L9412–9751 桌面 + 移动端评论样式,
  缺失基础组件(title-theme/dropdown-menu/line-form/tab-nav-theme 等)
  以 #comments 作用域补齐
- 删除全部 aksrt-comment__* 旧类名与旧样式,无兼容层
- JS 选择器对齐 zibll DOM:片段整块替换 #postcomments、骨架加载、
  跳页输入、prepend 插入、addComment onclick 剥离,
  移除 WP comment-reply enqueue 避免双 moveForm
- 表情资源替换为 zibll 全套 gif(内容逐字节一致,git 无差异)
- REST 后端 (CommentActions) 不变

验证:php -l 全部通过;5 个改动 JS 语法校验通过;
node --test tests/widget-system/post-visual-contract.test.cjs 12/12 通过
This commit is contained in:
2026-08-22 13:29:51 +08:00
parent 251fe86527
commit e1f176429b
15 changed files with 1286 additions and 1439 deletions
+72 -107
View File
@@ -97,13 +97,13 @@
}
function updateCommentCount(delta) {
var countEl = document.querySelector('.comments-count');
var countEl = document.querySelector('#comments .title-theme small');
if (!countEl) return;
var text = countEl.textContent || '';
var match = text.match(/(\d+)/);
if (!match) return;
var nextCount = Math.max(0, parseInt(match[1], 10) + delta);
countEl.textContent = '共 ' + nextCount + ' 条';
countEl.textContent = text.replace(match[1], String(nextCount));
}
function handleResponse(responseText, statusCode) {
try {
@@ -316,9 +316,9 @@
newComment.style.opacity = '0';
newComment.style.transition = 'max-height 0.4s ease, opacity 0.3s ease';
if (isReply && parentId) {
var parentComment = document.querySelector('#comment-' + parentId + ', [data-comment-id="' + parentId + '"]');
var parentComment = document.querySelector('#comment-' + parentId);
if (parentComment) {
var children = parentComment.querySelector('.children');
var children = parentComment.querySelector(':scope > .children');
if (!children) {
children = document.createElement('ol');
children.className = 'children';
@@ -354,8 +354,15 @@
}
function prependToCommentList(el) {
var list = document.querySelector('.commentlist, #comment-list > ol, #comment-list');
if (list) list.insertBefore(el, list.firstChild);
var list = document.querySelector('#comments .commentlist');
if (!list) return;
// 插到筛选栏之后、最新评论之前
var filter = list.querySelector('.comment-filter');
if (filter && filter.nextSibling) {
list.insertBefore(el, filter.nextSibling);
} else {
list.insertBefore(el, list.firstChild);
}
}
function restoreRespondPosition() {
@@ -471,66 +478,27 @@
function getCurrentAuthorOnly() {
var url = new URL(window.location.href);
if (url.searchParams.get("aksrt_author_only") === "1") return true;
var btn = document.querySelector("#comments .comment-author-filter");
var btn = document.querySelector("#comments .btn-only-author");
return !!(btn && btn.classList.contains("active") && btn.dataset.authorOnly === "0");
}
function applyFragmentPayload(commentsArea, data, urlState) {
if (!commentsArea || !data) return;
if (!commentsArea || !data || !data.html) return;
if (data.filter_html) {
var currentFilter = commentsArea.querySelector(".comment-filter");
var temp = document.createElement("div");
temp.innerHTML = data.filter_html;
var newFilter = temp.firstElementChild;
if (newFilter) {
if (currentFilter) currentFilter.replaceWith(newFilter);
else {
var listAnchor = commentsArea.querySelector("#postcomments, #comment-list");
if (listAnchor && listAnchor.parentNode) {
listAnchor.parentNode.insertBefore(newFilter, listAnchor);
}
}
}
}
// data.html 是完整的 <div id="postcomments">(含筛选、列表、分页)
var tempList = document.createElement("div");
tempList.innerHTML = data.html;
var newListWrap = tempList.querySelector("#postcomments");
if (!newListWrap) return;
var currentListWrap = commentsArea.querySelector("#postcomments");
var currentList = commentsArea.querySelector("#comment-list");
var currentEmpty = commentsArea.querySelector(".comments-empty");
var tempList = document.createElement("div");
tempList.innerHTML = data.html || "";
var newListWrap = tempList.querySelector("#postcomments");
var newEmpty = tempList.querySelector(".comments-empty");
if (newListWrap) {
if (currentListWrap) currentListWrap.replaceWith(newListWrap);
else if (currentList) currentList.replaceWith(newListWrap);
else commentsArea.appendChild(newListWrap);
if (currentEmpty) currentEmpty.remove();
} else if (newEmpty) {
if (currentListWrap) currentListWrap.remove();
if (currentList) currentList.remove();
if (currentEmpty) currentEmpty.replaceWith(newEmpty);
else commentsArea.appendChild(newEmpty);
if (currentListWrap) {
currentListWrap.replaceWith(newListWrap);
} else {
commentsArea.appendChild(newListWrap);
}
var currentPagination = commentsArea.querySelector(".aksrt-comment-pagination, .comment-navigation, .pagenav.ajax-pag");
if (data.pagination_html) {
var ptemp = document.createElement("div");
ptemp.innerHTML = data.pagination_html;
var newPag = ptemp.firstElementChild;
if (newPag) {
if (currentPagination) currentPagination.replaceWith(newPag);
else {
var list = commentsArea.querySelector("#postcomments, #comment-list");
if (list && list.parentNode) list.parentNode.insertBefore(newPag, list.nextSibling);
}
}
} else if (currentPagination) {
currentPagination.remove();
}
var currentCount = commentsArea.querySelector(".comments-count");
var currentCount = commentsArea.querySelector(".title-theme small");
if (currentCount && data.count_text) currentCount.textContent = data.count_text;
if (urlState && window.history && typeof window.history.replaceState === "function") {
@@ -562,20 +530,30 @@
}
/* ====== 评论列表动态刷新 ====== */
function showListLoading(commentsArea) {
var list = commentsArea.querySelector(".commentlist");
if (!list) return;
// 保留筛选栏,清空条目并显示 zibll 骨架
var filter = list.querySelector(".comment-filter");
var loader = list.querySelector(".post_ajax_loader");
var skeleton = loader ? loader.cloneNode(true) : null;
Array.prototype.slice.call(list.children).forEach(function (child) {
if (child !== filter && child !== loader) child.remove();
});
if (skeleton) {
skeleton.style.display = "block";
skeleton.removeAttribute("hidden");
list.appendChild(skeleton);
}
}
function reloadCommentList() {
var commentsArea = document.getElementById('comments');
var listContainer = document.getElementById('comment-list');
if (!commentsArea && !listContainer) {
if (!commentsArea) {
window.location.reload();
return;
}
if (listContainer) {
listContainer.innerHTML = '<li class="comment-loading-skeleton">' +
'<div class="aksrt-comment"><div class="aksrt-comment__body">' +
'<div style="height:60px;background:#f0f0f0;border-radius:8px;margin-bottom:10px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
'<div style="height:20px;width:70%;background:#f0f0f0;border-radius:4px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
'</div></div></li>';
}
showListLoading(commentsArea);
fetchCommentFragment({
order: getCurrentCommentOrder(),
@@ -583,7 +561,7 @@
page: 1
}).then(function (json) {
if (json && json.success && json.data) {
applyFragmentPayload(commentsArea || document, json.data, null);
applyFragmentPayload(commentsArea, json.data, null);
return;
}
throw new Error('fragment failed');
@@ -622,13 +600,7 @@
commentsArea.dataset.orderInit = "1";
function renderLoadingState() {
var listContainer = commentsArea.querySelector("#comment-list");
if (!listContainer) return;
listContainer.innerHTML = '<li class="comment-loading-skeleton">' +
'<div class="aksrt-comment"><div class="aksrt-comment__body">' +
'<div style="height:60px;background:#f0f0f0;border-radius:8px;margin-bottom:10px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
'<div style="height:20px;width:70%;background:#f0f0f0;border-radius:4px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
'</div></div></li>';
showListLoading(commentsArea);
}
function applyCommentOrder(order) {
if (order !== "newest" && order !== "oldest" && order !== "hottest") {
@@ -685,7 +657,7 @@
if (!target || typeof target.closest !== "function") return;
// 「只看作者」同时带 comment-orderby,需优先于排序按钮判断
var authorBtn = target.closest(".comment-author-filter");
var authorBtn = target.closest(".btn-only-author");
if (authorBtn && commentsArea.contains(authorBtn)) {
e.preventDefault();
applyAuthorFilter(authorBtn.getAttribute("data-author-only") || "0");
@@ -701,40 +673,33 @@
}
function initGuestFields() {
var root = document.getElementById("comments") || document;
root.querySelectorAll("[data-aksrt-guest-toggle]").forEach(function (btn) {
if (btn.dataset.aksrtGuestBound === "1") return;
btn.dataset.aksrtGuestBound = "1";
var wrap = btn.closest(".comment-form__guest");
var fields = wrap ? wrap.querySelector("[data-aksrt-guest-fields]") : null;
if (!fields) return;
btn.addEventListener("click", function (e) {
e.preventDefault();
var open = btn.getAttribute("aria-expanded") === "true";
btn.setAttribute("aria-expanded", open ? "false" : "true");
if (open) {
fields.setAttribute("hidden", "");
fields.classList.remove("is-open");
} else {
fields.removeAttribute("hidden");
fields.classList.add("is-open");
var first = fields.querySelector("input");
if (first) first.focus();
}
});
// Auto-open if browser restored values or validation fails later.
var form = btn.closest("form");
if (form) {
form.addEventListener("invalid", function () {
fields.removeAttribute("hidden");
fields.classList.add("is-open");
btn.setAttribute("aria-expanded", "true");
}, true);
}
/* ====== 数字分页跳页(zibll pag-jump) ====== */
function jumpToCommentPage(page) {
page = parseInt(page, 10) || 1;
var url = new URL(window.location.href);
url.searchParams.set("cpage", String(page));
url.hash = "comments";
window.location.href = url.toString();
}
function initCommentPageJump() {
document.addEventListener("click", function (e) {
var jump = e.target.closest ? e.target.closest("#comments .pag-jump") : null;
if (!jump) return;
e.preventDefault();
var input = jump.querySelector(".jump-input");
if (input) jumpToCommentPage(input.value);
});
document.addEventListener("keydown", function (e) {
if (e.key !== "Enter") return;
var input = e.target;
if (!input || !input.classList || !input.classList.contains("jump-input")) return;
if (!input.closest("#comments .pagenav")) return;
e.preventDefault();
jumpToCommentPage(input.value);
});
}
window.AksrtFrontend.register("aksrt-comment-system", function () { initCommentSystem(); initGuestFields(); });
window.AksrtFrontend.register("aksrt-comment-system", function () { initCommentSystem(); initCommentPageJump(); });
window.AksrtFrontend.register("aksrt-comment-order", function (root) { initCommentOrder(root); });
})();