From 66ea3038afb2c07b46fb796f2f458d2c16432ae1 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Thu, 20 Mar 2025 10:40:11 +0000 Subject: [PATCH] refactor(editor): align rich text util apis (#11039) --- .../configs/slash-menu.ts | 6 +-- .../block-note/src/commands/block-type.ts | 4 +- .../blocks/block-note/src/note-keymap.ts | 2 +- .../src/commands/split-paragraph.ts | 4 +- .../block-paragraph/src/paragraph-keymap.ts | 10 +---- .../src/utils/merge-with-prev.ts | 2 +- .../src/widgets/keyboard-toolbar/config.ts | 14 +++---- .../widgets/linked-doc/linked-doc-popover.ts | 2 +- .../linked-doc/mobile-linked-doc-menu.ts | 2 +- blocksuite/affine/rich-text/src/dom.ts | 37 ++++++++----------- .../affine/rich-text/src/format/utils.ts | 6 +-- .../affine/rich-text/src/keymap/basic.ts | 4 +- .../affine/rich-text/src/keymap/bracket.ts | 6 +-- .../rich-text/src/markdown/markdown-input.ts | 2 +- .../affine/shared/src/utils/model/getter.ts | 10 ++--- .../widgets/widget-slash-menu/src/config.ts | 8 ++-- .../src/slash-menu-popover.ts | 4 +- .../widgets/widget-slash-menu/src/widget.ts | 7 +--- 18 files changed, 57 insertions(+), 73 deletions(-) diff --git a/blocksuite/affine/blocks/block-embed/src/embed-linked-doc-block/configs/slash-menu.ts b/blocksuite/affine/blocks/block-embed/src/embed-linked-doc-block/configs/slash-menu.ts index 18450d0fe9..ffb1ad0ff4 100644 --- a/blocksuite/affine/blocks/block-embed/src/embed-linked-doc-block/configs/slash-menu.ts +++ b/blocksuite/affine/blocks/block-embed/src/embed-linked-doc-block/configs/slash-menu.ts @@ -29,7 +29,7 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = { model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc'), action: ({ std, model }) => { const newDoc = createDefaultDoc(std.host.doc.workspace); - insertContent(std.host, model, REFERENCE_NODE, { + insertContent(std, model, REFERENCE_NODE, { reference: { type: 'LinkedPage', pageId: newDoc.id, @@ -70,9 +70,9 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = { // @ts-expect-error same as above const triggerKey = linkedDocWidget.config.triggerKeys[0]; - insertContent(std.host, model, triggerKey); + insertContent(std, model, triggerKey); - const inlineEditor = getInlineEditorByModel(std.host, model); + const inlineEditor = getInlineEditorByModel(std, model); if (inlineEditor) { // Wait for range to be updated const subscription = inlineEditor.slots.inlineRangeSync.subscribe( diff --git a/blocksuite/affine/blocks/block-note/src/commands/block-type.ts b/blocksuite/affine/blocks/block-note/src/commands/block-type.ts index ab965d006e..bf35ad3197 100644 --- a/blocksuite/affine/blocks/block-note/src/commands/block-type.ts +++ b/blocksuite/affine/blocks/block-note/src/commands/block-type.ts @@ -86,7 +86,7 @@ export const updateBlockType: Command< if (!id) return; const model = doc.getModelById(id); if (!model) return; - asyncSetInlineRange(host, model, { + asyncSetInlineRange(std, model, { index: model.text?.length ?? 0, length: 0, }).catch(console.error); @@ -132,7 +132,7 @@ export const updateBlockType: Command< const lastNewModel = updatedBlocks[updatedBlocks.length - 1]; const allTextUpdated = updatedBlocks.map(model => - onModelTextUpdated(host, model) + onModelTextUpdated(std, model) ); const selectionManager = host.selection; const textSelection = selectionManager.find(TextSelection); diff --git a/blocksuite/affine/blocks/block-note/src/note-keymap.ts b/blocksuite/affine/blocks/block-note/src/note-keymap.ts index 1090bca4fe..6e468a6ef5 100644 --- a/blocksuite/affine/blocks/block-note/src/note-keymap.ts +++ b/blocksuite/affine/blocks/block-note/src/note-keymap.ts @@ -119,7 +119,7 @@ class NoteKeymap { } const [codeModel] = newModels; - asyncGetBlockComponent(ctx.std.host, codeModel.id) + asyncGetBlockComponent(ctx.std, codeModel.id) .then(codeElement => { if (!codeElement) { return; diff --git a/blocksuite/affine/blocks/block-paragraph/src/commands/split-paragraph.ts b/blocksuite/affine/blocks/block-paragraph/src/commands/split-paragraph.ts index f66b73d130..3d4310b7fe 100644 --- a/blocksuite/affine/blocks/block-paragraph/src/commands/split-paragraph.ts +++ b/blocksuite/affine/blocks/block-paragraph/src/commands/split-paragraph.ts @@ -15,7 +15,7 @@ export const splitParagraphCommand: Command< } > = (ctx, next) => { const { std } = ctx; - const { store, host, selection } = std; + const { store, selection } = std; let blockId = ctx.blockId; if (!blockId) { const text = selection.find(TextSelection); @@ -26,7 +26,7 @@ export const splitParagraphCommand: Command< const model = store.getBlock(blockId)?.model; if (!model || !matchModels(model, [ParagraphBlockModel])) return; - const inlineEditor = getInlineEditorByModel(host, model); + const inlineEditor = getInlineEditorByModel(std, model); const range = inlineEditor?.getInlineRange(); if (!range) return; diff --git a/blocksuite/affine/blocks/block-paragraph/src/paragraph-keymap.ts b/blocksuite/affine/blocks/block-paragraph/src/paragraph-keymap.ts index c414bf1bf7..42db42629a 100644 --- a/blocksuite/affine/blocks/block-paragraph/src/paragraph-keymap.ts +++ b/blocksuite/affine/blocks/block-paragraph/src/paragraph-keymap.ts @@ -83,10 +83,7 @@ export const ParagraphKeymapExtension = KeymapExtension( matchModels(model.parent, [CalloutBlockModel]) ) return; - const inlineEditor = getInlineEditorByModel( - std.host, - text.from.blockId - ); + const inlineEditor = getInlineEditorByModel(std, text.from.blockId); const inlineRange = inlineEditor?.getInlineRange(); if (!inlineRange || !inlineEditor) return; const raw = ctx.get('keyboardState').raw; @@ -115,10 +112,7 @@ export const ParagraphKeymapExtension = KeymapExtension( matchModels(model.parent, [CalloutBlockModel]) ) return; - const inlineEditor = getInlineEditorByModel( - std.host, - text.from.blockId - ); + const inlineEditor = getInlineEditorByModel(std, text.from.blockId); const inlineRange = inlineEditor?.getInlineRange(); if (!inlineRange || !inlineEditor) return; diff --git a/blocksuite/affine/blocks/block-paragraph/src/utils/merge-with-prev.ts b/blocksuite/affine/blocks/block-paragraph/src/utils/merge-with-prev.ts index e69a1f03bb..2cddc68170 100644 --- a/blocksuite/affine/blocks/block-paragraph/src/utils/merge-with-prev.ts +++ b/blocksuite/affine/blocks/block-paragraph/src/utils/merge-with-prev.ts @@ -77,7 +77,7 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) { doc.deleteBlock(model, { bringChildrenTo: parent, }); - asyncSetInlineRange(editorHost, prevBlock, { + asyncSetInlineRange(editorHost.std, prevBlock, { index: lengthBeforeJoin, length: 0, }).catch(console.error); diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts index dba2951485..a0dd83fdf7 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts @@ -318,7 +318,7 @@ const pageToolGroup: KeyboardToolPanelGroup = { .pipe(({ selectedModels }) => { const newDoc = createDefaultDoc(std.store.workspace); if (!selectedModels?.length) return; - insertContent(std.host, selectedModels[0], REFERENCE_NODE, { + insertContent(std, selectedModels[0], REFERENCE_NODE, { reference: { type: 'LinkedPage', pageId: newDoc.id, @@ -360,9 +360,9 @@ const pageToolGroup: KeyboardToolPanelGroup = { if (!selectedModels?.length) return; const currentModel = selectedModels[0]; - insertContent(std.host, currentModel, triggerKey); + insertContent(std, currentModel, triggerKey); - const inlineEditor = getInlineEditorByModel(std.host, currentModel); + const inlineEditor = getInlineEditorByModel(std, currentModel); // Wait for range to be updated if (inlineEditor) { const subscription = inlineEditor.slots.inlineRangeSync.subscribe( @@ -702,7 +702,7 @@ const dateToolGroup: KeyboardToolPanelGroup = { const model = selectedModels?.[0]; if (!model) return; - insertContent(std.host, model, formatDate(new Date())); + insertContent(std, model, formatDate(new Date())); }, }, { @@ -717,7 +717,7 @@ const dateToolGroup: KeyboardToolPanelGroup = { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); - insertContent(std.host, model, formatDate(tomorrow)); + insertContent(std, model, formatDate(tomorrow)); }, }, { @@ -732,7 +732,7 @@ const dateToolGroup: KeyboardToolPanelGroup = { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); - insertContent(std.host, model, formatDate(yesterday)); + insertContent(std, model, formatDate(yesterday)); }, }, { @@ -745,7 +745,7 @@ const dateToolGroup: KeyboardToolPanelGroup = { const model = selectedModels?.[0]; if (!model) return; - insertContent(std.host, model, formatTime(new Date())); + insertContent(std, model, formatTime(new Date())); }, }, ], diff --git a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/linked-doc-popover.ts b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/linked-doc-popover.ts index 56d223829b..51aa9e8f08 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/linked-doc-popover.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/linked-doc-popover.ts @@ -38,7 +38,7 @@ export class LinkedDocPopover extends SignalWatcher( this.context.close(); // clear input query cleanSpecifiedTail( - this.context.std.host, + this.context.std, this.context.inlineEditor, this.context.triggerKey + (this._query || '') ); diff --git a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts index afe4c61253..45e92b5943 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts @@ -134,7 +134,7 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher( () => { this.context.close(); cleanSpecifiedTail( - this.context.std.host, + this.context.std, this.context.inlineEditor, this.context.triggerKey + (this._query ?? '') ); diff --git a/blocksuite/affine/rich-text/src/dom.ts b/blocksuite/affine/rich-text/src/dom.ts index 6bfd347e98..831277b89d 100644 --- a/blocksuite/affine/rich-text/src/dom.ts +++ b/blocksuite/affine/rich-text/src/dom.ts @@ -4,29 +4,24 @@ import { getCurrentNativeRange, matchModels, } from '@blocksuite/affine-shared/utils'; -import { - type BlockStdScope, - type EditorHost, - TextSelection, -} from '@blocksuite/block-std'; +import { type BlockStdScope, TextSelection } from '@blocksuite/block-std'; import type { InlineEditor, InlineRange } from '@blocksuite/block-std/inline'; import { BlockModel } from '@blocksuite/store'; -import type { AffineInlineEditor } from './inline/index.js'; import type { RichText } from './rich-text.js'; /** * In most cases, you not need RichText, you can use {@link getInlineEditorByModel} instead. */ -export function getRichTextByModel(editorHost: EditorHost, id: string) { - const blockComponent = editorHost.view.getBlock(id); +export function getRichTextByModel(std: BlockStdScope, id: string) { + const blockComponent = std.view.getBlock(id); const richText = blockComponent?.querySelector('rich-text'); if (!richText) return null; return richText; } -export async function asyncGetRichText(editorHost: EditorHost, id: string) { - const blockComponent = await asyncGetBlockComponent(editorHost, id); +export async function asyncGetRichText(std: BlockStdScope, id: string) { + const blockComponent = await asyncGetBlockComponent(std, id); if (!blockComponent) return null; await blockComponent.updateComplete; const richText = blockComponent?.querySelector('rich-text'); @@ -35,29 +30,27 @@ export async function asyncGetRichText(editorHost: EditorHost, id: string) { } export function getInlineEditorByModel( - editorHost: EditorHost, + std: BlockStdScope, model: BlockModel | string ) { const blockModel = - typeof model === 'string' - ? editorHost.std.store.getBlock(model)?.model - : model; + typeof model === 'string' ? std.store.getBlock(model)?.model : model; if (!blockModel || matchModels(blockModel, [DatabaseBlockModel])) { // Not support database model since it's may be have multiple inline editor instances. // Support to enter the editing state through the Enter key in the database. return null; } - const richText = getRichTextByModel(editorHost, blockModel.id); + const richText = getRichTextByModel(std, blockModel.id); if (!richText) return null; return richText.inlineEditor; } export async function asyncSetInlineRange( - editorHost: EditorHost, + std: BlockStdScope, model: BlockModel, inlineRange: InlineRange ) { - const richText = await asyncGetRichText(editorHost, model.id); + const richText = await asyncGetRichText(std, model.id); if (!richText) { return; } @@ -94,11 +87,11 @@ export function selectTextModel( } export async function onModelTextUpdated( - editorHost: EditorHost, + std: BlockStdScope, model: BlockModel, callback?: (text: RichText) => void ) { - const richText = await asyncGetRichText(editorHost, model.id); + const richText = await asyncGetRichText(std, model.id); if (!richText) { console.error('RichText is not ready yet.'); return; @@ -121,8 +114,8 @@ export async function onModelTextUpdated( * Remove specified text from the current range. */ export function cleanSpecifiedTail( - editorHost: EditorHost, - inlineEditorOrModel: AffineInlineEditor | BlockModel, + std: BlockStdScope, + inlineEditorOrModel: InlineEditor | BlockModel, str: string ) { if (!str) { @@ -131,7 +124,7 @@ export function cleanSpecifiedTail( } const inlineEditor = inlineEditorOrModel instanceof BlockModel - ? getInlineEditorByModel(editorHost, inlineEditorOrModel) + ? getInlineEditorByModel(std, inlineEditorOrModel) : inlineEditorOrModel; if (!inlineEditor) { return; diff --git a/blocksuite/affine/rich-text/src/format/utils.ts b/blocksuite/affine/rich-text/src/format/utils.ts index d2b84d92e4..1e9f7217f4 100644 --- a/blocksuite/affine/rich-text/src/format/utils.ts +++ b/blocksuite/affine/rich-text/src/format/utils.ts @@ -7,8 +7,8 @@ import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; import { BLOCK_ID_ATTR, type BlockComponent, + type BlockStdScope, type Chain, - type EditorHost, type InitCommandCtx, } from '@blocksuite/block-std'; import { @@ -233,7 +233,7 @@ export function clearMarksOnDiscontinuousInput( } export function insertContent( - editorHost: EditorHost, + std: BlockStdScope, model: BlockModel, text: string, attributes?: AffineTextAttributes @@ -242,7 +242,7 @@ export function insertContent( console.error("Can't insert text! Text not found"); return; } - const inlineEditor = getInlineEditorByModel(editorHost, model); + const inlineEditor = getInlineEditorByModel(std, model); if (!inlineEditor) { console.error("Can't insert text! Inline editor not found"); return; diff --git a/blocksuite/affine/rich-text/src/keymap/basic.ts b/blocksuite/affine/rich-text/src/keymap/basic.ts index bdab1fd0f9..e580ad8aa2 100644 --- a/blocksuite/affine/rich-text/src/keymap/basic.ts +++ b/blocksuite/affine/rich-text/src/keymap/basic.ts @@ -18,14 +18,14 @@ export const textCommonKeymap = ( ArrowUp: () => { const text = std.selection.find(TextSelection); if (!text) return; - const inline = getInlineEditorByModel(std.host, text.from.blockId); + const inline = getInlineEditorByModel(std, text.from.blockId); if (!inline) return; return !inline.isFirstLine(inline.getInlineRange()); }, ArrowDown: () => { const text = std.selection.find(TextSelection); if (!text) return; - const inline = getInlineEditorByModel(std.host, text.from.blockId); + const inline = getInlineEditorByModel(std, text.from.blockId); if (!inline) return; return !inline.isLastLine(inline.getInlineRange()); }, diff --git a/blocksuite/affine/rich-text/src/keymap/bracket.ts b/blocksuite/affine/rich-text/src/keymap/bracket.ts index e39e0d535e..6021c31458 100644 --- a/blocksuite/affine/rich-text/src/keymap/bracket.ts +++ b/blocksuite/affine/rich-text/src/keymap/bracket.ts @@ -28,7 +28,7 @@ export const bracketKeymap = ( if (!model) return; if (!matchModels(model, [CodeBlockModel])) return; const inlineEditor = getInlineEditorByModel( - std.host, + std, textSelection.from.blockId ); if (!inlineEditor) return; @@ -61,7 +61,7 @@ export const bracketKeymap = ( ctx.get('keyboardState').raw.preventDefault(); const inlineEditor = getInlineEditorByModel( - std.host, + std, textSelection.from.blockId ); if (!inlineEditor) return; @@ -107,7 +107,7 @@ export const bracketKeymap = ( ctx.get('keyboardState').raw.preventDefault(); const inlineEditor = getInlineEditorByModel( - std.host, + std, textSelection.from.blockId ); if (!inlineEditor) return; diff --git a/blocksuite/affine/rich-text/src/markdown/markdown-input.ts b/blocksuite/affine/rich-text/src/markdown/markdown-input.ts index ee422d3377..d84f87543e 100644 --- a/blocksuite/affine/rich-text/src/markdown/markdown-input.ts +++ b/blocksuite/affine/rich-text/src/markdown/markdown-input.ts @@ -29,7 +29,7 @@ export function markdownInput( if (!id) return; const model = std.store.getBlock(id)?.model; if (!model) return; - const inline = getInlineEditorByModel(std.host, model); + const inline = getInlineEditorByModel(std, model); if (!inline) return; const range = inline.getInlineRange(); if (!range) return; diff --git a/blocksuite/affine/shared/src/utils/model/getter.ts b/blocksuite/affine/shared/src/utils/model/getter.ts index 850a71db1e..93a298ce28 100644 --- a/blocksuite/affine/shared/src/utils/model/getter.ts +++ b/blocksuite/affine/shared/src/utils/model/getter.ts @@ -1,5 +1,5 @@ import { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model'; -import type { BlockComponent, EditorHost } from '@blocksuite/block-std'; +import type { BlockComponent, BlockStdScope } from '@blocksuite/block-std'; import type { BlockModel, Store } from '@blocksuite/store'; import { matchModels } from './checker.js'; @@ -23,16 +23,16 @@ export function findAncestorModel( * */ export async function asyncGetBlockComponent( - editorHost: EditorHost, + std: BlockStdScope, id: string ): Promise { - const rootBlockId = editorHost.doc.root?.id; + const rootBlockId = std.store.root?.id; if (!rootBlockId) return null; - const rootComponent = editorHost.view.getBlock(rootBlockId); + const rootComponent = std.view.getBlock(rootBlockId); if (!rootComponent) return null; await rootComponent.updateComplete; - return editorHost.view.getBlock(id); + return std.view.getBlock(id); } export function findNoteBlockModel(model: BlockModel) { diff --git a/blocksuite/affine/widgets/widget-slash-menu/src/config.ts b/blocksuite/affine/widgets/widget-slash-menu/src/config.ts index bcea7c4ec2..8a08368c12 100644 --- a/blocksuite/affine/widgets/widget-slash-menu/src/config.ts +++ b/blocksuite/affine/widgets/widget-slash-menu/src/config.ts @@ -37,7 +37,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = { description: formatDate(now), group: '6_Date@0', action: ({ std, model }) => { - insertContent(std.host, model, formatDate(now)); + insertContent(std, model, formatDate(now)); }, }, { @@ -49,7 +49,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = { action: ({ std, model }) => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); - insertContent(std.host, model, formatDate(tomorrow)); + insertContent(std, model, formatDate(tomorrow)); }, }, { @@ -61,7 +61,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = { action: ({ std, model }) => { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); - insertContent(std.host, model, formatDate(yesterday)); + insertContent(std, model, formatDate(yesterday)); }, }, { @@ -71,7 +71,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = { description: formatTime(now), group: '6_Date@3', action: ({ std, model }) => { - insertContent(std.host, model, formatTime(now)); + insertContent(std, model, formatTime(now)); }, }, { diff --git a/blocksuite/affine/widgets/widget-slash-menu/src/slash-menu-popover.ts b/blocksuite/affine/widgets/widget-slash-menu/src/slash-menu-popover.ts index e7f2c2e5d7..44b913500a 100644 --- a/blocksuite/affine/widgets/widget-slash-menu/src/slash-menu-popover.ts +++ b/blocksuite/affine/widgets/widget-slash-menu/src/slash-menu-popover.ts @@ -56,7 +56,7 @@ export class SlashMenu extends WithDisposable(LitElement) { // We must to do clean the slash string before we do the action // Otherwise, the action may change the model and cause the slash string to be changed cleanSpecifiedTail( - this.host, + this.context.std, this.context.model, AFFINE_SLASH_MENU_TRIGGER_KEY + (this._query || '') ); @@ -496,7 +496,7 @@ export class InnerSlashMenu extends WithDisposable(LitElement) { }); const inlineEditor = getInlineEditorByModel( - this.context.std.host, + this.context.std, this.context.model ); diff --git a/blocksuite/affine/widgets/widget-slash-menu/src/widget.ts b/blocksuite/affine/widgets/widget-slash-menu/src/widget.ts index 7ff1a8658a..3207bd64b2 100644 --- a/blocksuite/affine/widgets/widget-slash-menu/src/widget.ts +++ b/blocksuite/affine/widgets/widget-slash-menu/src/widget.ts @@ -39,10 +39,7 @@ const showSlashMenu = debounce( disposables.dispose() ); - const inlineEditor = getInlineEditorByModel( - context.std.host, - context.model - ); + const inlineEditor = getInlineEditorByModel(context.std, context.model); if (!inlineEditor) return; const slashMenu = new SlashMenu(inlineEditor, abortController); disposables.add(() => slashMenu.remove()); @@ -84,7 +81,7 @@ export class AffineSlashMenuWidget extends WidgetComponent { const model = this.host.doc.getBlock(textSelection.blockId)?.model; if (!model) return; - return getInlineEditorByModel(this.host, model); + return getInlineEditorByModel(this.std, model); }; private readonly _handleInput = (