From 7bc069b806900029d4d6157cbb59b41f27fa16fb Mon Sep 17 00:00:00 2001 From: Accusys Date: Tue, 19 May 2026 03:18:36 +0800 Subject: [PATCH] feat: full-text search across all doc modules --- docs_v1.0/doc_wasm/index.html | 44 +++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/docs_v1.0/doc_wasm/index.html b/docs_v1.0/doc_wasm/index.html index d745764..b75bf52 100644 --- a/docs_v1.0/doc_wasm/index.html +++ b/docs_v1.0/doc_wasm/index.html @@ -142,6 +142,42 @@ async function loadDoc(name) { } } +function escapeHtml(s) { + return s.replace(/&/g,'&').replace(//g,'>'); +} + +async function fulltextSearch(q) { + el.innerHTML = '

Searching...

'; + var results = []; + for (var i = 0; i < MODULES.length; i++) { + var m = MODULES[i]; + try { + var resp = await fetch('/doc-wasm/modules/' + m[0] + '.md'); + if (!resp.ok) continue; + var md = await resp.text(); + var lines = md.split('\n'); + for (var li = 0; li < lines.length; li++) { + if (lines[li].toLowerCase().indexOf(q) >= 0) { + results.push({ module: m[0], title: m[1] + ' / ' + m[2], line: li + 1, text: lines[li].trim() }); + if (results.length > 50) break; + } + } + } catch(e) {} + } + if (results.length === 0) { + el.innerHTML = '

No results for ' + escapeHtml(q) + '

'; + return; + } + var html = '

Search: ' + escapeHtml(q) + '

' + results.length + ' result(s)

'; + for (var r of results) { + html += '

' + + r.module + ' ' + escapeHtml(r.title) + ' line ' + r.line + '
' + + '' + + escapeHtml(r.text) + '

'; + } + el.innerHTML = html; +} + async function loginUser(user, pass) { var resp = await fetch('/api/v1/auth/login', { method:'POST', headers:{'Content-Type':'application/json'}, @@ -187,14 +223,18 @@ async function initApp() { a.onclick = function(e) { e.preventDefault(); loadDoc(m[0]); }; listEl.appendChild(a); }); - // Search filter + // Search — full text across all modules + var searchTimer = null; var searchEl = document.getElementById('search'); if (searchEl) { searchEl.oninput = function() { - var q = this.value.toLowerCase(); + var q = this.value.toLowerCase().trim(); document.querySelectorAll('#module-list a').forEach(function(a) { a.style.display = a.textContent.toLowerCase().indexOf(q) >= 0 ? '' : 'none'; }); + if (searchTimer) clearTimeout(searchTimer); + if (q.length < 2) { loadDoc(location.hash.slice(1) || '01_auth'); return; } + searchTimer = setTimeout(function() { fulltextSearch(q); }, 300); }; } // Watch for logout disappearing