refactor: split sidebar shell runtime

This commit is contained in:
lix-2026
2026-05-25 22:56:16 +08:00
parent f0c01404c4
commit e90b8cb632
9 changed files with 369 additions and 162 deletions
@@ -77,73 +77,19 @@
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 shell = document.querySelector('.mnote-shell, .wolai-workspace-shell');
if (!(shell instanceof HTMLElement)) return;
var collapsed = shell.getAttribute('data-mnote-sidebar-collapsed') === 'true';
var next = !collapsed;
shell.setAttribute('data-mnote-sidebar-collapsed', String(next));
document.documentElement.setAttribute('data-mnote-sidebar-collapsed', String(next));
document.documentElement.setAttribute('data-mnote-sidebar-toggle-applied', 'true');
if (trigger instanceof HTMLElement) {
trigger.setAttribute('aria-pressed', String(next));
trigger.setAttribute('title', next ? '展开侧栏' : '切换侧栏');
}
var runtimeFn = sidebarShellRuntimeFunction('toggleWorkspaceSidebar');
if (runtimeFn) return runtimeFn(trigger);
}
function installWorkspaceSidebarResizer() {
var shell = document.querySelector('.mnote-shell, .wolai-workspace-shell');
var sidebar = document.querySelector('[data-testid="wolai-sidebar"]');
var resizer = document.querySelector('[data-mnote-sidebar-resizer="true"]');
if (!(shell instanceof HTMLElement) || !(sidebar instanceof HTMLElement) || !(resizer instanceof HTMLElement)) return;
if (resizer.getAttribute('data-mnote-sidebar-resizer-bound') === 'true') return;
resizer.setAttribute('data-mnote-sidebar-resizer-bound', 'true');
var storageKey = 'mnote.workspace.sidebarWidth.v1';
var minWidth = 220;
var maxWidth = 520;
function clampWidth(value) {
var width = Number(value);
if (!Number.isFinite(width)) return 248;
return Math.max(minWidth, Math.min(maxWidth, width));
}
function applyWidth(value) {
var width = clampWidth(value);
shell.style.setProperty('--mnote-sidebar-width', width + 'px');
document.documentElement.setAttribute('data-mnote-sidebar-width', String(width));
return width;
}
try {
var stored = Number(window.localStorage.getItem(storageKey) || '');
if (stored) applyWidth(stored);
} catch (_) {}
resizer.addEventListener('wheel', function(event) {
event.preventDefault();
event.stopPropagation();
}, { passive: false });
resizer.addEventListener('pointerdown', function(event) {
if (event.button !== 0) return;
event.preventDefault();
var startX = event.clientX;
var startWidth = sidebar.getBoundingClientRect().width || clampWidth(0);
resizer.setPointerCapture(event.pointerId);
document.documentElement.setAttribute('data-mnote-sidebar-resizing', 'true');
function onMove(moveEvent) {
applyWidth(startWidth + moveEvent.clientX - startX);
}
function onEnd(endEvent) {
resizer.removeEventListener('pointermove', onMove);
resizer.removeEventListener('pointerup', onEnd);
resizer.removeEventListener('pointercancel', onEnd);
try { resizer.releasePointerCapture(endEvent.pointerId); } catch (_) {}
document.documentElement.removeAttribute('data-mnote-sidebar-resizing');
try {
window.localStorage.setItem(storageKey, String(Math.round(sidebar.getBoundingClientRect().width)));
} catch (_) {}
}
resizer.addEventListener('pointermove', onMove);
resizer.addEventListener('pointerup', onEnd);
resizer.addEventListener('pointercancel', onEnd);
});
var runtimeFn = sidebarShellRuntimeFunction('installWorkspaceSidebarResizer');
if (runtimeFn) return runtimeFn();
}
function escapeHtml(value) {
@@ -680,6 +626,8 @@
}
function readStoredSidebarTreeMode() {
var runtimeFn = sidebarShellRuntimeFunction('readStoredSidebarTreeMode');
if (runtimeFn) return runtimeFn();
var params = new URLSearchParams(window.location.search);
var fromUrl = normalizeSidebarTreeMode(params.get('treeView') || params.get('sidebarTree'));
if (params.has('treeView') || params.has('sidebarTree')) return fromUrl;
@@ -692,6 +640,8 @@
}
function persistSidebarTreeMode(mode) {
var runtimeFn = sidebarShellRuntimeFunction('persistSidebarTreeMode');
if (runtimeFn) return runtimeFn(mode);
var normalized = normalizeSidebarTreeMode(mode);
document.documentElement.setAttribute('data-mnote-sidebar-tree-mode', normalized);
try {
@@ -701,6 +651,8 @@
}
function activeSidebarTreeMode() {
var runtimeFn = sidebarShellRuntimeFunction('activeSidebarTreeMode');
if (runtimeFn) return runtimeFn();
var active = document.querySelector('[data-mnote-sidebar-tree-tab][aria-selected="true"]');
if (active instanceof HTMLElement) {
return normalizeSidebarTreeMode(active.getAttribute('data-mnote-sidebar-tree-tab'));
@@ -1782,30 +1734,18 @@
}
function applySidebarTreeTab(mode, shell) {
mode = persistSidebarTreeMode(mode);
shell = shell || document.querySelector('[data-testid="wolai-sidebar-page-tree-shell"]');
if (!shell) return;
var tabs = shell.querySelectorAll('[data-mnote-sidebar-tree-tab]');
for (var i = 0; i < tabs.length; i++) {
var isActive = tabs[i].getAttribute('data-mnote-sidebar-tree-tab') === mode;
tabs[i].setAttribute('aria-selected', isActive ? 'true' : 'false');
tabs[i].classList.toggle('wolai-sidebar-tab-active', isActive);
tabs[i].classList.toggle('wolai-sidebar-tab-muted', !isActive);
}
var panels = shell.querySelectorAll('[data-mnote-sidebar-tree-panel]');
for (var j = 0; j < panels.length; j++) {
var isCurrentPanel = panels[j].getAttribute('data-mnote-sidebar-tree-panel') === mode;
panels[j].hidden = !isCurrentPanel;
}
var runtimeFn = sidebarShellRuntimeFunction('applySidebarTreeTab');
if (runtimeFn) return runtimeFn(mode, shell);
}
function switchSidebarTreeTab(trigger) {
var mode = trigger ? trigger.getAttribute('data-mnote-sidebar-tree-tab') : 'page';
applySidebarTreeTab(mode, trigger ? trigger.closest('[data-testid="wolai-sidebar-page-tree-shell"]') : null);
var runtimeFn = sidebarShellRuntimeFunction('switchSidebarTreeTab');
if (runtimeFn) return runtimeFn(trigger);
}
function restoreSidebarTreeTab() {
applySidebarTreeTab(readStoredSidebarTreeMode(), null);
var runtimeFn = sidebarShellRuntimeFunction('restoreSidebarTreeTab');
if (runtimeFn) return runtimeFn();
}
function updateTitleEverywhere(documentId, title) {