From 162b7adc1bbb68a3e00c0b7b89dd1fc8b8453b61 Mon Sep 17 00:00:00 2001 From: fundon Date: Mon, 24 Feb 2025 11:10:04 +0000 Subject: [PATCH] fix(editor): should check text length and stop event propagation when adding a link (#10391) --- .../components/src/rich-text/format/config.ts | 12 +++++++- .../components/src/rich-text/keymap/format.ts | 8 ++++- .../hooks/use-register-workspace-commands.ts | 30 ++----------------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/blocksuite/affine/components/src/rich-text/format/config.ts b/blocksuite/affine/components/src/rich-text/format/config.ts index 7277540eb..5e89954f7 100644 --- a/blocksuite/affine/components/src/rich-text/format/config.ts +++ b/blocksuite/affine/components/src/rich-text/format/config.ts @@ -1,4 +1,4 @@ -import type { EditorHost } from '@blocksuite/block-std'; +import { type EditorHost, TextSelection } from '@blocksuite/block-std'; import type { TemplateResult } from 'lit'; import { @@ -26,6 +26,7 @@ export interface TextFormatConfig { hotkey?: string; activeWhen: (host: EditorHost) => boolean; action: (host: EditorHost) => void; + textChecker?: (host: EditorHost) => boolean; } export const textFormatConfigs: TextFormatConfig[] = [ @@ -124,5 +125,14 @@ export const textFormatConfigs: TextFormatConfig[] = [ action: host => { host.std.command.chain().pipe(toggleLink).run(); }, + // should check text length + textChecker: host => { + const textSelection = host.std.selection.find(TextSelection); + if (!textSelection || textSelection.isCollapsed()) return false; + + return Boolean( + textSelection.from.length + (textSelection.to?.length ?? 0) + ); + }, }, ]; diff --git a/blocksuite/affine/components/src/rich-text/keymap/format.ts b/blocksuite/affine/components/src/rich-text/keymap/format.ts index 548920607..0f4a7bd04 100644 --- a/blocksuite/affine/components/src/rich-text/keymap/format.ts +++ b/blocksuite/affine/components/src/rich-text/keymap/format.ts @@ -20,8 +20,14 @@ export const textFormatKeymap = (std: BlockStdScope) => const textSelection = selection.find(TextSelection); if (!textSelection) return; + const allowed = config.textChecker?.(std.host) ?? true; + if (!allowed) return; + + const event = ctx.get('keyboardState').raw; + event.stopPropagation(); + event.preventDefault(); + config.action(std.host); - ctx.get('keyboardState').raw.preventDefault(); return true; }, }; diff --git a/packages/frontend/core/src/components/hooks/use-register-workspace-commands.ts b/packages/frontend/core/src/components/hooks/use-register-workspace-commands.ts index 8e64f9c09..11d14784e 100644 --- a/packages/frontend/core/src/components/hooks/use-register-workspace-commands.ts +++ b/packages/frontend/core/src/components/hooks/use-register-workspace-commands.ts @@ -8,13 +8,11 @@ import { I18nService } from '@affine/core/modules/i18n'; import { UrlService } from '@affine/core/modules/url'; import { WorkspaceService } from '@affine/core/modules/workspace'; import { useI18n } from '@affine/i18n'; -import { TextSelection } from '@blocksuite/affine/block-std'; import { useService, useServiceOptional } from '@toeverything/infra'; import { useStore } from 'jotai'; import { useTheme } from 'next-themes'; import { useEffect } from 'react'; -import type { AffineEditorContainer } from '../../blocksuite/block-suite-editor'; import { usePageHelper } from '../../blocksuite/block-suite-page-list/utils'; import { PreconditionStrategy, @@ -29,40 +27,19 @@ import { } from '../../commands'; import { EditorSettingService } from '../../modules/editor-setting'; import { CMDKQuickSearchService } from '../../modules/quicksearch/services/cmdk'; -import { useActiveBlocksuiteEditor } from './use-block-suite-editor'; import { useNavigateHelper } from './use-navigate-helper'; -function hasLinkPopover(editor: AffineEditorContainer | null) { - const textSelection = editor?.host?.std.selection.find(TextSelection); - if (editor && textSelection && textSelection.from.length > 0) { - const formatBar = editor.host?.querySelector('affine-format-bar-widget'); - if (formatBar) { - return true; - } - } - return false; -} - -function registerCMDKCommand( - service: CMDKQuickSearchService, - editor: AffineEditorContainer | null -) { +function registerCMDKCommand(service: CMDKQuickSearchService) { return registerAffineCommand({ id: 'affine:show-quick-search', preconditionStrategy: PreconditionStrategy.Never, category: 'affine:general', keyBinding: { binding: '$mod+K', - capture: true, }, label: '', icon: '', run() { - // Due to a conflict with the shortcut for creating a link after selecting text in blocksuite, - // opening the quick search modal is disabled when link-popup is visitable. - if (hasLinkPopover(editor)) { - return; - } service.toggle(); }, }); @@ -76,7 +53,6 @@ export function useRegisterWorkspaceCommands() { const urlService = useService(UrlService); const pageHelper = usePageHelper(currentWorkspace.docCollection); const navigationHelper = useNavigateHelper(); - const [editor] = useActiveBlocksuiteEditor(); const cmdkQuickSearchService = useService(CMDKQuickSearchService); const editorSettingService = useService(EditorSettingService); const workspaceDialogService = useService(WorkspaceDialogService); @@ -88,12 +64,12 @@ export function useRegisterWorkspaceCommands() { useServiceOptional(DesktopApiService)?.handler.updater.quitAndInstall; useEffect(() => { - const unsub = registerCMDKCommand(cmdkQuickSearchService, editor); + const unsub = registerCMDKCommand(cmdkQuickSearchService); return () => { unsub(); }; - }, [cmdkQuickSearchService, editor]); + }, [cmdkQuickSearchService]); // register AffineUpdatesCommands useEffect(() => {