| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- (function () {
- var BAR_ID = 'fb-inline-search';
- function q(sel, root) { return (root || document).querySelector(sel); }
- function qa(sel, root) { return Array.from((root || document).querySelectorAll(sel)); }
- function ensureBar() {
- var bar = q('#' + BAR_ID);
- if (bar) return bar;
- bar = document.createElement('div');
- bar.id = BAR_ID;
- bar.innerHTML = '' +
- '<input id="fb-inline-search-input" type="text" autocomplete="off" placeholder="筛选当前目录文件(Ctrl+F)" />' +
- '<button class="fb-clear" type="button" title="清空">×</button>' +
- '<span class="fb-count"></span>';
- document.body.appendChild(bar);
- var input = q('#fb-inline-search-input', bar);
- var clearBtn = q('.fb-clear', bar);
- input.addEventListener('input', applyFilter);
- input.addEventListener('keydown', function (e) {
- if (e.key === 'Escape') {
- input.value = '';
- applyFilter();
- }
- });
- clearBtn.addEventListener('click', function () {
- input.value = '';
- applyFilter();
- input.focus();
- });
- return bar;
- }
- function getItems() {
- var nodes = qa('#listing .item, #listing [data-type], #listing tr, #listing li');
- var seen = new Set();
- return nodes.filter(function (el) {
- if (!el || seen.has(el)) return false;
- seen.add(el);
- return !!(el.querySelector('.name') || el.getAttribute('data-type') || (el.textContent || '').trim());
- });
- }
- function getName(el) {
- var n = q('.name', el);
- if (n && n.textContent) return n.textContent.trim();
- var a = q('a', el);
- if (a && a.textContent) return a.textContent.trim();
- return (el.textContent || '').trim();
- }
- function setVisible(el, show) {
- if (show) {
- if (el.dataset.fbOrigDisplay !== undefined) {
- el.style.display = el.dataset.fbOrigDisplay;
- delete el.dataset.fbOrigDisplay;
- } else {
- el.style.removeProperty('display');
- }
- el.removeAttribute('data-fb-hidden');
- return;
- }
- if (el.dataset.fbOrigDisplay === undefined) {
- el.dataset.fbOrigDisplay = el.style.display || '';
- }
- el.style.display = 'none';
- el.setAttribute('data-fb-hidden', '1');
- }
- function applyFilter() {
- var bar = ensureBar();
- var input = q('#fb-inline-search-input', bar);
- var count = q('.fb-count', bar);
- var query = (input.value || '').trim().toLowerCase();
- var items = getItems();
- var shown = 0;
- items.forEach(function (el) {
- var ok = !query || getName(el).toLowerCase().indexOf(query) !== -1;
- setVisible(el, ok);
- if (ok) shown += 1;
- });
- count.textContent = query ? (shown + '/' + items.length) : '';
- }
- function focusSearch() {
- var input = q('#fb-inline-search-input') || q('#fb-inline-search-input', ensureBar());
- if (!input) return;
- input.focus();
- input.select();
- }
- function intercept(evt) {
- var ctrlF = evt.type === 'keydown' && (evt.ctrlKey || evt.metaKey) && (evt.key === 'f' || evt.key === 'F');
- var btn = evt.type === 'click' && evt.target && evt.target.closest && evt.target.closest('.search-button');
- if (!ctrlF && !btn) return;
- evt.preventDefault();
- evt.stopPropagation();
- if (evt.stopImmediatePropagation) evt.stopImmediatePropagation();
- ensureBar();
- focusSearch();
- }
- function closeNativeSearch() {
- var nativeSearch = q('#search');
- if (!nativeSearch) return;
- nativeSearch.classList.remove('active', 'ongoing');
- nativeSearch.style.display = 'none';
- document.body.style.overflow = 'auto';
- }
- function bootstrap() {
- ensureBar();
- closeNativeSearch();
- applyFilter();
- }
- window.addEventListener('keydown', intercept, true);
- window.addEventListener('click', intercept, true);
- var mo = new MutationObserver(function () {
- closeNativeSearch();
- if (q('#fb-inline-search-input') && q('#fb-inline-search-input').value) applyFilter();
- });
- bootstrap();
- mo.observe(document.documentElement, { childList: true, subtree: true });
- })();
|