diff --git a/rust/crates/mnote-web/src/routes/web_shell.rs b/rust/crates/mnote-web/src/routes/web_shell.rs index a61d868e..f82c73ed 100644 --- a/rust/crates/mnote-web/src/routes/web_shell.rs +++ b/rust/crates/mnote-web/src/routes/web_shell.rs @@ -3044,6 +3044,17 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str { }); }; + const bindMainEditorPageTab = () => { + const nodes = resourceTabHostNodes(); + if (!(nodes.pageTab instanceof HTMLElement)) return; + if (nodes.pageTab.getAttribute('data-mnote-page-tab-bound') === 'true') return; + nodes.pageTab.setAttribute('data-mnote-page-tab-bound', 'true'); + nodes.pageTab.addEventListener('click', (event) => { + event.preventDefault(); + activateMainEditorTab(''); + }); + }; + const closeResourceTab = (objectIdentity) => { const key = String(objectIdentity || '').trim(); const entry = resourceTabRegistry.get(key); @@ -3206,6 +3217,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str { }; const openResourceInActiveTab = async (input = {}) => { + bindMainEditorPageTab(); const objectIdentity = String(input.objectIdentity || input.assetId || input.href || '').trim(); if (!objectIdentity) return false; const existing = resourceTabRegistry.get(objectIdentity); @@ -3317,6 +3329,8 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str { }, }; + bindMainEditorPageTab(); + window.addEventListener('pagehide', () => { Array.from(documentSessionRegistry.values()).forEach((session) => { sessionViews(session).forEach((view) => { diff --git a/rust/crates/mnote-web/src/ssr/pages/layout.rs b/rust/crates/mnote-web/src/ssr/pages/layout.rs index 04acbef0..b3f81ba0 100644 --- a/rust/crates/mnote-web/src/ssr/pages/layout.rs +++ b/rust/crates/mnote-web/src/ssr/pages/layout.rs @@ -7486,17 +7486,16 @@ const SIDEBAR_TREE_JS: &str = r##" openEditorAttachmentLink(editorAttachmentLink); } - window.addEventListener('mousedown', interceptEditorAttachmentLink, true); - window.addEventListener('click', interceptEditorAttachmentLink, true); - - document.addEventListener('click', function(e) { - var editorAttachmentLink = closestAction(e.target, '.editor-surface .ProseMirror a[data-mnote-attachment-link="true"], .editor-surface .ProseMirror a.mnote-uploaded-attachment-row'); + function suppressEditorAttachmentLinkDefault(event) { + var editorAttachmentLink = closestAction(event.target, '.editor-surface .ProseMirror a[data-mnote-attachment-link="true"], .editor-surface .ProseMirror a.mnote-uploaded-attachment-row'); if (!(editorAttachmentLink instanceof HTMLAnchorElement)) return; - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation(); - openEditorAttachmentLink(editorAttachmentLink); - }, true); + event.preventDefault(); + event.stopPropagation(); + if (typeof event.stopImmediatePropagation === 'function') event.stopImmediatePropagation(); + } + + window.addEventListener('mousedown', suppressEditorAttachmentLinkDefault, true); + window.addEventListener('click', interceptEditorAttachmentLink, true); document.addEventListener('mouseover', function(event) { var link = closestAction(event.target, '.editor-surface .ProseMirror a[data-mnote-attachment-link="true"], .editor-surface .ProseMirror a.mnote-uploaded-attachment-row'); diff --git a/scripts/task459-local-markdown-attachment-tab-smoke.js b/scripts/task459-local-markdown-attachment-tab-smoke.js index 45066445..247ba32d 100644 --- a/scripts/task459-local-markdown-attachment-tab-smoke.js +++ b/scripts/task459-local-markdown-attachment-tab-smoke.js @@ -117,10 +117,31 @@ async function main() { const resourceText = await resourceEditor.innerText({ timeout: UI_TIMEOUT_MS }); assert(resourceText.includes("资源正文"), `MD 附件应在资源 tab 中用 tiptap 打开:${resourceText}`); assert.equal(popups.length, 0, `点击 MD 附件不应打开浏览器新窗口,实际 popup=${popups.length}`); + + const pageTab = page.locator('[data-mnote-main-tab="page"]').first(); + await pageTab.click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction(() => { + const pagePanel = document.querySelector("[data-mnote-page-tab-panel]"); + const resourceHost = document.querySelector("[data-mnote-resource-tab-host]"); + const pageTab = document.querySelector('[data-mnote-main-tab="page"]'); + return pagePanel && !pagePanel.hidden + && resourceHost && resourceHost.hidden + && pageTab && pageTab.classList.contains("is-active"); + }, null, { timeout: UI_TIMEOUT_MS }); + const pageText = await page.locator('.document-pane[data-pane-role="primary"] .editor-surface .ProseMirror').first().innerText({ timeout: UI_TIMEOUT_MS, }); assert(pageText.includes("resource-note.md"), "主页面正文应保持原附件链接"); + + const resourceTab = page.locator('.mnote-main-tab[data-mnote-tab-kind="markdown"]').first(); + await resourceTab.click({ timeout: UI_TIMEOUT_MS }); + await page.locator('.mnote-main-tab.is-active[data-mnote-tab-kind="markdown"]').waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await resourceEditor.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + console.log(JSON.stringify({ ok: true, root, documentId, popups: popups.length }, null, 2)); } finally { await context.close().catch(() => undefined);