(function () { var SEARCH_HISTORY_KEY = "searchHistory"; var SEARCH_HISTORY_LIMIT = 10; function readSearchHistory() { try { var stored = window.localStorage.getItem(SEARCH_HISTORY_KEY); var parsed = stored ? JSON.parse(stored) : []; if (!Array.isArray(parsed)) return []; return parsed .filter(function (item) { return typeof item === "string" && item.trim() !== ""; }) .map(function (item) { return item.trim(); }) .slice(0, SEARCH_HISTORY_LIMIT); } catch (_) { return []; } } function saveSearchHistory(keyword) { keyword = String(keyword || "").trim(); if (!keyword) return readSearchHistory(); var compareKeyword = keyword.toLocaleLowerCase(); var history = readSearchHistory().filter(function (item) { return item.toLocaleLowerCase() !== compareKeyword; }); history.unshift(keyword); history = history.slice(0, SEARCH_HISTORY_LIMIT); try { window.localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(history)); } catch (_) { // 隐私模式或存储空间不可用时不阻断搜索跳转。 } return history; } window.SearchHistory = { key: SEARCH_HISTORY_KEY, limit: SEARCH_HISTORY_LIMIT, get: readSearchHistory, add: saveSearchHistory, clear: function () { try { window.localStorage.removeItem(SEARCH_HISTORY_KEY); } catch (_) { // localStorage 不可用时保持静默。 } }, }; if (!document.querySelector('meta[name="viewport"]')) { var viewport = document.createElement("meta"); viewport.name = "viewport"; viewport.content = "width=device-width, initial-scale=1.0"; document.head.appendChild(viewport); } var mobileMenu = document.getElementById("homeMobileMenu"); var mobileMenuButton = document.querySelector(".header-menu-button"); var mobileMenuCloseButtons = mobileMenu ? mobileMenu.querySelectorAll("[data-home-menu-close]") : []; function setMobileMenu(open) { if (!mobileMenu || !mobileMenuButton) return; mobileMenu.hidden = !open; mobileMenuButton.setAttribute("aria-expanded", open ? "true" : "false"); document.body.classList.toggle("home-mobile-menu-open", open); if (open) { var closeButton = mobileMenu.querySelector(".home-mobile-menu-close"); if (closeButton) closeButton.focus({ preventScroll: true }); } else { mobileMenuButton.focus({ preventScroll: true }); } } if (mobileMenu && mobileMenuButton) { mobileMenuButton.addEventListener("click", function () { setMobileMenu(true); }); Array.prototype.forEach.call(mobileMenuCloseButtons, function (button) { button.addEventListener("click", function () { setMobileMenu(false); }); }); document.addEventListener("keydown", function (event) { if (event.key === "Escape" && !mobileMenu.hidden) setMobileMenu(false); }); } function refreshDecrypt(root) { if (typeof window.initLazyImages === "function") { window.initLazyImages(root || document); } } document.addEventListener( "click", function (event) { var el = event.target; if (el && el.nodeType === 3) { el = el.parentElement; } if (!el || !el.closest) return; var tag = el.closest(".poster-card-tag[data-tag-href], .ranking-card-tag[data-tag-href]"); if (!tag) return; var href = tag.getAttribute("data-tag-href"); if (!href) return; event.preventDefault(); event.stopPropagation(); if (event.stopImmediatePropagation) event.stopImmediatePropagation(); window.location.href = href; }, true ); function initDesktopSearchPopover() { var form = document.querySelector('form.header-search[action="/search/"]'); var input = form && form.querySelector('input[name="q"]'); var popover = document.querySelector("[data-header-search-popover]"); if (!form || !input || !popover) return; var desktopMedia = window.matchMedia("(min-width: 768px)"); var historyList = popover.querySelector("[data-search-history-list]"); var hotList = popover.querySelector("[data-search-hot-list]"); var guessList = popover.querySelector("[data-search-guess-list]"); var historySection = popover.querySelector(".header-search-history"); var hotSection = popover.querySelector(".header-search-hot"); var guessSection = popover.querySelector(".header-search-guess"); var dividers = popover.querySelectorAll(".header-search-popover-divider"); var clearButton = popover.querySelector("[data-search-history-clear]"); var closeButton = popover.querySelector("[data-header-search-close]"); var changeButton = popover.querySelector("[data-search-guess-change]"); var hotLikeData = null; var hotLikeRequest = null; var guessOffset = 0; var searchActive = false; function syncPopoverVisibility() { var hasHistory = historySection && !historySection.hidden; var hasHot = hotSection && !hotSection.hidden; var hasGuess = guessSection && !guessSection.hidden; var hasContent = hasHistory || hasHot || hasGuess; if (dividers[0]) dividers[0].hidden = !(hasHistory && (hasHot || hasGuess)); if (dividers[1]) dividers[1].hidden = !(hasHot && hasGuess); popover.hidden = !(searchActive && hasContent); form.classList.toggle("is-search-open", searchActive && hasContent); input.setAttribute("aria-expanded", searchActive && hasContent ? "true" : "false"); if (!popover.hidden) positionPopover(); } function searchKeyword(keyword) { keyword = String(keyword || "").trim(); if (!keyword) return; saveSearchHistory(keyword); window.location.href = "/search/" + encodeURIComponent(keyword) + "/"; } function renderHistory() { if (!historyList) return; historyList.textContent = ""; var history = readSearchHistory(); if (historySection) historySection.hidden = history.length === 0; history.forEach(function (keyword) { var button = document.createElement("button"); button.type = "button"; button.className = "header-search-history-tag"; button.textContent = keyword; button.addEventListener("click", function () { searchKeyword(keyword); }); historyList.appendChild(button); }); syncPopoverVisibility(); } function normalizeHotItems(data) { var hot = data && Array.isArray(data.hotSearch) ? data.hotSearch : []; return hot .map(function (item) { return { keyword: String((item && item.keyword) || "").trim() }; }) .filter(function (item) { return item.keyword !== ""; }) .slice(0, 6); } function renderHotSearch() { if (!hotList) return; hotList.textContent = ""; var items = normalizeHotItems(hotLikeData); if (hotSection) hotSection.hidden = items.length === 0; items.forEach(function (item, index) { var button = document.createElement("button"); var rank = document.createElement("span"); var keyword = document.createElement("span"); button.type = "button"; button.className = "header-search-hot-item"; rank.className = "header-search-hot-rank"; keyword.className = "header-search-hot-keyword"; rank.textContent = String(index + 1); keyword.textContent = item.keyword; button.appendChild(rank); button.appendChild(keyword); button.addEventListener("click", function () { searchKeyword(item.keyword); }); hotList.appendChild(button); }); syncPopoverVisibility(); } function detailHref(item) { var slug = String((item && item.slug) || "").trim(); var id = Number(item && item.id); var key = slug || (id > 0 ? String(id) : ""); return key ? "/detail/" + encodeURIComponent(key) + "/" : "#"; } function firstCardTag(item) { var tags = item && Array.isArray(item.tagNames) ? item.tagNames : []; var themes = item && Array.isArray(item.themeNames) ? item.themeNames : []; return String(tags[0] || themes[0] || "热门").trim(); } function setCardCover(img, rawURL, title) { var cover = String(rawURL || "").trim(); var imageTitle = String(title || "精彩短剧").trim(); img.alt = imageTitle; img.title = imageTitle; img.addEventListener("error", function () { img.classList.remove("lazy"); img.removeAttribute("data-src"); img.src = PLACEHOLDER; }, { once: true }); if (cover && typeof window.shouldDecryptImage === "function" && window.shouldDecryptImage(cover)) { img.className = "lazy"; img.src = PLACEHOLDER; img.setAttribute("data-src", cover); return; } img.src = cover || PLACEHOLDER; } function createGuessCard(item) { var card = document.createElement("a"); var cover = document.createElement("div"); var image = document.createElement("img"); var episode = document.createElement("span"); var copy = document.createElement("div"); var title = document.createElement("div"); var desc = document.createElement("div"); var tagRow = document.createElement("div"); var tag = document.createElement("span"); var totalEpisode = Math.max(0, Number(item && item.totalEpisode) || 0); card.className = "header-search-guess-card"; card.href = detailHref(item); card.setAttribute("aria-label", String((item && item.title) || "查看短剧")); cover.className = "header-search-guess-cover"; episode.className = "header-search-guess-episode"; copy.className = "header-search-guess-copy"; title.className = "header-search-guess-title"; desc.className = "header-search-guess-desc"; tagRow.className = "header-search-guess-tag-row"; tag.className = "header-search-guess-tag"; setCardCover(image, item && item.cover, item && item.title); episode.textContent = totalEpisode ? totalEpisode + "集" : "更新中"; title.textContent = String((item && item.title) || "精彩短剧"); desc.textContent = String((item && item.desc) || "精彩内容等你来看"); tag.textContent = firstCardTag(item); cover.appendChild(image); cover.appendChild(episode); tagRow.appendChild(tag); copy.appendChild(title); copy.appendChild(desc); copy.appendChild(tagRow); card.appendChild(cover); card.appendChild(copy); return card; } function currentGuessBatch(items) { if (items.length <= 4) return items.slice(0, 4); var batch = []; for (var index = 0; index < 4; index += 1) { batch.push(items[(guessOffset + index) % items.length]); } return batch; } function renderGuessLike() { if (!guessList) return; guessList.textContent = ""; var items = hotLikeData && Array.isArray(hotLikeData.guessLike) ? hotLikeData.guessLike.filter(function (item) { return item && (item.id || item.slug); }) : []; if (guessSection) guessSection.hidden = items.length === 0; currentGuessBatch(items).forEach(function (item) { guessList.appendChild(createGuessCard(item)); }); if (items.length) refreshDecrypt(guessList); syncPopoverVisibility(); } function renderHotLike() { renderHotSearch(); renderGuessLike(); } function loadHotLike() { if (hotLikeData) { renderHotLike(); return Promise.resolve(hotLikeData); } if (hotLikeRequest) return hotLikeRequest; if (hotSection) hotSection.hidden = true; if (guessSection) guessSection.hidden = true; syncPopoverVisibility(); if (!window.HttpRequest || typeof window.HttpRequest.get !== "function") { hotLikeData = {}; renderHotLike(); return Promise.resolve(hotLikeData); } hotLikeRequest = window.HttpRequest.get("/api/playlet/hot-like") .then(function (response) { hotLikeData = response && response.data ? response.data : {}; renderHotLike(); return hotLikeData; }) .catch(function () { hotLikeData = {}; renderHotLike(); return hotLikeData; }); return hotLikeRequest; } function positionPopover() { if (popover.hidden || !desktopMedia.matches) return; var rect = form.getBoundingClientRect(); var header = form.closest(".site-header"); var headerRect = header ? header.getBoundingClientRect() : rect; var viewportPadding = 24; var width = popover.offsetWidth; var left = rect.right - width; var top = Math.max(rect.bottom + 12, headerRect.bottom + 12); left = Math.max(viewportPadding, Math.min(left, window.innerWidth - width - viewportPadding)); popover.style.left = Math.round(left) + "px"; popover.style.top = Math.round(top) + "px"; popover.style.maxHeight = Math.max(240, window.innerHeight - top - 16) + "px"; } function setPopover(open, options) { options = options || {}; searchActive = Boolean(open && desktopMedia.matches); if (searchActive) { renderHistory(); if (hotLikeData) renderHotLike(); else loadHotLike(); } else if (options.blur) { input.blur(); } syncPopoverVisibility(); } input.addEventListener("focus", function () { setPopover(true); }); input.addEventListener("click", function () { setPopover(true); }); clearButton.addEventListener("click", function () { window.SearchHistory.clear(); renderHistory(); input.focus({ preventScroll: true }); }); closeButton.addEventListener("click", function () { setPopover(false, { blur: true }); }); changeButton.addEventListener("click", function () { var items = hotLikeData && Array.isArray(hotLikeData.guessLike) ? hotLikeData.guessLike : []; if (items.length > 4) guessOffset = (guessOffset + 4) % items.length; renderGuessLike(); }); document.addEventListener("pointerdown", function (event) { if (!searchActive || form.contains(event.target) || popover.contains(event.target)) return; setPopover(false); }); document.addEventListener("keydown", function (event) { if (event.key === "Escape" && searchActive) { setPopover(false, { blur: true }); } }); window.addEventListener("resize", function () { if (!desktopMedia.matches) { setPopover(false); return; } positionPopover(); }); window.addEventListener("scroll", positionPopover, { passive: true }); if (typeof desktopMedia.addEventListener === "function") { desktopMedia.addEventListener("change", function (event) { if (!event.matches) setPopover(false); }); } } initDesktopSearchPopover(); document.addEventListener("submit", function (event) { var form = event.target; if (!form || !form.matches || !form.matches('form[action="/search/"]')) return; var input = form.querySelector('input[name="q"]'); var keyword = String((input && input.value) || "").trim(); if (!keyword) return; saveSearchHistory(keyword); event.preventDefault(); window.location.href = "/search/" + encodeURIComponent(keyword) + "/"; }); if (document.body && document.body.classList.contains("search-layout")) { var currentSearchInput = document.querySelector('.header-search input[name="q"]'); saveSearchHistory(currentSearchInput && currentSearchInput.value); } })();