(() => { 'use strict'; // 浏览器插件在 document_start 阶段写入这个属性(见 extension/*/detect.js)。 const EXT_ATTR = 'data-navi-ext'; const INSTALL_SELECTOR = 'a[href*="/extension/install"]'; function extensionInstalled() { return document.documentElement.hasAttribute(EXT_ATTR); } // 已装插件的浏览器不需要安装入口:连外层网格单元一起隐藏, // 否则 .item-wrapper 会留下一个空位。 function hideInstallEntry() { if (!extensionInstalled()) return; document.querySelectorAll(INSTALL_SELECTOR).forEach((link) => { const cell = link.closest('.item-wrapper') || link.parentElement || link; if (cell.style.display !== 'none') cell.style.display = 'none'; }); } 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 = ''; 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); } function run() { mountSearch(); hideInstallEntry(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', run, { once: true }); } else { run(); } new MutationObserver(run).observe(document.documentElement, { childList: true, subtree: true }); })();