"use strict"; (() => { const globalWindow = window; if (globalWindow.searchInitialized) { return; } globalWindow.searchInitialized = true; let searchTimeout; const searchInput = document.getElementById('search-input'); const searchDropdown = document.getElementById('search-dropdown'); if (!searchInput || !searchDropdown) { return; } searchInput.addEventListener('input', (event) => { if (searchTimeout) { window.clearTimeout(searchTimeout); } const target = event.target; if (!(target instanceof HTMLInputElement)) { return; } const query = target.value.trim(); if (query.length < 2) { searchDropdown.replaceChildren(); return; } searchTimeout = window.setTimeout(() => { fetch('/api/search-quick?q=' + encodeURIComponent(query)) .then((res) => res.json()) .then((results) => { if (!results || results.length === 0) { searchDropdown.replaceChildren(); return; } const searchResults = document.createElement('div'); searchResults.className = 'search-results'; const title = document.createElement('div'); title.className = 'search-results-title'; title.textContent = 'Anime'; searchResults.appendChild(title); results.forEach((result) => { const item = document.createElement('a'); item.className = 'search-result-item'; item.setAttribute('href', '/anime/' + encodeURIComponent(String(result.id || ''))); if (isSafeImageUrl(result.image)) { const img = document.createElement('img'); img.className = 'search-result-thumb'; img.setAttribute('src', result.image || ''); img.setAttribute('alt', String(result.title || '')); item.appendChild(img); } else { const noImage = document.createElement('div'); noImage.className = 'search-result-no-image'; noImage.textContent = 'no image'; item.appendChild(noImage); } const info = document.createElement('div'); info.className = 'search-result-info'; const itemTitle = document.createElement('div'); itemTitle.className = 'search-result-title'; itemTitle.textContent = String(result.title || ''); info.appendChild(itemTitle); const itemType = document.createElement('div'); itemType.className = 'search-result-type'; itemType.textContent = String(result.type || ''); info.appendChild(itemType); item.appendChild(info); searchResults.appendChild(item); }); const viewAll = document.createElement('a'); viewAll.className = 'search-result-view-all'; viewAll.setAttribute('href', '/search?q=' + encodeURIComponent(query)); viewAll.textContent = 'View all results for ' + query; searchResults.appendChild(viewAll); searchDropdown.replaceChildren(searchResults); }) .catch((err) => { console.error('Search error:', err); }); }, 300); }); searchInput.addEventListener('blur', () => { window.setTimeout(() => { searchDropdown.replaceChildren(); }, 200); }); document.addEventListener('click', (event) => { const target = event.target; if (!(target instanceof Element)) { return; } if (!target.closest('.header-search-wrapper')) { searchDropdown.replaceChildren(); } }); function isSafeImageUrl(rawUrl) { if (!rawUrl || typeof rawUrl !== 'string') { return false; } try { const parsed = new URL(rawUrl, window.location.origin); return parsed.protocol === 'https:' || parsed.protocol === 'http:'; } catch { return false; } } })();