3764 lines
185 KiB
JavaScript
3764 lines
185 KiB
JavaScript
import { createSidebarWorkspaceRuntime } from './sidebar-workspace-runtime.js';
|
||
import { createSidebarPageTreeRuntime } from './sidebar-page-tree-runtime.js';
|
||
import { createSidebarTreeLiveApplyRuntime } from './sidebar-tree-live-apply-runtime.js';
|
||
import { createSidebarFileTreeOpenRuntime } from './sidebar-filetree-open-runtime.js';
|
||
import { createSidebarAttachmentOpenRuntime } from './sidebar-attachment-open-runtime.js';
|
||
import { createSidebarFileTreeCommandRuntime } from './sidebar-filetree-command-runtime.js';
|
||
import { createSidebarFileTreeUploadRuntime } from './sidebar-filetree-upload-runtime.js';
|
||
import { createSidebarPageAiRuntime } from './sidebar-page-ai-runtime.js';
|
||
import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtime.js';
|
||
|
||
(function(){
|
||
if (window.__mnoteSidebarTreeRuntimeStarted) return;
|
||
window.__mnoteSidebarTreeRuntimeStarted = true;
|
||
|
||
var FILETREE_DRAG_MIME = 'application/x-mnote-filetree-row-ids';
|
||
var MNOTE_SIDEBAR_TREE_MODE_KEY = 'mnote.sidebar.tree.mode';
|
||
var MNOTE_RECENT_LOCAL_ROOTS_KEY_PREFIX = 'mnote.localFolder.recentRoots:';
|
||
var MNOTE_LAST_CLOUD_WORKSPACE_KEY = 'mnote.workspace.lastCloudWorkspaceId';
|
||
var MNOTE_GLOBAL_SHOW_HEADING_NUMBERS_KEY = 'mnote.global.showHeadingNumbers';
|
||
var mnoteNavigationInFlight = '';
|
||
var draggingFileTreeRowIds = [];
|
||
var activeFileTreeDropRow = null;
|
||
var sidebarFileTreeClipboard = null;
|
||
var sidebarFileTreeSelection = {
|
||
selectedRowIds: new Set(),
|
||
anchorRowId: null,
|
||
focusedRowId: null
|
||
};
|
||
var activeTreeContextMenu = null;
|
||
var pageUiState = {
|
||
pageOptions: null,
|
||
pageWidthPreferences: null,
|
||
historySnapshots: [],
|
||
pageSettingsOpen: false,
|
||
localIndexSummary: {
|
||
scopeKey: '',
|
||
loading: false,
|
||
error: '',
|
||
backlinks: null,
|
||
tags: null
|
||
}
|
||
};
|
||
|
||
function closestAction(target, selector) {
|
||
var node = target && target.nodeType === Node.TEXT_NODE ? target.parentElement : target;
|
||
return node && typeof node.closest === 'function' ? node.closest(selector) : null;
|
||
}
|
||
|
||
function sidebarShellRuntimeFunction(name) {
|
||
var runtime = window.__mnoteSidebarShellRuntime;
|
||
return runtime && typeof runtime[name] === 'function' ? runtime[name] : null;
|
||
}
|
||
|
||
function toggleWorkspaceSidebar(trigger) {
|
||
var runtimeFn = sidebarShellRuntimeFunction('toggleWorkspaceSidebar');
|
||
if (runtimeFn) return runtimeFn(trigger);
|
||
}
|
||
|
||
function installWorkspaceSidebarResizer() {
|
||
var runtimeFn = sidebarShellRuntimeFunction('installWorkspaceSidebarResizer');
|
||
if (runtimeFn) return runtimeFn();
|
||
}
|
||
|
||
function escapeHtml(value) {
|
||
return String(value == null ? '' : value)
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"')
|
||
.replace(/'/g, ''');
|
||
}
|
||
|
||
function cssEscape(value) {
|
||
if (window.CSS && typeof window.CSS.escape === 'function') return window.CSS.escape(value);
|
||
return String(value).replace(/["\\]/g, '\\$&');
|
||
}
|
||
|
||
function parseJsonScript(id) {
|
||
var node = document.getElementById(id);
|
||
if (!node) return null;
|
||
try {
|
||
return JSON.parse(node.textContent || 'null');
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function currentDocumentId() {
|
||
var match = window.location.pathname.match(/^\/documents\/([^\/]+)/);
|
||
if (!match) match = window.location.pathname.match(/^\/mindmap\/([^\/]+)\/([^\/]+)/);
|
||
if (match) return decodeURIComponent(match[1]);
|
||
var params = new URLSearchParams(window.location.search);
|
||
var fromQuery = (params.get('documentId') || params.get('pageId') || '').trim();
|
||
if (fromQuery) return fromQuery;
|
||
var activePane = document.querySelector('.document-pane[data-pane-role="primary"][data-pane-document-id], .document-pane[data-pane-visible="true"][data-pane-document-id]');
|
||
if (activePane instanceof HTMLElement) {
|
||
var paneDocumentId = (activePane.getAttribute('data-pane-document-id') || '').trim();
|
||
if (paneDocumentId) return paneDocumentId;
|
||
}
|
||
var shell = document.querySelector('.document-shell[data-document-id]');
|
||
if (shell instanceof HTMLElement) return (shell.getAttribute('data-document-id') || '').trim();
|
||
return '';
|
||
}
|
||
|
||
function localFolderSelfChangeSuppressions() {
|
||
window.__mnoteLocalFolderSelfChangeSuppressions = window.__mnoteLocalFolderSelfChangeSuppressions || new Map();
|
||
return window.__mnoteLocalFolderSelfChangeSuppressions;
|
||
}
|
||
|
||
function persistLocalFolderSelfChangeSuppression(documentId, expiresAt) {
|
||
var doc = String(documentId || '').trim();
|
||
if (!doc) return;
|
||
localFolderSelfChangeSuppressions().set(doc, expiresAt);
|
||
try {
|
||
var key = 'mnote.localFolder.selfChangeSuppressions.v1';
|
||
var existing = JSON.parse(window.sessionStorage.getItem(key) || '{}');
|
||
existing[doc] = expiresAt;
|
||
window.sessionStorage.setItem(key, JSON.stringify(existing));
|
||
} catch (_) {}
|
||
}
|
||
|
||
var EDITOR_UPLOAD_ROOT_SELECTOR = '[data-editor-host-kind="leptos_tiptap_island"], [data-editor-host-kind="leptos_tiptap_resource"]';
|
||
|
||
function editorUploadRootFromElement(target) {
|
||
if (!(target instanceof Element)) return null;
|
||
var root = target.closest(EDITOR_UPLOAD_ROOT_SELECTOR);
|
||
return root instanceof HTMLElement ? root : null;
|
||
}
|
||
|
||
function rememberEditorUploadRootFromTarget(target) {
|
||
var root = editorUploadRootFromElement(target);
|
||
if (root instanceof HTMLElement) {
|
||
window.__mnoteLastEditorUploadRoot = root;
|
||
return root;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
document.addEventListener('pointerdown', function(event) {
|
||
rememberEditorUploadRootFromTarget(event.target);
|
||
}, true);
|
||
|
||
document.addEventListener('focusin', function(event) {
|
||
rememberEditorUploadRootFromTarget(event.target);
|
||
}, true);
|
||
|
||
function currentFileTreeActiveRowId() {
|
||
var explicitRowId = new URL(window.location.href).searchParams.get('restoreFocusRowId') || '';
|
||
if (explicitRowId) return explicitRowId;
|
||
var mindmapMatch = window.location.pathname.match(/^\/mindmap\/([^\/]+)\/([^\/]+)/);
|
||
if (mindmapMatch) return 'asset:' + decodeURIComponent(mindmapMatch[2]);
|
||
var documentId = currentDocumentId();
|
||
return documentId ? 'doc:' + documentId : '';
|
||
}
|
||
|
||
function currentPageAggregate() {
|
||
return parseJsonScript('__MNOTE_PAGE_AGGREGATE__') || {};
|
||
}
|
||
|
||
const sidebarWorkspace = createSidebarWorkspaceRuntime({
|
||
cssEscape,
|
||
currentDocumentId,
|
||
escapeHtml,
|
||
parseJsonScript,
|
||
setCommandPending: (...args) => setCommandPending(...args),
|
||
sidebarShellRuntimeFunction,
|
||
});
|
||
const normalizeSidebarTreeMode = (...args) => sidebarWorkspace.normalizeSidebarTreeMode(...args);
|
||
const readStoredSidebarTreeMode = (...args) => sidebarWorkspace.readStoredSidebarTreeMode(...args);
|
||
const persistSidebarTreeMode = (...args) => sidebarWorkspace.persistSidebarTreeMode(...args);
|
||
const activeSidebarTreeMode = (...args) => sidebarWorkspace.activeSidebarTreeMode(...args);
|
||
const resolveWorkspaceId = (...args) => sidebarWorkspace.resolveWorkspaceId(...args);
|
||
const currentWorkspaceId = (...args) => sidebarWorkspace.currentWorkspaceId(...args);
|
||
const currentSourceKind = (...args) => sidebarWorkspace.currentSourceKind(...args);
|
||
const currentRootUri = (...args) => sidebarWorkspace.currentRootUri(...args);
|
||
const copyWorkspaceSourceParams = (...args) => sidebarWorkspace.copyWorkspaceSourceParams(...args);
|
||
const currentWorkspaceSourcePayload = (...args) => sidebarWorkspace.currentWorkspaceSourcePayload(...args);
|
||
const openTrashModal = (...args) => sidebarWorkspace.openTrashModal(...args);
|
||
const closeTrashModal = (...args) => sidebarWorkspace.closeTrashModal(...args);
|
||
const closeLocalFolderDialog = (...args) => sidebarWorkspace.closeLocalFolderDialog(...args);
|
||
const requestOpenLocalFolder = (...args) => sidebarWorkspace.requestOpenLocalFolder(...args);
|
||
const createDefaultLocalWorkspace = (...args) => sidebarWorkspace.createDefaultLocalWorkspace(...args);
|
||
const closeWorkspaceSourceMenu = (...args) => sidebarWorkspace.closeWorkspaceSourceMenu(...args);
|
||
const openWorkspaceSourceMenu = (...args) => sidebarWorkspace.openWorkspaceSourceMenu(...args);
|
||
const closeAccountMenu = (...args) => sidebarWorkspace.closeAccountMenu(...args);
|
||
const openAccountMenu = (...args) => sidebarWorkspace.openAccountMenu(...args);
|
||
sidebarWorkspace.autoOpenRecentLocalRootOnHome();
|
||
|
||
const sidebarPageSettings = createSidebarPageSettingsRuntime({
|
||
currentDocumentId,
|
||
currentPageAggregate,
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
currentWorkspaceSourcePayload,
|
||
escapeHtml,
|
||
globalShowHeadingNumbersKey: MNOTE_GLOBAL_SHOW_HEADING_NUMBERS_KEY,
|
||
pageUiState,
|
||
resolveWorkspaceId,
|
||
searchText,
|
||
});
|
||
const applyPageOptionsToShell = (...args) => sidebarPageSettings.applyPageOptionsToShell(...args);
|
||
const closePageHistoryDrawer = (...args) => sidebarPageSettings.closePageHistoryDrawer(...args);
|
||
const closeAllSettingsPopovers = (...args) => sidebarPageSettings.closeAllSettingsPopovers(...args);
|
||
const closePageSettingsPopover = (...args) => sidebarPageSettings.closePageSettingsPopover(...args);
|
||
const closePageShareDialog = (...args) => sidebarPageSettings.closePageShareDialog(...args);
|
||
const currentPageOptions = (...args) => sidebarPageSettings.currentPageOptions(...args);
|
||
const ensureHistorySnapshotsSeeded = (...args) => sidebarPageSettings.ensureHistorySnapshotsSeeded(...args);
|
||
const isAnySettingsOpen = (...args) => sidebarPageSettings.isAnySettingsOpen(...args);
|
||
const isPageSettingsOpen = (...args) => sidebarPageSettings.isPageSettingsOpen(...args);
|
||
const openPageHistoryDrawer = (...args) => sidebarPageSettings.openPageHistoryDrawer(...args);
|
||
const openPageIndexSettingsPopover = (...args) => sidebarPageSettings.openPageIndexSettingsPopover(...args);
|
||
const openKnowledgeRagSettingsPopover = (...args) => sidebarPageSettings.openKnowledgeRagSettingsPopover(...args);
|
||
const openPageShareDialog = (...args) => sidebarPageSettings.openPageShareDialog(...args);
|
||
const pageOptionIsSupported = (...args) => sidebarPageSettings.pageOptionIsSupported(...args);
|
||
const addLocalIndexRange = (...args) => sidebarPageSettings.addLocalIndexRange(...args);
|
||
const addKnowledgeRagSourceInput = (...args) => sidebarPageSettings.addKnowledgeRagSourceInput(...args);
|
||
const deleteKnowledgeRagSource = (...args) => sidebarPageSettings.deleteKnowledgeRagSource(...args);
|
||
const ingestKnowledgeRagSources = (...args) => sidebarPageSettings.ingestKnowledgeRagSources(...args);
|
||
const ingestSingleKnowledgeRagSource = (...args) => sidebarPageSettings.ingestSingleKnowledgeRagSource(...args);
|
||
const loadKnowledgeRagStatus = (...args) => sidebarPageSettings.loadKnowledgeRagStatus(...args);
|
||
const openKnowledgeRagDashboard = (...args) => sidebarPageSettings.openKnowledgeRagDashboard(...args);
|
||
const pruneKnowledgeRagRegistry = (...args) => sidebarPageSettings.pruneKnowledgeRagRegistry(...args);
|
||
const setKnowledgeRagSourceFilter = (...args) => sidebarPageSettings.setKnowledgeRagSourceFilter(...args);
|
||
const useKnowledgeRagFileTreeSelection = (...args) => sidebarPageSettings.useKnowledgeRagFileTreeSelection(...args);
|
||
const persistLocalIndexSettings = (...args) => sidebarPageSettings.persistLocalIndexSettings(...args);
|
||
const persistPageOptionsPatch = (...args) => sidebarPageSettings.persistPageOptionsPatch(...args);
|
||
const persistPageWidthPreference = (...args) => sidebarPageSettings.persistPageWidthPreference(...args);
|
||
const refreshLocalIndex = (...args) => sidebarPageSettings.refreshLocalIndex(...args);
|
||
const removeKnowledgeRagSourceInput = (...args) => sidebarPageSettings.removeKnowledgeRagSourceInput(...args);
|
||
const removeLocalIndexRange = (...args) => sidebarPageSettings.removeLocalIndexRange(...args);
|
||
const recordPageHistorySnapshot = (...args) => sidebarPageSettings.recordPageHistorySnapshot(...args);
|
||
const renderPageSettingsPopover = (...args) => sidebarPageSettings.renderPageSettingsPopover(...args);
|
||
const setActivePageSettingsTab = (...args) => sidebarPageSettings.setActivePageSettingsTab(...args);
|
||
const togglePageSettingsPopover = (...args) => sidebarPageSettings.togglePageSettingsPopover(...args);
|
||
const updatePageSettingsTriggerState = (...args) => sidebarPageSettings.updatePageSettingsTriggerState(...args);
|
||
const writeGlobalShowHeadingNumbers = (...args) => sidebarPageSettings.writeGlobalShowHeadingNumbers(...args);
|
||
const loadPageWidthPreferences = (...args) => sidebarPageSettings.loadPageWidthPreferences(...args);
|
||
|
||
function setCommandPending(trigger, pending) {
|
||
if (!(trigger instanceof HTMLElement)) return;
|
||
trigger.setAttribute('data-pending', pending ? 'true' : 'false');
|
||
if ('disabled' in trigger) {
|
||
if (pending) trigger.setAttribute('disabled', 'disabled');
|
||
else trigger.removeAttribute('disabled');
|
||
}
|
||
}
|
||
|
||
async function dispatchTreeCommand(trigger, body) {
|
||
setCommandPending(trigger, true);
|
||
var commandBody = Object.assign({}, currentWorkspaceSourcePayload(), body || {});
|
||
try {
|
||
var response = await fetch('/api/tree/commands', {
|
||
method: 'POST',
|
||
headers: { 'content-type': 'application/json' },
|
||
body: JSON.stringify(commandBody)
|
||
});
|
||
var payload = await response.json().catch(function(){ return null; });
|
||
if (!response.ok || !payload || !payload.result) {
|
||
throw new Error((payload && payload.message) || 'tree_command_failed_' + response.status);
|
||
}
|
||
window.dispatchEvent(new CustomEvent('tree:local-command', { detail: { body: commandBody, result: payload.result } }));
|
||
setCommandPending(trigger, false);
|
||
return payload.result;
|
||
} catch (error) {
|
||
setCommandPending(trigger, false);
|
||
if (trigger instanceof HTMLElement) {
|
||
trigger.setAttribute('data-error', error instanceof Error ? error.message : String(error));
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
var sidebarPageTree = null;
|
||
const navigateToDocument = (...args) => sidebarPageTree.navigateToDocument(...args);
|
||
const createPage = (...args) => sidebarPageTree.createPage(...args);
|
||
const startPageDrag = (...args) => sidebarPageTree.startPageDrag(...args);
|
||
const readPageDragNodeId = (...args) => sidebarPageTree.readPageDragNodeId(...args);
|
||
const clearPageDropFeedback = (...args) => sidebarPageTree.clearPageDropFeedback(...args);
|
||
const setActivePageDropRow = (...args) => sidebarPageTree.setActivePageDropRow(...args);
|
||
const clearPageDragState = (...args) => sidebarPageTree.clearPageDragState(...args);
|
||
const canDropPage = (...args) => sidebarPageTree.canDropPage(...args);
|
||
const pageDropPosition = (...args) => sidebarPageTree.pageDropPosition(...args);
|
||
const resolvePageMoveTarget = (...args) => sidebarPageTree.resolvePageMoveTarget(...args);
|
||
|
||
async function createFileTreeFolder(trigger, parentId) {
|
||
if (currentSourceKind() !== 'local_folder') return false;
|
||
var workspaceId = resolveWorkspaceId(trigger || document.body);
|
||
var effectiveParentId = String(parentId || '').trim();
|
||
var result = await dispatchTreeCommand(trigger || document.body, {
|
||
action: 'create_folder',
|
||
workspaceId: workspaceId,
|
||
parentId: effectiveParentId || null,
|
||
title: '新建文件夹'
|
||
});
|
||
document.documentElement.setAttribute('data-mnote-filetree-folder-created', 'true');
|
||
document.documentElement.setAttribute('data-mnote-filetree-folder-created-id', commandDocumentId(result, result.id || ''));
|
||
void refreshLocalFolderSidebarSnapshot();
|
||
return true;
|
||
}
|
||
|
||
function applySidebarTreeTab(mode, shell) {
|
||
var runtimeFn = sidebarShellRuntimeFunction('applySidebarTreeTab');
|
||
if (runtimeFn) return runtimeFn(mode, shell);
|
||
}
|
||
|
||
function switchSidebarTreeTab(trigger) {
|
||
var runtimeFn = sidebarShellRuntimeFunction('switchSidebarTreeTab');
|
||
if (runtimeFn) return runtimeFn(trigger);
|
||
}
|
||
|
||
function restoreSidebarTreeTab() {
|
||
var runtimeFn = sidebarShellRuntimeFunction('restoreSidebarTreeTab');
|
||
if (runtimeFn) return runtimeFn();
|
||
}
|
||
|
||
const sidebarTreeLiveApply = createSidebarTreeLiveApplyRuntime({
|
||
activeSidebarTreeMode,
|
||
cssEscape,
|
||
currentDocumentId: (...args) => currentDocumentId(...args),
|
||
currentFileTreeActiveRowId: (...args) => currentFileTreeActiveRowId(...args),
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
currentWorkspaceId,
|
||
escapeHtml,
|
||
fileTreeRuntimeFunction: (...args) => fileTreeRuntimeFunction(...args),
|
||
localFilePathFromAssetId: (...args) => localFilePathFromAssetId(...args),
|
||
navigateToDocument,
|
||
refreshEditorLocalAttachmentExistence: (...args) => refreshEditorLocalAttachmentExistence(...args),
|
||
restoreSidebarTreeTab,
|
||
rowTitle: (...args) => rowTitle(...args),
|
||
schedulePendingLocalFolderRestoreFocus: (...args) => schedulePendingLocalFolderRestoreFocus(...args),
|
||
shortMindmapFileName: (...args) => shortMindmapFileName(...args),
|
||
syncSidebarFileTreeSelection: (...args) => syncSidebarFileTreeSelection(...args),
|
||
});
|
||
const updateTitleEverywhere = (...args) => sidebarTreeLiveApply.updateTitleEverywhere(...args);
|
||
const commandDocumentId = (...args) => sidebarTreeLiveApply.commandDocumentId(...args);
|
||
sidebarPageTree = createSidebarPageTreeRuntime({
|
||
activeSidebarTreeMode,
|
||
commandDocumentId,
|
||
copyWorkspaceSourceParams,
|
||
cssEscape,
|
||
currentDocumentId,
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
dispatchTreeCommand,
|
||
normalizeSidebarTreeMode,
|
||
persistLocalFolderSelfChangeSuppression,
|
||
persistSidebarTreeMode,
|
||
refreshLocalFolderSidebarSnapshot: (...args) => refreshLocalFolderSidebarSnapshot(...args),
|
||
refreshLocalFolderAfterCommand: (...args) => refreshLocalFolderAfterCommand(...args),
|
||
resolveWorkspaceId,
|
||
rowCenter: (...args) => rowCenter(...args),
|
||
selectSidebarFileTreeDocument: (...args) => selectSidebarFileTreeDocument(...args),
|
||
toggleChildren: (...args) => toggleChildren(...args),
|
||
dispatchSidebarEvent: (...args) => dispatchSidebarEvent(...args),
|
||
openPageTreeContextMenu: (...args) => openPageTreeContextMenu(...args),
|
||
updateTitleEverywhere: (...args) => updateTitleEverywhere(...args),
|
||
});
|
||
const fileTreePageTitle = (...args) => sidebarTreeLiveApply.fileTreePageTitle(...args);
|
||
const isFileTreePageRow = (...args) => sidebarTreeLiveApply.isFileTreePageRow(...args);
|
||
const normalizeFileTreePageRenameTitle = (...args) => sidebarTreeLiveApply.normalizeFileTreePageRenameTitle(...args);
|
||
const validateFileTreeRename = (...args) => sidebarTreeLiveApply.validateFileTreeRename(...args);
|
||
const removeDocumentRowForMode = (...args) => sidebarTreeLiveApply.removeDocumentRowForMode(...args);
|
||
const applyCreatedDocumentLocally = (...args) => sidebarTreeLiveApply.applyCreatedDocumentLocally(...args);
|
||
const localCommandNeedsProjectionRefresh = (...args) => sidebarTreeLiveApply.localCommandNeedsProjectionRefresh(...args);
|
||
const refreshLocalFolderAfterCommand = (...args) => sidebarTreeLiveApply.refreshLocalFolderAfterCommand(...args);
|
||
const applyMoveDocumentDelta = (...args) => sidebarTreeLiveApply.applyMoveDocumentDelta(...args);
|
||
const applyRemoveDocumentDelta = (...args) => sidebarTreeLiveApply.applyRemoveDocumentDelta(...args);
|
||
const setTreeLiveApplyError = (...args) => sidebarTreeLiveApply.setTreeLiveApplyError(...args);
|
||
const objectIdentityAttr = (...args) => sidebarTreeLiveApply.objectIdentityAttr(...args);
|
||
const renderPageProjection = (...args) => sidebarTreeLiveApply.renderPageProjection(...args);
|
||
const renderSidebarSnapshot = (...args) => sidebarTreeLiveApply.renderSidebarSnapshot(...args);
|
||
const refreshLocalFolderSidebarSnapshot = (...args) => sidebarTreeLiveApply.refreshLocalFolderSidebarSnapshot(...args);
|
||
const startLocalFolderSidebarWatch = (...args) => sidebarTreeLiveApply.startLocalFolderSidebarWatch(...args);
|
||
const deltaNeedsProjectionRefresh = (...args) => sidebarTreeLiveApply.deltaNeedsProjectionRefresh(...args);
|
||
const toggleChildren = (...args) => sidebarTreeLiveApply.toggleChildren(...args);
|
||
const revealFileTreeResource = (...args) => sidebarTreeLiveApply.revealFileTreeResource(...args);
|
||
|
||
function dispatchSidebarEvent(name, detail) {
|
||
document.documentElement.setAttribute('data-mnote-last-tree-action', name);
|
||
window.dispatchEvent(new CustomEvent(name, { detail: detail }));
|
||
}
|
||
|
||
function sidebarShortcutWorkspaceId() {
|
||
return currentWorkspaceId()
|
||
|| (document.getElementById('sidebar-file-tree-root') && document.getElementById('sidebar-file-tree-root').getAttribute('data-workspace-id') || '')
|
||
|| (document.getElementById('sidebar-tree-root') && document.getElementById('sidebar-tree-root').getAttribute('data-workspace-id') || '');
|
||
}
|
||
|
||
function sidebarShortcutSourceKind() {
|
||
return currentSourceKind() || 'workspace';
|
||
}
|
||
|
||
function currentFileTreeScope() {
|
||
var params = new URLSearchParams(window.location.search);
|
||
var fromUrl = String(params.get('fileTreeScope') || '').trim();
|
||
if (fromUrl) return fromUrl;
|
||
var root = document.getElementById('sidebar-file-tree-root');
|
||
return root instanceof HTMLElement ? String(root.getAttribute('data-mnote-filetree-scope') || '').trim() : '';
|
||
}
|
||
|
||
function recordNavigationRecent(payload) {
|
||
var body = Object.assign({
|
||
sourceKind: currentSourceKind() || 'local_folder',
|
||
rootUri: currentRootUri() || '',
|
||
}, payload || {});
|
||
if (!body.kind || !body.rootUri || !body.title) return Promise.resolve(false);
|
||
return fetch('/api/navigation/recent', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: {
|
||
accept: 'application/json',
|
||
'content-type': 'application/json'
|
||
},
|
||
body: JSON.stringify(body)
|
||
}).then(function(response) {
|
||
return response.ok;
|
||
}).catch(function(error) {
|
||
console.warn('[mnote navigation] record recent failed', error);
|
||
return false;
|
||
});
|
||
}
|
||
|
||
function openNavigationPageForFolder(rootUri, relativePath, workspaceId, title, options) {
|
||
rootUri = String(rootUri || '').trim();
|
||
relativePath = String(relativePath || '').trim().replace(/^\/+|\/+$/g, '');
|
||
workspaceId = String(workspaceId || '').trim();
|
||
title = String(title || relativePath || '本地文件夹').trim();
|
||
if (!rootUri) return false;
|
||
void recordNavigationRecent({
|
||
kind: 'folder',
|
||
sourceKind: 'local_folder',
|
||
rootUri: rootUri,
|
||
relativePath: relativePath,
|
||
title: title,
|
||
workspaceId: workspaceId
|
||
});
|
||
var targetUrl = new URL('/', window.location.origin);
|
||
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
|
||
targetUrl.searchParams.set('sourceKind', 'local_folder');
|
||
targetUrl.searchParams.set('rootUri', rootUri);
|
||
targetUrl.searchParams.set('treeView', 'filetree');
|
||
if (relativePath) targetUrl.searchParams.set('fileTreeScope', relativePath);
|
||
var url = targetUrl.pathname + targetUrl.search;
|
||
if (options && options.newTab) {
|
||
window.open(url, '_blank', 'noopener');
|
||
} else {
|
||
window.location.assign(url);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function openCurrentNavigationPage(trigger) {
|
||
if (currentSourceKind() === 'local_folder') {
|
||
var rootUri = currentRootUri();
|
||
var scope = currentFileTreeScope();
|
||
var workspaceId = currentWorkspaceId() || sidebarShortcutWorkspaceId() || resolveWorkspaceId(trigger || document.body);
|
||
var title = scope ? scope.split('/').filter(Boolean).pop() : '本地文件夹';
|
||
return openNavigationPageForFolder(rootUri, scope, workspaceId, title || scope || '本地文件夹');
|
||
}
|
||
var targetUrl = new URL('/', window.location.origin);
|
||
var workspaceId = currentWorkspaceId() || resolveWorkspaceId(trigger || document.body);
|
||
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
|
||
window.location.assign(targetUrl.pathname + targetUrl.search);
|
||
return true;
|
||
}
|
||
|
||
function currentTopbarTitle() {
|
||
var title = document.querySelector('[data-page-title-current="true"]');
|
||
return title && title.textContent ? title.textContent.trim() : '无标题';
|
||
}
|
||
|
||
function fileTreeRowTitleForShortcut(row, fallback) {
|
||
var title = row && row.querySelector ? row.querySelector(':scope > .tree-link > .tree-link-title') : null;
|
||
return title && title.textContent ? title.textContent.trim() : (fallback || '文件夹');
|
||
}
|
||
|
||
function isRetiredOcrSidecarMarkdownPath(relativePath) {
|
||
var normalized = String(relativePath || '').trim().replace(/\\/g, '/').replace(/^\/+/, '');
|
||
return /(^|\/)[^/]+\.ocr\/[^/]+\.ocr\.md$/i.test(normalized);
|
||
}
|
||
|
||
function sidebarShortcutRows() {
|
||
return Array.from(document.querySelectorAll('.wolai-starred-section [data-mnote-shortcut-kind]'));
|
||
}
|
||
|
||
function shortcutMatches(row, kind, targetId, relativePath, documentId) {
|
||
if (!(row instanceof HTMLElement)) return false;
|
||
if ((row.getAttribute('data-mnote-shortcut-kind') || '') !== kind) return false;
|
||
if (documentId && (row.getAttribute('data-mnote-shortcut-document-id') || row.getAttribute('data-document-id') || '') === documentId) return true;
|
||
if (relativePath && (row.getAttribute('data-mnote-shortcut-relative-path') || '') === relativePath) return true;
|
||
return Boolean(targetId && (row.getAttribute('data-mnote-shortcut-target-id') || row.getAttribute('data-node-id') || '') === targetId);
|
||
}
|
||
|
||
async function listSidebarShortcuts(workspaceId) {
|
||
var url = new URL('/api/sidebar/shortcuts', window.location.origin);
|
||
url.searchParams.set('workspaceId', workspaceId);
|
||
var response = await fetch(url.toString(), {
|
||
method: 'GET',
|
||
credentials: 'include',
|
||
headers: { accept: 'application/json' },
|
||
cache: 'no-store'
|
||
});
|
||
var payload = await response.json().catch(function() { return null; });
|
||
if (!response.ok) throw new Error(payload && (payload.error || payload.message) || 'sidebar_shortcuts_list_failed_' + response.status);
|
||
return payload && Array.isArray(payload.shortcuts) ? payload.shortcuts : [];
|
||
}
|
||
|
||
function shortcutRecordMatches(shortcut, kind, targetId, relativePath, documentId) {
|
||
if (!shortcut || shortcut.kind !== kind) return false;
|
||
var shortcutMetadata = shortcut && shortcut.metadata && typeof shortcut.metadata === 'object' ? shortcut.metadata : {};
|
||
var shortcutRootUri = String(shortcut.rootUri || shortcut.root_uri || shortcutMetadata.rootUri || shortcutMetadata.root_uri || '').trim();
|
||
var currentShortcutRootUri = currentRootUri();
|
||
if (shortcutRootUri && currentShortcutRootUri && shortcutRootUri !== currentShortcutRootUri) return false;
|
||
if (documentId && String(shortcut.documentId || shortcut.document_id || '') === documentId) return true;
|
||
if (relativePath && String(shortcut.relativePath || shortcut.relative_path || '') === relativePath) return true;
|
||
return Boolean(targetId && String(shortcut.targetId || shortcut.target_id || '') === targetId);
|
||
}
|
||
|
||
async function findSidebarShortcut(payload) {
|
||
var workspaceId = payload.workspaceId || sidebarShortcutWorkspaceId();
|
||
if (!workspaceId) return null;
|
||
var shortcuts = await listSidebarShortcuts(workspaceId);
|
||
return shortcuts.find(function(shortcut) {
|
||
return shortcutRecordMatches(shortcut, payload.kind, payload.targetId, payload.relativePath, payload.documentId);
|
||
}) || null;
|
||
}
|
||
|
||
async function upsertSidebarShortcut(payload) {
|
||
var response = await fetch('/api/sidebar/shortcuts', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
headers: { accept: 'application/json', 'content-type': 'application/json' },
|
||
body: JSON.stringify(payload)
|
||
});
|
||
var result = await response.json().catch(function() { return null; });
|
||
if (!response.ok) throw new Error(result && (result.error || result.message) || 'sidebar_shortcut_upsert_failed_' + response.status);
|
||
return result && result.shortcut ? result.shortcut : null;
|
||
}
|
||
|
||
async function deleteSidebarShortcut(shortcutId) {
|
||
if (!shortcutId) return false;
|
||
var response = await fetch('/api/sidebar/shortcuts/' + encodeURIComponent(shortcutId), {
|
||
method: 'DELETE',
|
||
credentials: 'include',
|
||
headers: { accept: 'application/json' }
|
||
});
|
||
var result = await response.json().catch(function() { return null; });
|
||
if (!response.ok) throw new Error(result && (result.error || result.message) || 'sidebar_shortcut_delete_failed_' + response.status);
|
||
return true;
|
||
}
|
||
|
||
function closeSidebarShortcutMenu() {
|
||
var existing = document.querySelector('[data-testid="mnote-sidebar-shortcut-menu"]');
|
||
if (existing && existing.parentElement) existing.parentElement.removeChild(existing);
|
||
document.querySelectorAll('[data-mnote-shortcut-action="menu"][aria-expanded="true"]').forEach(function(button) {
|
||
button.setAttribute('aria-expanded', 'false');
|
||
});
|
||
}
|
||
|
||
async function removeSidebarShortcutByRow(row) {
|
||
if (!(row instanceof HTMLElement)) return false;
|
||
var shortcutId = String(row.getAttribute('data-mnote-shortcut-id') || '').trim();
|
||
if (!shortcutId) return false;
|
||
row.setAttribute('data-mnote-shortcut-pending', 'true');
|
||
try {
|
||
await deleteSidebarShortcut(shortcutId);
|
||
row.remove();
|
||
closeSidebarShortcutMenu();
|
||
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'remove');
|
||
return true;
|
||
} finally {
|
||
if (row.isConnected) row.removeAttribute('data-mnote-shortcut-pending');
|
||
}
|
||
}
|
||
|
||
function openSidebarShortcutMenu(row, trigger) {
|
||
if (!(row instanceof HTMLElement)) return;
|
||
closeSidebarShortcutMenu();
|
||
if (trigger instanceof HTMLElement) trigger.setAttribute('aria-expanded', 'true');
|
||
var rect = trigger && trigger.getBoundingClientRect ? trigger.getBoundingClientRect() : row.getBoundingClientRect();
|
||
var menu = document.createElement('div');
|
||
menu.className = 'mnote-tree-context-menu';
|
||
menu.setAttribute('role', 'menu');
|
||
menu.setAttribute('data-testid', 'mnote-sidebar-shortcut-menu');
|
||
menu.innerHTML = '<button type="button" class="mnote-tree-context-menu__item" role="menuitem" data-mnote-sidebar-shortcut-menu-action="open"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="login" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">在右侧边栏打开</span></button><div class="mnote-tree-context-menu__separator" role="separator"></div><button type="button" class="mnote-tree-context-menu__item" role="menuitem" data-mnote-sidebar-shortcut-menu-action="copy-link"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="link" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">复制访问链接</span></button><button type="button" class="mnote-tree-context-menu__item mnote-tree-context-menu__item--danger" role="menuitem" data-mnote-sidebar-shortcut-menu-action="remove"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="star_off" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">取消星标</span></button>';
|
||
menu.__mnoteShortcutRow = row;
|
||
document.body.appendChild(menu);
|
||
var width = menu.offsetWidth || 220;
|
||
var left = Math.min(Math.max(8, rect.right - width), Math.max(8, window.innerWidth - width - 8));
|
||
var top = Math.min(Math.max(8, rect.bottom + 4), Math.max(8, window.innerHeight - (menu.offsetHeight || 120) - 8));
|
||
menu.style.left = left + 'px';
|
||
menu.style.top = top + 'px';
|
||
}
|
||
|
||
function removeSidebarShortcutRow(shortcut) {
|
||
sidebarShortcutRows().forEach(function(row) {
|
||
if (shortcutMatches(
|
||
row,
|
||
shortcut.kind,
|
||
String(shortcut.targetId || shortcut.target_id || ''),
|
||
String(shortcut.relativePath || shortcut.relative_path || ''),
|
||
String(shortcut.documentId || shortcut.document_id || '')
|
||
)) {
|
||
row.remove();
|
||
}
|
||
});
|
||
}
|
||
|
||
function renderSidebarShortcutRow(shortcut) {
|
||
if (!shortcut) return;
|
||
var section = document.querySelector('.wolai-starred-section');
|
||
if (!(section instanceof HTMLElement)) return;
|
||
removeSidebarShortcutRow(shortcut);
|
||
var kind = String(shortcut.kind || '').trim();
|
||
var shortcutId = String(shortcut.id || shortcut.targetId || shortcut.target_id || '').trim();
|
||
var targetId = String(shortcut.targetId || shortcut.target_id || '').trim();
|
||
var relativePath = String(shortcut.relativePath || shortcut.relative_path || '').trim();
|
||
var documentId = String(shortcut.documentId || shortcut.document_id || '').trim();
|
||
var sourceKind = String(shortcut.sourceKind || shortcut.source_kind || '').trim();
|
||
var metadata = shortcut.metadata && typeof shortcut.metadata === 'object' ? shortcut.metadata : {};
|
||
var rootUri = String(shortcut.rootUri || shortcut.root_uri || metadata.rootUri || metadata.root_uri || '').trim();
|
||
var workspaceId = String(shortcut.workspaceId || shortcut.workspace_id || sidebarShortcutWorkspaceId() || '').trim();
|
||
var title = String(shortcut.title || (kind === 'folder' ? '文件夹' : '无标题')).trim();
|
||
var href = '';
|
||
if (documentId) {
|
||
var targetUrl = new URL('/documents/' + encodeURIComponent(documentId), window.location.origin);
|
||
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
|
||
if (sourceKind) targetUrl.searchParams.set('sourceKind', sourceKind);
|
||
if (rootUri) targetUrl.searchParams.set('rootUri', rootUri);
|
||
href = targetUrl.pathname + targetUrl.search;
|
||
}
|
||
var row = document.createElement(href ? 'a' : 'div');
|
||
row.className = 'wolai-page-row';
|
||
if (href) row.setAttribute('href', href);
|
||
else {
|
||
row.setAttribute('role', 'button');
|
||
row.setAttribute('tabindex', '0');
|
||
}
|
||
row.setAttribute('data-testid', 'wolai-sidebar-row');
|
||
row.setAttribute('data-node-id', shortcutId || targetId);
|
||
row.setAttribute('data-document-id', documentId || shortcutId || targetId);
|
||
if (shortcutId) row.setAttribute('data-mnote-shortcut-id', shortcutId);
|
||
if (workspaceId) row.setAttribute('data-workspace-id', workspaceId);
|
||
row.setAttribute('data-mnote-shortcut-kind', kind);
|
||
if (sourceKind) row.setAttribute('data-mnote-shortcut-source-kind', sourceKind);
|
||
row.setAttribute('data-mnote-shortcut-target-id', targetId);
|
||
if (relativePath) row.setAttribute('data-mnote-shortcut-relative-path', relativePath);
|
||
if (rootUri) row.setAttribute('data-mnote-shortcut-root-uri', rootUri);
|
||
if (documentId) row.setAttribute('data-mnote-shortcut-document-id', documentId);
|
||
row.setAttribute('data-depth', '0');
|
||
row.setAttribute('data-active', String(documentId && documentId === currentDocumentId()));
|
||
row.innerHTML = '<span class="wolai-row-caret" aria-hidden="true">›</span><span class="wolai-row-icon"><span class="material-symbols-outlined wolai-row-symbol" data-icon="' + (kind === 'folder' ? 'folder_open' : 'home') + '" aria-hidden="true"></span></span><span class="wolai-row-title">' + escapeHtml(title) + '</span><button type="button" class="wolai-row-more" data-mnote-shortcut-action="menu" aria-label="更多操作" title="更多操作"><span class="material-symbols-outlined" data-icon="more_horiz" aria-hidden="true"></span></button>';
|
||
section.appendChild(row);
|
||
}
|
||
|
||
async function toggleSidebarShortcut(payload) {
|
||
var workspaceId = payload.workspaceId || sidebarShortcutWorkspaceId();
|
||
if (!workspaceId) return false;
|
||
var normalized = Object.assign({}, payload, { workspaceId: workspaceId });
|
||
var existing = await findSidebarShortcut(normalized);
|
||
if (existing && existing.id) {
|
||
await deleteSidebarShortcut(existing.id);
|
||
removeSidebarShortcutRow(existing);
|
||
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'remove');
|
||
return true;
|
||
}
|
||
var shortcut = await upsertSidebarShortcut(normalized);
|
||
renderSidebarShortcutRow(shortcut);
|
||
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'upsert');
|
||
return true;
|
||
}
|
||
|
||
function currentPageShortcutPayload() {
|
||
var documentId = currentDocumentId();
|
||
var workspaceId = sidebarShortcutWorkspaceId();
|
||
if (!documentId || !workspaceId) return null;
|
||
return {
|
||
workspaceId: workspaceId,
|
||
kind: 'page',
|
||
sourceKind: sidebarShortcutSourceKind(),
|
||
targetId: documentId,
|
||
documentId: documentId,
|
||
title: currentTopbarTitle(),
|
||
icon: 'star',
|
||
rootUri: currentRootUri(),
|
||
metadataJson: JSON.stringify({ rootUri: currentRootUri() })
|
||
};
|
||
}
|
||
|
||
function folderShortcutPayload(detail, trigger) {
|
||
detail = detail || {};
|
||
var row = trigger && trigger.closest ? trigger.closest('.tree-row[data-shell-mode="filetree"]') : trigger;
|
||
var rowKind = String(detail.rowKind || (row && row.getAttribute('data-row-kind')) || '').trim();
|
||
if (rowKind !== 'folder' && rowKind !== 'directory') return null;
|
||
var relativePath = String(detail.localRelativePath || (row && row.getAttribute('data-local-relative-path')) || '').trim();
|
||
if (!relativePath) return null;
|
||
var workspaceId = String(detail.workspaceId || sidebarShortcutWorkspaceId() || '').trim();
|
||
if (!workspaceId) return null;
|
||
var rowId = String(detail.rowId || (row && row.getAttribute('data-row-id')) || '').trim();
|
||
return {
|
||
workspaceId: workspaceId,
|
||
kind: 'folder',
|
||
sourceKind: 'local_folder',
|
||
targetId: rowId || ('folder:' + relativePath),
|
||
relativePath: relativePath,
|
||
title: detail.title || fileTreeRowTitleForShortcut(row, relativePath),
|
||
icon: 'folder_open',
|
||
rootUri: currentRootUri(),
|
||
metadataJson: JSON.stringify({ rootUri: currentRootUri() })
|
||
};
|
||
}
|
||
|
||
async function toggleCurrentPageSidebarShortcut(trigger) {
|
||
var payload = currentPageShortcutPayload();
|
||
if (!payload) return;
|
||
if (trigger instanceof HTMLElement) trigger.setAttribute('data-mnote-shortcut-pending', 'true');
|
||
try {
|
||
await toggleSidebarShortcut(payload);
|
||
} finally {
|
||
if (trigger instanceof HTMLElement) trigger.removeAttribute('data-mnote-shortcut-pending');
|
||
}
|
||
}
|
||
|
||
async function toggleFolderSidebarShortcut(detail, trigger) {
|
||
var payload = folderShortcutPayload(detail, trigger);
|
||
if (!payload) return false;
|
||
await toggleSidebarShortcut(payload);
|
||
return true;
|
||
}
|
||
|
||
function ensureStarredFolderFileTreeHost(workspaceId) {
|
||
var root = document.getElementById('sidebar-file-tree-root');
|
||
if (root instanceof HTMLElement) return root;
|
||
var panel = document.getElementById('wolai-sidebar-file-tree-panel');
|
||
if (!(panel instanceof HTMLElement)) return null;
|
||
var section = document.createElement('div');
|
||
section.className = 'sidebar-tree-section sidebar-file-tree-section';
|
||
root = document.createElement('div');
|
||
root.id = 'sidebar-file-tree-root';
|
||
root.className = 'sidebar-tree';
|
||
root.setAttribute('data-tree-shell-mode', 'filetree');
|
||
if (workspaceId) root.setAttribute('data-workspace-id', workspaceId);
|
||
section.appendChild(root);
|
||
panel.appendChild(section);
|
||
return root;
|
||
}
|
||
|
||
function ensureStarredFolderPageTreeHost(workspaceId) {
|
||
var root = document.getElementById('sidebar-tree-root');
|
||
if (root instanceof HTMLElement) return root;
|
||
var panel = document.getElementById('wolai-sidebar-page-tree-panel') || document.querySelector('[data-mnote-sidebar-tree-panel="page"]');
|
||
if (!(panel instanceof HTMLElement)) return null;
|
||
var section = document.createElement('div');
|
||
section.className = 'sidebar-tree-section';
|
||
root = document.createElement('div');
|
||
root.id = 'sidebar-tree-root';
|
||
root.className = 'sidebar-tree';
|
||
root.setAttribute('data-tree-shell-mode', 'page');
|
||
if (workspaceId) root.setAttribute('data-workspace-id', workspaceId);
|
||
section.appendChild(root);
|
||
panel.appendChild(section);
|
||
return root;
|
||
}
|
||
|
||
function persistStarredFolderScope(workspaceId, rootUri, relativePath) {
|
||
var targetUrl = new URL(window.location.href);
|
||
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
|
||
targetUrl.searchParams.set('sourceKind', 'local_folder');
|
||
targetUrl.searchParams.set('rootUri', rootUri);
|
||
targetUrl.searchParams.set('treeView', 'filetree');
|
||
targetUrl.searchParams.set('fileTreeScope', relativePath);
|
||
window.history.replaceState(window.history.state, '', targetUrl.pathname + targetUrl.search + targetUrl.hash);
|
||
if (document.body instanceof HTMLElement) {
|
||
document.body.setAttribute('data-mnote-source-kind', 'local_folder');
|
||
document.body.setAttribute('data-mnote-root-uri', rootUri);
|
||
}
|
||
}
|
||
|
||
function readShortcutRootUri(row) {
|
||
if (!(row instanceof HTMLElement)) return '';
|
||
return String(row.getAttribute('data-mnote-shortcut-root-uri') || '').trim();
|
||
}
|
||
|
||
async function openStarredFolderShortcut(row) {
|
||
if (!(row instanceof HTMLElement)) return false;
|
||
var relativePath = String(row.getAttribute('data-mnote-shortcut-relative-path') || '').trim();
|
||
var workspaceId = String(row.getAttribute('data-workspace-id') || '').trim() || sidebarShortcutWorkspaceId();
|
||
var rootUri = readShortcutRootUri(row);
|
||
if (!relativePath || !rootUri || !workspaceId) {
|
||
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-open-error', !rootUri ? 'missing_root_uri' : 'missing_target');
|
||
return false;
|
||
}
|
||
document.documentElement.removeAttribute('data-mnote-sidebar-shortcut-open-error');
|
||
var tab = document.querySelector('[data-mnote-sidebar-tree-tab="filetree"]');
|
||
if (tab instanceof HTMLElement) switchSidebarTreeTab(tab);
|
||
var root = ensureStarredFolderFileTreeHost(workspaceId);
|
||
var pageRoot = ensureStarredFolderPageTreeHost(workspaceId);
|
||
if (root instanceof HTMLElement) {
|
||
root.setAttribute('data-workspace-id', workspaceId);
|
||
root.setAttribute('data-mnote-filetree-scope', relativePath);
|
||
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
|
||
}
|
||
if (pageRoot instanceof HTMLElement) {
|
||
pageRoot.setAttribute('data-workspace-id', workspaceId);
|
||
pageRoot.setAttribute('data-mnote-page-tree-scope', relativePath);
|
||
}
|
||
persistStarredFolderScope(workspaceId, rootUri, relativePath);
|
||
void recordNavigationRecent({
|
||
kind: 'folder',
|
||
sourceKind: 'local_folder',
|
||
rootUri: rootUri,
|
||
relativePath: relativePath,
|
||
title: row.textContent ? row.textContent.trim() : relativePath,
|
||
workspaceId: workspaceId
|
||
});
|
||
document.documentElement.setAttribute('data-mnote-filetree-scope', relativePath);
|
||
var sidebarUrl = new URL('/api/tree/projections/sidebar', window.location.origin);
|
||
sidebarUrl.searchParams.set('workspaceId', workspaceId);
|
||
sidebarUrl.searchParams.set('sourceKind', 'local_folder');
|
||
sidebarUrl.searchParams.set('rootUri', rootUri);
|
||
sidebarUrl.searchParams.set('parentRelativePath', relativePath);
|
||
var url = new URL('/api/tree/projections/file', window.location.origin);
|
||
url.searchParams.set('workspaceId', workspaceId);
|
||
url.searchParams.set('sourceKind', 'local_folder');
|
||
url.searchParams.set('rootUri', rootUri);
|
||
url.searchParams.set('parentRelativePath', relativePath);
|
||
var sidebarRequest = fetch(sidebarUrl.toString(), {
|
||
method: 'GET',
|
||
credentials: 'include',
|
||
headers: { accept: 'application/json' },
|
||
cache: 'no-store'
|
||
});
|
||
var fileRequest = fetch(url.toString(), {
|
||
method: 'GET',
|
||
credentials: 'include',
|
||
headers: { accept: 'application/json' },
|
||
cache: 'no-store'
|
||
});
|
||
var response = await fileRequest;
|
||
var payload = await response.json().catch(function() { return null; });
|
||
if (!response.ok) throw new Error(payload && (payload.error || payload.message) || 'scoped_filetree_failed_' + response.status);
|
||
var fileProjection = payload && (payload.result || payload);
|
||
var renderedFile = renderSidebarSnapshot({
|
||
dataset: { kernel_file_tree_projection: fileProjection }
|
||
});
|
||
root = document.getElementById('sidebar-file-tree-root');
|
||
if (root instanceof HTMLElement) {
|
||
root.setAttribute('data-workspace-id', workspaceId);
|
||
root.setAttribute('data-mnote-filetree-scope', relativePath);
|
||
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
|
||
}
|
||
var sidebarResponse = await sidebarRequest;
|
||
var sidebarPayload = await sidebarResponse.json().catch(function() { return null; });
|
||
if (!sidebarResponse.ok) throw new Error(sidebarPayload && (sidebarPayload.error || sidebarPayload.message) || 'local_page_tree_failed_' + sidebarResponse.status);
|
||
var sidebarProjection = sidebarPayload && (sidebarPayload.result || sidebarPayload) || {};
|
||
var renderedPage = sidebarProjection ? await renderPageProjection(sidebarProjection) : false;
|
||
root = document.getElementById('sidebar-file-tree-root');
|
||
if (root instanceof HTMLElement) {
|
||
root.setAttribute('data-workspace-id', workspaceId);
|
||
root.setAttribute('data-mnote-filetree-scope', relativePath);
|
||
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
|
||
}
|
||
return renderedFile || renderedPage;
|
||
}
|
||
|
||
const sidebarFileTreeOpen = createSidebarFileTreeOpenRuntime({
|
||
copyWorkspaceSourceParams,
|
||
currentDocumentId,
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
fileTreeIconKindForFileName: (...args) => fileTreeIconKindForFileName(...args),
|
||
getNavigationInFlight: () => mnoteNavigationInFlight,
|
||
isCodeAttachmentFileName: (...args) => isCodeAttachmentFileName(...args),
|
||
isNonOfficeAttachmentName: (...args) => isNonOfficeAttachmentName(...args),
|
||
isPdfAttachmentFileName: (...args) => isPdfAttachmentFileName(...args),
|
||
openCodeEditorAttachment: (...args) => openCodeEditorAttachment(...args),
|
||
resolveWorkspaceId,
|
||
setNavigationInFlight: (value) => { mnoteNavigationInFlight = String(value || ''); },
|
||
shouldOpenLocalResourceInNewWindow: (...args) => shouldOpenLocalResourceInNewWindow(...args),
|
||
uploadedFileSize: (...args) => uploadedFileSize(...args),
|
||
});
|
||
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);
|
||
const buildMindmapOpenPath = (...args) => sidebarFileTreeOpen.buildMindmapOpenPath(...args);
|
||
const navigateToMindmapObject = (...args) => sidebarFileTreeOpen.navigateToMindmapObject(...args);
|
||
const isMindmapAssetDetail = (...args) => sidebarFileTreeOpen.isMindmapAssetDetail(...args);
|
||
const localFilePathFromAssetId = (...args) => sidebarFileTreeOpen.localFilePathFromAssetId(...args);
|
||
const buildLocalFileOpenUrl = (...args) => sidebarFileTreeOpen.buildLocalFileOpenUrl(...args);
|
||
const openLocalResourceInActiveTab = (...args) => sidebarFileTreeOpen.openLocalResourceInActiveTab(...args);
|
||
const readFileTreeObjectIdentity = (...args) => sidebarFileTreeOpen.readFileTreeObjectIdentity(...args);
|
||
const fetchCurrentOnlyOfficeUserId = (...args) => sidebarFileTreeOpen.fetchCurrentOnlyOfficeUserId(...args);
|
||
const openConvexAssetFromFileTree = (...args) => sidebarFileTreeOpen.openConvexAssetFromFileTree(...args);
|
||
|
||
var sidebarFileTreeUpload = null;
|
||
const fileTreeRowsForUploadPreflight = (...args) => sidebarFileTreeUpload.fileTreeRowsForUploadPreflight(...args);
|
||
const fileTreeRowCapabilities = (...args) => sidebarFileTreeUpload.fileTreeRowCapabilities(...args);
|
||
const fileTreeRowIsReadonly = (...args) => sidebarFileTreeUpload.fileTreeRowIsReadonly(...args);
|
||
const blockReadonlyFileTreeAction = (...args) => sidebarFileTreeUpload.blockReadonlyFileTreeAction(...args);
|
||
const fileTreeDocumentParentsForPreflight = (...args) => sidebarFileTreeUpload.fileTreeDocumentParentsForPreflight(...args);
|
||
const fileTreeTargetChildrenForPreflight = (...args) => sidebarFileTreeUpload.fileTreeTargetChildrenForPreflight(...args);
|
||
const fileTreeDropPreflightRows = (...args) => sidebarFileTreeUpload.fileTreeDropPreflightRows(...args);
|
||
const ensureFileTreeWritableTarget = (...args) => sidebarFileTreeUpload.ensureFileTreeWritableTarget(...args);
|
||
const fileTreeDocumentWorkspacesForUploadPreflight = (...args) => sidebarFileTreeUpload.fileTreeDocumentWorkspacesForUploadPreflight(...args);
|
||
const preflightFileTreeUploadTarget = (...args) => sidebarFileTreeUpload.preflightFileTreeUploadTarget(...args);
|
||
const fallbackFileTreeUploadTarget = (...args) => sidebarFileTreeUpload.fallbackFileTreeUploadTarget(...args);
|
||
const resolveFileTreeUploadTarget = (...args) => sidebarFileTreeUpload.resolveFileTreeUploadTarget(...args);
|
||
|
||
function localUploadRuntimeFunction(name) {
|
||
var runtime = window.__mnoteLocalUploadRuntime;
|
||
var fn = runtime && runtime[name];
|
||
return typeof fn === 'function' ? fn : null;
|
||
}
|
||
|
||
function fileTreeRuntimeFunction(name) {
|
||
var runtime = window.__mnoteFileTreeRuntime;
|
||
var fn = runtime && runtime[name];
|
||
return typeof fn === 'function' ? fn : null;
|
||
}
|
||
|
||
function fileTreeRuntimeDeps() {
|
||
return {
|
||
currentSourceKind: currentSourceKind,
|
||
currentRootUri: currentRootUri,
|
||
currentDocumentId: currentDocumentId,
|
||
localFilePathFromAssetId: localFilePathFromAssetId,
|
||
rowTitle: rowTitle,
|
||
resolveWorkspaceId: resolveWorkspaceId,
|
||
cssEscape: cssEscape,
|
||
escapeHtml: escapeHtml,
|
||
objectIdentityAttr: objectIdentityAttr,
|
||
uploadedAssetTitle: uploadedAssetTitle,
|
||
uploadedAssetType: uploadedAssetType,
|
||
fileTreeIconKindForFileName: fileTreeIconKindForFileName
|
||
};
|
||
}
|
||
|
||
function fileTreeSelectionRuntimeFunction(name) {
|
||
var runtime = window.__mnoteFileTreeSelectionRuntime;
|
||
var fn = runtime && runtime[name];
|
||
return typeof fn === 'function' ? fn : null;
|
||
}
|
||
|
||
function fileTreeSelectionRuntimeDeps() {
|
||
return {
|
||
cssEscape: cssEscape
|
||
};
|
||
}
|
||
|
||
function uploadedAssetTitle(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAssetTitle');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
return String(asset && (asset.file_name || asset.title || asset.name) || '未命名附件').trim() || '未命名附件';
|
||
}
|
||
|
||
function uploadedAssetUrl(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAssetUrl');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
return String(asset && (asset.sourcePath || asset.file_url || asset.signedUrl || asset.signed_url || asset.thumbnail_url) || '').trim();
|
||
}
|
||
|
||
function uploadedAssetMarkdownHref(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAssetMarkdownHref');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
var href = String(asset && (asset.markdownHref || asset.markdown_href) || '').trim();
|
||
if (href) {
|
||
var normalizedHref = href.replace(/\\/g, '/');
|
||
if (normalizedHref.indexOf('../') === 0 || normalizedHref.indexOf('/../') >= 0) return '';
|
||
return href;
|
||
}
|
||
var relativePath = String(asset && (asset.markdownRelativePath || asset.markdown_relative_path) || '').trim().replace(/\\/g, '/');
|
||
if (!relativePath) return '';
|
||
if (relativePath.indexOf('../') === 0 || relativePath.indexOf('/../') >= 0) return '';
|
||
if (relativePath.indexOf('./') === 0) return relativePath;
|
||
return './' + relativePath;
|
||
}
|
||
|
||
function localAssetOpenUrl(asset, download) {
|
||
var runtimeFn = localUploadRuntimeFunction('localAssetOpenUrl');
|
||
if (runtimeFn) return runtimeFn(asset, download, { rootUri: currentRootUri() });
|
||
if (!isLocalUploadedAsset(asset)) return '';
|
||
var rootUri = String(asset && (asset.rootUri || asset.root_uri) || '').trim() || currentRootUri();
|
||
var rootRelativePath = String(asset && (asset.rootRelativePath || asset.root_relative_path) || '').trim();
|
||
if (!rootUri || !rootRelativePath) return '';
|
||
var url = new URL('/api/local-folder/files/open', window.location.origin);
|
||
url.searchParams.set('rootUri', rootUri);
|
||
url.searchParams.set('path', rootRelativePath);
|
||
if (download) url.searchParams.set('download', 'true');
|
||
return url.toString();
|
||
}
|
||
|
||
function uploadedAssetType(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAssetType');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
return String(asset && (asset.asset_type || asset.assetType || asset.mime_type || '') || '').trim();
|
||
}
|
||
|
||
function fileTreeIconKindForFileName(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('fileTreeIconKindForFileName');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
var name = String(fileName || '').trim().toLowerCase();
|
||
var ext = name.indexOf('.') >= 0 ? name.split('.').pop() : '';
|
||
if (['doc', 'docx', 'odt', 'rtf', 'ppt', 'pptx', 'odp', 'xls', 'xlsx', 'ods', 'csv'].indexOf(ext) >= 0) return 'office';
|
||
if (ext === 'md' || ext === 'markdown') return 'markdown';
|
||
if (ext === 'pdf') return 'pdf';
|
||
if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp'].indexOf(ext) >= 0) return 'image';
|
||
if (['html', 'htm', 'css', 'scss', 'less', 'js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'vue', 'svelte', 'astro'].indexOf(ext) >= 0) return 'web';
|
||
if (['json', 'jsonc', 'json5', 'toml', 'yaml', 'yml', 'ini', 'env', 'xml', 'lock', 'hcl', 'tf', 'tfvars', 'nix', 'properties', 'conf', 'cfg', 'config', 'service', 'desktop', 'gitignore', 'gitattributes', 'editorconfig', 'npmrc', 'prettierrc', 'eslintrc'].indexOf(ext) >= 0 || ['.dockerignore', '.editorconfig', '.env', '.eslintrc', '.gitattributes', '.gitignore', '.npmrc', '.prettierrc', 'dockerfile', 'containerfile', 'makefile', 'cmakelists.txt', 'gemfile', 'rakefile', 'procfile'].indexOf(name) >= 0) return 'config';
|
||
if (['rs', 'py', 'go', 'java', 'c', 'cpp', 'h', 'hpp', 'cs', 'php', 'rb', 'sh', 'bash', 'zsh', 'sql', 'lua', 'dart', 'kt', 'kts', 'swift', 'scala', 'gradle', 'groovy', 'clj', 'ex', 'exs', 'erl', 'hrl', 'fs', 'fsx', 'r', 'jl', 'm', 'mm', 'pl', 'pm', 'ps1', 'bat', 'cmd', 'psm1', 'psd1', 'proto', 'graphql', 'gql', 'prisma', 'cmake', 'bazel', 'bzl'].indexOf(ext) >= 0) return 'code';
|
||
return '';
|
||
}
|
||
|
||
function shouldOpenLocalResourceInNewWindow(fileName) {
|
||
return false;
|
||
}
|
||
|
||
function isLocalUploadedAsset(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('isLocalUploadedAsset');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
var id = String(asset && asset.id || '').trim();
|
||
return String(asset && asset.sourceKind || '').trim() === 'local_folder' || id.indexOf('local:asset:') === 0;
|
||
}
|
||
|
||
function uploadedAssetExtension(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAssetExtension');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
var match = uploadedAssetTitle(asset).toLowerCase().match(/\.([a-z0-9]+)$/);
|
||
return match ? match[1] : '';
|
||
}
|
||
|
||
function isNonOfficeAttachmentName(name, ext) {
|
||
var runtimeFn = localUploadRuntimeFunction('isNonOfficeAttachmentName');
|
||
if (runtimeFn) return runtimeFn(name, ext);
|
||
var codeFileNames = [
|
||
'.dockerignore', '.editorconfig', '.env', '.eslintrc', '.gitattributes', '.gitignore', '.npmrc', '.prettierrc',
|
||
'dockerfile', 'makefile', 'cmakelists.txt', 'gemfile', 'rakefile', 'procfile'
|
||
];
|
||
return [
|
||
'pdf', 'toml', 'json', 'yaml', 'yml', 'md', 'markdown', 'txt', 'ini', 'env', 'xml', 'html', 'htm', 'css', 'scss',
|
||
'less', 'js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py', 'rs', 'go', 'java', 'c', 'cpp', 'h', 'hpp', 'cs',
|
||
'php', 'rb', 'sh', 'bash', 'zsh', 'sql', 'lock', 'log', 'vue', 'svelte', 'astro', 'jsonc', 'json5',
|
||
'mts', 'cts', 'lua', 'dart', 'kt', 'kts', 'swift', 'scala', 'gradle', 'groovy', 'clj',
|
||
'ex', 'exs', 'erl', 'hrl', 'fs', 'fsx', 'r', 'jl', 'm', 'mm', 'pl', 'pm', 'ps1', 'bat', 'cmd',
|
||
'psm1', 'psd1', 'dockerfile', 'containerfile', 'proto', 'graphql', 'gql', 'prisma', 'tf', 'tfvars',
|
||
'hcl', 'nix', 'cmake', 'bazel', 'bzl', 'properties', 'conf', 'cfg', 'config', 'service', 'desktop',
|
||
'gitignore', 'gitattributes', 'editorconfig', 'npmrc', 'prettierrc', 'eslintrc'
|
||
].indexOf(ext) >= 0 || codeFileNames.indexOf(name) >= 0;
|
||
}
|
||
|
||
function attachmentExtensionFromFileName(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('attachmentExtensionFromFileName');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
var name = String(fileName || '').trim().toLowerCase();
|
||
return name.indexOf('.') >= 0 ? name.split('.').pop() : '';
|
||
}
|
||
|
||
function isPdfAttachmentFileName(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('isPdfAttachmentFileName');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
return attachmentExtensionFromFileName(fileName) === 'pdf';
|
||
}
|
||
|
||
function isCodeAttachmentFileName(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('isCodeAttachmentFileName');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
var name = String(fileName || '').trim().toLowerCase();
|
||
var ext = attachmentExtensionFromFileName(name);
|
||
return ext !== 'pdf' && isNonOfficeAttachmentName(name, ext);
|
||
}
|
||
|
||
function inferCodeAttachmentLanguage(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('inferCodeAttachmentLanguage');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
var name = String(fileName || '').trim().toLowerCase();
|
||
var ext = attachmentExtensionFromFileName(name);
|
||
var byName = {
|
||
'dockerfile': 'dockerfile',
|
||
'makefile': 'makefile',
|
||
'cmakelists.txt': 'cmake',
|
||
'.gitignore': 'gitignore',
|
||
'.gitattributes': 'gitattributes',
|
||
'.editorconfig': 'ini',
|
||
'.env': 'dotenv'
|
||
};
|
||
if (byName[name]) return byName[name];
|
||
var byExt = {
|
||
bash: 'bash', bat: 'batch', c: 'c', cjs: 'javascript', cmd: 'batch', conf: 'text', cpp: 'cpp',
|
||
cs: 'csharp', css: 'css', cts: 'typescript', dart: 'dart', dockerfile: 'dockerfile', env: 'dotenv',
|
||
go: 'go', gql: 'graphql', gradle: 'groovy', graphql: 'graphql', h: 'c', hcl: 'hcl', hpp: 'cpp',
|
||
htm: 'html', html: 'html', ini: 'ini', java: 'java', js: 'javascript', json: 'json', json5: 'json',
|
||
jsonc: 'jsonc', jsx: 'javascript', kt: 'kotlin', kts: 'kotlin', less: 'less', log: 'text',
|
||
lua: 'lua', m: 'objective-c', markdown: 'markdown', md: 'markdown', mjs: 'javascript',
|
||
mts: 'typescript', nix: 'nix', php: 'php', pl: 'perl', pm: 'perl', prisma: 'prisma',
|
||
proto: 'protobuf', ps1: 'powershell', py: 'python', r: 'r', rb: 'ruby', rs: 'rust',
|
||
scss: 'scss', sh: 'bash', sql: 'sql', svelte: 'svelte', swift: 'swift', tf: 'terraform',
|
||
tfvars: 'terraform', toml: 'toml', ts: 'typescript', tsx: 'typescript', txt: 'text',
|
||
vue: 'vue', xml: 'xml', yaml: 'yaml', yml: 'yaml', zsh: 'bash'
|
||
};
|
||
return byExt[ext] || 'text';
|
||
}
|
||
|
||
function attachmentClassForFileName(fileName) {
|
||
var runtimeFn = localUploadRuntimeFunction('attachmentClassForFileName');
|
||
if (runtimeFn) return runtimeFn(fileName);
|
||
var name = String(fileName || '').trim().toLowerCase();
|
||
var ext = name.indexOf('.') >= 0 ? name.split('.').pop() : '';
|
||
if (['doc', 'docx', 'odt', 'rtf'].indexOf(ext) >= 0) return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-word';
|
||
if (['ppt', 'pptx', 'odp'].indexOf(ext) >= 0) return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-ppt';
|
||
if (['xls', 'xlsx', 'ods', 'csv'].indexOf(ext) >= 0) return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-sheet';
|
||
if (ext === 'pdf') return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-pdf';
|
||
if (isNonOfficeAttachmentName(name, ext)) {
|
||
return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-code';
|
||
}
|
||
return 'mnote-uploaded-attachment-row mnote-uploaded-attachment-file';
|
||
}
|
||
|
||
function uploadedAttachmentClass(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedAttachmentClass');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
return attachmentClassForFileName(uploadedAssetTitle(asset));
|
||
}
|
||
|
||
function buildOnlyOfficeAssetOpenUrl(asset, userId) {
|
||
var title = uploadedAssetTitle(asset);
|
||
var fileType = inferOnlyOfficeFileType(title, asset && asset.mime_type);
|
||
if (!fileType) return '';
|
||
var assetId = String(asset && asset.id || '').trim();
|
||
if (isLocalUploadedAsset(asset)) {
|
||
var localUrl = localAssetOpenUrl(asset, false);
|
||
if (!localUrl) return '';
|
||
return buildOnlyOfficeOpenUrl({
|
||
fileUrl: localUrl,
|
||
fileName: title,
|
||
fileType: fileType,
|
||
assetId: assetId,
|
||
documentId: String(asset && (asset.document_id || asset.documentId) || currentDocumentId() || '').trim(),
|
||
userId: userId || '',
|
||
mode: 'view'
|
||
});
|
||
}
|
||
return buildOnlyOfficeOpenUrl({
|
||
fileUrl: assetId ? '' : uploadedAssetUrl(asset),
|
||
fileName: title,
|
||
fileType: fileType,
|
||
assetId: assetId,
|
||
documentId: String(asset && (asset.document_id || asset.documentId) || currentDocumentId() || '').trim(),
|
||
userId: userId || '',
|
||
mode: 'view'
|
||
});
|
||
}
|
||
|
||
function uploadedFileSize(asset) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadedFileSize');
|
||
if (runtimeFn) return runtimeFn(asset);
|
||
var size = Number(asset && (asset.file_size || asset.fileSize) || 0);
|
||
if (!Number.isFinite(size) || size <= 0) return '';
|
||
if (size >= 1024 * 1024) return (size / 1024 / 1024).toFixed(size >= 10 * 1024 * 1024 ? 1 : 2) + ' MB';
|
||
if (size >= 1024) return (size / 1024).toFixed(size >= 100 * 1024 ? 0 : 2) + ' KB';
|
||
return String(Math.round(size)) + ' B';
|
||
}
|
||
|
||
var attachmentMetaCache = Object.create(null);
|
||
var attachmentMetaPending = Object.create(null);
|
||
var legacyOfficeAttachmentIndex = null;
|
||
var legacyOfficeAttachmentIndexPending = null;
|
||
|
||
function parseCurrentWorkspaceId() {
|
||
return (new URLSearchParams(window.location.search).get('workspaceId') || '').trim();
|
||
}
|
||
|
||
async function fetchLegacyOfficeAttachmentIndex() {
|
||
if (legacyOfficeAttachmentIndex) return legacyOfficeAttachmentIndex;
|
||
if (legacyOfficeAttachmentIndexPending) return legacyOfficeAttachmentIndexPending;
|
||
var documentId = currentDocumentId();
|
||
var workspaceId = parseCurrentWorkspaceId();
|
||
if (!documentId || !workspaceId) {
|
||
legacyOfficeAttachmentIndex = Object.create(null);
|
||
return legacyOfficeAttachmentIndex;
|
||
}
|
||
var projectionUrl = new URL('/api/tree/projections/file', window.location.origin);
|
||
projectionUrl.searchParams.set('documentId', documentId);
|
||
projectionUrl.searchParams.set('workspaceId', workspaceId);
|
||
var sourcePayload = currentWorkspaceSourcePayload();
|
||
if (sourcePayload.sourceKind) projectionUrl.searchParams.set('sourceKind', sourcePayload.sourceKind);
|
||
if (sourcePayload.rootUri) projectionUrl.searchParams.set('rootUri', sourcePayload.rootUri);
|
||
legacyOfficeAttachmentIndexPending = fetch(projectionUrl.toString(), {
|
||
method: 'GET',
|
||
credentials: 'include',
|
||
cache: 'no-store'
|
||
}).then(function(response) {
|
||
return response.json().catch(function() { return null; }).then(function(payload) {
|
||
var items = payload && payload.ok && payload.result && Array.isArray(payload.result.items)
|
||
? payload.result.items
|
||
: [];
|
||
var index = Object.create(null);
|
||
items.forEach(function(item) {
|
||
if (!item || item.rowKind !== 'asset') return;
|
||
var title = String(item.title || '').trim();
|
||
if (!title || index[title]) return;
|
||
var fileType = inferOnlyOfficeFileType(title, '');
|
||
if (!fileType) return;
|
||
var rowId = String(item.rowId || '').trim();
|
||
var assetId = String(item.assetId || '').trim();
|
||
if (!assetId && rowId.indexOf('asset:') === 0) assetId = rowId.slice('asset:'.length);
|
||
if (!assetId) return;
|
||
index[title] = {
|
||
assetId: assetId,
|
||
fileName: title,
|
||
fileType: fileType,
|
||
documentId: documentId
|
||
};
|
||
});
|
||
legacyOfficeAttachmentIndex = index;
|
||
return index;
|
||
});
|
||
}).catch(function() {
|
||
var empty = Object.create(null);
|
||
legacyOfficeAttachmentIndex = empty;
|
||
return empty;
|
||
}).finally(function() {
|
||
legacyOfficeAttachmentIndexPending = null;
|
||
});
|
||
return legacyOfficeAttachmentIndexPending;
|
||
}
|
||
|
||
async function healLegacyOfficeAttachmentParagraphs() {
|
||
var editor = document.querySelector('.editor-surface .ProseMirror');
|
||
if (!(editor instanceof HTMLElement)) return;
|
||
var paragraphs = Array.from(editor.querySelectorAll('p'));
|
||
var candidates = paragraphs.filter(function(paragraph) {
|
||
if (!(paragraph instanceof HTMLParagraphElement)) return;
|
||
if (paragraph.querySelector('a, img, video, audio, table, iframe, canvas')) return;
|
||
if (paragraph.childNodes.length !== 1 || paragraph.firstChild?.nodeType !== Node.TEXT_NODE) return;
|
||
var fileName = String(paragraph.textContent || '').trim();
|
||
if (!fileName) return;
|
||
return Boolean(inferOnlyOfficeFileType(fileName, ''));
|
||
});
|
||
if (!candidates.length) return;
|
||
var index = await fetchLegacyOfficeAttachmentIndex();
|
||
candidates.forEach(function(paragraph) {
|
||
var fileName = String(paragraph.textContent || '').trim();
|
||
var detail = index[fileName];
|
||
if (!detail) return;
|
||
var link = document.createElement('a');
|
||
link.textContent = fileName;
|
||
link.setAttribute('href', buildOnlyOfficeOpenPath({
|
||
fileUrl: '',
|
||
fileName: detail.fileName,
|
||
fileType: detail.fileType,
|
||
assetId: detail.assetId,
|
||
documentId: detail.documentId || currentDocumentId() || '',
|
||
userId: '',
|
||
mode: 'view'
|
||
}));
|
||
link.setAttribute('data-asset-id', detail.assetId);
|
||
attachmentClassForFileName(fileName).split(/\s+/).forEach(function(name) {
|
||
if (name) link.classList.add(name);
|
||
});
|
||
paragraph.replaceChildren(link);
|
||
enhanceEditorAttachmentLink(link);
|
||
});
|
||
}
|
||
|
||
function applyEditorAttachmentMeta(link, meta) {
|
||
if (!(link instanceof HTMLAnchorElement) || !meta) return;
|
||
if (meta.assetId) link.setAttribute('data-asset-id', meta.assetId);
|
||
if (meta.fileSize) link.setAttribute('data-file-size', meta.fileSize);
|
||
}
|
||
|
||
async function hydrateEditorAttachmentMeta(link) {
|
||
if (!(link instanceof HTMLAnchorElement)) return;
|
||
var detail = detailFromEditorAttachmentLink(link);
|
||
var assetId = String(detail && detail.assetId || '').trim();
|
||
if (!assetId) return;
|
||
var localFilePath = localFilePathFromAssetId(assetId);
|
||
if (localFilePath) {
|
||
var localMeta = {
|
||
assetId: assetId,
|
||
fileSize: String(detail && detail.fileSize || '').trim()
|
||
};
|
||
attachmentMetaCache[assetId] = localMeta;
|
||
applyEditorAttachmentMeta(link, localMeta);
|
||
return;
|
||
}
|
||
if (attachmentMetaCache[assetId]) {
|
||
applyEditorAttachmentMeta(link, attachmentMetaCache[assetId]);
|
||
return;
|
||
}
|
||
if (attachmentMetaPending[assetId]) {
|
||
try { await attachmentMetaPending[assetId]; } catch (_) {}
|
||
applyEditorAttachmentMeta(link, attachmentMetaCache[assetId]);
|
||
return;
|
||
}
|
||
document.documentElement.setAttribute('data-mnote-media-sign-retired', 'true');
|
||
attachmentMetaPending[assetId] = Promise.resolve(null).finally(function() {
|
||
delete attachmentMetaPending[assetId];
|
||
});
|
||
try {
|
||
var meta = await attachmentMetaPending[assetId];
|
||
applyEditorAttachmentMeta(link, meta);
|
||
} catch (_) {}
|
||
}
|
||
|
||
function revealFileTreeRow(row) {
|
||
var runtimeFn = fileTreeRuntimeFunction('revealFileTreeRow');
|
||
if (runtimeFn) return runtimeFn(row, fileTreeRuntimeDeps());
|
||
if (!(row instanceof HTMLElement)) return;
|
||
var node = row.closest('.tree-node');
|
||
while (node && node.parentElement) {
|
||
if (node.parentElement.classList && node.parentElement.classList.contains('tree-children')) {
|
||
node.parentElement.classList.remove('tree-children--collapsed');
|
||
var parentNode = node.parentElement.closest('.tree-node');
|
||
var parentRow = parentNode ? parentNode.querySelector(':scope > .tree-row') : null;
|
||
if (parentRow instanceof HTMLElement) {
|
||
parentRow.setAttribute('aria-expanded', 'true');
|
||
var toggle = parentRow.querySelector('[data-rust-action="toggle"]');
|
||
if (toggle) toggle.setAttribute('aria-expanded', 'true');
|
||
}
|
||
}
|
||
node = node.parentElement.closest('.tree-node');
|
||
}
|
||
try { row.scrollIntoView({ block: 'nearest' }); } catch (_) {}
|
||
}
|
||
|
||
function revealFileTreeAssetRow(assetId) {
|
||
var runtimeFn = fileTreeRuntimeFunction('revealFileTreeAssetRow');
|
||
if (runtimeFn) return runtimeFn(assetId, fileTreeRuntimeDeps());
|
||
if (!assetId) return false;
|
||
var row = document.querySelector('.tree-row[data-shell-mode="filetree"][data-asset-id="' + cssEscape(assetId) + '"]');
|
||
if (!(row instanceof HTMLElement)) return false;
|
||
revealFileTreeRow(row);
|
||
return true;
|
||
}
|
||
|
||
function appendUploadedAssetRow(asset, documentId) {
|
||
var runtimeFn = fileTreeRuntimeFunction('appendUploadedAssetRow');
|
||
if (runtimeFn) return runtimeFn(asset, documentId, fileTreeRuntimeDeps());
|
||
var assetId = String(asset && asset.id || '').trim();
|
||
if (!assetId) return false;
|
||
if (revealFileTreeAssetRow(assetId)) return true;
|
||
var objectKind = String(asset && (asset.objectKind || asset.resourceKind || '') || '').trim();
|
||
if (!objectKind && (String(asset && (asset.asset_type || asset.assetType) || '').trim() === 'mindmap' || /\.mindmap\.json$/i.test(assetId))) {
|
||
objectKind = 'mindmap';
|
||
}
|
||
var targetDocumentId = String(documentId || asset.document_id || asset.documentId || currentDocumentId() || '').trim();
|
||
var parentRow = targetDocumentId
|
||
? document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape('doc:' + targetDocumentId) + '"]')
|
||
: null;
|
||
if (!parentRow && currentSourceKind() === 'local_folder' && objectKind === 'mindmap') return false;
|
||
if (!parentRow) parentRow = document.querySelector('.tree-row[data-shell-mode="filetree"][data-row-kind="document"]');
|
||
var root = document.querySelector('#sidebar-file-tree-root .tree-root');
|
||
if (!root && !parentRow) return false;
|
||
var parentLi = parentRow ? parentRow.closest('.tree-node') : null;
|
||
var children = parentLi ? parentLi.querySelector(':scope > .tree-children') : null;
|
||
if (parentLi && !children) {
|
||
children = document.createElement('ul');
|
||
children.className = 'tree-children';
|
||
parentLi.appendChild(children);
|
||
}
|
||
if (children) {
|
||
children.classList.remove('tree-children--collapsed');
|
||
if (parentRow) {
|
||
parentRow.setAttribute('aria-expanded', 'true');
|
||
var toggle = parentRow.querySelector('[data-rust-action="toggle"]');
|
||
if (toggle) toggle.setAttribute('aria-expanded', 'true');
|
||
}
|
||
}
|
||
var container = children || root;
|
||
var li = document.createElement('li');
|
||
li.className = 'tree-node';
|
||
var objectIdentity = {
|
||
objectKind: objectKind || 'attachment',
|
||
documentId: targetDocumentId || null,
|
||
blockId: null,
|
||
assetId: assetId
|
||
};
|
||
li.setAttribute('data-node-id', 'asset:' + assetId);
|
||
var title = uploadedAssetTitle(asset);
|
||
var iconKind = fileTreeIconKindForFileName(title) || uploadedAssetType(asset) || 'file';
|
||
if (objectKind === 'mindmap') iconKind = 'mindmap';
|
||
li.innerHTML =
|
||
'<div class="tree-row" role="treeitem" aria-level="' + (parentRow ? '2' : '1') + '" aria-expanded="false" data-rust-rendered-row="filetree" data-testid="filetree-asset-row" data-row-id="' + escapeHtml('asset:' + assetId) + '" data-row-kind="asset" data-node-id="' + escapeHtml('asset:' + assetId) + '" data-document-id="' + escapeHtml(targetDocumentId) + '" data-doc-id="' + escapeHtml(targetDocumentId) + '" data-asset-id="' + escapeHtml(assetId) + '" data-object-identity="' + escapeHtml(objectIdentityAttr(objectIdentity)) + '" data-object-kind="' + escapeHtml(objectKind || 'attachment') + '" data-shell-mode="filetree" data-selected="false" data-active="false" draggable="true">' +
|
||
'<span class="tree-spacer" aria-hidden="true"></span><span class="tree-kind-badge" data-kind="' + escapeHtml(iconKind) + '" aria-hidden="true"></span>' +
|
||
'<button type="button" class="tree-link" data-rust-action="open" data-row-id="' + escapeHtml('asset:' + assetId) + '" data-document-id="' + escapeHtml(targetDocumentId) + '" data-asset-id="' + escapeHtml(assetId) + '"><span class="tree-link-title">' + escapeHtml(title) + '</span></button>' +
|
||
'<div class="tree-actions"><button type="button" class="tree-action" data-testid="filetree-action-menu" data-rust-action="menu" data-row-id="' + escapeHtml('asset:' + assetId) + '" aria-label="更多操作">…</button></div></div>';
|
||
container.appendChild(li);
|
||
revealFileTreeRow(li.querySelector('.tree-row'));
|
||
document.documentElement.setAttribute('data-mnote-last-upload-asset-id', assetId);
|
||
return true;
|
||
}
|
||
|
||
function removeFileTreeAssetRow(assetId) {
|
||
var normalized = String(assetId || '').trim();
|
||
if (!normalized) return false;
|
||
var row = document.querySelector('.tree-row[data-shell-mode="filetree"][data-asset-id="' + cssEscape(normalized) + '"]');
|
||
var node = row ? row.closest('.tree-node') : null;
|
||
if (!node || !node.parentElement) return false;
|
||
node.parentElement.removeChild(node);
|
||
return true;
|
||
}
|
||
|
||
function applyAssetsChangedToFileTree(detail) {
|
||
detail = detail || {};
|
||
var docId = String(detail.docId || detail.documentId || currentDocumentId() || '').trim();
|
||
var changed = false;
|
||
var explicitAsset = detail.asset && typeof detail.asset === 'object' ? detail.asset : null;
|
||
if (explicitAsset) {
|
||
appendUploadedAssetRow(explicitAsset, docId);
|
||
changed = true;
|
||
}
|
||
var mindmapAssetIds = Array.isArray(detail.mindmapAssetIds) ? detail.mindmapAssetIds : [];
|
||
if (detail.mindmapDeleted === true) {
|
||
mindmapAssetIds.forEach(function(assetId) {
|
||
if (removeFileTreeAssetRow(assetId)) changed = true;
|
||
});
|
||
}
|
||
if (changed) {
|
||
document.documentElement.setAttribute('data-mnote-assets-local-applied', 'true');
|
||
}
|
||
}
|
||
|
||
function mindmapAssetFromTarget(documentId, mindmapId, writeResult) {
|
||
var docId = String(documentId || currentDocumentId() || '').trim();
|
||
var assetId = String(mindmapId || '').trim();
|
||
if (!docId || !assetId) return null;
|
||
var result = writeResult && typeof writeResult === 'object' ? writeResult : {};
|
||
var resultAssetId = String(result.assetId || result.id || '').trim();
|
||
var relativePath = String(result.relativePath || result.rootRelativePath || '').trim();
|
||
var fileName = String(result.fileName || '').trim() || shortMindmapFileName(assetId);
|
||
return {
|
||
id: resultAssetId || (relativePath ? 'local-file:' + relativePath : assetId),
|
||
document_id: docId,
|
||
asset_type: 'mindmap',
|
||
file_name: fileName,
|
||
file_url: relativePath || ('/documents/' + encodeURIComponent(docId) + '/' + encodeURIComponent(fileName)),
|
||
sourcePath: relativePath,
|
||
rootRelativePath: relativePath,
|
||
sourceKind: currentSourceKind(),
|
||
rootUri: currentRootUri(),
|
||
objectKind: 'mindmap'
|
||
};
|
||
}
|
||
|
||
function shortMindmapFileName(mindmapId) {
|
||
var runtimeFn = fileTreeRuntimeFunction('shortMindmapFileName');
|
||
if (runtimeFn) return runtimeFn(mindmapId);
|
||
var raw = String(mindmapId || '').trim();
|
||
var pathName = raw.indexOf('/') >= 0 ? raw.split('/').pop() : raw;
|
||
if (/\.json$/i.test(pathName)) return pathName;
|
||
var digits = raw.match(/(\d{4,})$/);
|
||
var suffix = digits ? digits[1].slice(-6) : '';
|
||
return suffix ? '思维导图' + suffix + '.json' : '思维导图.json';
|
||
}
|
||
|
||
function parseMindmapApiTarget(input) {
|
||
var runtimeFn = fileTreeRuntimeFunction('parseMindmapApiTarget');
|
||
if (runtimeFn) return runtimeFn(input);
|
||
try {
|
||
var rawUrl = typeof input === 'string'
|
||
? input
|
||
: input && typeof input.url === 'string'
|
||
? input.url
|
||
: '';
|
||
if (!rawUrl) return null;
|
||
var url = new URL(rawUrl, window.location.origin);
|
||
var match = /^\/api\/mindmap\/([^/]+)\/([^/]+)$/.exec(url.pathname);
|
||
if (!match) return null;
|
||
return {
|
||
documentId: decodeURIComponent(match[1]),
|
||
mindmapId: decodeURIComponent(match[2])
|
||
};
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function withLocalMindmapSourceParams(input) {
|
||
var target = parseMindmapApiTarget(input);
|
||
if (!target || currentSourceKind() !== 'local_folder') return input;
|
||
var rootUri = currentRootUri();
|
||
if (!rootUri) return input;
|
||
var rawUrl = typeof input === 'string'
|
||
? input
|
||
: input && typeof input.url === 'string'
|
||
? input.url
|
||
: '';
|
||
if (!rawUrl) return input;
|
||
var url = new URL(rawUrl, window.location.origin);
|
||
url.searchParams.set('sourceKind', 'local_folder');
|
||
url.searchParams.set('rootUri', rootUri);
|
||
if (typeof input === 'string') return url.pathname + url.search;
|
||
if (typeof Request !== 'undefined' && input instanceof Request) {
|
||
return new Request(url.toString(), input);
|
||
}
|
||
return url.toString();
|
||
}
|
||
|
||
function requestMethod(input, init) {
|
||
var runtimeFn = fileTreeRuntimeFunction('requestMethod');
|
||
if (runtimeFn) return runtimeFn(input, init);
|
||
return String(
|
||
init && init.method
|
||
? init.method
|
||
: input && typeof input.method === 'string'
|
||
? input.method
|
||
: 'GET'
|
||
).toUpperCase();
|
||
}
|
||
|
||
function requestBodyHasMindmapCreateOnly(init) {
|
||
var runtimeFn = fileTreeRuntimeFunction('requestBodyHasMindmapCreateOnly');
|
||
if (runtimeFn) return runtimeFn(init);
|
||
var body = init && typeof init.body === 'string' ? init.body : '';
|
||
if (!body) return false;
|
||
try {
|
||
var payload = JSON.parse(body);
|
||
return payload && payload.createOnly === true;
|
||
} catch (_) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function applyMindmapApiMutationToFileTree(target, payload) {
|
||
if (!target || !target.documentId || !target.mindmapId) return;
|
||
var asset = mindmapAssetFromTarget(target.documentId, target.mindmapId, payload && payload.writeResult);
|
||
if (!asset) return;
|
||
var appended = appendUploadedAssetRow(asset, target.documentId);
|
||
if (!appended && currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();
|
||
document.documentElement.setAttribute('data-mnote-assets-local-applied', 'true');
|
||
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', asset.id || target.mindmapId);
|
||
}
|
||
|
||
function installMindmapAssetFetchObserver() {
|
||
if (window.__mnoteMindmapAssetFetchObserverInstalled === true) return;
|
||
if (typeof window.fetch !== 'function') return;
|
||
window.__mnoteMindmapAssetFetchObserverInstalled = true;
|
||
var originalFetch = window.fetch.bind(window);
|
||
window.fetch = function(input, init) {
|
||
var nextInput = withLocalMindmapSourceParams(input);
|
||
var target = parseMindmapApiTarget(nextInput);
|
||
var method = requestMethod(input, init);
|
||
var createOnly = requestBodyHasMindmapCreateOnly(init || {});
|
||
return originalFetch(nextInput, init).then(function(response) {
|
||
if (target && method === 'POST' && response && response.ok) {
|
||
var cloned = response.clone();
|
||
void cloned.json().then(function(payload) {
|
||
if (createOnly || target.documentId === currentDocumentId()) {
|
||
applyMindmapApiMutationToFileTree(target, payload);
|
||
}
|
||
}).catch(function() {
|
||
if (createOnly || target.documentId === currentDocumentId()) {
|
||
applyMindmapApiMutationToFileTree(target, null);
|
||
}
|
||
});
|
||
}
|
||
return response;
|
||
});
|
||
};
|
||
}
|
||
|
||
async function archiveLocalFileTreeAsset(row, assetId) {
|
||
if (!assetId) return false;
|
||
await dispatchTreeCommand(row || document.body, {
|
||
action: 'archive',
|
||
workspaceId: resolveWorkspaceId(row || document.body),
|
||
documentId: assetId
|
||
});
|
||
removeFileTreeAssetRow(assetId);
|
||
return true;
|
||
}
|
||
|
||
async function deleteSingleFileTreeAsset(detail, trigger) {
|
||
var assetId = String(detail && detail.assetId || '').trim();
|
||
if (!assetId) return false;
|
||
var row = trigger && trigger.closest ? trigger.closest('.tree-row[data-shell-mode="filetree"]') : null;
|
||
if (!row) row = document.querySelector('.tree-row[data-shell-mode="filetree"][data-asset-id="' + cssEscape(assetId) + '"]');
|
||
if (currentSourceKind() === 'local_folder') {
|
||
return archiveLocalFileTreeAsset(row, assetId);
|
||
}
|
||
var documentId = String(detail && detail.documentId || '').trim();
|
||
var kind = classifySidebarFileTreeAsset(row);
|
||
if (kind === 'mindmap') {
|
||
var response = await fetch('/api/mindmap/' + encodeURIComponent(documentId) + '/' + encodeURIComponent(assetId), { method: 'DELETE' });
|
||
if (!response.ok) throw new Error('mindmap_delete_failed_' + response.status);
|
||
removeFileTreeAssetRow(assetId);
|
||
return true;
|
||
}
|
||
if (kind === 'table') {
|
||
var tableResponse = await fetch('/api/tables/' + encodeURIComponent(assetId), { method: 'DELETE' });
|
||
if (!tableResponse.ok) throw new Error('table_delete_failed_' + tableResponse.status);
|
||
removeFileTreeAssetRow(assetId);
|
||
return true;
|
||
}
|
||
await postSidebarFileTreeJson('/api/media/batch', { action: 'delete', assetIds: [assetId] });
|
||
removeFileTreeAssetRow(assetId);
|
||
return true;
|
||
}
|
||
|
||
function resolveEditorUploadContext(detail) {
|
||
var runtimeFn = localUploadRuntimeFunction('resolveEditorUploadContext');
|
||
if (runtimeFn) {
|
||
return runtimeFn(detail || {}, {
|
||
rootSelector: EDITOR_UPLOAD_ROOT_SELECTOR,
|
||
editorUploadRootFromElement: editorUploadRootFromElement,
|
||
currentDocumentId: currentDocumentId,
|
||
resolveWorkspaceId: resolveWorkspaceId
|
||
});
|
||
}
|
||
var root = null;
|
||
var selector = detail && detail.editorRootSelector ? String(detail.editorRootSelector) : '';
|
||
if (selector) {
|
||
try {
|
||
var selected = document.querySelector(selector);
|
||
if (selected instanceof HTMLElement) root = selected;
|
||
} catch (_) {}
|
||
}
|
||
if (!root && window.__mnoteIntendedSlashRoot instanceof HTMLElement && window.__mnoteIntendedSlashRoot.isConnected) {
|
||
root = window.__mnoteIntendedSlashRoot;
|
||
}
|
||
if (!root && window.__mnoteLastEditorUploadRoot instanceof HTMLElement && window.__mnoteLastEditorUploadRoot.isConnected) {
|
||
root = window.__mnoteLastEditorUploadRoot;
|
||
}
|
||
if (!root && document.activeElement instanceof Element) {
|
||
root = editorUploadRootFromElement(document.activeElement);
|
||
}
|
||
if (!root) {
|
||
var focused = document.querySelector(EDITOR_UPLOAD_ROOT_SELECTOR + ' .ProseMirror:focus-within');
|
||
root = editorUploadRootFromElement(focused);
|
||
}
|
||
if (!root) {
|
||
root = document.querySelector('[data-editor-host-kind="leptos_tiptap_island"][data-pane-role="primary"]');
|
||
}
|
||
var pane = root instanceof Element ? root.closest('.document-pane[data-pane-role]') : null;
|
||
var shell = root instanceof Element ? root.closest('.document-shell[data-document-id]') : null;
|
||
return {
|
||
root: root instanceof HTMLElement ? root : null,
|
||
documentId: String(
|
||
detail && detail.documentId
|
||
|| (root instanceof HTMLElement && root.getAttribute('data-document-id'))
|
||
|| (pane instanceof HTMLElement && pane.getAttribute('data-pane-document-id'))
|
||
|| (shell instanceof HTMLElement && shell.getAttribute('data-document-id'))
|
||
|| currentDocumentId()
|
||
|| ''
|
||
).trim(),
|
||
workspaceId: String(
|
||
detail && detail.workspaceId
|
||
|| (root instanceof HTMLElement && root.getAttribute('data-workspace-id'))
|
||
|| (pane instanceof HTMLElement && pane.getAttribute('data-pane-workspace-id'))
|
||
|| (shell instanceof HTMLElement && shell.getAttribute('data-workspace-id'))
|
||
|| resolveWorkspaceId(document.body)
|
||
|| ''
|
||
).trim()
|
||
};
|
||
}
|
||
|
||
function editorRootFromUploadOptions(options) {
|
||
var runtimeFn = localUploadRuntimeFunction('editorRootFromUploadOptions');
|
||
if (runtimeFn) {
|
||
return runtimeFn(options || {}, {
|
||
rootSelector: EDITOR_UPLOAD_ROOT_SELECTOR,
|
||
editorUploadRootFromElement: editorUploadRootFromElement
|
||
});
|
||
}
|
||
if (options && options.editorRoot instanceof HTMLElement) return options.editorRoot;
|
||
if (window.__mnoteIntendedSlashRoot instanceof HTMLElement && window.__mnoteIntendedSlashRoot.isConnected) {
|
||
return window.__mnoteIntendedSlashRoot;
|
||
}
|
||
if (window.__mnoteLastEditorUploadRoot instanceof HTMLElement && window.__mnoteLastEditorUploadRoot.isConnected) {
|
||
return window.__mnoteLastEditorUploadRoot;
|
||
}
|
||
var focused = document.querySelector(EDITOR_UPLOAD_ROOT_SELECTOR + ' .ProseMirror:focus-within');
|
||
return editorUploadRootFromElement(focused);
|
||
}
|
||
|
||
async function fetchWithTimeout(input, init, timeoutMs, label) {
|
||
var runtimeFn = localUploadRuntimeFunction('fetchWithTimeout');
|
||
if (runtimeFn) {
|
||
return await runtimeFn(input, init || {}, timeoutMs, label);
|
||
}
|
||
var controller = typeof AbortController === 'function' ? new AbortController() : null;
|
||
var timer = 0;
|
||
try {
|
||
if (controller) {
|
||
timer = window.setTimeout(function() {
|
||
controller.abort();
|
||
}, Math.max(1000, Number(timeoutMs) || 15000));
|
||
}
|
||
var nextInit = Object.assign({}, init || {});
|
||
if (controller) nextInit.signal = controller.signal;
|
||
return await fetch(input, nextInit);
|
||
} catch (error) {
|
||
if (error && error.name === 'AbortError') {
|
||
throw new Error((label || '请求') + '超时');
|
||
}
|
||
throw error;
|
||
} finally {
|
||
if (timer) window.clearTimeout(timer);
|
||
}
|
||
}
|
||
|
||
async function insertUploadedAssetIntoEditor(asset, targetRoot) {
|
||
var runtimeFn = localUploadRuntimeFunction('insertUploadedAssetIntoEditor');
|
||
if (runtimeFn) {
|
||
return await runtimeFn(asset, targetRoot, {
|
||
uploadedAssetTitle: uploadedAssetTitle,
|
||
localAssetOpenUrl: localAssetOpenUrl,
|
||
uploadedAssetUrl: uploadedAssetUrl,
|
||
uploadedAssetType: uploadedAssetType,
|
||
isLocalUploadedAsset: isLocalUploadedAsset,
|
||
buildOnlyOfficeAssetOpenUrl: buildOnlyOfficeAssetOpenUrl,
|
||
fetchCurrentOnlyOfficeUserId: fetchCurrentOnlyOfficeUserId,
|
||
buildOnlyOfficeOpenPath: buildOnlyOfficeOpenPath,
|
||
inferOnlyOfficeFileType: inferOnlyOfficeFileType,
|
||
currentDocumentId: currentDocumentId,
|
||
currentRootUri: currentRootUri,
|
||
uploadedAttachmentClass: uploadedAttachmentClass,
|
||
uploadedFileSize: uploadedFileSize,
|
||
cssEscape: cssEscape,
|
||
enhanceEditorAttachmentLinks: enhanceEditorAttachmentLinks
|
||
});
|
||
}
|
||
var editorRoot = targetRoot instanceof HTMLElement
|
||
? targetRoot.querySelector('.editor-surface .ProseMirror')
|
||
: document.querySelector('.editor-surface .ProseMirror');
|
||
if (targetRoot instanceof HTMLElement) window.__mnoteLastEditorUploadRoot = targetRoot;
|
||
var editor = editorRoot && editorRoot.editor;
|
||
if (!editor || !editor.chain) {
|
||
document.documentElement.setAttribute('data-mnote-last-upload-inserted', 'false');
|
||
document.documentElement.setAttribute('data-mnote-last-upload-insert-error', 'editor_unavailable');
|
||
return false;
|
||
}
|
||
var title = uploadedAssetTitle(asset);
|
||
var markdownHref = uploadedAssetMarkdownHref(asset);
|
||
var localOpenUrl = localAssetOpenUrl(asset, false);
|
||
var fallbackUrl = uploadedAssetUrl(asset);
|
||
var imageUrl = localOpenUrl || fallbackUrl || markdownHref;
|
||
var url = markdownHref || localOpenUrl || fallbackUrl;
|
||
var type = uploadedAssetType(asset);
|
||
var assetId = String(asset && asset.id || '').trim();
|
||
var sizeLabel = uploadedFileSize(asset);
|
||
try {
|
||
if (type === 'image' && imageUrl) {
|
||
return editor.chain().focus().setImage({ src: imageUrl, alt: title, title: title }).run() === true;
|
||
}
|
||
var href = markdownHref || url;
|
||
if (href) {
|
||
var inserted = editor.chain().focus().insertContent([
|
||
{
|
||
type: 'paragraph',
|
||
content: [{
|
||
type: 'text',
|
||
text: title,
|
||
marks: [{
|
||
type: 'link',
|
||
attrs: {
|
||
href: href,
|
||
target: '_blank',
|
||
rel: 'noopener noreferrer nofollow',
|
||
class: uploadedAttachmentClass(asset)
|
||
}
|
||
}]
|
||
}]
|
||
},
|
||
{ type: 'paragraph' }
|
||
]).focus('end').run() === true;
|
||
if (inserted) {
|
||
document.documentElement.setAttribute('data-mnote-last-upload-inserted', 'true');
|
||
document.documentElement.setAttribute('data-mnote-last-upload-asset-id', assetId || '');
|
||
document.documentElement.removeAttribute('data-mnote-last-upload-insert-error');
|
||
} else {
|
||
document.documentElement.setAttribute('data-mnote-last-upload-inserted', 'false');
|
||
document.documentElement.setAttribute('data-mnote-last-upload-insert-error', 'insert_content_failed');
|
||
}
|
||
window.setTimeout(function annotateUploadedLink(attempt) {
|
||
if (targetRoot instanceof HTMLElement) window.__mnoteLastEditorUploadRoot = targetRoot;
|
||
enhanceEditorAttachmentLinks();
|
||
var selector = assetId
|
||
? '.editor-surface .ProseMirror a[href*="' + cssEscape(assetId) + '"]'
|
||
: '.editor-surface .ProseMirror a';
|
||
var link = targetRoot instanceof HTMLElement
|
||
? targetRoot.querySelector(selector)
|
||
: document.querySelector(selector);
|
||
if (!(link instanceof HTMLElement) && assetId) {
|
||
var scope = targetRoot instanceof HTMLElement ? targetRoot : document;
|
||
link = Array.from(scope.querySelectorAll('.editor-surface .ProseMirror a')).find(function(candidate) {
|
||
var href = String(candidate.getAttribute('href') || '');
|
||
try { href = decodeURIComponent(href); } catch (_) {}
|
||
return href.indexOf(assetId) >= 0;
|
||
}) || null;
|
||
}
|
||
if (link instanceof HTMLElement) {
|
||
if (assetId) link.setAttribute('data-asset-id', assetId);
|
||
if (sizeLabel) link.setAttribute('data-file-size', sizeLabel);
|
||
} else if (Number(attempt) < 20) {
|
||
window.setTimeout(function() { annotateUploadedLink(Number(attempt) + 1); }, 50);
|
||
}
|
||
}, 0, 0);
|
||
return inserted;
|
||
}
|
||
} catch (error) {
|
||
console.warn('[mnote upload] insert uploaded asset failed', error);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
async function uploadFileToMediaAsset(file, plan, options) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadFileToMediaAsset');
|
||
if (runtimeFn) {
|
||
return await runtimeFn(file, plan, options || {}, {
|
||
currentSourceKind: currentSourceKind,
|
||
currentRootUri: currentRootUri,
|
||
currentDocumentId: currentDocumentId,
|
||
editorRootFromUploadOptions: editorRootFromUploadOptions,
|
||
appendUploadedAssetRow: appendUploadedAssetRow,
|
||
refreshLocalFolderSidebarSnapshot: refreshLocalFolderSidebarSnapshot,
|
||
dispatchEvent: function(event) { return window.dispatchEvent(event); },
|
||
CustomEvent: CustomEvent,
|
||
buildOnlyOfficeAssetOpenUrl: buildOnlyOfficeAssetOpenUrl,
|
||
fetchCurrentOnlyOfficeUserId: fetchCurrentOnlyOfficeUserId,
|
||
buildOnlyOfficeOpenPath: buildOnlyOfficeOpenPath,
|
||
inferOnlyOfficeFileType: inferOnlyOfficeFileType,
|
||
enhanceEditorAttachmentLinks: enhanceEditorAttachmentLinks,
|
||
cssEscape: cssEscape
|
||
});
|
||
}
|
||
if (currentSourceKind() === 'local_folder') {
|
||
var rootUri = currentRootUri();
|
||
var documentId = String(plan && plan.targetDocumentId || currentDocumentId() || '').trim();
|
||
var hasFolderTarget = plan && Object.prototype.hasOwnProperty.call(plan, 'targetRelativePath');
|
||
var uploadIntent = String(plan && plan.uploadIntent || (hasFolderTarget ? 'filetree.folder.drop' : 'editor.markdown.attach')).trim();
|
||
if (!rootUri || !uploadIntent) {
|
||
throw new Error('本地 Markdown 上传缺少 rootUri 或 documentId');
|
||
}
|
||
var localUploadRuntime = localUploadRuntimeFunction('uploadLocalFolderAsset');
|
||
var localPayload = null;
|
||
if (localUploadRuntime) {
|
||
var localResult = await localUploadRuntime(file, plan, {
|
||
rootUri: rootUri,
|
||
documentId: documentId,
|
||
timeoutMs: 15000
|
||
});
|
||
localPayload = localResult && localResult.asset ? { asset: localResult.asset } : null;
|
||
} else {
|
||
var localForm = new FormData();
|
||
localForm.append('file', file);
|
||
localForm.append('rootUri', rootUri);
|
||
localForm.append('uploadIntent', uploadIntent);
|
||
if (documentId) localForm.append('documentId', documentId);
|
||
if (hasFolderTarget) localForm.append('targetRelativePath', String(plan.targetRelativePath || ''));
|
||
localForm.append('kind', file && String(file.type || '').indexOf('image/') === 0 ? 'image' : 'attachment');
|
||
var localResponse = await fetchWithTimeout('/api/local-folder/assets/upload', {
|
||
method: 'POST',
|
||
credentials: 'include',
|
||
body: localForm
|
||
}, 15000, '本地上传');
|
||
localPayload = await localResponse.json().catch(function() { return null; });
|
||
if (!localResponse.ok || !localPayload || !localPayload.asset) {
|
||
throw new Error(localPayload && localPayload.error ? localPayload.error : '上传失败');
|
||
}
|
||
}
|
||
if (options && options.insertIntoEditor) {
|
||
await insertUploadedAssetIntoEditor(localPayload.asset, editorRootFromUploadOptions(options));
|
||
}
|
||
if (!(options && options.insertIntoEditor)) void refreshLocalFolderSidebarSnapshot();
|
||
window.dispatchEvent(new CustomEvent('wolai:local-assets-changed', {
|
||
detail: { docId: documentId, asset: localPayload.asset, assetIds: [localPayload.asset.id] }
|
||
}));
|
||
return localPayload.asset;
|
||
}
|
||
var mediaUploadRuntime = localUploadRuntimeFunction('uploadMediaAsset');
|
||
var payload = null;
|
||
if (mediaUploadRuntime) {
|
||
var mediaResult = await mediaUploadRuntime(file, plan, { timeoutMs: 15000 });
|
||
payload = mediaResult && mediaResult.asset ? { asset: mediaResult.asset } : null;
|
||
if (!payload || !payload.asset) {
|
||
throw new Error('上传失败');
|
||
}
|
||
} else {
|
||
document.documentElement.setAttribute('data-mnote-media-upload-retired', 'true');
|
||
throw new Error('旧 Convex Files 上传链已退役;local-first 附件请使用本地文件夹上传目标。');
|
||
}
|
||
appendUploadedAssetRow(payload.asset, plan.targetDocumentId);
|
||
if (options && options.insertIntoEditor) {
|
||
await insertUploadedAssetIntoEditor(payload.asset, editorRootFromUploadOptions(options));
|
||
}
|
||
window.dispatchEvent(new CustomEvent('wolai:assets-changed', {
|
||
detail: { docId: plan.targetDocumentId, asset: payload.asset, assetIds: [payload.asset.id] }
|
||
}));
|
||
return payload.asset;
|
||
}
|
||
|
||
window.addEventListener('wolai:assets-changed', function(event) {
|
||
applyAssetsChangedToFileTree(event.detail || {});
|
||
});
|
||
window.addEventListener('wolai:local-assets-changed', function(event) {
|
||
applyAssetsChangedToFileTree(event.detail || {});
|
||
});
|
||
window.addEventListener('mnote:knowledge-rag-source-updated', function() {
|
||
if (currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();
|
||
});
|
||
installMindmapAssetFetchObserver();
|
||
|
||
async function uploadFilesWithResolvedTarget(files, detail, options) {
|
||
var runtimeFn = localUploadRuntimeFunction('uploadFilesWithResolvedTarget');
|
||
if (runtimeFn) {
|
||
return await runtimeFn(files, detail || {}, options || {}, {
|
||
resolveFileTreeUploadTarget: resolveFileTreeUploadTarget,
|
||
uploadFileToMediaAsset: uploadFileToMediaAsset,
|
||
alert: function(message) { window.alert(message); }
|
||
});
|
||
}
|
||
var list = Array.from(files || []).filter(Boolean);
|
||
if (!list.length) return [];
|
||
var plan = await resolveFileTreeUploadTarget(detail || {});
|
||
var uploaded = [];
|
||
var errors = [];
|
||
for (var i = 0; i < list.length; i += 1) {
|
||
try {
|
||
uploaded.push(await uploadFileToMediaAsset(list[i], plan, options || {}));
|
||
} catch (error) {
|
||
errors.push(list[i].name + ': ' + (error && error.message ? error.message : '上传失败'));
|
||
}
|
||
}
|
||
if (errors.length) {
|
||
window.alert('部分文件上传失败:\n' + errors.slice(0, 6).join('\n') + (errors.length > 6 ? '\n...' : ''));
|
||
}
|
||
return uploaded;
|
||
}
|
||
|
||
function openEditorUploadFilePicker(detail) {
|
||
var runtimeFn = localUploadRuntimeFunction('openEditorUploadFilePicker');
|
||
if (runtimeFn) {
|
||
return runtimeFn(detail || {}, {
|
||
rootSelector: EDITOR_UPLOAD_ROOT_SELECTOR,
|
||
editorUploadRootFromElement: editorUploadRootFromElement,
|
||
currentDocumentId: currentDocumentId,
|
||
resolveWorkspaceId: resolveWorkspaceId,
|
||
uploadFilesWithResolvedTarget: uploadFilesWithResolvedTarget
|
||
});
|
||
}
|
||
var uploadContext = resolveEditorUploadContext(detail || {});
|
||
var input = document.createElement('input');
|
||
input.type = 'file';
|
||
input.multiple = detail && detail.multiple !== false;
|
||
if (detail && detail.accept) input.accept = String(detail.accept);
|
||
input.style.position = 'fixed';
|
||
input.style.left = '-9999px';
|
||
input.style.top = '-9999px';
|
||
document.body.appendChild(input);
|
||
input.addEventListener('change', function() {
|
||
var files = Array.from(input.files || []);
|
||
input.remove();
|
||
void uploadFilesWithResolvedTarget(files, {
|
||
workspaceId: uploadContext.workspaceId || resolveWorkspaceId(document.body),
|
||
documentId: uploadContext.documentId || currentDocumentId(),
|
||
targetRowId: null,
|
||
uploadIntent: 'editor.markdown.attach'
|
||
}, {
|
||
insertIntoEditor: detail && detail.insertIntoEditor !== false,
|
||
editorRoot: uploadContext.root
|
||
});
|
||
}, { once: true });
|
||
input.click();
|
||
}
|
||
|
||
window.addEventListener('mnote:editor-upload-request', function(event) {
|
||
openEditorUploadFilePicker(event.detail || {});
|
||
});
|
||
|
||
window.addEventListener('tree.filetree.external-drop', function(event) {
|
||
var detail = event.detail || {};
|
||
void uploadFilesWithResolvedTarget(detail.files || [], detail, {
|
||
insertIntoEditor: String(detail.documentId || '') === currentDocumentId()
|
||
});
|
||
});
|
||
|
||
document.addEventListener('dragover', function(event) {
|
||
var editorTarget = closestAction(event.target, '[data-testid="mnote-leptos-tiptap-editor-stage"], .editor-surface .ProseMirror');
|
||
var hasFiles = event.dataTransfer && Array.prototype.indexOf.call(event.dataTransfer.types || [], 'Files') >= 0;
|
||
if (!editorTarget || !hasFiles) return;
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';
|
||
}, true);
|
||
|
||
document.addEventListener('drop', function(event) {
|
||
var editorTarget = closestAction(event.target, '[data-testid="mnote-leptos-tiptap-editor-stage"], .editor-surface .ProseMirror');
|
||
var files = event.dataTransfer ? Array.from(event.dataTransfer.files || []) : [];
|
||
if (!editorTarget || !files.length) return;
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
void uploadFilesWithResolvedTarget(files, {
|
||
workspaceId: resolveWorkspaceId(document.body),
|
||
documentId: currentDocumentId(),
|
||
targetRowId: null,
|
||
uploadIntent: 'editor.markdown.attach'
|
||
}, {
|
||
insertIntoEditor: true,
|
||
editorRoot: editorUploadRootFromElement(editorTarget)
|
||
});
|
||
}, true);
|
||
|
||
const sidebarFileTreeCommandState = {
|
||
get activeTreeContextMenu() { return activeTreeContextMenu; },
|
||
set activeTreeContextMenu(value) { activeTreeContextMenu = value; },
|
||
get sidebarFileTreeClipboard() { return sidebarFileTreeClipboard; },
|
||
set sidebarFileTreeClipboard(value) { sidebarFileTreeClipboard = value; },
|
||
};
|
||
const sidebarFileTreeCommand = createSidebarFileTreeCommandRuntime({
|
||
applyRemoveDocumentDelta,
|
||
createFileTreeFolder,
|
||
createPage,
|
||
cssEscape,
|
||
currentDocumentId,
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
deleteSingleFileTreeAsset,
|
||
dispatchSidebarEvent,
|
||
dispatchTreeCommand,
|
||
ensureFileTreeWritableTarget,
|
||
fileTreeRuntimeDeps,
|
||
fileTreeRuntimeFunction,
|
||
fileTreeSelectionRuntimeDeps,
|
||
fileTreeSelectionRuntimeFunction,
|
||
isFileTreePageRow,
|
||
localFilePathFromAssetId,
|
||
normalizeFileTreePageRenameTitle,
|
||
openConvexAssetFromFileTree,
|
||
openEditorAttachmentDetail: (...args) => openEditorAttachmentDetail(...args),
|
||
openEditorAttachmentDownload: (...args) => openEditorAttachmentDownload(...args),
|
||
openEditorAttachmentEditTab: (...args) => openEditorAttachmentEditTab(...args),
|
||
openEditorAttachmentNewWindow: (...args) => openEditorAttachmentNewWindow(...args),
|
||
openLocalResourceInActiveTab: (...args) => openLocalResourceInActiveTab(...args),
|
||
refreshLocalFolderSidebarSnapshot,
|
||
removeFileTreeAssetRow,
|
||
revealFileTreeResource,
|
||
resolveWorkspaceId,
|
||
runtimeState: sidebarFileTreeCommandState,
|
||
selectedSidebarFileTreeSelection: sidebarFileTreeSelection,
|
||
updateTitleEverywhere,
|
||
validateFileTreeRename,
|
||
});
|
||
const rowTitle = (...args) => sidebarFileTreeCommand.rowTitle(...args);
|
||
const rowCenter = (...args) => sidebarFileTreeCommand.rowCenter(...args);
|
||
const renameFileTreeAsset = (...args) => sidebarFileTreeCommand.renameFileTreeAsset(...args);
|
||
const beginFileTreeInlineRename = (...args) => sidebarFileTreeCommand.beginFileTreeInlineRename(...args);
|
||
const closeTreeContextMenu = (...args) => sidebarFileTreeCommand.closeTreeContextMenu(...args);
|
||
const copyTreeContextValue = (...args) => sidebarFileTreeCommand.copyTreeContextValue(...args);
|
||
const triggerBrowserDownload = (...args) => sidebarFileTreeCommand.triggerBrowserDownload(...args);
|
||
const recordFileTreeAction = (...args) => sidebarFileTreeCommand.recordFileTreeAction(...args);
|
||
const recordFileTreeActionStatus = (...args) => sidebarFileTreeCommand.recordFileTreeActionStatus(...args);
|
||
const documentHref = (...args) => sidebarFileTreeCommand.documentHref(...args);
|
||
const convertToPreviousSiblingChild = (...args) => sidebarFileTreeCommand.convertToPreviousSiblingChild(...args);
|
||
const fileTreeCopyPath = (...args) => sidebarFileTreeCommand.fileTreeCopyPath(...args);
|
||
const fileTreeMenuTargetParentId = (...args) => sidebarFileTreeCommand.fileTreeMenuTargetParentId(...args);
|
||
const withOfficeEditModeGuard = (...args) => sidebarFileTreeCommand.withOfficeEditModeGuard(...args);
|
||
const handleTreeContextMenuAction = (...args) => sidebarFileTreeCommand.handleTreeContextMenuAction(...args);
|
||
const appendTreeContextMenuButton = (...args) => sidebarFileTreeCommand.appendTreeContextMenuButton(...args);
|
||
const buildSidebarFileTreeContext = (...args) => sidebarFileTreeCommand.buildSidebarFileTreeContext(...args);
|
||
const evaluateSidebarFileTreeWhen = (...args) => sidebarFileTreeCommand.evaluateSidebarFileTreeWhen(...args);
|
||
const openTreeContextMenu = (...args) => sidebarFileTreeCommand.openTreeContextMenu(...args);
|
||
const openPageTreeContextMenu = (...args) => sidebarFileTreeCommand.openPageTreeContextMenu(...args);
|
||
const openFileTreeContextMenu = (...args) => sidebarFileTreeCommand.openFileTreeContextMenu(...args);
|
||
const visibleFileTreeRows = (...args) => sidebarFileTreeCommand.visibleFileTreeRows(...args);
|
||
const syncSidebarFileTreeSelection = (...args) => sidebarFileTreeCommand.syncSidebarFileTreeSelection(...args);
|
||
const selectSidebarFileTreeRow = (...args) => sidebarFileTreeCommand.selectSidebarFileTreeRow(...args);
|
||
const selectSidebarFileTreeDocument = (...args) => sidebarFileTreeCommand.selectSidebarFileTreeDocument(...args);
|
||
const selectSidebarFileTreeRowById = (...args) => sidebarFileTreeCommand.selectSidebarFileTreeRowById(...args);
|
||
const pendingLocalFolderRestoreRowId = (...args) => sidebarFileTreeCommand.pendingLocalFolderRestoreRowId(...args);
|
||
const clearPendingLocalFolderRestoreRowId = (...args) => sidebarFileTreeCommand.clearPendingLocalFolderRestoreRowId(...args);
|
||
const applyPendingLocalFolderRestoreFocusOnce = (...args) => sidebarFileTreeCommand.applyPendingLocalFolderRestoreFocusOnce(...args);
|
||
const schedulePendingLocalFolderRestoreFocus = (...args) => sidebarFileTreeCommand.schedulePendingLocalFolderRestoreFocus(...args);
|
||
const selectedSidebarFileTreeRowIdsForDrag = (...args) => sidebarFileTreeCommand.selectedSidebarFileTreeRowIdsForDrag(...args);
|
||
const selectedSidebarFileTreeRows = (...args) => sidebarFileTreeCommand.selectedSidebarFileTreeRows(...args);
|
||
const fileTreeRowDocumentId = (...args) => sidebarFileTreeCommand.fileTreeRowDocumentId(...args);
|
||
const fileTreeRowAssetId = (...args) => sidebarFileTreeCommand.fileTreeRowAssetId(...args);
|
||
const decodeLocalEncodedPath = (...args) => sidebarFileTreeCommand.decodeLocalEncodedPath(...args);
|
||
const fileTreeRowLocalRelativePath = (...args) => sidebarFileTreeCommand.fileTreeRowLocalRelativePath(...args);
|
||
const fileTreeRowLocalUploadTargetRelativePath = (...args) => sidebarFileTreeCommand.fileTreeRowLocalUploadTargetRelativePath(...args);
|
||
const readWorkspacePathFromRow = (...args) => sidebarFileTreeCommand.readWorkspacePathFromRow(...args);
|
||
const fileTreeRowKind = (...args) => sidebarFileTreeCommand.fileTreeRowKind(...args);
|
||
const isFileTreeDownloadableAssetRow = (...args) => sidebarFileTreeCommand.isFileTreeDownloadableAssetRow(...args);
|
||
const isFileTreeDownloadableRow = (...args) => sidebarFileTreeCommand.isFileTreeDownloadableRow(...args);
|
||
const fileTreeAssetDownloadDetail = (...args) => sidebarFileTreeCommand.fileTreeAssetDownloadDetail(...args);
|
||
const selectedSidebarFileTreeRowsForDownload = (...args) => sidebarFileTreeCommand.selectedSidebarFileTreeRowsForDownload(...args);
|
||
const selectedSidebarFileTreeAssetRowsForDownload = (...args) => sidebarFileTreeCommand.selectedSidebarFileTreeAssetRowsForDownload(...args);
|
||
const downloadSelectedFileTreeAssetRows = (...args) => sidebarFileTreeCommand.downloadSelectedFileTreeAssetRows(...args);
|
||
const hasSelectedDocumentAncestor = (...args) => sidebarFileTreeCommand.hasSelectedDocumentAncestor(...args);
|
||
const classifySidebarFileTreeAsset = (...args) => sidebarFileTreeCommand.classifySidebarFileTreeAsset(...args);
|
||
const buildSidebarFileTreeDeletePlan = (...args) => sidebarFileTreeCommand.buildSidebarFileTreeDeletePlan(...args);
|
||
const sidebarFileTreeDeleteConfirmText = (...args) => sidebarFileTreeCommand.sidebarFileTreeDeleteConfirmText(...args);
|
||
const postSidebarFileTreeJson = (...args) => sidebarFileTreeCommand.postSidebarFileTreeJson(...args);
|
||
const fileTreeRowsByRowIds = (...args) => sidebarFileTreeCommand.fileTreeRowsByRowIds(...args);
|
||
const fileTreeChildCount = (...args) => sidebarFileTreeCommand.fileTreeChildCount(...args);
|
||
const moveSidebarFileTreeRows = (...args) => sidebarFileTreeCommand.moveSidebarFileTreeRows(...args);
|
||
const pasteSidebarFileTreeClipboard = (...args) => sidebarFileTreeCommand.pasteSidebarFileTreeClipboard(...args);
|
||
const deleteSelectedSidebarFileTreeRows = (...args) => sidebarFileTreeCommand.deleteSelectedSidebarFileTreeRows(...args);
|
||
|
||
sidebarFileTreeUpload = createSidebarFileTreeUploadRuntime({
|
||
cssEscape,
|
||
currentDocumentId,
|
||
fileTreeRuntimeDeps,
|
||
fileTreeRuntimeFunction,
|
||
recordFileTreeAction,
|
||
recordFileTreeActionStatus,
|
||
resolveWorkspaceId,
|
||
rowTitle,
|
||
selectedSidebarFileTreeSelection: sidebarFileTreeSelection,
|
||
});
|
||
|
||
function ensureSearchModal() {
|
||
var existing = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
if (existing instanceof HTMLElement) return existing;
|
||
|
||
var overlay = document.createElement('div');
|
||
overlay.className = 'wolai-search-overlay';
|
||
overlay.setAttribute('data-testid', 'wolai-search-modal');
|
||
overlay.setAttribute('role', 'dialog');
|
||
overlay.setAttribute('aria-modal', 'true');
|
||
overlay.hidden = true;
|
||
|
||
overlay.innerHTML = '' +
|
||
'<div class="wolai-search-dialog">' +
|
||
'<div class="wolai-search-input-row">' +
|
||
'<span class="material-symbols-outlined wolai-search-input-icon" data-icon="search" aria-hidden="true"></span>' +
|
||
'<input data-testid="wolai-search-input" class="wolai-search-input" type="search" autocomplete="off" placeholder="在当前工作区中搜索" />' +
|
||
'<button type="button" class="wolai-search-close" data-testid="wolai-search-close" aria-label="关闭搜索">×</button>' +
|
||
'</div>' +
|
||
'<div class="wolai-search-options" data-testid="wolai-search-options" aria-label="搜索选项" hidden>' +
|
||
'<div class="wolai-search-options-left">' +
|
||
'<span class="wolai-search-switch-control"><span>仅匹配标题</span><button type="button" class="wolai-search-switch" data-search-switch="title" role="switch" aria-checked="false" aria-label="仅匹配标题"></button></span>' +
|
||
'<span class="wolai-search-switch-control"><span>精确匹配</span><button type="button" class="wolai-search-switch" data-search-switch="exact" role="switch" aria-checked="false" aria-label="精确匹配"></button></span>' +
|
||
'<span class="wolai-search-sort-control"><span>资料库模式</span><select class="wolai-search-sort-value" data-search-knowledge-mode aria-label="资料库检索模式"><option value="mix">综合</option><option value="hybrid">图谱混合</option><option value="naive">向量</option><option value="local">实体</option><option value="global">关系</option><option value="exact">关键词</option></select></span>' +
|
||
'<span class="wolai-search-sort-control"><span>按编辑时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="updated" aria-label="按编辑时间范围">所有</button></span>' +
|
||
'<span class="wolai-search-sort-control"><span>按创建时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="created" aria-label="按创建时间范围">所有</button></span>' +
|
||
'</div>' +
|
||
'<div class="wolai-search-options-right">' +
|
||
'<span class="wolai-search-switch-control"><span>全盘资料库</span><button type="button" class="wolai-search-switch" data-search-switch="knowledge" role="switch" aria-checked="false" aria-label="全盘资料库检索"></button></span>' +
|
||
'<span class="wolai-search-switch-control"><span>页面内搜索</span><button type="button" class="wolai-search-switch" data-search-switch="page" role="switch" aria-checked="false" aria-label="页面内搜索"></button></span>' +
|
||
'<span class="wolai-search-switch-control"><span>折叠同来源</span><button type="button" class="wolai-search-switch is-on" data-search-switch="collapseSource" role="switch" aria-checked="true" aria-label="默认折叠相同来源结果"></button></span>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div class="wolai-search-result-meta" data-testid="wolai-search-result-meta"></div>' +
|
||
'<div class="wolai-search-results" data-testid="wolai-search-results" data-search-results-owner="rust-kernel"></div>' +
|
||
'</div>';
|
||
|
||
document.body.appendChild(overlay);
|
||
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
|
||
var closeButton = overlay.querySelector('[data-testid="wolai-search-close"]');
|
||
applySearchSwitchState(overlay, { collapseSource: readSearchCollapseSourcesDefault() });
|
||
if (input) input.addEventListener('input', function() {
|
||
searchUiState.hasRendered = false;
|
||
scheduleSearchResultsRender();
|
||
});
|
||
overlay.querySelectorAll('[data-search-switch]').forEach(function(button) {
|
||
button.addEventListener('click', function() {
|
||
var switchName = searchText(button.getAttribute('data-search-switch'));
|
||
var isOn = button.getAttribute('aria-checked') !== 'true';
|
||
button.setAttribute('aria-checked', isOn ? 'true' : 'false');
|
||
button.classList.toggle('is-on', isOn);
|
||
if (switchName === 'collapseSource') {
|
||
writeSearchCollapseSourcesDefault(isOn);
|
||
searchUiState.sourceCollapsed = {};
|
||
}
|
||
searchUiState.hasRendered = false;
|
||
scheduleSearchResultsRender();
|
||
});
|
||
});
|
||
var knowledgeModeSelect = overlay.querySelector('[data-search-knowledge-mode]');
|
||
if (knowledgeModeSelect) {
|
||
knowledgeModeSelect.addEventListener('change', function() {
|
||
searchUiState.hasRendered = false;
|
||
scheduleSearchResultsRender();
|
||
});
|
||
}
|
||
if (closeButton) closeButton.addEventListener('click', closeSearchModal);
|
||
overlay.addEventListener('click', function(event) {
|
||
if (event.target === overlay) closeSearchModal();
|
||
});
|
||
return overlay;
|
||
}
|
||
|
||
var activeSearchRequestId = 0;
|
||
var searchRenderTimer = 0;
|
||
var SEARCH_COLLAPSE_SOURCES_KEY = 'mnote.search.collapseSourcesDefault.v1';
|
||
var searchUiState = {
|
||
query: '',
|
||
switches: {},
|
||
metaHtml: '',
|
||
resultsHtml: '',
|
||
items: [],
|
||
knowledgeMode: 'mix',
|
||
sourceCollapsed: {},
|
||
scrollTop: 0,
|
||
signature: '',
|
||
hasRendered: false
|
||
};
|
||
|
||
function searchText(value) {
|
||
return String(value == null ? '' : value).replace(/\s+/g, ' ').trim();
|
||
}
|
||
|
||
function searchNonWhitespaceCharCount(value) {
|
||
return String(value == null ? '' : value).replace(/\s+/g, '').length;
|
||
}
|
||
|
||
function currentWorkspaceName() {
|
||
var name = document.querySelector('.sidebar-workspace-name');
|
||
return searchText(name && name.textContent) || '当前工作区';
|
||
}
|
||
|
||
function currentDocumentId() {
|
||
var shell = document.querySelector('.document-shell[data-document-id]');
|
||
var bodyId = document.body && document.body.getAttribute('data-document-id');
|
||
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 searchKnowledgeModeValue(overlay) {
|
||
var select = overlay.querySelector('[data-search-knowledge-mode]');
|
||
var value = select && 'value' in select ? searchText(select.value).toLowerCase() : '';
|
||
if (['mix', 'hybrid', 'naive', 'local', 'global', 'exact'].indexOf(value) >= 0) return value;
|
||
return 'mix';
|
||
}
|
||
|
||
function knowledgeSearchRequestMode(overlay) {
|
||
if (searchSwitchValue(overlay, 'exact')) return 'exact';
|
||
return searchKnowledgeModeValue(overlay);
|
||
}
|
||
|
||
function knowledgeSearchModeLabel(mode) {
|
||
if (mode === 'exact') return '关键词';
|
||
if (mode === 'naive') return '向量';
|
||
if (mode === 'local') return '实体';
|
||
if (mode === 'global') return '关系';
|
||
if (mode === 'hybrid') return '图谱混合';
|
||
return '综合';
|
||
}
|
||
|
||
function readSearchCollapseSourcesDefault() {
|
||
try {
|
||
var stored = window.localStorage && window.localStorage.getItem(SEARCH_COLLAPSE_SOURCES_KEY);
|
||
if (stored === '0') return false;
|
||
if (stored === '1') return true;
|
||
} catch (_) {}
|
||
return true;
|
||
}
|
||
|
||
function writeSearchCollapseSourcesDefault(value) {
|
||
try {
|
||
if (window.localStorage) window.localStorage.setItem(SEARCH_COLLAPSE_SOURCES_KEY, value ? '1' : '0');
|
||
} catch (_) {}
|
||
}
|
||
|
||
function collectSearchSwitchState(overlay) {
|
||
var state = {};
|
||
if (!(overlay instanceof HTMLElement)) return state;
|
||
overlay.querySelectorAll('[data-search-switch]').forEach(function(button) {
|
||
if (!(button instanceof HTMLElement)) return;
|
||
var name = searchText(button.getAttribute('data-search-switch'));
|
||
if (!name) return;
|
||
state[name] = button.getAttribute('aria-checked') === 'true';
|
||
});
|
||
return state;
|
||
}
|
||
|
||
function applySearchSwitchState(overlay, switches) {
|
||
if (!(overlay instanceof HTMLElement) || !switches || typeof switches !== 'object') return;
|
||
overlay.querySelectorAll('[data-search-switch]').forEach(function(button) {
|
||
if (!(button instanceof HTMLElement)) return;
|
||
var name = searchText(button.getAttribute('data-search-switch'));
|
||
if (!name || !Object.prototype.hasOwnProperty.call(switches, name)) return;
|
||
var isOn = Boolean(switches[name]);
|
||
button.setAttribute('aria-checked', isOn ? 'true' : 'false');
|
||
button.classList.toggle('is-on', isOn);
|
||
});
|
||
}
|
||
|
||
function searchRequestSignature(overlay, query) {
|
||
var switches = collectSearchSwitchState(overlay);
|
||
return JSON.stringify({
|
||
query: searchText(query),
|
||
knowledge: Boolean(switches.knowledge),
|
||
page: Boolean(switches.page),
|
||
title: Boolean(switches.title),
|
||
exact: Boolean(switches.exact),
|
||
collapseSource: Boolean(switches.collapseSource),
|
||
knowledgeMode: searchKnowledgeModeValue(overlay),
|
||
workspaceId: resolveWorkspaceId(document.body) || '',
|
||
rootUri: currentRootUri() || ''
|
||
});
|
||
}
|
||
|
||
function saveSearchUiState(overlay) {
|
||
if (!(overlay instanceof HTMLElement)) return;
|
||
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
|
||
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
|
||
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
|
||
var query = input && 'value' in input ? searchText(input.value) : searchUiState.query;
|
||
searchUiState.query = query;
|
||
searchUiState.switches = collectSearchSwitchState(overlay);
|
||
searchUiState.knowledgeMode = searchKnowledgeModeValue(overlay);
|
||
searchUiState.metaHtml = meta ? meta.innerHTML : searchUiState.metaHtml;
|
||
searchUiState.resultsHtml = results ? results.innerHTML : searchUiState.resultsHtml;
|
||
searchUiState.items = Array.isArray(window.__mnoteSearchResults) ? window.__mnoteSearchResults.slice() : searchUiState.items;
|
||
searchUiState.scrollTop = results instanceof HTMLElement ? results.scrollTop : searchUiState.scrollTop;
|
||
searchUiState.signature = query ? searchRequestSignature(overlay, query) : '';
|
||
}
|
||
|
||
function restoreSearchUiState(overlay) {
|
||
if (!(overlay instanceof HTMLElement) || !searchUiState.hasRendered) return false;
|
||
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
|
||
var options = overlay.querySelector('[data-testid="wolai-search-options"]');
|
||
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
|
||
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
|
||
if (input && 'value' in input) input.value = searchUiState.query || '';
|
||
applySearchSwitchState(overlay, searchUiState.switches);
|
||
var knowledgeModeSelect = overlay.querySelector('[data-search-knowledge-mode]');
|
||
if (knowledgeModeSelect && 'value' in knowledgeModeSelect) knowledgeModeSelect.value = searchUiState.knowledgeMode || 'mix';
|
||
if (options instanceof HTMLElement) options.hidden = !searchText(searchUiState.query);
|
||
if (meta && searchUiState.metaHtml) meta.innerHTML = searchUiState.metaHtml;
|
||
if (results && searchUiState.resultsHtml) {
|
||
results.innerHTML = searchUiState.resultsHtml;
|
||
results.scrollTop = Number(searchUiState.scrollTop || 0);
|
||
}
|
||
window.__mnoteSearchResults = Array.isArray(searchUiState.items) ? searchUiState.items.slice() : [];
|
||
return true;
|
||
}
|
||
|
||
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);
|
||
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));
|
||
}
|
||
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);
|
||
}
|
||
});
|
||
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 cleanSearchDisplayText(value) {
|
||
var text = String(value == null ? '' : value);
|
||
text = text.replace(/<drawing\b[^>]*\/?>/gi, ' ');
|
||
text = text.replace(/<equation\b[^>]*>([\s\S]*?)<\/equation>/gi, '$1');
|
||
text = text.replace(/<drawing\b[^<>]*$/gi, ' ');
|
||
text = text.replace(/<\/?equat[^<>]*$/gi, ' ');
|
||
text = text.replace(/<\/?e(?:q(?:uation)?)?[^<>]*$/gi, ' ');
|
||
text = text.replace(/<[^>]+>/g, ' ');
|
||
text = text
|
||
.replace(/\b(?:equation|latex|drawing)\b(?:\s+[a-z_-]+=(?:"[^"]*"|'[^']*'|[^\s<>]+))*/gi, ' ')
|
||
.replace(/\\left|\\right|\\mathrm|\\text|\\operatorname/g, '')
|
||
.replace(/\\gt/g, '>')
|
||
.replace(/\\lt/g, '<')
|
||
.replace(/\\sim/g, '∼')
|
||
.replace(/\\[a-zA-Z]+/g, ' ')
|
||
.replace(/\{([^{}]*)\}/g, '$1')
|
||
.replace(/\{([^{}]*)\}/g, '$1')
|
||
.replace(/[_^]/g, '')
|
||
.replace(/[<>]\/?(?:equation|eq)\b[^<>]*>?/gi, ' ')
|
||
.replace(/<\/?e(?:q(?:uation)?)?[^<>\s]*>?/gi, ' ')
|
||
.replace(/\s+(?:equation|latex|drawing)\s+/gi, ' ');
|
||
return searchText(text);
|
||
}
|
||
|
||
function searchResultEvidenceLocator(item) {
|
||
if (item && item.locator && typeof item.locator === 'object') return item.locator;
|
||
if (item && item.evidence && item.evidence.source && typeof item.evidence.source === 'object') return item.evidence.source;
|
||
if (item && item.source && item.source.locator && typeof item.source.locator === 'object') return item.source.locator;
|
||
if (item && Array.isArray(item.evidence) && item.evidence[0] && item.evidence[0].source && typeof item.evidence[0].source === 'object') return item.evidence[0].source;
|
||
return null;
|
||
}
|
||
|
||
function searchResultSourceKey(item) {
|
||
var locator = searchResultEvidenceLocator(item);
|
||
var locatorPath = locator ? searchText(locator.resourcePath || locator.resource_path || locator.ownerDocumentPath || locator.owner_document_path) : '';
|
||
return locatorPath || searchText(item && (item.path || item.documentId || item.nodeId || item.id)) || 'unknown-source';
|
||
}
|
||
|
||
function searchResultSourceTitle(item) {
|
||
var key = searchResultSourceKey(item);
|
||
var locator = searchResultEvidenceLocator(item);
|
||
var path = locator ? searchText(locator.resourcePath || locator.resource_path || locator.ownerDocumentPath || locator.owner_document_path) : '';
|
||
var sourcePath = path || searchText(item && item.path) || key;
|
||
var title = searchText(item && (item.title || item.name || item.documentTitle));
|
||
return title || sourcePath.split('/').filter(Boolean).pop() || sourcePath || '未知来源';
|
||
}
|
||
|
||
function renderSearchResultButton(item, index, query, exact, grouped) {
|
||
var title = searchText(item.title || item.name || item.documentTitle || '无标题');
|
||
var snippet = searchText(item.displayQuote || item.snippet || item.evidence && item.evidence.displayQuote || item.evidence && item.evidence.quote || (Array.isArray(item.evidence) && item.evidence[0] && (item.evidence[0].displayQuote || item.evidence[0].quote || item.evidence[0].snippet)) || '');
|
||
if (!item.displayQuote) snippet = cleanSearchDisplayText(snippet);
|
||
var path = searchText(item.path || item.parentTitle || item.workspaceName || currentWorkspaceName());
|
||
var resourceType = searchText(item.resourceType || item.resourceKind || 'page');
|
||
var locator = searchResultEvidenceLocator(item);
|
||
var locatorAttr = locator ? escapeHtml(JSON.stringify(locator)) : '';
|
||
var highlightTerms = searchHighlightTerms(item, query);
|
||
var titleHtml = grouped && snippet ? '' : '<span class="wolai-search-result-title">' + highlightSearchText(title, query, exact, highlightTerms) + '</span>';
|
||
var page = locator && locator.page != null && locator.page !== '' ? String(locator.page) : '';
|
||
var metaParts = grouped ? [] : [escapeHtml(path)];
|
||
if (page) metaParts.push('第 ' + escapeHtml(page) + ' 页');
|
||
if (!grouped) metaParts.push('<span class="wolai-search-result-type">' + escapeHtml(resourceType) + '</span>');
|
||
var metaHtml = metaParts.length ? '<span class="wolai-search-result-path"><span>' + metaParts.join('</span><span>') + '</span></span>' : '';
|
||
return '<button type="button" class="wolai-search-result-row" data-testid="wolai-search-result-row" data-search-result-owner="' + escapeHtml(item.provider || '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">' + titleHtml +
|
||
'<span class="wolai-search-result-snippet">' + (snippet ? highlightSearchText(snippet, query, exact, highlightTerms) : escapeHtml(path)) + '</span>' +
|
||
metaHtml + '</span>' +
|
||
'</button>';
|
||
}
|
||
|
||
function renderSearchResultsHtml(items, overlay, query) {
|
||
var exact = searchSwitchValue(overlay, 'exact');
|
||
if (!searchSwitchValue(overlay, 'collapseSource')) {
|
||
return items.map(function(item, index) {
|
||
return renderSearchResultButton(item, index, query, exact, false);
|
||
}).join('');
|
||
}
|
||
var groups = [];
|
||
var groupByKey = {};
|
||
items.forEach(function(item, index) {
|
||
var key = searchResultSourceKey(item);
|
||
var group = groupByKey[key];
|
||
if (!group) {
|
||
group = { key: key, title: searchResultSourceTitle(item), path: searchText(item.path || key), resourceType: searchText(item.resourceType || item.resourceKind || 'page'), rows: [] };
|
||
groupByKey[key] = group;
|
||
groups.push(group);
|
||
}
|
||
group.rows.push({ item: item, index: index });
|
||
});
|
||
return groups.map(function(group) {
|
||
var collapsed = Object.prototype.hasOwnProperty.call(searchUiState.sourceCollapsed, group.key)
|
||
? searchUiState.sourceCollapsed[group.key]
|
||
: true;
|
||
var children = group.rows.map(function(row) {
|
||
return renderSearchResultButton(row.item, row.index, query, exact, true);
|
||
}).join('');
|
||
return '<section class="wolai-search-source-group" data-search-source-key="' + escapeHtml(group.key) + '">' +
|
||
'<button type="button" class="wolai-search-source-header" data-search-source-toggle="true" aria-expanded="' + (collapsed ? 'false' : 'true') + '">' +
|
||
'<span class="material-symbols-outlined wolai-search-result-icon" data-icon="article" aria-hidden="true"></span>' +
|
||
'<span class="wolai-search-source-main"><span class="wolai-search-result-title">' + escapeHtml(group.title) + '</span>' +
|
||
'<span class="wolai-search-result-path"><span class="wolai-search-result-type">' + escapeHtml(group.resourceType) + '</span><span>' + String(group.rows.length) + ' 处</span></span></span>' +
|
||
'<span class="wolai-search-source-chevron" aria-hidden="true">' + (collapsed ? '展开' : '收起') + '</span>' +
|
||
'</button>' +
|
||
'<div class="wolai-search-source-results" data-search-source-results="true"' + (collapsed ? ' hidden' : '') + '>' + children + '</div>' +
|
||
'</section>';
|
||
}).join('');
|
||
}
|
||
|
||
function evidenceLocatorResourceKind(locator, fallback) {
|
||
return searchText(locator && (locator.resourceKind || locator.resource_kind) || fallback || '').toLowerCase();
|
||
}
|
||
|
||
function evidenceLocatorBbox(locator) {
|
||
var bbox = locator && locator.bbox;
|
||
if (Array.isArray(bbox)) return bbox.slice(0, 4).join(',');
|
||
if (bbox && typeof bbox === 'object') return [bbox.x0, bbox.y0, bbox.x1, bbox.y1].join(',');
|
||
return '';
|
||
}
|
||
|
||
function evidenceLocatorOpenUrl(locator) {
|
||
var action = locator && locator.openAction && typeof locator.openAction === 'object' ? locator.openAction : null;
|
||
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) {
|
||
var citationUrl = searchText(item && (item.citationUrl || item.publicPath));
|
||
if (citationUrl) {
|
||
closeSearchModal();
|
||
window.location.assign(citationUrl);
|
||
return;
|
||
}
|
||
var fallbackId = searchText(item && (item.documentId || item.nodeId || item.id));
|
||
if (fallbackId) window.location.assign('/documents/' + encodeURIComponent(fallbackId));
|
||
return;
|
||
}
|
||
var resourcePath = searchText(locator.resourcePath || locator.resource_path || locator.ownerDocumentPath || locator.owner_document_path);
|
||
var ownerDocumentId = searchText(locator.ownerDocumentId || locator.owner_document_id || item.documentId || '');
|
||
var resourceKind = evidenceLocatorResourceKind(locator, item && item.resourceType);
|
||
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
var searchInput = overlay instanceof HTMLElement ? overlay.querySelector('[data-testid="wolai-search-input"]') : null;
|
||
var searchQueryText = searchText(item && (item.searchQuery || item.query) || locator && locator.openAction && locator.openAction.params && locator.openAction.params.searchQuery)
|
||
|| searchText(searchInput && 'value' in searchInput ? searchInput.value : '')
|
||
|| searchText(searchUiState.query);
|
||
var locatorEvidenceText = searchText(item && item.locatorEvidenceText || locator.evidenceText || locator.query || locator.openAction && locator.openAction.params && (locator.openAction.params.evidenceText || locator.openAction.params.query) || '');
|
||
var locatorParams = locator && locator.openAction && locator.openAction.params && typeof locator.openAction.params === 'object' ? locator.openAction.params : {};
|
||
var openTarget = event && event.altKey ? 'side' : 'active-tab';
|
||
if (resourcePath && resourceKind) {
|
||
var fileName = resourcePath.split('/').filter(Boolean).pop() || resourcePath;
|
||
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: normalizedKind,
|
||
href: href,
|
||
officeUrl: normalizedKind === 'office' ? href : '',
|
||
assetId: 'local-file:' + resourcePath,
|
||
documentId: hostDocumentId,
|
||
ownerDocumentId: ownerDocumentId || hostDocumentId,
|
||
workspaceId: resolveWorkspaceId(document.body) || '',
|
||
sourceKind: currentSourceKind() || 'local_folder',
|
||
rootUri: searchText(locator.rootUri || locator.root_uri || currentRootUri()),
|
||
paneRole: openTarget === 'side' ? 'secondary' : 'primary',
|
||
evidenceLocator: locator,
|
||
page: locator.page,
|
||
bbox: locator.bbox,
|
||
sourceMapPath: searchText(locator.sourceMapPath || locator.source_map_path),
|
||
blockId: evidenceLocatorBlockId(locator),
|
||
paragraphOrdinal: searchText(locator.paragraphOrdinal || locatorParams.paragraphOrdinal),
|
||
paraIdStart: searchText(locator.paraIdStart || locatorParams.paraIdStart),
|
||
paraIdEnd: searchText(locator.paraIdEnd || locatorParams.paraIdEnd),
|
||
textFingerprint: searchText(locator.textFingerprint || locatorParams.textFingerprint),
|
||
evidenceText: locatorEvidenceText,
|
||
query: searchQueryText,
|
||
searchQuery: searchQueryText,
|
||
lineRange: evidenceLocatorLineRange(locator),
|
||
charRange: evidenceLocatorCharRange(locator)
|
||
});
|
||
if (!openedInResourceTab) console.warn('mnote evidence 搜索结果无法在当前页面资源标签打开', locator);
|
||
closeSearchModal();
|
||
return;
|
||
}
|
||
var url = evidenceLocatorOpenUrl(locator) || ('/documents/' + encodeURIComponent(ownerDocumentId || currentDocumentId() || ''));
|
||
try {
|
||
var target = new URL(url, window.location.origin);
|
||
var blockId = searchText(locator.blockId || locator.block_id);
|
||
var sourceMapPath = searchText(locator.sourceMapPath || locator.source_map_path);
|
||
if (blockId) target.searchParams.set('blockId', blockId);
|
||
if (locator.page) target.searchParams.set('page', String(locator.page));
|
||
var bbox = evidenceLocatorBbox(locator);
|
||
if (bbox) target.searchParams.set('bbox', bbox);
|
||
if (sourceMapPath) target.searchParams.set('sourceMapPath', sourceMapPath);
|
||
if (locatorParams.paragraphOrdinal != null) target.searchParams.set('paragraphOrdinal', searchText(locatorParams.paragraphOrdinal));
|
||
if (locatorParams.paraIdStart) target.searchParams.set('paraIdStart', searchText(locatorParams.paraIdStart));
|
||
if (locatorParams.paraIdEnd) target.searchParams.set('paraIdEnd', searchText(locatorParams.paraIdEnd));
|
||
if (locatorParams.textFingerprint) target.searchParams.set('textFingerprint', searchText(locatorParams.textFingerprint));
|
||
window.location.assign(target.pathname + target.search + target.hash);
|
||
} catch (_) {
|
||
window.location.assign(url);
|
||
}
|
||
}
|
||
|
||
function renderSearchRecentState(overlay) {
|
||
var options = overlay.querySelector('[data-testid="wolai-search-options"]');
|
||
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
|
||
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
|
||
if (options instanceof HTMLElement) options.hidden = true;
|
||
if (meta) meta.innerHTML = '<span>最近浏览</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
|
||
if (results) {
|
||
results.innerHTML = '<div class="wolai-search-recent" data-testid="wolai-search-recent">暂无最近浏览</div>';
|
||
}
|
||
saveSearchUiState(overlay);
|
||
searchUiState.hasRendered = true;
|
||
}
|
||
|
||
function scheduleSearchResultsRender() {
|
||
window.clearTimeout(searchRenderTimer);
|
||
searchRenderTimer = window.setTimeout(function() { void renderSearchResults(); }, 120);
|
||
}
|
||
|
||
async function renderSearchResults() {
|
||
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
if (!(overlay instanceof HTMLElement)) return;
|
||
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
|
||
var options = overlay.querySelector('[data-testid="wolai-search-options"]');
|
||
var meta = overlay.querySelector('[data-testid="wolai-search-result-meta"]');
|
||
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
|
||
if (!input || !meta || !results) return;
|
||
var query = searchText(input.value);
|
||
if (!query) {
|
||
activeSearchRequestId += 1;
|
||
renderSearchRecentState(overlay);
|
||
return;
|
||
}
|
||
if (options instanceof HTMLElement) options.hidden = false;
|
||
var knowledgeMode = searchSwitchValue(overlay, 'knowledge');
|
||
if (knowledgeMode && searchNonWhitespaceCharCount(query) < 2) {
|
||
activeSearchRequestId += 1;
|
||
meta.innerHTML = '<span>资料库检索</span><span>请输入至少 2 个字再搜索</span>';
|
||
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">请输入至少 2 个字再搜索</div>';
|
||
window.__mnoteSearchResults = [];
|
||
saveSearchUiState(overlay);
|
||
searchUiState.hasRendered = true;
|
||
return;
|
||
}
|
||
var requestId = ++activeSearchRequestId;
|
||
var knowledgeRequestMode = knowledgeMode ? knowledgeSearchRequestMode(overlay) : '';
|
||
meta.innerHTML = '<span>搜索中…</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
|
||
results.innerHTML = '<div class="wolai-search-empty" data-search-loading="true">搜索中…</div>';
|
||
try {
|
||
var response = await fetch(knowledgeMode ? '/api/knowledge-rag/search' : '/api/search/documents', {
|
||
method: 'POST',
|
||
headers: { 'content-type': 'application/json' },
|
||
body: JSON.stringify(knowledgeMode ? {
|
||
workspaceId: resolveWorkspaceId(document.body),
|
||
rootUri: currentRootUri() || null,
|
||
query: query,
|
||
mode: knowledgeRequestMode,
|
||
topK: 12,
|
||
chunkTopK: 24,
|
||
includeChunkContent: true
|
||
} : {
|
||
workspaceId: resolveWorkspaceId(document.body),
|
||
sourceKind: currentSourceKind() || null,
|
||
rootUri: currentRootUri() || null,
|
||
documentId: searchSwitchValue(overlay, 'page') ? (currentSearchDocumentId() || null) : (currentDocumentId() || null),
|
||
query: query,
|
||
limit: 30,
|
||
filters: {
|
||
titleOnly: searchSwitchValue(overlay, 'title'),
|
||
exact: searchSwitchValue(overlay, 'exact'),
|
||
includeOcr: false,
|
||
onlyCurrentPage: searchSwitchValue(overlay, 'page'),
|
||
timeRange: 'any',
|
||
timeField: 'updated'
|
||
}
|
||
})
|
||
});
|
||
var payload = await response.json();
|
||
if (requestId !== activeSearchRequestId) return;
|
||
var items = Array.isArray(payload.results) ? payload.results : [];
|
||
var ownerLabel = knowledgeMode ? ('资料库检索 · ' + knowledgeSearchModeLabel(payload.retrievalMode || knowledgeRequestMode)) : '工作区搜索';
|
||
meta.innerHTML = '<span>' + ownerLabel + ' · 共 ' + items.length + ' 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
|
||
if (!items.length) {
|
||
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">没有搜索结果</div>';
|
||
window.__mnoteSearchResults = [];
|
||
saveSearchUiState(overlay);
|
||
searchUiState.hasRendered = true;
|
||
return;
|
||
}
|
||
window.__mnoteSearchResults = items;
|
||
results.innerHTML = renderSearchResultsHtml(items, overlay, query);
|
||
saveSearchUiState(overlay);
|
||
searchUiState.hasRendered = true;
|
||
} catch (error) {
|
||
if (requestId !== activeSearchRequestId) return;
|
||
meta.innerHTML = '<span>共 0 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
|
||
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">没有搜索结果</div>';
|
||
window.__mnoteSearchResults = [];
|
||
saveSearchUiState(overlay);
|
||
searchUiState.hasRendered = true;
|
||
}
|
||
}
|
||
|
||
function isSearchModalOpen() {
|
||
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
return overlay instanceof HTMLElement && !overlay.hidden;
|
||
}
|
||
|
||
function openSearchModal() {
|
||
var overlay = ensureSearchModal();
|
||
overlay.hidden = false;
|
||
document.documentElement.setAttribute('data-mnote-search-modal-open', 'true');
|
||
var restored = restoreSearchUiState(overlay);
|
||
var input = overlay.querySelector('[data-testid="wolai-search-input"]');
|
||
if (input) input.setAttribute('placeholder', '在 ' + currentWorkspaceName() + ' 中搜索');
|
||
var query = input && 'value' in input ? searchText(input.value) : '';
|
||
var signature = query ? searchRequestSignature(overlay, query) : '';
|
||
if (!restored || signature !== searchUiState.signature) void renderSearchResults();
|
||
if (input) {
|
||
setTimeout(function() { input.focus(); input.select(); }, 0);
|
||
}
|
||
}
|
||
|
||
function closeSearchModal() {
|
||
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
if (overlay instanceof HTMLElement) {
|
||
saveSearchUiState(overlay);
|
||
overlay.hidden = true;
|
||
}
|
||
document.documentElement.removeAttribute('data-mnote-search-modal-open');
|
||
}
|
||
|
||
function toggleSearchModal() {
|
||
if (isSearchModalOpen()) closeSearchModal();
|
||
else openSearchModal();
|
||
}
|
||
|
||
function isSearchShortcutEvent(event) {
|
||
return Boolean(event && (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey && event.key && event.key.toLowerCase() === 'p');
|
||
}
|
||
|
||
document.addEventListener('keydown', function(event) {
|
||
if (!isSearchShortcutEvent(event)) return;
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
openSearchModal();
|
||
}, true);
|
||
|
||
const sidebarPageAi = createSidebarPageAiRuntime({
|
||
buildLocalFileOpenUrl,
|
||
currentDocumentId,
|
||
currentPageAggregate,
|
||
currentPageOptions,
|
||
currentRootUri,
|
||
currentSourceKind,
|
||
escapeHtml,
|
||
cssEscape,
|
||
openLocalResourceInActiveTab,
|
||
pageUiState,
|
||
resolveWorkspaceId,
|
||
searchText,
|
||
});
|
||
const openPageAiDrawer = (...args) => sidebarPageAi.openPageAiDrawer(...args);
|
||
const closePageAiDrawer = (...args) => sidebarPageAi.closePageAiDrawer(...args);
|
||
const isPageAiDrawerOpen = (...args) => sidebarPageAi.isPageAiDrawerOpen(...args);
|
||
const ensurePageAiDrawer = (...args) => sidebarPageAi.ensurePageAiDrawer(...args);
|
||
const sendPageAiMessage = (...args) => sidebarPageAi.sendPageAiMessage(...args);
|
||
const pageAiOpenHermesSettings = (...args) => sidebarPageAi.pageAiOpenHermesSettings(...args);
|
||
const pageAiStopRun = (...args) => sidebarPageAi.pageAiStopRun(...args);
|
||
const pageAiLoadGatewayHealth = (...args) => sidebarPageAi.pageAiLoadGatewayHealth(...args);
|
||
const renderPageAiControls = (...args) => sidebarPageAi.renderPageAiControls(...args);
|
||
const renderPageAiConversation = (...args) => sidebarPageAi.renderPageAiConversation(...args);
|
||
const renderPageAiProviderButtons = (...args) => sidebarPageAi.renderPageAiProviderButtons(...args);
|
||
const renderPageAiSuggestions = (...args) => sidebarPageAi.renderPageAiSuggestions(...args);
|
||
const pageAiSaveProfileMemory = (...args) => sidebarPageAi.pageAiSaveProfileMemory(...args);
|
||
const pageAiToggleSkill = (...args) => sidebarPageAi.pageAiToggleSkill(...args);
|
||
const pageAiToggleTool = (...args) => sidebarPageAi.pageAiToggleTool(...args);
|
||
const pageAiResumeBackendSession = (...args) => sidebarPageAi.pageAiResumeBackendSession(...args);
|
||
const pageAiRenameBackendSession = (...args) => sidebarPageAi.pageAiRenameBackendSession(...args);
|
||
const pageAiDeleteBackendSession = (...args) => sidebarPageAi.pageAiDeleteBackendSession(...args);
|
||
const pageAiResolvePermission = (...args) => sidebarPageAi.pageAiResolvePermission(...args);
|
||
const pageAiOpenLocation = (...args) => sidebarPageAi.pageAiOpenLocation(...args);
|
||
const pageAiSetActiveSession = (...args) => sidebarPageAi.pageAiSetActiveSession(...args);
|
||
const pageAiStartNewSession = (...args) => sidebarPageAi.pageAiStartNewSession(...args);
|
||
const pageAiLoadSessions = (...args) => sidebarPageAi.pageAiLoadSessions(...args);
|
||
const pageAiLoadBackendSessions = (...args) => sidebarPageAi.pageAiLoadBackendSessions(...args);
|
||
const pageAiCancelQueuedRun = (...args) => sidebarPageAi.pageAiCancelQueuedRun(...args);
|
||
const pageAiSearchBackendSessions = (...args) => sidebarPageAi.pageAiSearchBackendSessions(...args);
|
||
const pageAiPersistSessions = (...args) => sidebarPageAi.pageAiPersistSessions(...args);
|
||
const pageAiLoadProfiles = (...args) => sidebarPageAi.pageAiLoadProfiles(...args);
|
||
const pageAiLoadProfileMemory = (...args) => sidebarPageAi.pageAiLoadProfileMemory(...args);
|
||
const pageAiLoadSkills = (...args) => sidebarPageAi.pageAiLoadSkills(...args);
|
||
const pageAiSwitchProfile = (...args) => sidebarPageAi.pageAiSwitchProfile(...args);
|
||
const pageAiSetSkillSource = (...args) => sidebarPageAi.pageAiSetSkillSource(...args);
|
||
const pageAiToggleSkillGroup = (...args) => sidebarPageAi.pageAiToggleSkillGroup(...args);
|
||
const pageAiSetReasonixMemoryEnabled = (...args) => sidebarPageAi.pageAiSetReasonixMemoryEnabled(...args);
|
||
const pageAiSetHideHermesBuiltinSkills = (...args) => sidebarPageAi.pageAiSetHideHermesBuiltinSkills(...args);
|
||
const pageAiSetContextScope = (...args) => sidebarPageAi.pageAiSetContextScope(...args);
|
||
const pageAiSetAgentId = (...args) => sidebarPageAi.pageAiSetAgentId(...args);
|
||
const pageAiToggleContextRef = (...args) => sidebarPageAi.pageAiToggleContextRef(...args);
|
||
const pageAiSetAgentPopoverOpen = (...args) => sidebarPageAi.pageAiSetAgentPopoverOpen(...args);
|
||
const pageAiSetTargetPopoverOpen = (...args) => sidebarPageAi.pageAiSetTargetPopoverOpen(...args);
|
||
const pageAiSelectTarget = (...args) => sidebarPageAi.pageAiSelectTarget(...args);
|
||
const updatePageAiTriggerState = (...args) => sidebarPageAi.updatePageAiTriggerState(...args);
|
||
|
||
const sidebarAttachmentOpen = createSidebarAttachmentOpenRuntime({
|
||
attachmentClassForFileName: (...args) => attachmentClassForFileName(...args),
|
||
buildLocalFileOpenUrl,
|
||
buildLocalOnlyOfficeOpenUrl,
|
||
buildOnlyOfficeOpenPath,
|
||
buildOnlyOfficeOpenUrl,
|
||
buildPdfPreviewOpenUrl,
|
||
closestAction,
|
||
currentDocumentId,
|
||
currentRootUri,
|
||
currentWorkspaceSourcePayload,
|
||
fileTreeIconKindForFileName,
|
||
healLegacyOfficeAttachmentParagraphs,
|
||
hydrateEditorAttachmentMeta,
|
||
inferCodeAttachmentLanguage: (...args) => inferCodeAttachmentLanguage(...args),
|
||
inferOnlyOfficeFileType,
|
||
isCodeAttachmentFileName: (...args) => isCodeAttachmentFileName(...args),
|
||
isPdfAttachmentFileName: (...args) => isPdfAttachmentFileName(...args),
|
||
localFilePathFromAssetId,
|
||
openLocalOfficeFileInActiveTab,
|
||
openLocalResourceInActiveTab,
|
||
openTreeContextMenu: (...args) => openTreeContextMenu(...args),
|
||
resolveWorkspaceId,
|
||
triggerBrowserDownload: (...args) => triggerBrowserDownload(...args),
|
||
uploadedFileSize,
|
||
});
|
||
const refreshEditorLocalAttachmentExistence = (...args) => sidebarAttachmentOpen.refreshEditorLocalAttachmentExistence(...args);
|
||
const detailFromEditorAttachmentLink = (...args) => sidebarAttachmentOpen.detailFromEditorAttachmentLink(...args);
|
||
const enhanceEditorAttachmentLink = (...args) => sidebarAttachmentOpen.enhanceEditorAttachmentLink(...args);
|
||
const enhanceEditorAttachmentLinks = (...args) => sidebarAttachmentOpen.enhanceEditorAttachmentLinks(...args);
|
||
const openEditorAttachmentDetail = (...args) => sidebarAttachmentOpen.openEditorAttachmentDetail(...args);
|
||
const openEditorAttachmentNewWindow = (...args) => sidebarAttachmentOpen.openEditorAttachmentNewWindow(...args);
|
||
const openEditorAttachmentEditTab = (...args) => sidebarAttachmentOpen.openEditorAttachmentEditTab(...args);
|
||
const openCodeEditorAttachment = (...args) => sidebarAttachmentOpen.openCodeEditorAttachment(...args);
|
||
const openEditorAttachmentDownload = (...args) => sidebarAttachmentOpen.openEditorAttachmentDownload(...args);
|
||
|
||
document.addEventListener('click', function(e) {
|
||
if (activeTreeContextMenu && activeTreeContextMenu.contains(e.target)) return;
|
||
if (activeTreeContextMenu) closeTreeContextMenu();
|
||
|
||
var sidebarToggle = closestAction(e.target, '[data-mnote-action="toggle-sidebar"]');
|
||
if (sidebarToggle) {
|
||
e.preventDefault();
|
||
toggleWorkspaceSidebar(sidebarToggle);
|
||
return;
|
||
}
|
||
|
||
var attachmentAction = closestAction(e.target, '[data-attachment-action]');
|
||
if (attachmentAction) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
var link = activeEditorAttachmentLink;
|
||
if (!(link instanceof HTMLAnchorElement)) return;
|
||
var attachmentDetail = detailFromEditorAttachmentLink(link);
|
||
var attachmentActionName = attachmentAction.getAttribute('data-attachment-action') || '';
|
||
if (attachmentActionName === 'download') {
|
||
openEditorAttachmentDownload(attachmentDetail);
|
||
return;
|
||
}
|
||
if (attachmentActionName === 'menu') {
|
||
openEditorAttachmentMenu(link, attachmentAction);
|
||
return;
|
||
}
|
||
return;
|
||
}
|
||
|
||
var editorAttachmentLink = closestAction(e.target, '.editor-surface .ProseMirror a.mnote-uploaded-attachment-row');
|
||
if (editorAttachmentLink instanceof HTMLAnchorElement) {
|
||
e.preventDefault();
|
||
openEditorAttachmentLink(editorAttachmentLink);
|
||
return;
|
||
}
|
||
|
||
var historyClose = closestAction(e.target, '[data-page-history-action="close"]');
|
||
if (historyClose) {
|
||
e.preventDefault();
|
||
closePageHistoryDrawer();
|
||
return;
|
||
}
|
||
|
||
var shareClose = closestAction(e.target, '[data-page-share-action="close"]');
|
||
if (shareClose) {
|
||
e.preventDefault();
|
||
closePageShareDialog();
|
||
return;
|
||
}
|
||
|
||
var shareCopy = closestAction(e.target, '[data-page-share-action="copy-link"]');
|
||
if (shareCopy) {
|
||
e.preventDefault();
|
||
void copyTreeContextValue(window.location.href, 'page-share-link');
|
||
return;
|
||
}
|
||
|
||
var pageHistoryTrigger = closestAction(e.target, '[data-mnote-action="open-page-history"]');
|
||
if (pageHistoryTrigger) {
|
||
e.preventDefault();
|
||
openPageHistoryDrawer();
|
||
return;
|
||
}
|
||
|
||
var pageSettingsTrigger = closestAction(e.target, '[data-mnote-action="open-page-settings"]');
|
||
if (pageSettingsTrigger) {
|
||
e.preventDefault();
|
||
togglePageSettingsPopover();
|
||
return;
|
||
}
|
||
|
||
var indexSettingsTrigger = closestAction(e.target, '[data-mnote-action="open-index-settings"]');
|
||
if (indexSettingsTrigger) {
|
||
e.preventDefault();
|
||
openKnowledgeRagSettingsPopover();
|
||
return;
|
||
}
|
||
|
||
var knowledgeRagSettingsTrigger = closestAction(e.target, '[data-mnote-action="open-knowledge-rag-settings"]');
|
||
if (knowledgeRagSettingsTrigger) {
|
||
e.preventDefault();
|
||
openKnowledgeRagSettingsPopover();
|
||
return;
|
||
}
|
||
|
||
var settingsClose = closestAction(e.target, '[data-settings-action="close"]');
|
||
if (settingsClose) {
|
||
e.preventDefault();
|
||
closeAllSettingsPopovers();
|
||
return;
|
||
}
|
||
|
||
var pageSettingsPanel = closestAction(e.target, '.wolai-page-settings-panel');
|
||
if (isAnySettingsOpen() && !pageSettingsPanel) {
|
||
closeAllSettingsPopovers();
|
||
}
|
||
|
||
var pageSettingsTab = closestAction(e.target, '[data-page-settings-tab]');
|
||
if (pageSettingsTab) {
|
||
e.preventDefault();
|
||
setActivePageSettingsTab(pageSettingsTab.getAttribute('data-page-settings-tab') || 'page');
|
||
return;
|
||
}
|
||
|
||
var localIndexAction = closestAction(e.target, '[data-local-index-action]');
|
||
if (localIndexAction) {
|
||
e.preventDefault();
|
||
var localIndexActionName = localIndexAction.getAttribute('data-local-index-action') || '';
|
||
if (localIndexActionName === 'save') {
|
||
void persistLocalIndexSettings();
|
||
return;
|
||
}
|
||
if (localIndexActionName === 'refresh') {
|
||
void refreshLocalIndex();
|
||
return;
|
||
}
|
||
if (localIndexActionName === 'add-path') {
|
||
addLocalIndexRange();
|
||
return;
|
||
}
|
||
if (localIndexActionName === 'remove-path') {
|
||
removeLocalIndexRange(localIndexAction.getAttribute('data-local-index-path-index') || '0');
|
||
return;
|
||
}
|
||
}
|
||
|
||
var knowledgeRagAction = closestAction(e.target, '[data-knowledge-rag-action]');
|
||
if (knowledgeRagAction) {
|
||
e.preventDefault();
|
||
var knowledgeRagActionName = knowledgeRagAction.getAttribute('data-knowledge-rag-action') || '';
|
||
if (knowledgeRagActionName === 'refresh') {
|
||
void loadKnowledgeRagStatus(true);
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'add-source') {
|
||
addKnowledgeRagSourceInput();
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'remove-source') {
|
||
removeKnowledgeRagSourceInput(knowledgeRagAction);
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'use-filetree-selection') {
|
||
useKnowledgeRagFileTreeSelection();
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'ingest') {
|
||
void ingestKnowledgeRagSources();
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'reindex-source') {
|
||
void ingestSingleKnowledgeRagSource(knowledgeRagAction.getAttribute('data-knowledge-rag-source-path') || '');
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'delete-source') {
|
||
void deleteKnowledgeRagSource(knowledgeRagAction.getAttribute('data-knowledge-rag-source-path') || '');
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'prune') {
|
||
void pruneKnowledgeRagRegistry();
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'filter-sources') {
|
||
setKnowledgeRagSourceFilter(knowledgeRagAction.getAttribute('data-knowledge-rag-filter') || 'attention');
|
||
return;
|
||
}
|
||
if (knowledgeRagActionName === 'open-dashboard') {
|
||
openKnowledgeRagDashboard();
|
||
return;
|
||
}
|
||
}
|
||
|
||
var pageSettingsAction = closestAction(e.target, '[data-page-settings-action]');
|
||
if (pageSettingsAction) {
|
||
e.preventDefault();
|
||
var actionName = pageSettingsAction.getAttribute('data-page-settings-action') || '';
|
||
if (actionName === 'history') {
|
||
openPageHistoryDrawer();
|
||
return;
|
||
}
|
||
if (actionName === 'share') {
|
||
openPageShareDialog();
|
||
return;
|
||
}
|
||
return;
|
||
}
|
||
|
||
var pageAiTrigger = closestAction(e.target, '[data-mnote-action="open-page-ai"]');
|
||
if (pageAiTrigger) {
|
||
e.preventDefault();
|
||
openPageAiDrawer();
|
||
return;
|
||
}
|
||
|
||
var navigationPageTrigger = closestAction(e.target, '[data-mnote-action="open-navigation-page"]');
|
||
if (navigationPageTrigger) {
|
||
e.preventDefault();
|
||
openCurrentNavigationPage(navigationPageTrigger);
|
||
return;
|
||
}
|
||
|
||
var searchTrigger = closestAction(e.target, '[data-mnote-action="open-search-modal"]');
|
||
if (searchTrigger) {
|
||
e.preventDefault();
|
||
toggleSearchModal();
|
||
return;
|
||
}
|
||
var searchDialog = closestAction(e.target, '.wolai-search-dialog');
|
||
if (isSearchModalOpen() && !searchDialog) {
|
||
closeSearchModal();
|
||
return;
|
||
}
|
||
var searchSourceToggle = closestAction(e.target, '[data-search-source-toggle]');
|
||
if (searchSourceToggle) {
|
||
e.preventDefault();
|
||
var sourceGroup = searchSourceToggle.closest('.wolai-search-source-group');
|
||
var sourceResults = sourceGroup && sourceGroup.querySelector('[data-search-source-results="true"]');
|
||
var sourceKey = sourceGroup ? searchText(sourceGroup.getAttribute('data-search-source-key')) : '';
|
||
var nextCollapsed = !(sourceResults instanceof HTMLElement && sourceResults.hidden);
|
||
if (sourceResults instanceof HTMLElement) sourceResults.hidden = nextCollapsed;
|
||
searchSourceToggle.setAttribute('aria-expanded', nextCollapsed ? 'false' : 'true');
|
||
var chevron = searchSourceToggle.querySelector('.wolai-search-source-chevron');
|
||
if (chevron) chevron.textContent = nextCollapsed ? '展开' : '收起';
|
||
if (sourceKey) searchUiState.sourceCollapsed[sourceKey] = nextCollapsed;
|
||
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
|
||
if (overlay instanceof HTMLElement) saveSearchUiState(overlay);
|
||
return;
|
||
}
|
||
var searchResultRow = closestAction(e.target, '[data-testid="wolai-search-result-row"]');
|
||
if (searchResultRow) {
|
||
e.preventDefault();
|
||
var index = Number(searchResultRow.getAttribute('data-search-result-index') || -1);
|
||
var item = Array.isArray(window.__mnoteSearchResults) && index >= 0 ? window.__mnoteSearchResults[index] : null;
|
||
if (!item) {
|
||
var locatorPayload = searchResultRow.getAttribute('data-evidence-locator') || '';
|
||
try {
|
||
var locator = locatorPayload ? JSON.parse(locatorPayload) : null;
|
||
item = locator ? { evidence: { source: locator }, documentId: searchResultRow.getAttribute('data-document-id') || '' } : null;
|
||
} catch (_) {
|
||
item = null;
|
||
}
|
||
}
|
||
void openEvidenceSearchResult(item || { documentId: searchResultRow.getAttribute('data-document-id') || '' }, e)
|
||
.catch(function(error) { console.warn('mnote evidence 搜索结果打开失败', error); });
|
||
return;
|
||
}
|
||
|
||
var sourceMenuTrigger = closestAction(e.target, '[data-mnote-action="open-workspace-source-menu"]');
|
||
if (sourceMenuTrigger) {
|
||
e.preventDefault();
|
||
var existingSourceMenu = document.querySelector('[data-testid="mnote-workspace-source-menu"]');
|
||
if (existingSourceMenu) closeWorkspaceSourceMenu();
|
||
else openWorkspaceSourceMenu(sourceMenuTrigger);
|
||
return;
|
||
}
|
||
var sourceMenu = closestAction(e.target, '[data-testid="mnote-workspace-source-menu"]');
|
||
if (!sourceMenu) closeWorkspaceSourceMenu();
|
||
|
||
var accountMenuTrigger = closestAction(e.target, '[data-mnote-action="open-account-menu"]');
|
||
if (accountMenuTrigger) {
|
||
e.preventDefault();
|
||
var existingAccountMenu = document.querySelector('[data-testid="mnote-account-menu"]');
|
||
if (existingAccountMenu) closeAccountMenu();
|
||
else openAccountMenu(accountMenuTrigger);
|
||
return;
|
||
}
|
||
var accountMenu = closestAction(e.target, '[data-testid="mnote-account-menu"]');
|
||
if (!accountMenu) closeAccountMenu();
|
||
|
||
var trashTrigger = closestAction(e.target, '[data-mnote-action="open-trash-modal"]');
|
||
if (trashTrigger) {
|
||
e.preventDefault();
|
||
openTrashModal(trashTrigger);
|
||
return;
|
||
}
|
||
var trashClose = closestAction(e.target, '[data-mnote-trash-modal-close]');
|
||
if (trashClose) {
|
||
e.preventDefault();
|
||
closeTrashModal();
|
||
return;
|
||
}
|
||
|
||
var tabTrigger = closestAction(e.target, '[data-mnote-sidebar-tree-tab]');
|
||
if (tabTrigger) {
|
||
e.preventDefault();
|
||
switchSidebarTreeTab(tabTrigger);
|
||
return;
|
||
}
|
||
|
||
var pageShortcutTrigger = closestAction(e.target, '[data-mnote-action="toggle-sidebar-shortcut"]');
|
||
if (pageShortcutTrigger) {
|
||
e.preventDefault();
|
||
void toggleCurrentPageSidebarShortcut(pageShortcutTrigger);
|
||
return;
|
||
}
|
||
|
||
var shortcutMenu = closestAction(e.target, '[data-testid="mnote-sidebar-shortcut-menu"]');
|
||
var shortcutMenuAction = closestAction(e.target, '[data-mnote-sidebar-shortcut-menu-action]');
|
||
if (shortcutMenuAction) {
|
||
e.preventDefault();
|
||
var action = String(shortcutMenuAction.getAttribute('data-mnote-sidebar-shortcut-menu-action') || '').trim();
|
||
var shortcutRowFromMenu = shortcutMenu && shortcutMenu.__mnoteShortcutRow instanceof HTMLElement
|
||
? shortcutMenu.__mnoteShortcutRow
|
||
: null;
|
||
if (action === 'remove') {
|
||
void removeSidebarShortcutByRow(shortcutRowFromMenu);
|
||
return;
|
||
}
|
||
if (action === 'open') {
|
||
closeSidebarShortcutMenu();
|
||
if (shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('data-mnote-shortcut-kind') === 'folder') {
|
||
void openStarredFolderShortcut(shortcutRowFromMenu);
|
||
} else if (shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('href')) {
|
||
window.location.assign(shortcutRowFromMenu.getAttribute('href'));
|
||
}
|
||
return;
|
||
}
|
||
if (action === 'copy-link') {
|
||
var href = shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('href') || window.location.href;
|
||
if (navigator.clipboard && href) void navigator.clipboard.writeText(new URL(href, window.location.origin).toString());
|
||
closeSidebarShortcutMenu();
|
||
return;
|
||
}
|
||
}
|
||
if (!shortcutMenu) closeSidebarShortcutMenu();
|
||
|
||
var shortcutMenuTrigger = closestAction(e.target, '.wolai-starred-section [data-mnote-shortcut-action="menu"]');
|
||
if (shortcutMenuTrigger) {
|
||
e.preventDefault();
|
||
var shortcutRow = shortcutMenuTrigger.closest('[data-mnote-shortcut-id]');
|
||
openSidebarShortcutMenu(shortcutRow, shortcutMenuTrigger);
|
||
return;
|
||
}
|
||
|
||
var folderShortcutRow = closestAction(e.target, '.wolai-starred-section [data-mnote-shortcut-kind="folder"]');
|
||
if (folderShortcutRow) {
|
||
e.preventDefault();
|
||
void openStarredFolderShortcut(folderShortcutRow);
|
||
return;
|
||
}
|
||
|
||
var localFolderTrigger = closestAction(e.target, '[data-mnote-action="open-local-folder"]');
|
||
if (localFolderTrigger) {
|
||
e.preventDefault();
|
||
requestOpenLocalFolder();
|
||
return;
|
||
}
|
||
|
||
var createLocalWorkspaceTrigger = closestAction(e.target, '[data-mnote-action="create-local-workspace"]');
|
||
if (createLocalWorkspaceTrigger) {
|
||
e.preventDefault();
|
||
void createDefaultLocalWorkspace(createLocalWorkspaceTrigger);
|
||
return;
|
||
}
|
||
|
||
var createTrigger = closestAction(e.target, '[data-mnote-action="create-page"]');
|
||
if (createTrigger) {
|
||
e.preventDefault();
|
||
void createPage(createTrigger, null);
|
||
return;
|
||
}
|
||
|
||
var createFolderTrigger = closestAction(e.target, '[data-mnote-action="create-folder"]');
|
||
if (createFolderTrigger) {
|
||
e.preventDefault();
|
||
if (currentSourceKind() !== 'local_folder') return;
|
||
var scope = currentFileTreeScope();
|
||
var parentId = scope ? 'local:folder:' + scope : null;
|
||
void createFileTreeFolder(createFolderTrigger, parentId);
|
||
return;
|
||
}
|
||
|
||
var fileTree = document.getElementById('sidebar-file-tree-root');
|
||
if (fileTree && fileTree.contains(e.target)) {
|
||
var fileBtn = closestAction(e.target, '[data-rust-action]');
|
||
var fileRow = closestAction(e.target, '.tree-row[data-shell-mode="filetree"]');
|
||
if (!fileRow) return;
|
||
var fileAction = fileBtn ? fileBtn.getAttribute('data-rust-action') : 'open';
|
||
var rowId = fileRow.getAttribute('data-row-id') || '';
|
||
var rowKind = fileRow.getAttribute('data-row-kind') || '';
|
||
var documentId = fileRow.getAttribute('data-document-id') || fileRow.getAttribute('data-doc-id') || '';
|
||
var ownerDocumentId = fileRow.getAttribute('data-owner-document-id') || documentId;
|
||
var assetId = fileRow.getAttribute('data-asset-id') || '';
|
||
var assetType = '';
|
||
var kindBadge = fileRow.querySelector('.tree-kind-badge');
|
||
if (kindBadge instanceof HTMLElement) {
|
||
assetType = kindBadge.getAttribute('data-kind') || '';
|
||
}
|
||
if (fileAction === 'toggle') {
|
||
e.preventDefault();
|
||
toggleChildren(fileRow, fileBtn);
|
||
return;
|
||
}
|
||
if (fileAction === 'create') {
|
||
e.preventDefault();
|
||
void createPage(fileBtn || fileRow, documentId || fileRow.getAttribute('data-node-id'));
|
||
return;
|
||
}
|
||
if (fileAction === 'menu') {
|
||
e.preventDefault();
|
||
if (rowId && !sidebarFileTreeSelection.selectedRowIds.has(rowId)) {
|
||
selectSidebarFileTreeRow(fileRow, { ctrlKey: false, metaKey: false, shiftKey: false });
|
||
}
|
||
var point = rowCenter(fileBtn || fileRow);
|
||
dispatchSidebarEvent('tree.filetree.context-menu', { rowId: rowId, rowKind: rowKind, documentId: documentId || null, assetId: assetId || null });
|
||
openFileTreeContextMenu(fileRow, point.x, point.y, fileBtn || fileRow);
|
||
return;
|
||
}
|
||
if (fileAction === 'open' && rowKind === 'folder') {
|
||
e.preventDefault();
|
||
selectSidebarFileTreeRow(fileRow, { ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey });
|
||
toggleChildren(fileRow, fileRow.querySelector('[data-rust-action="toggle"]'));
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
selectSidebarFileTreeRow(fileRow, { ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey });
|
||
var objectIdentity = readFileTreeObjectIdentity(fileRow);
|
||
var workspacePath = readWorkspacePathFromRow(fileRow);
|
||
var localRelativePath = fileTreeRowLocalRelativePath(fileRow) || String(workspacePath && (workspacePath.relativePath || workspacePath.localRelativePath) || '').trim();
|
||
dispatchSidebarEvent('tree.filetree.open', { rowId: rowId, rowKind: rowKind, documentId: ownerDocumentId || null, assetId: assetId || null, assetType: assetType || null, objectIdentity: objectIdentity, workspacePath: workspacePath, workspaceId: resolveWorkspaceId(fileRow) });
|
||
if (e.shiftKey || e.ctrlKey || e.metaKey) {
|
||
return;
|
||
}
|
||
if ((rowKind === 'document' || rowKind === 'index' || rowKind === 'markdown') && isRetiredOcrSidecarMarkdownPath(localRelativePath)) {
|
||
document.documentElement.setAttribute('data-mnote-retired-ocr-sidecar-filetree-open', 'resource-tab');
|
||
var retiredOcrSidecarResourceInput = {
|
||
path: localRelativePath,
|
||
title: fileTreeRowTitleForShortcut(fileRow, localRelativePath),
|
||
kind: 'markdown',
|
||
objectIdentity: 'retired-ocr-sidecar:' + localRelativePath,
|
||
assetId: 'retired-ocr-sidecar:' + localRelativePath,
|
||
documentId: documentId || ownerDocumentId || null,
|
||
workspaceId: resolveWorkspaceId(fileRow),
|
||
sourceKind: 'local_folder',
|
||
rootUri: currentRootUri(),
|
||
resourceKind: 'markdown',
|
||
workspacePath: workspacePath,
|
||
paneRole: 'primary'
|
||
};
|
||
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
|
||
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab(retiredOcrSidecarResourceInput);
|
||
} else {
|
||
void openLocalResourceInActiveTab(retiredOcrSidecarResourceInput);
|
||
}
|
||
return;
|
||
}
|
||
if ((rowKind === 'document' || rowKind === 'index' || rowKind === 'markdown') && documentId) {
|
||
void recordNavigationRecent({
|
||
kind: 'page',
|
||
sourceKind: currentSourceKind() || 'local_folder',
|
||
rootUri: currentRootUri(),
|
||
relativePath: String(fileRow.getAttribute('data-local-relative-path') || '').trim(),
|
||
documentId: documentId,
|
||
title: fileTreeRowTitleForShortcut(fileRow, documentId),
|
||
workspaceId: resolveWorkspaceId(fileRow)
|
||
});
|
||
navigateToDocument(documentId, resolveWorkspaceId(fileRow), { treeView: 'filetree', fileTreeScope: currentFileTreeScope() });
|
||
} else if (assetId) {
|
||
dispatchSidebarEvent('tree.asset.open', { rowId: rowId, rowKind: rowKind, documentId: ownerDocumentId || null, assetId: assetId, assetType: assetType || null, objectIdentity: objectIdentity, workspacePath: workspacePath, workspaceId: resolveWorkspaceId(fileRow), openTarget: e.shiftKey || e.ctrlKey || e.metaKey ? 'new-window' : 'active-tab' });
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (sidebarPageTree.handlePageTreeClick(e, { closestAction: closestAction })) return;
|
||
});
|
||
|
||
window.addEventListener('tree.sidebarShortcut.toggleFolder', function(event) {
|
||
var detail = event.detail || {};
|
||
var row = detail.rowId
|
||
? document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(detail.rowId) + '"]')
|
||
: null;
|
||
void toggleFolderSidebarShortcut(detail, row);
|
||
});
|
||
|
||
window.addEventListener('tree.filetree.internal-drop', function(event) {
|
||
var detail = event.detail || {};
|
||
var rowIds = Array.isArray(detail.rowIds) ? detail.rowIds : [];
|
||
if (!rowIds.length) return;
|
||
var targetRow = detail.targetRowId
|
||
? document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(detail.targetRowId) + '"]')
|
||
: null;
|
||
recordFileTreeAction('internal-drop', {
|
||
rowId: detail.targetRowId || '',
|
||
sourceRowIds: rowIds,
|
||
copy: Boolean(detail.copy)
|
||
});
|
||
void moveSidebarFileTreeRows(rowIds, targetRow, { copy: Boolean(detail.copy) });
|
||
});
|
||
|
||
document.addEventListener('contextmenu', function(event) {
|
||
var editorAttachmentLink = closestAction(event.target, '.editor-surface .ProseMirror a.mnote-uploaded-attachment-row');
|
||
if (editorAttachmentLink instanceof HTMLAnchorElement) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
enhanceEditorAttachmentLink(editorAttachmentLink);
|
||
openEditorAttachmentMenu(editorAttachmentLink, editorAttachmentLink, { x: event.clientX, y: event.clientY });
|
||
return;
|
||
}
|
||
var fileRow = closestAction(event.target, '.tree-row[data-shell-mode="filetree"]');
|
||
if (fileRow) {
|
||
event.preventDefault();
|
||
var contextRowId = fileRow.getAttribute('data-row-id') || '';
|
||
if (contextRowId && !sidebarFileTreeSelection.selectedRowIds.has(contextRowId)) {
|
||
selectSidebarFileTreeRow(fileRow, { ctrlKey: false, metaKey: false, shiftKey: false });
|
||
}
|
||
openFileTreeContextMenu(fileRow, event.clientX, event.clientY, fileRow);
|
||
return;
|
||
}
|
||
if (sidebarPageTree.handlePageTreeContextMenu(event, { closestAction: closestAction })) return;
|
||
});
|
||
|
||
document.addEventListener('keydown', function(event) {
|
||
var keyTarget = event.target;
|
||
var fileTreeRootForKey = document.getElementById('sidebar-file-tree-root');
|
||
var fileTreeRowForKey = closestAction(keyTarget, '.tree-row[data-shell-mode="filetree"]');
|
||
if (!fileTreeRowForKey && fileTreeRootForKey && fileTreeRootForKey.contains(document.activeElement)) {
|
||
fileTreeRowForKey = closestAction(document.activeElement, '.tree-row[data-shell-mode="filetree"]');
|
||
}
|
||
if (fileTreeRowForKey) {
|
||
var _kbRT_ = window.__mnoteFileTreeKeyboardRuntime;
|
||
if (_kbRT_ && typeof _kbRT_.handleFileTreeKeyDown === 'function') {
|
||
var handled = _kbRT_.handleFileTreeKeyDown(event, {
|
||
closestAction: closestAction,
|
||
beginFileTreeInlineRename: beginFileTreeInlineRename,
|
||
selectedSidebarFileTreeRows: selectedSidebarFileTreeRows,
|
||
buildSidebarFileTreeContext: buildSidebarFileTreeContext,
|
||
evaluateSidebarFileTreeWhen: evaluateSidebarFileTreeWhen,
|
||
deleteSelectedSidebarFileTreeRows: deleteSelectedSidebarFileTreeRows,
|
||
pasteSidebarFileTreeClipboard: pasteSidebarFileTreeClipboard,
|
||
});
|
||
if (handled) return;
|
||
} else {
|
||
// inline fallback
|
||
if (event.key === 'F2') {
|
||
event.preventDefault();
|
||
var renameCtx = buildSidebarFileTreeContext('filetree', { targetRow: fileTreeRowForKey });
|
||
if (!evaluateSidebarFileTreeWhen(renameCtx, '!workspace.readonly && !editor.dirty')) {
|
||
return;
|
||
}
|
||
beginFileTreeInlineRename(fileTreeRowForKey);
|
||
return;
|
||
}
|
||
if ((event.ctrlKey || event.metaKey) && !event.altKey && event.key) {
|
||
var shortcutKey = event.key.toLowerCase();
|
||
if (shortcutKey === 'c' || shortcutKey === 'x') {
|
||
var selectedRows = selectedSidebarFileTreeRows();
|
||
var selectedRowIds = selectedRows.map(function(row) { return row.getAttribute('data-row-id') || ''; }).filter(Boolean);
|
||
if (selectedRowIds.length > 0) {
|
||
event.preventDefault();
|
||
sidebarFileTreeClipboard = { action: shortcutKey === 'x' ? 'cut' : 'copy', rowIds: selectedRowIds };
|
||
document.documentElement.setAttribute('data-mnote-filetree-clipboard-action', sidebarFileTreeClipboard.action);
|
||
}
|
||
return;
|
||
}
|
||
if (shortcutKey === 'v') {
|
||
event.preventDefault();
|
||
var pasteCtx = buildSidebarFileTreeContext('filetree', { targetRow: fileTreeRowForKey });
|
||
if (!evaluateSidebarFileTreeWhen(pasteCtx, '!workspace.readonly')) {
|
||
return;
|
||
}
|
||
void pasteSidebarFileTreeClipboard(fileTreeRowForKey);
|
||
return;
|
||
}
|
||
}
|
||
if (event.key === 'Delete' || event.key === 'Backspace') {
|
||
event.preventDefault();
|
||
var delCtx = buildSidebarFileTreeContext('filetree', { targetRow: fileTreeRowForKey });
|
||
if (!evaluateSidebarFileTreeWhen(delCtx, '!workspace.readonly && !editor.dirty')) {
|
||
return;
|
||
}
|
||
void deleteSelectedSidebarFileTreeRows(fileTreeRowForKey);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
if (event.key === 'Escape' && isAnySettingsOpen()) {
|
||
event.preventDefault();
|
||
closeAllSettingsPopovers();
|
||
return;
|
||
}
|
||
if (isSearchShortcutEvent(event)) {
|
||
event.preventDefault();
|
||
openSearchModal();
|
||
return;
|
||
}
|
||
if (event.key === 'Escape') {
|
||
closeTrashModal();
|
||
closeSearchModal();
|
||
closeTreeContextMenu();
|
||
}
|
||
});
|
||
|
||
document.addEventListener('change', function(event) {
|
||
var globalCheckbox = closestAction(event.target, '[data-global-option-checkbox="showHeadingNumbers"]');
|
||
if (globalCheckbox instanceof HTMLInputElement) {
|
||
writeGlobalShowHeadingNumbers(globalCheckbox.checked);
|
||
applyPageOptionsToShell();
|
||
renderPageSettingsPopover();
|
||
return;
|
||
}
|
||
var checkbox = closestAction(event.target, '[data-page-option-checkbox]');
|
||
if (checkbox instanceof HTMLInputElement) {
|
||
var key = checkbox.getAttribute('data-page-option-checkbox') || '';
|
||
if (!pageOptionIsSupported(key)) return;
|
||
var patch = {};
|
||
patch[key] = checkbox.checked;
|
||
void persistPageOptionsPatch(patch);
|
||
return;
|
||
}
|
||
var select = closestAction(event.target, '[data-page-option-select]');
|
||
if (select instanceof HTMLSelectElement) {
|
||
var selectKey = select.getAttribute('data-page-option-select') || '';
|
||
var next = {};
|
||
if (selectKey === 'layoutDensity') next.layoutDensity = select.value;
|
||
if (selectKey === 'pageFont') next.pageFont = select.value;
|
||
if (Object.keys(next).length) {
|
||
void persistPageOptionsPatch(next);
|
||
}
|
||
return;
|
||
}
|
||
var pageWidthSelect = closestAction(event.target, '[data-page-width-select]');
|
||
if (pageWidthSelect instanceof HTMLSelectElement) {
|
||
var pageWidthType = pageWidthSelect.getAttribute('data-page-width-select') || '';
|
||
void persistPageWidthPreference(pageWidthType, pageWidthSelect.value);
|
||
}
|
||
});
|
||
sidebarPageAi.installPageAiDelegates();
|
||
|
||
function initializePageUiSurfaces() {
|
||
pageUiState.pageOptions = null;
|
||
pageUiState.pageWidthPreferences = null;
|
||
applyPageOptionsToShell();
|
||
void loadPageWidthPreferences();
|
||
updatePageSettingsTriggerState();
|
||
updatePageAiTriggerState();
|
||
ensureHistorySnapshotsSeeded();
|
||
installWorkspaceSidebarResizer();
|
||
}
|
||
|
||
window.__mnoteRecordPageHistorySnapshot = recordPageHistorySnapshot;
|
||
window.__mnoteApplyPageOptionsToShell = applyPageOptionsToShell;
|
||
function scheduleInitializePageUiSurfaces() {
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
setTimeout(initializePageUiSurfaces, 0);
|
||
}, { once: true });
|
||
return;
|
||
}
|
||
setTimeout(initializePageUiSurfaces, 0);
|
||
}
|
||
scheduleInitializePageUiSurfaces();
|
||
|
||
function mnoteDevHotReloadEnabled() {
|
||
try {
|
||
return new URL(import.meta.url).searchParams.has('devHot');
|
||
} catch (_) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function installMnoteDevHotReload() {
|
||
var bootId = '';
|
||
var failedOnce = false;
|
||
var timer = 0;
|
||
function tick() {
|
||
fetch('/api/dev/hot-reload', { cache: 'no-store', headers: { accept: 'application/json' } })
|
||
.then(function(response) { return response.ok ? response.json() : null; })
|
||
.then(function(payload) {
|
||
if (!payload || payload.enabled !== true || !payload.bootId) {
|
||
if (!bootId && timer) window.clearInterval(timer);
|
||
return;
|
||
}
|
||
document.documentElement.setAttribute('data-mnote-dev-hot-reload', 'enabled');
|
||
if (!bootId) {
|
||
bootId = String(payload.bootId);
|
||
return;
|
||
}
|
||
if (failedOnce || String(payload.bootId) !== bootId) {
|
||
window.location.assign(window.location.href);
|
||
}
|
||
})
|
||
.catch(function() {
|
||
if (bootId) failedOnce = true;
|
||
});
|
||
}
|
||
tick();
|
||
timer = window.setInterval(tick, 1000);
|
||
}
|
||
if (mnoteDevHotReloadEnabled()) {
|
||
installMnoteDevHotReload();
|
||
}
|
||
|
||
document.addEventListener('dragstart', function(event) {
|
||
var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"][draggable="true"]');
|
||
if (pageRow) {
|
||
startPageDrag(pageRow, event);
|
||
return;
|
||
}
|
||
var fileRow = closestAction(event.target, '.tree-row[data-shell-mode="filetree"][draggable="true"]');
|
||
if (fileRow) {
|
||
var _dndRT_ = window.__mnoteFileTreeDndRuntime;
|
||
if (_dndRT_ && typeof _dndRT_.startFileTreeDrag === 'function') {
|
||
var dragInfo = _dndRT_.startFileTreeDrag(fileRow, {
|
||
selectedSidebarFileTreeRowIdsForDrag: selectedSidebarFileTreeRowIdsForDrag,
|
||
});
|
||
draggingFileTreeRowIds = _dndRT_.draggingFileTreeRowIds;
|
||
if (event.dataTransfer && dragInfo) {
|
||
event.dataTransfer.effectAllowed = dragInfo.effectAllowed || 'copyMove';
|
||
event.dataTransfer.setData(_dndRT_.FILETREE_DRAG_MIME, dragInfo.payload);
|
||
event.dataTransfer.setData('application/x-mnote-file-tree', dragInfo.payload);
|
||
event.dataTransfer.setData('text/plain', dragInfo.payload);
|
||
}
|
||
} else {
|
||
// inline fallback
|
||
draggingFileTreeRowIds = selectedSidebarFileTreeRowIdsForDrag(fileRow);
|
||
if (event.dataTransfer) {
|
||
var payload = JSON.stringify({ type: 'mnote-file-tree-dnd', version: 1, rowIds: draggingFileTreeRowIds });
|
||
event.dataTransfer.effectAllowed = 'copyMove';
|
||
event.dataTransfer.setData(FILETREE_DRAG_MIME, payload);
|
||
event.dataTransfer.setData('application/x-mnote-file-tree', payload);
|
||
event.dataTransfer.setData('text/plain', payload);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
document.addEventListener('dragover', function(event) {
|
||
var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"]');
|
||
var sourceNodeId = readPageDragNodeId(event);
|
||
if (pageRow && canDropPage(sourceNodeId, pageRow)) {
|
||
event.preventDefault();
|
||
clearPageDropFeedback();
|
||
pageRow.setAttribute('data-drop-feedback', 'true');
|
||
pageRow.setAttribute('data-drop-position', pageDropPosition(event, pageRow));
|
||
setActivePageDropRow(pageRow);
|
||
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
||
return;
|
||
}
|
||
var _dndRT_ = window.__mnoteFileTreeDndRuntime;
|
||
if (_dndRT_ && typeof _dndRT_.handleFileTreeDragOver === 'function') {
|
||
if (_dndRT_.handleFileTreeDragOver(event, { closestAction: closestAction })) {
|
||
return;
|
||
}
|
||
} else {
|
||
// inline fallback
|
||
var fileTree = document.getElementById('sidebar-file-tree-root');
|
||
if (fileTree && fileTree.contains(event.target)) {
|
||
var hasFiles = event.dataTransfer && Array.prototype.indexOf.call(event.dataTransfer.types || [], 'Files') >= 0;
|
||
var hasInternal = event.dataTransfer && Array.prototype.indexOf.call(event.dataTransfer.types || [], FILETREE_DRAG_MIME) >= 0;
|
||
if (!hasFiles && !hasInternal && draggingFileTreeRowIds.length === 0) return;
|
||
event.preventDefault();
|
||
if (activeFileTreeDropRow instanceof HTMLElement) activeFileTreeDropRow.setAttribute('data-drop-target', 'false');
|
||
activeFileTreeDropRow = closestAction(event.target, '.tree-row[data-shell-mode="filetree"]') || fileTree;
|
||
if (activeFileTreeDropRow instanceof HTMLElement) activeFileTreeDropRow.setAttribute('data-drop-target', 'true');
|
||
var copyModifier = event.altKey || event.ctrlKey || event.metaKey;
|
||
if (event.dataTransfer) event.dataTransfer.dropEffect = hasFiles || copyModifier ? 'copy' : 'move';
|
||
}
|
||
}
|
||
});
|
||
|
||
document.addEventListener('drop', function(event) {
|
||
var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"]');
|
||
var sourceNodeId = readPageDragNodeId(event);
|
||
if (pageRow && canDropPage(sourceNodeId, pageRow)) {
|
||
event.preventDefault();
|
||
var position = pageDropPosition(event, pageRow);
|
||
var target = resolvePageMoveTarget(pageRow, position);
|
||
clearPageDragState();
|
||
void dispatchTreeCommand(pageRow, {
|
||
action: 'move',
|
||
workspaceId: resolveWorkspaceId(pageRow),
|
||
documentId: sourceNodeId,
|
||
parentId: target.parentId,
|
||
sortOrder: target.sortOrder
|
||
});
|
||
return;
|
||
}
|
||
var _dndRT_ = window.__mnoteFileTreeDndRuntime;
|
||
if (_dndRT_ && typeof _dndRT_.handleFileTreeDrop === 'function') {
|
||
_dndRT_.handleFileTreeDrop(event, {
|
||
closestAction: closestAction,
|
||
resolveWorkspaceId: resolveWorkspaceId,
|
||
fileTreeRowLocalUploadTargetRelativePath: fileTreeRowLocalUploadTargetRelativePath,
|
||
ensureFileTreeWritableTarget: ensureFileTreeWritableTarget,
|
||
dispatchSidebarEvent: dispatchSidebarEvent,
|
||
});
|
||
} else {
|
||
// inline fallback
|
||
var fileTree = document.getElementById('sidebar-file-tree-root');
|
||
if (fileTree && fileTree.contains(event.target)) {
|
||
var targetRow = closestAction(event.target, '.tree-row[data-shell-mode="filetree"]');
|
||
var files = event.dataTransfer ? Array.from(event.dataTransfer.files || []) : [];
|
||
var raw = event.dataTransfer ? event.dataTransfer.getData(FILETREE_DRAG_MIME) || event.dataTransfer.getData('application/x-mnote-file-tree') || '' : '';
|
||
var rowIds = draggingFileTreeRowIds.slice();
|
||
if (raw) {
|
||
try {
|
||
var parsed = JSON.parse(raw);
|
||
if (Array.isArray(parsed.rowIds)) rowIds = parsed.rowIds;
|
||
} catch (_) {}
|
||
}
|
||
if (!files.length && !rowIds.length) return;
|
||
event.preventDefault();
|
||
var detail = {
|
||
workspaceId: resolveWorkspaceId(targetRow || fileTree),
|
||
targetRowId: targetRow ? targetRow.getAttribute('data-row-id') : null,
|
||
targetRowKind: targetRow ? targetRow.getAttribute('data-row-kind') : 'root',
|
||
documentId: targetRow ? targetRow.getAttribute('data-document-id') || targetRow.getAttribute('data-doc-id') : null,
|
||
assetId: targetRow ? targetRow.getAttribute('data-asset-id') : null,
|
||
targetRelativePath: targetRow ? fileTreeRowLocalUploadTargetRelativePath(targetRow) : '',
|
||
uploadIntent: 'filetree.folder.drop'
|
||
};
|
||
if (activeFileTreeDropRow instanceof HTMLElement) activeFileTreeDropRow.setAttribute('data-drop-target', 'false');
|
||
activeFileTreeDropRow = null;
|
||
if (files.length) {
|
||
dispatchSidebarEvent('tree.filetree.external-drop', Object.assign({}, detail, { files: files }));
|
||
} else {
|
||
void Promise.resolve(ensureFileTreeWritableTarget('drop', targetRow, rowIds, event.altKey === true || event.ctrlKey === true || event.metaKey === true)).then(function(writable) {
|
||
if (!writable) return;
|
||
dispatchSidebarEvent('tree.filetree.internal-drop', Object.assign({}, detail, { rowIds: rowIds, copy: event.altKey === true || event.ctrlKey === true || event.metaKey === true }));
|
||
});
|
||
}
|
||
draggingFileTreeRowIds = [];
|
||
}
|
||
}
|
||
});
|
||
|
||
document.addEventListener('dragend', function() {
|
||
clearPageDragState();
|
||
var _dndRT_ = window.__mnoteFileTreeDndRuntime;
|
||
if (_dndRT_ && typeof _dndRT_.resetFileTreeDragState === 'function') {
|
||
_dndRT_.resetFileTreeDragState();
|
||
} else {
|
||
draggingFileTreeRowIds = [];
|
||
clearPageDropFeedback();
|
||
if (activeFileTreeDropRow instanceof HTMLElement) activeFileTreeDropRow.setAttribute('data-drop-target', 'false');
|
||
activeFileTreeDropRow = null;
|
||
}
|
||
});
|
||
|
||
sidebarTreeLiveApply.installTreeLiveApplyEventListeners();
|
||
|
||
var tree = document.getElementById('sidebar-tree-root');
|
||
var activeId = currentDocumentId();
|
||
if (tree && activeId) {
|
||
var activeRow = tree.querySelector('.tree-row[data-node-id="' + cssEscape(activeId) + '"]');
|
||
if (activeRow instanceof HTMLElement) activeRow.setAttribute('data-active', 'true');
|
||
}
|
||
var initiallySelectedFileRows = document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-selected="true"]');
|
||
initiallySelectedFileRows.forEach(function(row) {
|
||
if (!(row instanceof HTMLElement)) return;
|
||
var rowId = row.getAttribute('data-row-id') || '';
|
||
if (!rowId) return;
|
||
sidebarFileTreeSelection.selectedRowIds.add(rowId);
|
||
if (!sidebarFileTreeSelection.anchorRowId) sidebarFileTreeSelection.anchorRowId = rowId;
|
||
sidebarFileTreeSelection.focusedRowId = rowId;
|
||
});
|
||
syncSidebarFileTreeSelection();
|
||
schedulePendingLocalFolderRestoreFocus();
|
||
window.addEventListener('mnote:primary-document-activated', function(event) {
|
||
var detail = event && event.detail ? event.detail : {};
|
||
pageUiState.pageOptions = null;
|
||
applyPageOptionsToShell();
|
||
if (isPageSettingsOpen()) renderPageSettingsPopover();
|
||
selectSidebarFileTreeDocument(detail.documentId, { scrollIntoView: false });
|
||
});
|
||
window.addEventListener('mnote:page-aggregate-synced', function(event) {
|
||
var detail = event && event.detail ? event.detail : {};
|
||
if (detail.scriptId && detail.scriptId !== '__MNOTE_PAGE_AGGREGATE__') return;
|
||
var documentId = searchText(detail.documentId || '');
|
||
if (documentId && currentDocumentId() && documentId !== currentDocumentId()) return;
|
||
pageUiState.pageOptions = null;
|
||
applyPageOptionsToShell();
|
||
if (isPageSettingsOpen()) renderPageSettingsPopover();
|
||
});
|
||
restoreSidebarTreeTab();
|
||
startLocalFolderSidebarWatch();
|
||
})();
|