export const createSidebarPageTreeRuntime = (dependencies = {}) => { const { activeSidebarTreeMode, commandDocumentId, copyWorkspaceSourceParams, cssEscape, currentDocumentId, currentSourceKind, dispatchSidebarEvent, dispatchTreeCommand, normalizeSidebarTreeMode, openPageTreeContextMenu, persistLocalFolderSelfChangeSuppression, persistSidebarTreeMode, refreshLocalFolderSidebarSnapshot, refreshLocalFolderAfterCommand, resolveWorkspaceId, rowCenter, selectSidebarFileTreeDocument, toggleChildren, updateTitleEverywhere, } = dependencies; const PAGE_DRAG_MIME = 'application/x-mnote-page-tree-node'; var mnoteNavigationInFlight = ''; var draggingPageNodeId = ''; var activePageDropRow = null; function navigateToDocument(nodeId, workspaceId, options) { if (!nodeId) return; var treeView = normalizeSidebarTreeMode(options && options.treeView ? options.treeView : activeSidebarTreeMode()); persistSidebarTreeMode(treeView); if (currentDocumentId() === nodeId && window.location.pathname.indexOf('/documents/') === 0) { if (typeof window.__mnoteDocumentPaneRuntime?.activatePageTab === 'function') { window.__mnoteDocumentPaneRuntime.activatePageTab(); } document.querySelectorAll('.tree-row[data-active="true"], .tree-row[data-selected="true"]').forEach(function(row) { if (row instanceof HTMLElement) { row.setAttribute('data-active', 'false'); row.setAttribute('data-selected', 'false'); } }); document.querySelectorAll('.tree-row[data-node-id="' + cssEscape(nodeId) + '"], .tree-row[data-document-id="' + cssEscape(nodeId) + '"], .tree-row[data-doc-id="' + cssEscape(nodeId) + '"]').forEach(function(row) { if (row instanceof HTMLElement) { if (row.getAttribute('data-shell-mode') === 'filetree') { row.setAttribute('data-selected', String(row.getAttribute('data-row-id') === 'doc:' + nodeId)); } else { row.setAttribute('data-active', 'true'); } } }); selectSidebarFileTreeDocument(nodeId, { scrollIntoView: true }); return; } var targetUrl = new URL('/documents/' + encodeURIComponent(nodeId), window.location.origin); if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId); if (treeView === 'filetree') targetUrl.searchParams.set('treeView', 'filetree'); var fileTreeScope = String(options && options.fileTreeScope || '').trim(); if (fileTreeScope) targetUrl.searchParams.set('fileTreeScope', fileTreeScope); copyWorkspaceSourceParams(targetUrl); var url = targetUrl.pathname + targetUrl.search; if (mnoteNavigationInFlight === url) return; if (typeof window.__mnoteDocumentPaneRuntime?.openPrimaryDocument === 'function') { mnoteNavigationInFlight = url; document.documentElement.setAttribute('data-mnote-navigation-pending', 'true'); document.documentElement.setAttribute('data-mnote-navigation-target', nodeId); window.__mnoteDocumentPaneRuntime.openPrimaryDocument({ documentId: nodeId, workspaceId: workspaceId || '', sourceKind: targetUrl.searchParams.get('sourceKind') || 'local_folder', rootUri: targetUrl.searchParams.get('rootUri') || '', url: targetUrl, }).then(function(){ if (mnoteNavigationInFlight === url) mnoteNavigationInFlight = ''; document.documentElement.removeAttribute('data-mnote-navigation-pending'); selectSidebarFileTreeDocument(nodeId, { scrollIntoView: true }); }).catch(function(error){ console.warn('mnote pane 内导航失败,将回退整页导航', error); if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') { window.__mnoteTreeLiveEventSource.close(); } window.location.assign(url); }); return; } mnoteNavigationInFlight = url; document.documentElement.setAttribute('data-mnote-navigation-pending', 'true'); document.documentElement.setAttribute('data-mnote-navigation-target', nodeId); if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') { window.__mnoteTreeLiveEventSource.close(); } window.location.assign(url); } async function createPage(trigger, parentId) { var workspaceId = resolveWorkspaceId(trigger); var effectiveParentId = (parentId || trigger.getAttribute('data-parent-id') || '').trim(); if (!workspaceId) return; var result = await dispatchTreeCommand(trigger, { action: 'create', workspaceId: workspaceId, parentId: effectiveParentId || null, title: '新页面' }); var nextWorkspaceId = result.workspaceId || workspaceId; var nextDocumentId = commandDocumentId(result, ''); if (nextDocumentId) { persistLocalFolderSelfChangeSuppression(nextDocumentId, Date.now() + 5000); } if (nextDocumentId && currentSourceKind() === 'local_folder') { if (typeof refreshLocalFolderAfterCommand === 'function') { await refreshLocalFolderAfterCommand('create', result, { parentId: effectiveParentId || null }); } selectSidebarFileTreeDocument(nextDocumentId, { scrollIntoView: true }); document.documentElement.setAttribute('data-mnote-create-page-selected-document-id', nextDocumentId); } navigateToDocument(nextDocumentId, nextWorkspaceId, { treeView: activeSidebarTreeMode() }); } function startPageDrag(pageRow, event) { if (!(pageRow instanceof HTMLElement)) return false; draggingPageNodeId = pageRow.getAttribute('data-node-id') || ''; if (event && event.dataTransfer) { event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.setData(PAGE_DRAG_MIME, draggingPageNodeId); event.dataTransfer.setData('text/plain', draggingPageNodeId); } return true; } function readPageDragNodeId(event) { var fromTransfer = event.dataTransfer ? event.dataTransfer.getData(PAGE_DRAG_MIME) || event.dataTransfer.getData('text/plain') : ''; return (fromTransfer || draggingPageNodeId || '').trim(); } function clearPageDropFeedback() { if (activePageDropRow instanceof HTMLElement) { activePageDropRow.setAttribute('data-drop-feedback', 'false'); } activePageDropRow = null; } function setActivePageDropRow(row) { activePageDropRow = row instanceof HTMLElement ? row : null; } function clearPageDragState() { draggingPageNodeId = ''; clearPageDropFeedback(); } function handlePageTreeClick(event, helpers = {}) { var closestAction = helpers.closestAction; if (typeof closestAction !== 'function') return false; var tree = document.getElementById('sidebar-tree-root'); if (!tree || !tree.contains(event.target)) return false; var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"]'); var btn = closestAction(event.target, '[data-rust-action]'); if (!btn && !pageRow) return false; var nodeId = (btn && btn.getAttribute('data-node-id')) || (pageRow && pageRow.getAttribute('data-node-id')) || ''; var action = btn ? btn.getAttribute('data-rust-action') : 'open'; if (action === 'toggle') { var row = btn.closest('.tree-row'); if (!row) return true; toggleChildren(row, btn); event.preventDefault(); } else if (action === 'open') { var openTrigger = btn || pageRow; if (openTrigger && openTrigger.getAttribute('data-page-openable') === 'false') { event.preventDefault(); return true; } var workspaceId = resolveWorkspaceId(openTrigger); navigateToDocument(nodeId, workspaceId, { treeView: 'page' }); event.preventDefault(); } else if (action === 'create') { event.preventDefault(); void createPage(btn, nodeId); } else if (action === 'rename') { event.preventDefault(); var title = window.prompt('重命名页面'); if (title && title.trim()) { void dispatchTreeCommand(btn, { action: 'rename', workspaceId: resolveWorkspaceId(btn), documentId: nodeId, title: title.trim() }).then(function(){ updateTitleEverywhere(nodeId, title.trim()); }); } } else if (action === 'menu') { event.preventDefault(); var menuPoint = rowCenter(btn); dispatchSidebarEvent('tree.page.context-menu', { documentId: nodeId, target: { documentId: nodeId } }); openPageTreeContextMenu(btn.closest('.tree-row'), menuPoint.x, menuPoint.y, btn); } return true; } function handlePageTreeContextMenu(event, helpers = {}) { var closestAction = helpers.closestAction; if (typeof closestAction !== 'function') return false; var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"]'); if (!pageRow) return false; event.preventDefault(); openPageTreeContextMenu(pageRow, event.clientX, event.clientY, pageRow); return true; } function canDropPage(sourceNodeId, targetRow) { if (!sourceNodeId || !(targetRow instanceof HTMLElement)) return false; var targetNodeId = targetRow.getAttribute('data-node-id') || ''; if (!targetNodeId || targetNodeId === sourceNodeId) return false; var sourceNode = document.querySelector('#sidebar-tree-root .tree-node[data-node-id="' + cssEscape(sourceNodeId) + '"]'); return !(sourceNode instanceof HTMLElement && sourceNode.contains(targetRow)); } function pageDropPosition(event, row) { var rect = row.getBoundingClientRect(); var ratio = rect.height > 0 ? (event.clientY - rect.top) / rect.height : 0.5; if (ratio < 0.25) return 'before'; if (ratio > 0.75) return 'after'; return 'inside'; } function resolvePageMoveTarget(targetRow, position) { var targetNodeId = targetRow.getAttribute('data-node-id') || ''; var parentId = targetRow.getAttribute('data-parent-id') || null; if (position === 'inside') { var children = targetRow.parentElement ? targetRow.parentElement.querySelectorAll(':scope > .tree-children > .tree-node > .tree-row[data-shell-mode="page"]') : []; return { parentId: targetNodeId, sortOrder: children.length }; } var siblings = Array.from(document.querySelectorAll('#sidebar-tree-root .tree-row[data-shell-mode="page"]')).filter(function(row) { return (row.getAttribute('data-parent-id') || '') === (parentId || ''); }); var index = siblings.indexOf(targetRow); return { parentId: parentId, sortOrder: Math.max(0, index + (position === 'after' ? 1 : 0)) }; } return { navigateToDocument, createPage, startPageDrag, readPageDragNodeId, clearPageDropFeedback, setActivePageDropRow, clearPageDragState, handlePageTreeClick, handlePageTreeContextMenu, canDropPage, pageDropPosition, resolvePageMoveTarget, }; };