From 9d38f79395cd8356478a5024a1a80503f12b1493 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Thu, 14 Aug 2025 14:49:53 +0800 Subject: [PATCH] fix(editor): deactivate editor when selection out of editor (#13490) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close [AI-415](https://linear.app/affine-design/issue/AI-415/code-artifact-复制更好的支持code-block和插入正文) #### PR Dependency Tree * **PR #13490** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Bug Fixes** * Editor now deactivates when text selection moves outside the app, preventing unintended interactions. * Better handling when selection changes to external content, reducing cases where the editor stayed active incorrectly. * **Stability** * Improved reliability around selection, focus, and visibility changes to avoid accidental edits or actions. #### PR Dependency Tree * **PR #13490** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) --- blocksuite/framework/std/src/event/dispatcher.ts | 12 ++++++++++++ tests/blocksuite/e2e/link.spec.ts | 2 ++ 2 files changed, 14 insertions(+) diff --git a/blocksuite/framework/std/src/event/dispatcher.ts b/blocksuite/framework/std/src/event/dispatcher.ts index 8d567893c..244ab4e49 100644 --- a/blocksuite/framework/std/src/event/dispatcher.ts +++ b/blocksuite/framework/std/src/event/dispatcher.ts @@ -226,6 +226,18 @@ export class UIEventDispatcher extends LifeCycleWatcher { this._setActive(false); } }); + // When the selection is outside the host, the event dispatcher should be inactive + this.disposables.addFromEvent(document, 'selectionchange', () => { + const sel = document.getSelection(); + if (!sel || sel.rangeCount === 0) return; + const { anchorNode, focusNode } = sel; + if ( + (anchorNode && !this.host.contains(anchorNode)) || + (focusNode && !this.host.contains(focusNode)) + ) { + this._setActive(false); + } + }); } private _buildEventScopeBySelection(name: EventName) { diff --git a/tests/blocksuite/e2e/link.spec.ts b/tests/blocksuite/e2e/link.spec.ts index 2e47dd765..cc113d857 100644 --- a/tests/blocksuite/e2e/link.spec.ts +++ b/tests/blocksuite/e2e/link.spec.ts @@ -241,6 +241,7 @@ test('should keyboard work in link popover', async ({ page }) => { const toolbar = page.locator('affine-toolbar-widget editor-toolbar'); const linkLocator = page.locator(`text="${linkText}"`); + await focusRichText(page); // hover link await linkLocator.hover(); // wait for popover delay open @@ -294,6 +295,7 @@ test('link bar should not be appear when the range is collapsed', async ({ // create auto line-break in span element await type(page, 'd'.repeat(67)); await page.mouse.click(1, 1); + await focusRichText(page); await waitNextFrame(page); await dragBetweenIndices(page, [1, 1], [1, 66]); await pressCreateLinkShortCut(page);