Improve local evidence search and AI capabilities

This commit is contained in:
lix-2026
2026-06-05 23:00:53 +08:00
parent a1dcfc9f76
commit 4dbd9a978b
52 changed files with 6415 additions and 527 deletions
@@ -874,6 +874,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
const inferOnlyOfficeFileType = (...args) => sidebarFileTreeOpen.inferOnlyOfficeFileType(...args);
const buildOnlyOfficeOpenUrl = (...args) => sidebarFileTreeOpen.buildOnlyOfficeOpenUrl(...args);
const buildOnlyOfficeOpenPath = (...args) => sidebarFileTreeOpen.buildOnlyOfficeOpenPath(...args);
const buildOfficePreviewOpenUrl = (...args) => sidebarFileTreeOpen.buildOfficePreviewOpenUrl(...args);
const buildPdfPreviewOpenUrl = (...args) => sidebarFileTreeOpen.buildPdfPreviewOpenUrl(...args);
const buildLocalOnlyOfficeOpenUrl = (...args) => sidebarFileTreeOpen.buildLocalOnlyOfficeOpenUrl(...args);
const openLocalOfficeFileInActiveTab = (...args) => sidebarFileTreeOpen.openLocalOfficeFileInActiveTab(...args);
@@ -2198,26 +2199,57 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return searchText(shell && shell.getAttribute('data-document-id')) || searchText(bodyId);
}
function localResourceDocumentIdFromPath(path) {
var normalized = searchText(path).replace(/\\/g, '/');
return normalized ? 'local-resource:' + normalized.replace(/\//g, '~2F') : '';
}
function currentSearchDocumentId() {
var activePanel = document.querySelector('[data-mnote-resource-tab-panel][data-pane-role="primary"]:not([hidden])');
if (activePanel instanceof HTMLElement) {
var resourceKind = searchText(activePanel.getAttribute('data-resource-kind')).toLowerCase();
var resourcePath = searchText(activePanel.getAttribute('data-resource-path'));
if (resourceKind && resourceKind !== 'markdown' && resourcePath) return localResourceDocumentIdFromPath(resourcePath);
try {
var locator = JSON.parse(activePanel.getAttribute('data-mnote-evidence-locator') || 'null');
var locatorDoc = searchText(locator && (locator.ownerDocumentId || locator.owner_document_id));
if (locatorDoc) return locatorDoc;
} catch (_) {}
}
return currentDocumentId();
}
function searchSwitchValue(overlay, name) {
var button = overlay.querySelector('[data-search-switch="' + name + '"]');
return button instanceof HTMLElement && button.getAttribute('aria-checked') === 'true';
}
function highlightedHtml(value) {
return escapeHtml(value)
.replace(/&lt;mark&gt;/g, '<mark>')
.replace(/&lt;\/mark&gt;/g, '</mark>');
}
function highlightSearchTitle(title, query) {
var cleanTitle = searchText(title);
function highlightSearchText(value, query, exact) {
var text = searchText(value);
var cleanQuery = searchText(query);
if (!cleanQuery) return escapeHtml(cleanTitle);
var index = cleanTitle.toLowerCase().indexOf(cleanQuery.toLowerCase());
if (index < 0) return escapeHtml(cleanTitle);
return escapeHtml(cleanTitle.slice(0, index)) +
'<mark>' + escapeHtml(cleanTitle.slice(index, index + cleanQuery.length)) + '</mark>' +
escapeHtml(cleanTitle.slice(index + cleanQuery.length));
if (!text || !cleanQuery) return escapeHtml(text);
var lower = text.toLowerCase();
var lowerQuery = cleanQuery.toLowerCase();
var exactIndex = lower.indexOf(lowerQuery);
if (exact || exactIndex >= 0) {
if (exactIndex < 0) return escapeHtml(text);
return escapeHtml(text.slice(0, exactIndex)) +
'<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);
}
});
return next >= chars.length ? html : escapeHtml(text);
}
function searchResultEvidenceLocator(item) {
@@ -2243,6 +2275,38 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return searchText(action && action.url);
}
function evidenceLocatorLineRange(locator) {
return locator && (locator.lineRange || locator.line_range) || null;
}
function evidenceLocatorCharRange(locator) {
return locator && (locator.charRange || locator.char_range) || null;
}
function evidenceLocatorBlockId(locator) {
return searchText(locator && (locator.blockId || locator.block_id));
}
function resourceHrefForEvidenceLocator(resourceKind, resourcePath, fileName, ownerDocumentId, locator) {
var localFileUrl = buildLocalFileOpenUrl(resourcePath, false);
if (!localFileUrl) return '';
if (resourceKind === 'pdf') return buildPdfPreviewOpenUrl(localFileUrl, fileName);
if (resourceKind === 'office') {
var fileType = inferOnlyOfficeFileType(fileName, '') || (fileName.indexOf('.') >= 0 ? fileName.split('.').pop() : 'docx');
return buildOfficePreviewOpenUrl({
fileUrl: localFileUrl,
fileName: fileName,
fileType: fileType,
assetId: 'local-file:' + resourcePath,
documentId: ownerDocumentId || currentDocumentId() || '',
workspaceId: resolveWorkspaceId(document.body) || '',
sourceKind: currentSourceKind() || 'local_folder',
rootUri: searchText(locator && (locator.rootUri || locator.root_uri) || currentRootUri())
});
}
return localFileUrl;
}
async function openEvidenceSearchResult(item, event) {
var locator = searchResultEvidenceLocator(item);
if (!locator) {
@@ -2254,18 +2318,20 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var ownerDocumentId = searchText(locator.ownerDocumentId || locator.owner_document_id || item.documentId || '');
var resourceKind = evidenceLocatorResourceKind(locator, item && item.resourceType);
var openTarget = event && event.altKey ? 'side' : 'active-tab';
if (resourcePath && resourceKind && resourceKind !== 'markdown') {
if (resourcePath && resourceKind) {
var fileName = resourcePath.split('/').filter(Boolean).pop() || resourcePath;
var localFileUrl = buildLocalFileOpenUrl(resourcePath, false);
var href = resourceKind === 'pdf' ? buildPdfPreviewOpenUrl(localFileUrl, fileName) : localFileUrl;
await openLocalResourceInActiveTab({
var normalizedKind = resourceKind === 'raw_file' || resourceKind === 'resource' ? fileTreeIconKindForFileName(fileName) || 'file' : resourceKind;
var hostDocumentId = currentDocumentId() || ownerDocumentId || '';
var href = resourceHrefForEvidenceLocator(normalizedKind, resourcePath, fileName, hostDocumentId, locator);
var openedInResourceTab = await openLocalResourceInActiveTab({
path: resourcePath,
title: fileName,
kind: resourceKind,
kind: normalizedKind,
href: href,
officeUrl: normalizedKind === 'office' ? href : '',
assetId: 'local-file:' + resourcePath,
documentId: ownerDocumentId || currentDocumentId() || '',
ownerDocumentId: ownerDocumentId || currentDocumentId() || '',
documentId: hostDocumentId,
ownerDocumentId: ownerDocumentId || hostDocumentId,
workspaceId: resolveWorkspaceId(document.body) || '',
sourceKind: currentSourceKind() || 'local_folder',
rootUri: searchText(locator.rootUri || locator.root_uri || currentRootUri()),
@@ -2274,10 +2340,11 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
page: locator.page,
bbox: locator.bbox,
sourceMapPath: searchText(locator.sourceMapPath || locator.source_map_path),
blockId: searchText(locator.blockId || locator.block_id),
lineRange: locator.lineRange || locator.line_range || null,
charRange: locator.charRange || locator.char_range || null
blockId: evidenceLocatorBlockId(locator),
lineRange: evidenceLocatorLineRange(locator),
charRange: evidenceLocatorCharRange(locator)
});
if (!openedInResourceTab) console.warn('mnote evidence 搜索结果无法在当前页面资源标签打开', locator);
closeSearchModal();
return;
}
@@ -2339,7 +2406,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
workspaceId: resolveWorkspaceId(document.body),
sourceKind: currentSourceKind() || null,
rootUri: currentRootUri() || null,
documentId: currentDocumentId() || null,
documentId: searchSwitchValue(overlay, 'page') ? (currentSearchDocumentId() || null) : (currentDocumentId() || null),
query: query,
limit: 30,
filters: {
@@ -2368,10 +2435,11 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var locator = searchResultEvidenceLocator(item);
var locatorAttr = locator ? escapeHtml(JSON.stringify(locator)) : '';
var index = items.indexOf(item);
var exact = searchSwitchValue(overlay, 'exact');
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">' + highlightSearchTitle(title, query) + '</span>' +
'<span class="wolai-search-result-snippet">' + (snippet ? highlightedHtml(snippet) : escapeHtml(path)) + '</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-path"><span>' + escapeHtml(path) + '</span><span class="wolai-search-result-type">' + escapeHtml(resourceType) + '</span></span></span>' +
'</button>';
}).join('');
@@ -2583,7 +2651,16 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return;
}
var ocrSettingsTrigger = closestAction(e.target, '[data-mnote-action="open-ocr-settings"], [data-mnote-action="toggle-ocr-tasks"]');
var ocrTaskTrigger = closestAction(e.target, '[data-mnote-action="toggle-ocr-tasks"]');
if (ocrTaskTrigger) {
e.preventDefault();
window.dispatchEvent(new CustomEvent('mnote:local-ocr-settings-action', {
detail: { action: 'tasks' }
}));
return;
}
var ocrSettingsTrigger = closestAction(e.target, '[data-mnote-action="open-ocr-settings"]');
if (ocrSettingsTrigger) {
e.preventDefault();
openLocalOcrSettingsPopover();