Wire header_nav_style transparent/blur, login history sync, plate publish type, clean dead search CSS, rebuild admin SPA locally (build gitignored).
390 lines
12 KiB
JavaScript
390 lines
12 KiB
JavaScript
/**
|
|
* 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";
|
|
|
|
var HISTORY_KEY = "aksrt-mobile-search-history";
|
|
|
|
function ajaxUrl() {
|
|
return (window.aksrtData && aksrtData.ajaxUrl) || "";
|
|
}
|
|
function nonce() {
|
|
return (window.aksrtData && aksrtData.nonce) || "";
|
|
}
|
|
|
|
function readLocalHistory() {
|
|
try {
|
|
var raw = localStorage.getItem(HISTORY_KEY);
|
|
var list = raw ? JSON.parse(raw) : [];
|
|
if (!Array.isArray(list)) return [];
|
|
return list
|
|
.map(function (it) {
|
|
if (typeof it === "string") return it;
|
|
return it && it.keyword ? String(it.keyword) : "";
|
|
})
|
|
.filter(Boolean)
|
|
.slice(0, 10);
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function writeLocalHistory(keywords) {
|
|
try {
|
|
var items = (keywords || []).slice(0, 10).map(function (k) {
|
|
return { keyword: k, type: "post" };
|
|
});
|
|
localStorage.setItem(HISTORY_KEY, JSON.stringify(items));
|
|
} catch (e) {}
|
|
}
|
|
|
|
|
|
function saveLoggedHistory(keyword, type) {
|
|
if (!(window.aksrtData && aksrtData.isLoggedIn) || !ajaxUrl() || !keyword) return;
|
|
var items = readLocalHistory().filter(function (k) { return k !== keyword; });
|
|
items.unshift(keyword);
|
|
items = items.slice(0, 20);
|
|
// Also update local cache for panel paint consistency.
|
|
writeLocalHistory(items);
|
|
var payload =
|
|
"action=aksrt_search_history&nonce=" +
|
|
encodeURIComponent(nonce()) +
|
|
"&mode=save&items=" +
|
|
encodeURIComponent(
|
|
JSON.stringify(
|
|
items.map(function (k) {
|
|
return { keyword: k, type: type || "post" };
|
|
})
|
|
)
|
|
);
|
|
try {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("POST", ajaxUrl(), true);
|
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
|
xhr.send(payload);
|
|
} 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");
|
|
if (!url) return;
|
|
box.setAttribute("data-loaded", "1");
|
|
var sep = url.indexOf("?") >= 0 ? "&" : "?";
|
|
if (nonce()) {
|
|
url = url + sep + "nonce=" + encodeURIComponent(nonce());
|
|
}
|
|
fetch(url, { credentials: "same-origin" })
|
|
.then(function (r) {
|
|
return r.text();
|
|
})
|
|
.then(function (html) {
|
|
if (!html || html === "0") {
|
|
box.innerHTML = "";
|
|
return;
|
|
}
|
|
var parent = box.parentNode;
|
|
box.outerHTML = html;
|
|
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 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) {}
|
|
});
|
|
}
|
|
|
|
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 = keywordChips(local);
|
|
}
|
|
}
|
|
|
|
// 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();
|
|
writeLocalHistory([]);
|
|
if (histList) {
|
|
histList.innerHTML =
|
|
'<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"], input[name="type"]');
|
|
return (t && t.value) || searchConfig.defaultType || "post";
|
|
}
|
|
|
|
function requestSuggest(q) {
|
|
if (!suggestMount || !ajaxUrl() || q.length < 2) {
|
|
if (suggestMount) {
|
|
suggestMount.hidden = true;
|
|
suggestMount.innerHTML = "";
|
|
}
|
|
return;
|
|
}
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("POST", ajaxUrl(), true);
|
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
|
xhr.onload = function () {
|
|
if (xhr.status < 200 || xhr.status >= 300) return;
|
|
try {
|
|
var json = JSON.parse(xhr.responseText);
|
|
var items = (json.success && json.data && json.data.items) || [];
|
|
if (!items.length) {
|
|
suggestMount.hidden = true;
|
|
suggestMount.innerHTML = "";
|
|
return;
|
|
}
|
|
var html =
|
|
'<div class="muted-2-color em09 mb6">' +
|
|
(searchConfig.suggestTitle || "搜索建议") +
|
|
'</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>" +
|
|
(it.meta
|
|
? '<span class="meta muted-2-color em09">' + it.meta + "</span>"
|
|
: "") +
|
|
"</a>";
|
|
});
|
|
html += "</div>";
|
|
suggestMount.innerHTML = html;
|
|
suggestMount.hidden = false;
|
|
} catch (e) {}
|
|
};
|
|
xhr.send(
|
|
"action=aksrt_search_suggestions&nonce=" +
|
|
encodeURIComponent(nonce()) +
|
|
"&q=" +
|
|
encodeURIComponent(q) +
|
|
"&type=" +
|
|
encodeURIComponent(typeValue())
|
|
);
|
|
}
|
|
|
|
if (input && !input._aksrtMenuSearchBound) {
|
|
input._aksrtMenuSearchBound = 1;
|
|
input.addEventListener("input", function () {
|
|
var q = (input.value || "").trim();
|
|
if (timer) clearTimeout(timer);
|
|
timer = setTimeout(function () {
|
|
requestSuggest(q);
|
|
}, 180);
|
|
});
|
|
input.addEventListener("focus", function () {
|
|
var remote = form.querySelector("[remote-box]");
|
|
if (remote) loadRemote(remote);
|
|
var p = form.querySelector(".dropdown-menu.hover-show-con");
|
|
if (p) {
|
|
p.classList.add("is-open");
|
|
p.style.display = "block";
|
|
p.style.visibility = "visible";
|
|
}
|
|
});
|
|
form.addEventListener("submit", function () {
|
|
var q = (input.value || "").trim();
|
|
if (!q) return;
|
|
if (window.aksrtData && aksrtData.isLoggedIn) {
|
|
saveLoggedHistory(q, typeValue());
|
|
} else {
|
|
var list = readLocalHistory().filter(function (k) {
|
|
return k !== q;
|
|
});
|
|
list.unshift(q);
|
|
writeLocalHistory(list);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/** 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(
|
|
"mouseenter",
|
|
function () {
|
|
loadRemote(box);
|
|
},
|
|
{ once: true }
|
|
);
|
|
form.addEventListener(
|
|
"focusin",
|
|
function () {
|
|
loadRemote(box);
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
if ("requestIdleCallback" in window) {
|
|
requestIdleCallback(function () {
|
|
loadRemote(box);
|
|
});
|
|
} else {
|
|
setTimeout(function () {
|
|
loadRemote(box);
|
|
}, 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 bindFullSearchBoxHistory() {
|
|
document.querySelectorAll('form[data-aksrt-search-form="box"]').forEach(function (form) {
|
|
if (form._aksrtHistBound) return;
|
|
form._aksrtHistBound = 1;
|
|
form.addEventListener("submit", function () {
|
|
var input = form.querySelector('input[name="s"]');
|
|
var q = input ? (input.value || "").trim() : "";
|
|
if (!q) return;
|
|
var typeInput = form.querySelector('input[name="aksrt_search_type"], input[name="type"]');
|
|
var type = (typeInput && typeInput.value) || "post";
|
|
if (window.aksrtData && aksrtData.isLoggedIn) {
|
|
saveLoggedHistory(q, type);
|
|
} else {
|
|
var list = readLocalHistory().filter(function (k) {
|
|
return k !== q;
|
|
});
|
|
list.unshift(q);
|
|
writeLocalHistory(list);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
bindRemoteBoxes(document);
|
|
bindFullSearchBoxHistory();
|
|
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") {
|
|
window.AksrtFrontend.register("aksrt-inline-search-suggest", function () {
|
|
init();
|
|
});
|
|
} else if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|