feat(nav): deep 1:1 zibll search-box + navbar-search + newposts unify

Port aksrt_get_search_box/posts for menu_search and layout 1/3 slide;
unify publish switch; expand user-box admin row; CSS/JS remote-box parity.
This commit is contained in:
2026-07-22 17:06:24 +08:00
parent 70f7ef71e1
commit 1d1fef50af
19 changed files with 980 additions and 267 deletions
+9 -8
View File
@@ -291,19 +291,20 @@
document.querySelectorAll(".main-search-btn, .nav-search-toggle, [data-aksrt-open-search]").forEach(function (btn) {
btn.addEventListener("click", function (e) {
// Top bar uses zibll .navbar-search slide — skip tabbar overlay.
var tgt = btn.getAttribute("data-target") || "";
if (tgt.indexOf("navbar-search") !== -1 || tgt.indexOf("main-search") !== -1) {
return;
}
e.preventDefault();
setOpen(true);
});
});
// Zibll-compatible data-toggle-class for .navbar-search
document.addEventListener("click", function (e) {
var toggle = e.target.closest('[data-toggle-class][data-target=".navbar-search"], [data-toggle-class][data-target=".main-search"]');
if (!toggle) return;
e.preventDefault();
var isOpen = mobileOverlay && !mobileOverlay.hasAttribute("hidden");
setOpen(!isOpen);
});
// Top-nav .navbar-search is toggled by aksrt-runtime (data-toggle-class="show").
// Do NOT redirect those clicks into the footer tabbar overlay.
// Only open tabbar overlay for explicit main-search-btn without .navbar-search target
// (handled above via .main-search-btn listeners).
if (historyClear) {
historyClear.addEventListener("click", function () {
+128 -49
View File
@@ -1,6 +1,7 @@
/**
* Layout-2 navbar search — zibll remote-box + live suggestions.
* Loads aksrt_menu_search panel (history/hot/posts), then suggests on input.
* Layout-2 navbar search — zibll remote-box + search-input panel.
* Loads menu_search panel (.dropdown-menu.hover-show-con > .search-input),
* fills guest history from localStorage, live suggestions optional.
*/
(function () {
"use strict";
@@ -40,6 +41,24 @@
} catch (e) {}
}
function keywordChips(list) {
return (list || [])
.map(function (kw) {
return (
'<a class="but jb-sm" data-search-keyword="' +
encodeURIComponent(kw) +
'" href="' +
(window.location.origin || "") +
"/?s=" +
encodeURIComponent(kw) +
'">' +
kw +
"</a> "
);
})
.join("");
}
function loadRemote(box) {
if (!box || box.getAttribute("data-loaded") === "1") return;
var url = box.getAttribute("remote-box") || box.getAttribute("data-url");
@@ -58,57 +77,51 @@
box.innerHTML = "";
return;
}
var parent = box.parentNode;
box.outerHTML = html;
var form = document.querySelector('form[data-aksrt-search-form="inline"]');
var form = parent ? parent.closest("form") : document.querySelector('form[data-aksrt-search-form="inline"]');
if (form) enhancePanel(form);
initSwiperScroll(form || document);
})
.catch(function () {
box.removeAttribute("data-loaded");
});
}
function enhancePanel(form) {
var group = form.querySelector(".form-group");
var panel = form.querySelector(".navbar-inline-search-panel");
var input = form.querySelector(".search-input");
if (!group || !input) return;
function initSwiperScroll(root) {
if (!root || typeof window.Swiper === "undefined") return;
root.querySelectorAll(".relates-thumb .swiper-container:not(.swiper-initialized)").forEach(function (el) {
try {
new window.Swiper(el, {
slidesPerView: "auto",
freeMode: true,
navigation: {
nextEl: el.querySelector(".swiper-button-next"),
prevEl: el.querySelector(".swiper-button-prev"),
},
});
} catch (e) {}
});
}
// Merge guest local history into panel list.
var histList = form.querySelector(".aksrt-menu-search-history__list");
function enhancePanel(form) {
if (!form || form._aksrtMenuSearchEnhanced) return;
form._aksrtMenuSearchEnhanced = 1;
var input = form.querySelector(".search-input, input[name='s']");
var histList = form.querySelector(".history-search-list, .history-search > div:last-child");
// Guest local history → panel.
if (histList && !(window.aksrtData && aksrtData.isLoggedIn)) {
var local = readLocalHistory();
if (local.length) {
histList.innerHTML = local
.map(function (kw) {
return (
'<a class="but jb-sm" href="' +
(window.location.origin || "") +
"/?s=" +
encodeURIComponent(kw) +
'">' +
kw +
"</a> "
);
})
.join("");
histList.innerHTML = keywordChips(local);
}
}
form.querySelectorAll("[data-aksrt-menu-search-type]").forEach(function (chip) {
chip.addEventListener("click", function (e) {
e.preventDefault();
var v = chip.getAttribute("data-aksrt-menu-search-type") || "post";
var tin = form.querySelector('input[name="aksrt_search_type"]');
if (tin) tin.value = v;
form.querySelectorAll("[data-aksrt-menu-search-type]").forEach(function (c) {
c.classList.toggle("active", c === chip);
});
});
});
var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
if (clearBtn && !clearBtn._bound) {
// Clear history (zibll .trash-history-search).
form.querySelectorAll(".trash-history-search, [data-aksrt-clear-menu-history]").forEach(function (clearBtn) {
if (clearBtn._bound) return;
clearBtn._bound = 1;
clearBtn.addEventListener("click", function (e) {
e.preventDefault();
@@ -118,14 +131,30 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
'<span class="muted-3-color em09" data-empty="1">暂无历史</span>';
}
});
}
});
// Type chips inside panel (if any).
form.querySelectorAll("[data-for='type'], [data-aksrt-menu-search-type]").forEach(function (chip) {
chip.addEventListener("click", function (e) {
e.preventDefault();
var v =
chip.getAttribute("data-value") ||
chip.getAttribute("data-aksrt-menu-search-type") ||
"post";
var tin = form.querySelector('input[name="aksrt_search_type"], input[name="type"]');
if (tin) tin.value = v;
form.querySelectorAll("[data-for='type'], [data-aksrt-menu-search-type]").forEach(function (c) {
c.classList.toggle("active", c === chip);
});
});
});
var suggestMount = form.querySelector("[data-aksrt-menu-suggest]");
var timer = null;
var searchConfig = (window.aksrtData && aksrtData.search) || {};
function typeValue() {
var t = form.querySelector('input[name="aksrt_search_type"]');
var t = form.querySelector('input[name="aksrt_search_type"], input[name="type"]');
return (t && t.value) || searchConfig.defaultType || "post";
}
@@ -153,14 +182,14 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
var html =
'<div class="muted-2-color em09 mb6">' +
(searchConfig.suggestTitle || "搜索建议") +
"</div><div class=\"navbar-inline-search-suggest\">";
'</div><div class="navbar-inline-search-suggest">';
items.forEach(function (it) {
html +=
'<a class="navbar-inline-search-suggest__item" href="' +
(it.url || "#") +
'"><span class="title">' +
(it.title || "") +
'</span>' +
"</span>" +
(it.meta
? '<span class="meta muted-2-color em09">' + it.meta + "</span>"
: "") +
@@ -181,7 +210,7 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
);
}
if (!input._aksrtMenuSearchBound) {
if (input && !input._aksrtMenuSearchBound) {
input._aksrtMenuSearchBound = 1;
input.addEventListener("input", function () {
var q = (input.value || "").trim();
@@ -191,9 +220,9 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
}, 180);
});
input.addEventListener("focus", function () {
var remote = form.querySelector("[data-aksrt-menu-search-remote]");
var remote = form.querySelector("[remote-box]");
if (remote) loadRemote(remote);
var p = form.querySelector(".navbar-inline-search-panel");
var p = form.querySelector(".dropdown-menu.hover-show-con");
if (p) {
p.classList.add("is-open");
p.style.display = "block";
@@ -214,9 +243,9 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
}
}
function init() {
document.querySelectorAll("[data-aksrt-menu-search-remote]").forEach(function (box) {
// Prefetch on idle / first hover of form.
/** Generic remote-box / lazyload-action=ias (zibll-compatible). */
function bindRemoteBoxes(root) {
(root || document).querySelectorAll("[remote-box]").forEach(function (box) {
var form = box.closest("form");
if (form) {
form.addEventListener(
@@ -226,8 +255,14 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
},
{ once: true }
);
form.addEventListener(
"focusin",
function () {
loadRemote(box);
},
{ once: true }
);
}
// Also load when lazyload-action ias would fire — simple viewport/idle.
if ("requestIdleCallback" in window) {
requestIdleCallback(function () {
loadRemote(box);
@@ -238,9 +273,53 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]");
}, 600);
}
});
}
function bindNavbarSearchSlide() {
// Ensure .navbar-search show toggle clears aria-hidden / focuses input.
document.addEventListener("click", function (e) {
var toggle = e.target.closest
? e.target.closest('[data-toggle-class="show"][data-target=".navbar-search"]')
: null;
if (!toggle) return;
// Let runtime toggle class; after tick sync aria + focus.
setTimeout(function () {
var panel = document.querySelector(".navbar-search");
if (!panel) return;
var open = panel.classList.contains("show");
panel.setAttribute("aria-hidden", open ? "false" : "true");
if (open) {
var input = panel.querySelector('input[name="s"]');
if (input) input.focus();
initSwiperScroll(panel);
}
}, 0);
});
}
function init() {
bindRemoteBoxes(document);
bindNavbarSearchSlide();
var form = document.querySelector('form[data-aksrt-search-form="inline"]');
if (form) enhancePanel(form);
// Full navbar-search box history for guests.
document.querySelectorAll(".navbar-search .history-search-list").forEach(function (histList) {
if (window.aksrtData && aksrtData.isLoggedIn) return;
var local = readLocalHistory();
if (local.length) histList.innerHTML = keywordChips(local);
});
document.querySelectorAll(".navbar-search .trash-history-search").forEach(function (btn) {
if (btn._bound) return;
btn._bound = 1;
btn.addEventListener("click", function (e) {
e.preventDefault();
writeLocalHistory([]);
document.querySelectorAll(".navbar-search .history-search-list").forEach(function (list) {
list.innerHTML = '<span class="muted-3-color em09" data-empty="1">暂无历史</span>';
});
});
});
initSwiperScroll(document);
}
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {