diff --git a/blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-caption-edit-modal.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-caption-edit-modal.ts similarity index 100% rename from blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-caption-edit-modal.ts rename to blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-caption-edit-modal.ts diff --git a/blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-create-modal.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-create-modal.ts similarity index 93% rename from blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-create-modal.ts rename to blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-create-modal.ts index 4e44c8ef9f..cfbefbedbf 100644 --- a/blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-create-modal.ts +++ b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-create-modal.ts @@ -6,6 +6,7 @@ import { EMBED_CARD_WIDTH, } from '@blocksuite/affine-shared/consts'; import { EmbedOptionProvider } from '@blocksuite/affine-shared/services'; +import { isValidUrl } from '@blocksuite/affine-shared/utils'; import type { EditorHost } from '@blocksuite/block-std'; import { ShadowlessElement } from '@blocksuite/block-std'; import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx'; @@ -15,8 +16,6 @@ import { html } from 'lit'; import { property, query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; -import type { EdgelessRootBlockComponent } from '../../../../root-block/edgeless/edgeless-root-block.js'; -import { getRootByEditorHost, isValidUrl } from '../../../utils/index.js'; import { embedCardModalStyles } from './styles.js'; export class EmbedCardCreateModal extends WithDisposable(ShadowlessElement) { @@ -64,13 +63,6 @@ export class EmbedCardCreateModal extends WithDisposable(ShadowlessElement) { targetStyle = embedOptions.styles[0]; } - const edgelessRoot = getRootByEditorHost( - this.host - ) as EdgelessRootBlockComponent | null; - if (!edgelessRoot) { - return; - } - const gfx = this.host.std.get(GfxControllerIdentifier); const crud = this.host.std.get(EdgelessCRUDIdentifier); @@ -95,7 +87,10 @@ export class EmbedCardCreateModal extends WithDisposable(ShadowlessElement) { surfaceModel ); - gfx.tool.setTool('default'); + gfx.tool.setTool( + // @ts-expect-error FIXME: resolve after gfx tool refactor + 'default' + ); } this.onConfirm(); this.remove(); diff --git a/blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-edit-modal.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-edit-modal.ts similarity index 99% rename from blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-edit-modal.ts rename to blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-edit-modal.ts index 2bdc565ed3..aa664b789c 100644 --- a/blocksuite/blocks/src/_common/components/embed-card/modal/embed-card-edit-modal.ts +++ b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/embed-card-edit-modal.ts @@ -37,8 +37,8 @@ import { choose } from 'lit/directives/choose.js'; import { classMap } from 'lit/directives/class-map.js'; import { live } from 'lit/directives/live.js'; -import type { LinkableEmbedModel } from '../type.js'; -import { isInternalEmbedModel } from '../type.js'; +import type { LinkableEmbedModel } from './type.js'; +import { isInternalEmbedModel } from './type.js'; export class EmbedCardEditModal extends SignalWatcher( WithDisposable(LitElement) diff --git a/blocksuite/affine/block-bookmark/src/components/embed-card-modal/index.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/index.ts new file mode 100644 index 0000000000..db8503be6e --- /dev/null +++ b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/index.ts @@ -0,0 +1,4 @@ +export * from './embed-card-caption-edit-modal'; +export * from './embed-card-create-modal'; +export * from './embed-card-edit-modal'; +export * from './type'; diff --git a/blocksuite/blocks/src/_common/components/embed-card/modal/styles.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/styles.ts similarity index 100% rename from blocksuite/blocks/src/_common/components/embed-card/modal/styles.ts rename to blocksuite/affine/block-bookmark/src/components/embed-card-modal/styles.ts diff --git a/blocksuite/blocks/src/_common/components/embed-card/type.ts b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/type.ts similarity index 89% rename from blocksuite/blocks/src/_common/components/embed-card/type.ts rename to blocksuite/affine/block-bookmark/src/components/embed-card-modal/type.ts index 233c852d8e..c420b8cb73 100644 --- a/blocksuite/blocks/src/_common/components/embed-card/type.ts +++ b/blocksuite/affine/block-bookmark/src/components/embed-card-modal/type.ts @@ -1,4 +1,3 @@ -import { BookmarkBlockComponent } from '@blocksuite/affine-block-bookmark'; import { EmbedFigmaBlockComponent, EmbedGithubBlockComponent, @@ -22,6 +21,8 @@ import { } from '@blocksuite/affine-model'; import type { BlockComponent } from '@blocksuite/block-std'; +import { BookmarkBlockComponent } from '../../bookmark-block'; + export type ExternalEmbedBlockComponent = | BookmarkBlockComponent | EmbedFigmaBlockComponent @@ -37,7 +38,7 @@ export type LinkableEmbedBlockComponent = | ExternalEmbedBlockComponent | InternalEmbedBlockComponent; -export type EmbedBlockComponent = +export type BuiltInEmbedBlockComponent = | LinkableEmbedBlockComponent | EmbedHtmlBlockComponent; @@ -52,11 +53,11 @@ export type InternalEmbedModel = EmbedLinkedDocModel | EmbedSyncedDocModel; export type LinkableEmbedModel = ExternalEmbedModel | InternalEmbedModel; -export type EmbedModel = LinkableEmbedModel | EmbedHtmlModel; +export type BuiltInEmbedModel = LinkableEmbedModel | EmbedHtmlModel; export function isEmbedCardBlockComponent( block: BlockComponent -): block is EmbedBlockComponent { +): block is BuiltInEmbedBlockComponent { return ( block instanceof BookmarkBlockComponent || block instanceof EmbedFigmaBlockComponent || @@ -70,7 +71,7 @@ export function isEmbedCardBlockComponent( } export function isInternalEmbedModel( - model: EmbedModel + model: BuiltInEmbedModel ): model is InternalEmbedModel { return ( model instanceof EmbedLinkedDocModel || model instanceof EmbedSyncedDocModel diff --git a/blocksuite/affine/block-bookmark/src/components/index.ts b/blocksuite/affine/block-bookmark/src/components/index.ts new file mode 100644 index 0000000000..fca078dd30 --- /dev/null +++ b/blocksuite/affine/block-bookmark/src/components/index.ts @@ -0,0 +1,2 @@ +export * from './bookmark-card'; +export * from './embed-card-modal'; diff --git a/blocksuite/affine/block-bookmark/src/effects.ts b/blocksuite/affine/block-bookmark/src/effects.ts index ea1c9c407b..3f0751a2b9 100644 --- a/blocksuite/affine/block-bookmark/src/effects.ts +++ b/blocksuite/affine/block-bookmark/src/effects.ts @@ -4,6 +4,11 @@ import type { BookmarkBlockService } from './bookmark-service'; import type { insertBookmarkCommand } from './commands/insert-bookmark'; import type { insertLinkByQuickSearchCommand } from './commands/insert-link-by-quick-search'; import { BookmarkCard } from './components/bookmark-card'; +import { + EmbedCardCreateModal, + EmbedCardEditCaptionEditModal, + EmbedCardEditModal, +} from './components/embed-card-modal'; export function effects() { customElements.define( @@ -12,6 +17,13 @@ export function effects() { ); customElements.define('affine-bookmark', BookmarkBlockComponent); customElements.define('bookmark-card', BookmarkCard); + + customElements.define('embed-card-create-modal', EmbedCardCreateModal); + customElements.define('embed-card-edit-modal', EmbedCardEditModal); + customElements.define( + 'embed-card-caption-edit-modal', + EmbedCardEditCaptionEditModal + ); } declare global { diff --git a/blocksuite/affine/block-bookmark/src/index.ts b/blocksuite/affine/block-bookmark/src/index.ts index 9c8f614b67..e0162267ca 100644 --- a/blocksuite/affine/block-bookmark/src/index.ts +++ b/blocksuite/affine/block-bookmark/src/index.ts @@ -2,3 +2,4 @@ export * from './adapters'; export * from './bookmark-block'; export * from './bookmark-service'; export * from './bookmark-spec'; +export * from './components'; diff --git a/blocksuite/affine/components/src/rich-text/dom.ts b/blocksuite/affine/components/src/rich-text/dom.ts index dbc6b35971..053d622b08 100644 --- a/blocksuite/affine/components/src/rich-text/dom.ts +++ b/blocksuite/affine/components/src/rich-text/dom.ts @@ -1,11 +1,13 @@ import { asyncGetBlockComponent, + getCurrentNativeRange, matchFlavours, } from '@blocksuite/affine-shared/utils'; import type { BlockStdScope, EditorHost } from '@blocksuite/block-std'; -import type { InlineRange } from '@blocksuite/inline'; -import type { BlockModel } from '@blocksuite/store'; +import type { InlineEditor, InlineRange } from '@blocksuite/inline'; +import { BlockModel } from '@blocksuite/store'; +import type { AffineInlineEditor } from './inline/index.js'; import type { RichText } from './rich-text.js'; /** @@ -109,3 +111,63 @@ export async function onModelTextUpdated( } }); } + +/** + * Remove specified text from the current range. + */ +export function cleanSpecifiedTail( + editorHost: EditorHost, + inlineEditorOrModel: AffineInlineEditor | BlockModel, + str: string +) { + if (!str) { + console.warn('Failed to clean text! Unexpected empty string'); + return; + } + const inlineEditor = + inlineEditorOrModel instanceof BlockModel + ? getInlineEditorByModel(editorHost, inlineEditorOrModel) + : inlineEditorOrModel; + if (!inlineEditor) { + return; + } + const inlineRange = inlineEditor.getInlineRange(); + if (!inlineRange) { + return; + } + const idx = inlineRange.index - str.length; + const textStr = inlineEditor.yText.toString().slice(idx, idx + str.length); + if (textStr !== str) { + console.warn( + `Failed to clean text! Text mismatch expected: ${str} but actual: ${textStr}` + ); + return; + } + inlineEditor.deleteText({ index: idx, length: str.length }); + inlineEditor.setInlineRange({ + index: idx, + length: 0, + }); +} + +export function getTextContentFromInlineRange( + inlineEditor: InlineEditor, + startRange: InlineRange | null +) { + const nativeRange = getCurrentNativeRange(); + if (!nativeRange) { + return null; + } + if (nativeRange.startContainer !== nativeRange.endContainer) { + return null; + } + const curRange = inlineEditor.getInlineRange(); + if (!startRange || !curRange) { + return null; + } + if (curRange.index < startRange.index) { + return null; + } + const text = inlineEditor.yText.toString(); + return text.slice(startRange.index, curRange.index); +} diff --git a/blocksuite/affine/components/src/rich-text/index.ts b/blocksuite/affine/components/src/rich-text/index.ts index 124dbd399d..cc079c2cfe 100644 --- a/blocksuite/affine/components/src/rich-text/index.ts +++ b/blocksuite/affine/components/src/rich-text/index.ts @@ -3,9 +3,11 @@ export { type TextConversionConfig, textConversionConfigs } from './conversion'; export { asyncGetRichText, asyncSetInlineRange, + cleanSpecifiedTail, focusTextModel, getInlineEditorByModel, getRichTextByModel, + getTextContentFromInlineRange, onModelTextUpdated, selectTextModel, } from './dom'; diff --git a/blocksuite/affine/shared/src/utils/event.ts b/blocksuite/affine/shared/src/utils/event.ts index d47508016d..56edcce8ea 100644 --- a/blocksuite/affine/shared/src/utils/event.ts +++ b/blocksuite/affine/shared/src/utils/event.ts @@ -194,3 +194,156 @@ export const captureEventTarget = (target: EventTarget | null) => { : target.parentElement : null; }; + +interface ObserverParams { + target: HTMLElement; + signal: AbortSignal; + onInput?: (isComposition: boolean) => void; + onDelete?: () => void; + onMove?: (step: 1 | -1) => void; + onConfirm?: () => void; + onAbort?: () => void; + onPaste?: () => void; + interceptor?: (e: KeyboardEvent, next: () => void) => void; +} + +/** + * @deprecated don't use this, use event dispatch instead + */ +export const createKeydownObserver = ({ + target, + signal, + onInput, + onDelete, + onMove, + onConfirm, + onAbort, + onPaste, + interceptor = (_, next) => next(), +}: ObserverParams) => { + const keyDownListener = (e: KeyboardEvent) => { + if (e.key === 'Process' || e.isComposing) return; + + if (e.defaultPrevented) return; + + if (isControlledKeyboardEvent(e)) { + const isOnlyCmd = (e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey; + // Ctrl/Cmd + alphabet key + if (isOnlyCmd && e.key.length === 1) { + switch (e.key) { + // Previous command + case 'p': { + onMove?.(-1); + e.stopPropagation(); + e.preventDefault(); + return; + } + // Next command + case 'n': { + onMove?.(1); + e.stopPropagation(); + e.preventDefault(); + return; + } + // Paste command + case 'v': { + onPaste?.(); + return; + } + } + } + + // Pressing **only** modifier key is allowed and will be ignored + // Because we don't know the user's intention + // Aborting here will cause the above hotkeys to not work + if (e.key === 'Control' || e.key === 'Meta' || e.key === 'Alt') { + e.stopPropagation(); + return; + } + + // Abort when press modifier key + any other key to avoid weird behavior + // e.g. press ctrl + a to select all + onAbort?.(); + return; + } + + e.stopPropagation(); + + if ( + // input abc, 123, etc. + !isControlledKeyboardEvent(e) && + e.key.length === 1 + ) { + onInput?.(false); + return; + } + + switch (e.key) { + case 'Backspace': { + onDelete?.(); + return; + } + case 'Enter': { + if (e.shiftKey) { + onAbort?.(); + return; + } + onConfirm?.(); + e.preventDefault(); + return; + } + case 'Tab': { + if (e.shiftKey) { + onMove?.(-1); + } else { + onMove?.(1); + } + e.preventDefault(); + return; + } + case 'ArrowUp': { + if (e.shiftKey) { + onAbort?.(); + return; + } + onMove?.(-1); + e.preventDefault(); + return; + } + case 'ArrowDown': { + if (e.shiftKey) { + onAbort?.(); + return; + } + onMove?.(1); + e.preventDefault(); + return; + } + case 'Escape': + case 'ArrowLeft': + case 'ArrowRight': { + onAbort?.(); + return; + } + default: + // Other control keys + return; + } + }; + + target.addEventListener( + 'keydown', + (e: KeyboardEvent) => interceptor(e, () => keyDownListener(e)), + { + // Workaround: Use capture to prevent the event from triggering the keyboard bindings action + capture: true, + signal, + } + ); + + // Fix paste input + target.addEventListener('paste', () => onDelete?.(), { signal }); + + // Fix composition input + target.addEventListener('compositionend', () => onInput?.(true), { signal }); +}; diff --git a/blocksuite/blocks/src/_common/components/embed-card/modal/index.ts b/blocksuite/blocks/src/_common/components/embed-card/modal/index.ts deleted file mode 100644 index df177666cf..0000000000 --- a/blocksuite/blocks/src/_common/components/embed-card/modal/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './embed-card-create-modal.js'; -export * from './embed-card-edit-modal.js'; diff --git a/blocksuite/blocks/src/_common/components/utils.ts b/blocksuite/blocks/src/_common/components/utils.ts deleted file mode 100644 index 34d900ae37..0000000000 --- a/blocksuite/blocks/src/_common/components/utils.ts +++ /dev/null @@ -1,219 +0,0 @@ -import type { AffineInlineEditor } from '@blocksuite/affine-components/rich-text'; -import { getInlineEditorByModel } from '@blocksuite/affine-components/rich-text'; -import { - getCurrentNativeRange, - isControlledKeyboardEvent, -} from '@blocksuite/affine-shared/utils'; -import type { EditorHost } from '@blocksuite/block-std'; -import type { InlineEditor, InlineRange } from '@blocksuite/inline'; -import { BlockModel } from '@blocksuite/store'; - -export function getQuery( - inlineEditor: InlineEditor, - startRange: InlineRange | null -) { - const nativeRange = getCurrentNativeRange(); - if (!nativeRange) { - return null; - } - if (nativeRange.startContainer !== nativeRange.endContainer) { - return null; - } - const curRange = inlineEditor.getInlineRange(); - if (!startRange || !curRange) { - return null; - } - if (curRange.index < startRange.index) { - return null; - } - const text = inlineEditor.yText.toString(); - return text.slice(startRange.index, curRange.index); -} - -interface ObserverParams { - target: HTMLElement; - signal: AbortSignal; - onInput?: (isComposition: boolean) => void; - onDelete?: () => void; - onMove?: (step: 1 | -1) => void; - onConfirm?: () => void; - onAbort?: () => void; - onPaste?: () => void; - interceptor?: (e: KeyboardEvent, next: () => void) => void; -} - -export const createKeydownObserver = ({ - target, - signal, - onInput, - onDelete, - onMove, - onConfirm, - onAbort, - onPaste, - interceptor = (_, next) => next(), -}: ObserverParams) => { - const keyDownListener = (e: KeyboardEvent) => { - if (e.key === 'Process' || e.isComposing) return; - - if (e.defaultPrevented) return; - - if (isControlledKeyboardEvent(e)) { - const isOnlyCmd = (e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey; - // Ctrl/Cmd + alphabet key - if (isOnlyCmd && e.key.length === 1) { - switch (e.key) { - // Previous command - case 'p': { - onMove?.(-1); - e.stopPropagation(); - e.preventDefault(); - return; - } - // Next command - case 'n': { - onMove?.(1); - e.stopPropagation(); - e.preventDefault(); - return; - } - // Paste command - case 'v': { - onPaste?.(); - return; - } - } - } - - // Pressing **only** modifier key is allowed and will be ignored - // Because we don't know the user's intention - // Aborting here will cause the above hotkeys to not work - if (e.key === 'Control' || e.key === 'Meta' || e.key === 'Alt') { - e.stopPropagation(); - return; - } - - // Abort when press modifier key + any other key to avoid weird behavior - // e.g. press ctrl + a to select all - onAbort?.(); - return; - } - - e.stopPropagation(); - - if ( - // input abc, 123, etc. - !isControlledKeyboardEvent(e) && - e.key.length === 1 - ) { - onInput?.(false); - return; - } - - switch (e.key) { - case 'Backspace': { - onDelete?.(); - return; - } - case 'Enter': { - if (e.shiftKey) { - onAbort?.(); - return; - } - onConfirm?.(); - e.preventDefault(); - return; - } - case 'Tab': { - if (e.shiftKey) { - onMove?.(-1); - } else { - onMove?.(1); - } - e.preventDefault(); - return; - } - case 'ArrowUp': { - if (e.shiftKey) { - onAbort?.(); - return; - } - onMove?.(-1); - e.preventDefault(); - return; - } - case 'ArrowDown': { - if (e.shiftKey) { - onAbort?.(); - return; - } - onMove?.(1); - e.preventDefault(); - return; - } - case 'Escape': - case 'ArrowLeft': - case 'ArrowRight': { - onAbort?.(); - return; - } - default: - // Other control keys - return; - } - }; - - target.addEventListener( - 'keydown', - (e: KeyboardEvent) => interceptor(e, () => keyDownListener(e)), - { - // Workaround: Use capture to prevent the event from triggering the keyboard bindings action - capture: true, - signal, - } - ); - - // Fix paste input - target.addEventListener('paste', () => onDelete?.(), { signal }); - - // Fix composition input - target.addEventListener('compositionend', () => onInput?.(true), { signal }); -}; - -/** - * Remove specified text from the current range. - */ -export function cleanSpecifiedTail( - editorHost: EditorHost, - inlineEditorOrModel: AffineInlineEditor | BlockModel, - str: string -) { - if (!str) { - console.warn('Failed to clean text! Unexpected empty string'); - return; - } - const inlineEditor = - inlineEditorOrModel instanceof BlockModel - ? getInlineEditorByModel(editorHost, inlineEditorOrModel) - : inlineEditorOrModel; - if (!inlineEditor) { - return; - } - const inlineRange = inlineEditor.getInlineRange(); - if (!inlineRange) { - return; - } - const idx = inlineRange.index - str.length; - const textStr = inlineEditor.yText.toString().slice(idx, idx + str.length); - if (textStr !== str) { - console.warn( - `Failed to clean text! Text mismatch expected: ${str} but actual: ${textStr}` - ); - return; - } - inlineEditor.deleteText({ index: idx, length: str.length }); - inlineEditor.setInlineRange({ - index: idx, - length: 0, - }); -} diff --git a/blocksuite/blocks/src/effects.ts b/blocksuite/blocks/src/effects.ts index 52990613a7..d61e6c3fcd 100644 --- a/blocksuite/blocks/src/effects.ts +++ b/blocksuite/blocks/src/effects.ts @@ -33,9 +33,6 @@ import { effects as dataViewEffects } from '@blocksuite/data-view/effects'; import { effects as inlineEffects } from '@blocksuite/inline/effects'; import type { BlockModel } from '@blocksuite/store'; -import { EmbedCardEditCaptionEditModal } from './_common/components/embed-card/modal/embed-card-caption-edit-modal.js'; -import { EmbedCardCreateModal } from './_common/components/embed-card/modal/embed-card-create-modal.js'; -import { EmbedCardEditModal } from './_common/components/embed-card/modal/embed-card-edit-modal.js'; import { registerSpecs } from './_specs/register-specs.js'; import { DataViewBlockComponent } from './data-view-block/index.js'; import { CenterPeek } from './database-block/components/layout.js'; @@ -372,15 +369,9 @@ export function effects() { ); customElements.define('edgeless-align-panel', EdgelessAlignPanel); customElements.define('card-style-panel', CardStylePanel); - customElements.define( - 'embed-card-caption-edit-modal', - EmbedCardEditCaptionEditModal - ); customElements.define('edgeless-color-button', EdgelessColorButton); customElements.define('edgeless-color-panel', EdgelessColorPanel); customElements.define('edgeless-text-color-icon', EdgelessTextColorIcon); - customElements.define('embed-card-create-modal', EmbedCardCreateModal); - customElements.define('embed-card-edit-modal', EmbedCardEditModal); customElements.define( 'edgeless-mindmap-tool-button', EdgelessMindmapToolButton diff --git a/blocksuite/blocks/src/root-block/widgets/element-toolbar/change-embed-card-button.ts b/blocksuite/blocks/src/root-block/widgets/element-toolbar/change-embed-card-button.ts index 2bb506e71d..018e4250da 100644 --- a/blocksuite/blocks/src/root-block/widgets/element-toolbar/change-embed-card-button.ts +++ b/blocksuite/blocks/src/root-block/widgets/element-toolbar/change-embed-card-button.ts @@ -1,3 +1,11 @@ +import type { + BuiltInEmbedBlockComponent, + BuiltInEmbedModel, +} from '@blocksuite/affine-block-bookmark'; +import { + isInternalEmbedModel, + toggleEmbedCardEditModal, +} from '@blocksuite/affine-block-bookmark'; import { getDocContentWithMaxLength, getEmbedCardIcons, @@ -44,12 +52,6 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import { join } from 'lit/directives/join.js'; import { repeat } from 'lit/directives/repeat.js'; -import { toggleEmbedCardEditModal } from '../../../_common/components/embed-card/modal/embed-card-edit-modal.js'; -import type { - EmbedBlockComponent, - EmbedModel, -} from '../../../_common/components/embed-card/type.js'; -import { isInternalEmbedModel } from '../../../_common/components/embed-card/type.js'; import type { EmbedCardStyle } from '../../../_common/types.js'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; import { @@ -373,7 +375,7 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) { const blockComponent = this.std.view.getBlock( blockSelection[0].blockId - ) as EmbedBlockComponent | null; + ) as BuiltInEmbedBlockComponent | null; if (!blockComponent) return; @@ -837,7 +839,7 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) { accessor edgeless!: EdgelessRootBlockComponent; @property({ attribute: false }) - accessor model!: EmbedModel; + accessor model!: BuiltInEmbedModel; @property({ attribute: false }) accessor quickConnectButton!: TemplateResult<1> | typeof nothing; @@ -861,7 +863,7 @@ export function renderEmbedButton( function track( std: BlockStdScope, - model: EmbedModel, + model: BuiltInEmbedModel, viewType: string, event: LinkEventType, props: Partial diff --git a/blocksuite/blocks/src/root-block/widgets/element-toolbar/index.ts b/blocksuite/blocks/src/root-block/widgets/element-toolbar/index.ts index e76773a0e5..b27ec9f897 100644 --- a/blocksuite/blocks/src/root-block/widgets/element-toolbar/index.ts +++ b/blocksuite/blocks/src/root-block/widgets/element-toolbar/index.ts @@ -1,3 +1,4 @@ +import type { BuiltInEmbedModel } from '@blocksuite/affine-block-bookmark'; import { CommonUtils } from '@blocksuite/affine-block-surface'; import { ConnectorCWithArrowIcon } from '@blocksuite/affine-components/icons'; import { @@ -38,7 +39,6 @@ import { css, html, nothing, type TemplateResult, unsafeCSS } from 'lit'; import { property, state } from 'lit/decorators.js'; import { join } from 'lit/directives/join.js'; -import type { EmbedModel } from '../../../_common/components/embed-card/type.js'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; import { isAttachmentBlock, @@ -79,7 +79,7 @@ type CategorizedElements = { image?: ImageBlockModel[]; attachment?: AttachmentBlockModel[]; mindmap?: MindmapElementModel[]; - embedCard?: EmbedModel[]; + embedCard?: BuiltInEmbedModel[]; edgelessText?: EdgelessTextBlockModel[]; }; diff --git a/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/context.ts b/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/context.ts index 24b59bedb8..549a1c9ffa 100644 --- a/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/context.ts +++ b/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/context.ts @@ -1,7 +1,6 @@ +import type { BuiltInEmbedBlockComponent } from '@blocksuite/affine-block-bookmark'; import { MenuContext } from '@blocksuite/affine-components/toolbar'; -import type { EmbedBlockComponent } from '../../../_common/components/embed-card/type.js'; - export class EmbedCardToolbarContext extends MenuContext { override close = () => { this.abortController.abort(); @@ -25,7 +24,7 @@ export class EmbedCardToolbarContext extends MenuContext { } constructor( - public blockComponent: EmbedBlockComponent, + public blockComponent: BuiltInEmbedBlockComponent, public abortController: AbortController ) { super(); diff --git a/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/embed-card-toolbar.ts b/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/embed-card-toolbar.ts index 3573b41378..c85b4e2a10 100644 --- a/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/embed-card-toolbar.ts +++ b/blocksuite/blocks/src/root-block/widgets/embed-card-toolbar/embed-card-toolbar.ts @@ -1,3 +1,11 @@ +import { + type BuiltInEmbedBlockComponent, + type BuiltInEmbedModel, + isEmbedCardBlockComponent, + isInternalEmbedModel, + toggleEmbedCardCaptionEditModal, + toggleEmbedCardEditModal, +} from '@blocksuite/affine-block-bookmark'; import { getDocContentWithMaxLength, getEmbedCardIcons, @@ -54,14 +62,6 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import { join } from 'lit/directives/join.js'; import { repeat } from 'lit/directives/repeat.js'; -import { toggleEmbedCardCaptionEditModal } from '../../../_common/components/embed-card/modal/embed-card-caption-edit-modal.js'; -import { toggleEmbedCardEditModal } from '../../../_common/components/embed-card/modal/embed-card-edit-modal.js'; -import { - type EmbedBlockComponent, - type EmbedModel, - isEmbedCardBlockComponent, - isInternalEmbedModel, -} from '../../../_common/components/embed-card/type.js'; import { isBookmarkBlock, isEmbedGithubBlock, @@ -303,7 +303,7 @@ export class EmbedCardToolbar extends WidgetComponent< return 'inline'; } - get focusModel(): EmbedModel | undefined { + get focusModel(): BuiltInEmbedModel | undefined { return this.focusBlock?.model; } @@ -726,7 +726,7 @@ export class EmbedCardToolbar extends WidgetComponent< return; } - this.focusBlock = block as EmbedBlockComponent; + this.focusBlock = block as BuiltInEmbedBlockComponent; this._show(); }) ); @@ -848,7 +848,7 @@ export class EmbedCardToolbar extends WidgetComponent< accessor embedCardToolbarElement!: HTMLElement; @state() - accessor focusBlock: EmbedBlockComponent | null = null; + accessor focusBlock: BuiltInEmbedBlockComponent | null = null; @state() accessor hide: boolean = true; @@ -865,7 +865,7 @@ declare global { function track( std: BlockStdScope, - model: EmbedModel, + model: BuiltInEmbedModel, viewType: string, event: LinkEventType, props: Partial diff --git a/blocksuite/blocks/src/root-block/widgets/keyboard-toolbar/config.ts b/blocksuite/blocks/src/root-block/widgets/keyboard-toolbar/config.ts index 3844584000..085fa55400 100644 --- a/blocksuite/blocks/src/root-block/widgets/keyboard-toolbar/config.ts +++ b/blocksuite/blocks/src/root-block/widgets/keyboard-toolbar/config.ts @@ -1,4 +1,5 @@ import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment'; +import { toggleEmbedCardCreateModal } from '@blocksuite/affine-block-bookmark'; import { getSurfaceBlock } from '@blocksuite/affine-block-surface'; import { getInlineEditorByModel, @@ -61,7 +62,6 @@ import { computed } from '@preact/signals-core'; import { cssVarV2 } from '@toeverything/theme/v2'; import type { TemplateResult } from 'lit'; -import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js'; import type { PageRootBlockComponent } from '../../page/page-root-block.js'; import { formatDate, formatTime } from '../../utils/misc.js'; import type { AffineLinkedDocWidget } from '../linked-doc/index.js'; diff --git a/blocksuite/blocks/src/root-block/widgets/linked-doc/linked-doc-popover.ts b/blocksuite/blocks/src/root-block/widgets/linked-doc/linked-doc-popover.ts index d1b121bab2..d866b55a5b 100644 --- a/blocksuite/blocks/src/root-block/widgets/linked-doc/linked-doc-popover.ts +++ b/blocksuite/blocks/src/root-block/widgets/linked-doc/linked-doc-popover.ts @@ -2,6 +2,11 @@ import { LoadingIcon } from '@blocksuite/affine-block-image'; import type { IconButton } from '@blocksuite/affine-components/icon-button'; import { MoreHorizontalIcon } from '@blocksuite/affine-components/icons'; import { + cleanSpecifiedTail, + getTextContentFromInlineRange, +} from '@blocksuite/affine-components/rich-text'; +import { + createKeydownObserver, getCurrentNativeRange, getViewportElement, } from '@blocksuite/affine-shared/utils'; @@ -15,11 +20,6 @@ import { html, LitElement, nothing } from 'lit'; import { property, query, queryAll, state } from 'lit/decorators.js'; import { styleMap } from 'lit/directives/style-map.js'; -import { - cleanSpecifiedTail, - createKeydownObserver, - getQuery, -} from '../../../_common/components/utils.js'; import { getPopperPosition } from '../../utils/position.js'; import type { LinkedDocContext, LinkedMenuGroup } from './config.js'; import { linkedDocPopoverStyles } from './styles.js'; @@ -86,7 +86,10 @@ export class LinkedDocPopover extends SignalWatcher( } private get _query() { - return getQuery(this.context.inlineEditor, this.context.startRange); + return getTextContentFromInlineRange( + this.context.inlineEditor, + this.context.startRange + ); } private _getActionItems(group: LinkedMenuGroup) { diff --git a/blocksuite/blocks/src/root-block/widgets/linked-doc/mobile-linked-doc-menu.ts b/blocksuite/blocks/src/root-block/widgets/linked-doc/mobile-linked-doc-menu.ts index 5487676c89..b00bdfe56c 100644 --- a/blocksuite/blocks/src/root-block/widgets/linked-doc/mobile-linked-doc-menu.ts +++ b/blocksuite/blocks/src/root-block/widgets/linked-doc/mobile-linked-doc-menu.ts @@ -1,8 +1,15 @@ +import { + cleanSpecifiedTail, + getTextContentFromInlineRange, +} from '@blocksuite/affine-components/rich-text'; import { VirtualKeyboardController, type VirtualKeyboardControllerConfig, } from '@blocksuite/affine-components/virtual-keyboard'; -import { getViewportElement } from '@blocksuite/affine-shared/utils'; +import { + createKeydownObserver, + getViewportElement, +} from '@blocksuite/affine-shared/utils'; import { PropTypes, requiredProperties } from '@blocksuite/block-std'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { MoreHorizontalIcon } from '@blocksuite/icons/lit'; @@ -12,11 +19,6 @@ import { property } from 'lit/decorators.js'; import { join } from 'lit/directives/join.js'; import { repeat } from 'lit/directives/repeat.js'; -import { - cleanSpecifiedTail, - createKeydownObserver, - getQuery, -} from '../../../_common/components/utils.js'; import { PageRootBlockComponent } from '../../index.js'; import type { LinkedDocContext, @@ -151,7 +153,10 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher( private _updateLinkedDocGroupAbortController: AbortController | null = null; private get _query() { - return getQuery(this.context.inlineEditor, this.context.startRange); + return getTextContentFromInlineRange( + this.context.inlineEditor, + this.context.startRange + ); } get virtualKeyboardControllerConfig(): VirtualKeyboardControllerConfig { diff --git a/blocksuite/blocks/src/root-block/widgets/slash-menu/config.ts b/blocksuite/blocks/src/root-block/widgets/slash-menu/config.ts index c79f931589..59135fb9ed 100644 --- a/blocksuite/blocks/src/root-block/widgets/slash-menu/config.ts +++ b/blocksuite/blocks/src/root-block/widgets/slash-menu/config.ts @@ -1,4 +1,5 @@ import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment'; +import { toggleEmbedCardCreateModal } from '@blocksuite/affine-block-bookmark'; import { FigmaIcon, GithubIcon, @@ -50,7 +51,6 @@ import type { BlockModel } from '@blocksuite/store'; import { Slice, Text } from '@blocksuite/store'; import type { TemplateResult } from 'lit'; -import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js'; import type { DataViewBlockComponent } from '../../../data-view-block/index.js'; import type { RootBlockComponent } from '../../types.js'; import { formatDate, formatTime } from '../../utils/misc.js'; diff --git a/blocksuite/blocks/src/root-block/widgets/slash-menu/slash-menu-popover.ts b/blocksuite/blocks/src/root-block/widgets/slash-menu/slash-menu-popover.ts index c879fff1b6..f57bc3b993 100644 --- a/blocksuite/blocks/src/root-block/widgets/slash-menu/slash-menu-popover.ts +++ b/blocksuite/blocks/src/root-block/widgets/slash-menu/slash-menu-popover.ts @@ -1,8 +1,13 @@ import { ArrowDownIcon } from '@blocksuite/affine-components/icons'; import { createLitPortal } from '@blocksuite/affine-components/portal'; import type { AffineInlineEditor } from '@blocksuite/affine-components/rich-text'; -import { getInlineEditorByModel } from '@blocksuite/affine-components/rich-text'; import { + cleanSpecifiedTail, + getInlineEditorByModel, + getTextContentFromInlineRange, +} from '@blocksuite/affine-components/rich-text'; +import { + createKeydownObserver, isControlledKeyboardEvent, isFuzzyMatch, substringMatchScore, @@ -14,11 +19,6 @@ import { property, query, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { styleMap } from 'lit/directives/style-map.js'; -import { - cleanSpecifiedTail, - createKeydownObserver, - getQuery, -} from '../../../_common/components/utils.js'; import type { SlashMenuActionItem, SlashMenuContext, @@ -144,7 +144,7 @@ export class SlashMenu extends WithDisposable(LitElement) { }; private get _query() { - return getQuery(this.inlineEditor, this._startRange); + return getTextContentFromInlineRange(this.inlineEditor, this._startRange); } get host() {