Improve evidence search ranking and diagnostics

This commit is contained in:
lix-2026
2026-06-06 00:33:02 +08:00
parent 4dbd9a978b
commit 5157a5960c
6 changed files with 891 additions and 235 deletions
@@ -2224,7 +2224,18 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return button instanceof HTMLElement && button.getAttribute('aria-checked') === 'true';
}
function highlightSearchText(value, query, exact) {
function searchHighlightTerms(item, query) {
var info = item && item.matchInfo || item && item.evidence && item.evidence.matchInfo || null;
var terms = info && Array.isArray(info.matchedTerms) ? info.matchedTerms : [];
terms = terms.map(searchText).filter(Boolean);
if (!terms.length) {
terms = searchText(query).split(/[\s,;:,;:。、()[\]{}]+/).map(searchText).filter(Boolean);
}
terms.sort(function(left, right) { return right.length - left.length; });
return terms.filter(function(term, index) { return terms.indexOf(term) === index; });
}
function highlightSearchText(value, query, exact, terms) {
var text = searchText(value);
var cleanQuery = searchText(query);
if (!text || !cleanQuery) return escapeHtml(text);
@@ -2237,19 +2248,30 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
'<mark>' + escapeHtml(text.slice(exactIndex, exactIndex + cleanQuery.length)) + '</mark>' +
escapeHtml(text.slice(exactIndex + cleanQuery.length));
}
var chars = Array.from(cleanQuery.replace(/\s+/g, '').toLowerCase());
if (!chars.length) return escapeHtml(text);
var next = 0;
var html = '';
Array.from(text).forEach(function(ch) {
if (next < chars.length && ch.toLowerCase() === chars[next]) {
html += '<mark>' + escapeHtml(ch) + '</mark>';
next += 1;
} else {
html += escapeHtml(ch);
terms = Array.isArray(terms) ? terms.map(searchText).filter(Boolean) : [];
if (!terms.length) return escapeHtml(text);
var ranges = [];
terms.forEach(function(term) {
var lowerTerm = term.toLowerCase();
var start = lower.indexOf(lowerTerm);
while (start >= 0) {
var end = start + lowerTerm.length;
var overlaps = ranges.some(function(range) { return start < range.end && end > range.start; });
if (!overlaps) ranges.push({ start: start, end: end });
start = lower.indexOf(lowerTerm, end);
}
});
return next >= chars.length ? html : escapeHtml(text);
if (!ranges.length) return escapeHtml(text);
ranges.sort(function(left, right) { return left.start - right.start; });
var html = '';
var cursor = 0;
ranges.forEach(function(range) {
if (range.start > cursor) html += escapeHtml(text.slice(cursor, range.start));
html += '<mark>' + escapeHtml(text.slice(range.start, range.end)) + '</mark>';
cursor = range.end;
});
if (cursor < text.length) html += escapeHtml(text.slice(cursor));
return html;
}
function searchResultEvidenceLocator(item) {
@@ -2436,10 +2458,11 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var locatorAttr = locator ? escapeHtml(JSON.stringify(locator)) : '';
var index = items.indexOf(item);
var exact = searchSwitchValue(overlay, 'exact');
var highlightTerms = searchHighlightTerms(item, query);
return '<button type="button" class="wolai-search-result-row" data-testid="wolai-search-result-row" data-search-result-owner="rust-kernel" data-search-result-index="' + String(index) + '" data-document-id="' + escapeHtml(item.documentId || item.nodeId || item.id || '') + '" data-resource-type="' + escapeHtml(resourceType) + '"' + (locatorAttr ? ' data-evidence-locator="' + locatorAttr + '"' : '') + '>' +
'<span class="material-symbols-outlined wolai-search-result-icon" data-icon="article" aria-hidden="true"></span>' +
'<span class="wolai-search-result-main"><span class="wolai-search-result-title">' + highlightSearchText(title, query, exact) + '</span>' +
'<span class="wolai-search-result-snippet">' + (snippet ? highlightSearchText(snippet, query, exact) : escapeHtml(path)) + '</span>' +
'<span class="wolai-search-result-main"><span class="wolai-search-result-title">' + highlightSearchText(title, query, exact, highlightTerms) + '</span>' +
'<span class="wolai-search-result-snippet">' + (snippet ? highlightSearchText(snippet, query, exact, highlightTerms) : escapeHtml(path)) + '</span>' +
'<span class="wolai-search-result-path"><span>' + escapeHtml(path) + '</span><span class="wolai-search-result-type">' + escapeHtml(resourceType) + '</span></span></span>' +
'</button>';
}).join('');