Files
HomeDash/web/navi.js
JianFeeeee 7e49d2b51c feat: HomeDash - unified self-hosted navigation portal
Single-container navigation service combining:
- Dashy dashboard + SearXNG metasearch + history sync API + admin WebUI
- Go services for history/admin APIs, nginx as unified entry
- Browser extensions (Chrome MV3 / Firefox MV2) with 30s batched sync
- Production guide: portal-nginx unified auth reverse proxy + webui4frpc/frp tunnel
- Fully sanitized (no internal IPs/domains/credentials)
2026-09-08 22:25:00 +08:00

40 lines
1.4 KiB
JavaScript

(() => {
'use strict';
function mountSearch() {
if (document.querySelector('.navi-search-bar')) return;
const form = document.createElement('form');
form.className = 'navi-search-bar';
form.method = 'GET';
form.action = '/search';
form.target = '_blank';
form.setAttribute('role', 'search');
const icon = document.createElement('span');
icon.innerHTML = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>';
icon.setAttribute('aria-hidden', 'true');
const input = document.createElement('input');
input.type = 'search';
input.name = 'q';
input.placeholder = '搜索…';
input.autocomplete = 'off';
input.setAttribute('aria-label', '搜索');
const button = document.createElement('button');
button.type = 'submit';
button.textContent = '→';
button.title = '搜索';
form.append(icon, input, button);
document.body.appendChild(form);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', mountSearch, { once: true });
} else {
mountSearch();
}
new MutationObserver(mountSearch).observe(document.documentElement, { childList: true, subtree: true });
})();