From 22e4bd8c204de22a002d97dcf7a41721306b9294 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Fri, 21 Feb 2025 09:01:57 +0000 Subject: [PATCH] refactor: move image proxy middleware and adapter extensions (#10345) ### TL;DR Moved image proxy middleware and adapter extensions to their respective packages and introduced a new spec provider for adapter registration. ### What changed? - Relocated `defaultImageProxyMiddleware` from blocks to `@blocksuite/affine-block-image` - Moved `PresentTool` from fragment-frame-panel to block-frame - Created new adapter extension specs for HTML, Markdown, and Notion HTML - Introduced a spec provider pattern for adapter registration - Removed direct transformer references from RootService - Updated imports across affected files to use new locations ### How to test? 1. Verify image proxy functionality works in exports and imports 2. Test HTML, Markdown, and Notion HTML adapters still function correctly 3. Confirm presentation mode works with the relocated PresentTool 4. Check that all file import/export operations continue to work as expected ### Why make this change? This reorganization improves code modularity by placing features in their logical packages and introduces a more maintainable pattern for adapter registration. The spec provider pattern makes it easier to manage and extend adapter functionality while reducing coupling between components. --- .../src/adapters/notion-html.ts | 8 +- .../src/common/render-linked-doc.ts | 2 +- .../embed-linked-doc-block/adapters/html.ts | 4 +- .../adapters/markdown.ts | 4 +- .../adapters/plain-text.ts | 4 +- .../embed-edgeless-synced-doc-block.ts | 4 +- .../embed-synced-doc-block.ts | 6 +- blocksuite/affine/block-frame/src/index.ts | 1 + .../src/tool.ts | 3 +- .../affine/block-image/src/adapters/index.ts | 1 + .../affine/block-list/src/adapters/html.ts | 6 +- .../block-list/src/adapters/markdown.ts | 10 +- .../block-surface-ref/src/portal/note.ts | 2 +- .../src/surface-ref-block.ts | 2 +- .../affine/block-table/src/adapters/utils.ts | 7 +- .../inline/adapters/html/inline-delta.ts | 4 +- .../inline/adapters/markdown/inline-delta.ts | 4 +- .../adapters/plain-text/inline-delta.ts | 4 +- .../affine/fragment-frame-panel/src/index.ts | 1 - blocksuite/affine/model/src/utils/types.ts | 13 +++ .../src/adapters/html/delta-converter.ts | 4 +- .../src/adapters/middlewares/doc-link.ts | 44 +++++++ .../src/adapters/middlewares/file-name.ts | 23 ++++ .../shared/src/adapters/middlewares/index.ts | 4 + .../src/adapters/middlewares/replace-id.ts} | 107 +----------------- .../shared/src/adapters/middlewares/title.ts | 11 ++ .../affine/shared/src/adapters/utils/text.ts | 2 +- .../shared/src/utils/spec/spec-provider.ts | 32 +++--- .../src/helpers/preview-helper.ts | 2 +- .../src/__tests__/adapters/html.unit.spec.ts | 6 +- .../__tests__/adapters/markdown.unit.spec.ts | 6 +- .../adapters/plain-text.unit.spec.ts | 6 +- .../blocks/src/__tests__/utils/create-job.ts | 2 +- .../blocks/src/_common/transformers/index.ts | 15 --- blocksuite/blocks/src/_common/types.ts | 11 -- blocksuite/blocks/src/_specs/common.ts | 9 ++ .../blocks/src/_specs/preset/adapters.ts | 31 +++++ .../src/_specs/preset/edgeless-specs.ts | 2 +- .../blocks/src/_specs/register-specs.ts | 7 +- blocksuite/blocks/src/index.ts | 27 +---- .../root-block/clipboard/page-clipboard.ts | 2 +- .../clipboard/readonly-clipboard.ts | 6 +- .../components/frame/frame-preview.ts | 2 +- .../root-block/edgeless/edgeless-keyboard.ts | 10 +- .../edgeless/edgeless-root-block.ts | 2 +- .../mind-map-ext/mind-map-ext.ts | 2 +- .../edgeless/gfx-tool/default-tool.ts | 2 +- .../src/root-block/edgeless/utils/crud.ts | 2 +- .../edgeless/utils/mindmap.ts} | 0 .../src/root-block/edgeless/utils/query.ts | 3 +- blocksuite/blocks/src/root-block/index.ts | 1 + .../blocks/src/root-block/root-service.ts | 11 -- .../transformers/html.ts | 39 +++---- .../src/root-block/transformers/index.ts | 5 + .../transformers/markdown.ts | 40 ++++--- .../transformers/notion-html.ts | 23 ++-- .../transformers/utils.ts | 0 .../transformers/zip.ts | 5 +- .../linked-doc/import-doc/import-doc.ts | 6 +- .../src/__tests__/main/snapshot.spec.ts | 11 +- .../presets/ai/messages/slides-renderer.ts | 2 +- .../specs/custom/root-block.ts | 4 +- .../block-suite-editor/specs/preview.ts | 9 +- .../editor/edgeless/snapshot.tsx | 2 +- 64 files changed, 301 insertions(+), 329 deletions(-) rename blocksuite/affine/{fragment-frame-panel => block-frame}/src/tool.ts (85%) create mode 100644 blocksuite/affine/shared/src/adapters/middlewares/doc-link.ts create mode 100644 blocksuite/affine/shared/src/adapters/middlewares/file-name.ts rename blocksuite/{blocks/src/_common/transformers/middlewares.ts => affine/shared/src/adapters/middlewares/replace-id.ts} (69%) create mode 100644 blocksuite/affine/shared/src/adapters/middlewares/title.ts delete mode 100644 blocksuite/blocks/src/_common/transformers/index.ts delete mode 100644 blocksuite/blocks/src/_common/types.ts create mode 100644 blocksuite/blocks/src/_specs/preset/adapters.ts rename blocksuite/blocks/src/{_common/edgeless/mindmap/index.ts => root-block/edgeless/utils/mindmap.ts} (100%) rename blocksuite/blocks/src/{_common => root-block}/transformers/html.ts (90%) create mode 100644 blocksuite/blocks/src/root-block/transformers/index.ts rename blocksuite/blocks/src/{_common => root-block}/transformers/markdown.ts (92%) rename blocksuite/blocks/src/{_common => root-block}/transformers/notion-html.ts (91%) rename blocksuite/blocks/src/{_common => root-block}/transformers/utils.ts (100%) rename blocksuite/blocks/src/{_common => root-block}/transformers/zip.ts (97%) diff --git a/blocksuite/affine/block-database/src/adapters/notion-html.ts b/blocksuite/affine/block-database/src/adapters/notion-html.ts index 5d3869bd3..a8b7fcb41 100644 --- a/blocksuite/affine/block-database/src/adapters/notion-html.ts +++ b/blocksuite/affine/block-database/src/adapters/notion-html.ts @@ -1,9 +1,9 @@ import { DatabaseBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockNotionHtmlAdapterExtension, type BlockNotionHtmlAdapterMatcher, HastUtils, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import { getTagColor } from '@blocksuite/data-view'; import { type BlockSnapshot, nanoid } from '@blocksuite/store'; @@ -219,7 +219,7 @@ export const databaseBlockNotionHtmlAdapterMatcher: BlockNotionHtmlAdapterMatche column.type = 'rich-text'; row[column.id] = { columnId: column.id, - value: TextUtils.createText(text), + value: AdapterTextUtils.createText(text), }; } else { row[column.id] = { @@ -235,11 +235,11 @@ export const databaseBlockNotionHtmlAdapterMatcher: BlockNotionHtmlAdapterMatche } if ( column.type === 'rich-text' && - !TextUtils.isText(row[column.id].value) + !AdapterTextUtils.isText(row[column.id].value) ) { row[column.id] = { columnId: column.id, - value: TextUtils.createText(row[column.id].value), + value: AdapterTextUtils.createText(row[column.id].value), }; } }); diff --git a/blocksuite/affine/block-embed/src/common/render-linked-doc.ts b/blocksuite/affine/block-embed/src/common/render-linked-doc.ts index 3ed5f5cd4..a978d1982 100644 --- a/blocksuite/affine/block-embed/src/common/render-linked-doc.ts +++ b/blocksuite/affine/block-embed/src/common/render-linked-doc.ts @@ -197,7 +197,7 @@ async function renderNoteContent( match: ids.map(id => ({ id, viewType: 'display' })), }; const previewDoc = doc.doc.getStore({ query }); - const previewSpec = SpecProvider.getInstance().getSpec('page:preview'); + const previewSpec = SpecProvider.getInstance().getSpec('preview:page'); const previewStd = new BlockStdScope({ store: previewDoc, extensions: previewSpec.value, diff --git a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/html.ts b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/html.ts index cd81dac2a..59ab7c22a 100644 --- a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/html.ts +++ b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/html.ts @@ -1,8 +1,8 @@ import { EmbedLinkedDocBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockHtmlAdapterExtension, type BlockHtmlAdapterMatcher, - TextUtils, } from '@blocksuite/affine-shared/adapters'; export const embedLinkedDocBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { @@ -18,7 +18,7 @@ export const embedLinkedDocBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { return; } const title = configs.get('title:' + o.node.props.pageId) ?? 'untitled'; - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(o.node.props.pageId), o.node.props.params ?? Object.create(null) diff --git a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/markdown.ts b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/markdown.ts index eafa6b52a..796a67ac3 100644 --- a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/markdown.ts +++ b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/markdown.ts @@ -1,8 +1,8 @@ import { EmbedLinkedDocBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockMarkdownAdapterExtension, type BlockMarkdownAdapterMatcher, - TextUtils, } from '@blocksuite/affine-shared/adapters'; export const embedLinkedDocBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher = @@ -19,7 +19,7 @@ export const embedLinkedDocBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatc return; } const title = configs.get('title:' + o.node.props.pageId) ?? 'untitled'; - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(o.node.props.pageId), o.node.props.params ?? Object.create(null) diff --git a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/plain-text.ts b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/plain-text.ts index 2df2e154e..c8b6c7291 100644 --- a/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/plain-text.ts +++ b/blocksuite/affine/block-embed/src/embed-linked-doc-block/adapters/plain-text.ts @@ -1,8 +1,8 @@ import { EmbedLinkedDocBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockPlainTextAdapterExtension, type BlockPlainTextAdapterMatcher, - TextUtils, } from '@blocksuite/affine-shared/adapters'; export const embedLinkedDocBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMatcher = @@ -19,7 +19,7 @@ export const embedLinkedDocBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMa return; } const title = configs.get('title:' + o.node.props.pageId) ?? 'untitled'; - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(o.node.props.pageId), o.node.props.params ?? Object.create(null) diff --git a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-edgeless-synced-doc-block.ts b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-edgeless-synced-doc-block.ts index 00600120d..3aac6d216 100644 --- a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-edgeless-synced-doc-block.ts +++ b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-edgeless-synced-doc-block.ts @@ -70,7 +70,7 @@ export class EmbedEdgelessSyncedDocBlockComponent extends toEdgelessEmbedBlock(
${new BlockStdScope({ store: syncedDoc, - extensions: this._buildPreviewSpec('page:preview'), + extensions: this._buildPreviewSpec('preview:page'), }).render()}
`, @@ -81,7 +81,7 @@ export class EmbedEdgelessSyncedDocBlockComponent extends toEdgelessEmbedBlock(
${new BlockStdScope({ store: syncedDoc, - extensions: this._buildPreviewSpec('edgeless:preview'), + extensions: this._buildPreviewSpec('preview:edgeless'), }).render()}
`, diff --git a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts index 5c10b2438..32f9438ec 100644 --- a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts +++ b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts @@ -116,7 +116,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent { + protected _buildPreviewSpec = (name: 'preview:page' | 'preview:edgeless') => { const nextDepth = this.depth + 1; const previewSpecBuilder = SpecProvider.getInstance().getSpec(name); const currentDisposables = this.disposables; @@ -203,7 +203,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent ${new BlockStdScope({ store: syncedDoc, - extensions: this._buildPreviewSpec('page:preview'), + extensions: this._buildPreviewSpec('preview:page'), }).render()} `, @@ -214,7 +214,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent ${new BlockStdScope({ store: syncedDoc, - extensions: this._buildPreviewSpec('edgeless:preview'), + extensions: this._buildPreviewSpec('preview:edgeless'), }).render()} `, diff --git a/blocksuite/affine/block-frame/src/index.ts b/blocksuite/affine/block-frame/src/index.ts index 4adaa45b6..4f3971956 100644 --- a/blocksuite/affine/block-frame/src/index.ts +++ b/blocksuite/affine/block-frame/src/index.ts @@ -1,3 +1,4 @@ export * from './frame-block.js'; export * from './frame-manager.js'; export * from './frame-spec.js'; +export * from './tool.js'; diff --git a/blocksuite/affine/fragment-frame-panel/src/tool.ts b/blocksuite/affine/block-frame/src/tool.ts similarity index 85% rename from blocksuite/affine/fragment-frame-panel/src/tool.ts rename to blocksuite/affine/block-frame/src/tool.ts index ad411d3fb..83d33a4e5 100644 --- a/blocksuite/affine/fragment-frame-panel/src/tool.ts +++ b/blocksuite/affine/block-frame/src/tool.ts @@ -1,6 +1,7 @@ -import type { NavigatorMode } from '@blocksuite/affine-block-frame'; import { BaseTool } from '@blocksuite/block-std/gfx'; +import type { NavigatorMode } from './frame-manager'; + type PresentToolOption = { mode?: NavigatorMode; }; diff --git a/blocksuite/affine/block-image/src/adapters/index.ts b/blocksuite/affine/block-image/src/adapters/index.ts index 94b5ef70c..eff5f4e0e 100644 --- a/blocksuite/affine/block-image/src/adapters/index.ts +++ b/blocksuite/affine/block-image/src/adapters/index.ts @@ -1,3 +1,4 @@ export * from './html.js'; export * from './markdown.js'; +export * from './middleware.js'; export * from './notion-html.js'; diff --git a/blocksuite/affine/block-list/src/adapters/html.ts b/blocksuite/affine/block-list/src/adapters/html.ts index 8b98f3e36..4dcb66f6c 100644 --- a/blocksuite/affine/block-list/src/adapters/html.ts +++ b/blocksuite/affine/block-list/src/adapters/html.ts @@ -1,9 +1,9 @@ import { ListBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockHtmlAdapterExtension, type BlockHtmlAdapterMatcher, HastUtils, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import type { DeltaInsert } from '@blocksuite/inline'; import { nanoid } from '@blocksuite/store'; @@ -124,7 +124,7 @@ export const listBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { Array.isArray(currentTNode.properties.className) && currentTNode.properties.className.includes('todo-list') ) === - TextUtils.isNullish( + AdapterTextUtils.isNullish( o.node.props.type === 'todo' ? (o.node.props.checked as boolean) : undefined @@ -177,7 +177,7 @@ export const listBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = { Array.isArray(previousTNode.properties.className) && previousTNode.properties.className.includes('todo-list') ) === - TextUtils.isNullish( + AdapterTextUtils.isNullish( o.node.props.type === 'todo' ? (o.node.props.checked as boolean) : undefined diff --git a/blocksuite/affine/block-list/src/adapters/markdown.ts b/blocksuite/affine/block-list/src/adapters/markdown.ts index bd9bc4032..47ddf70e6 100644 --- a/blocksuite/affine/block-list/src/adapters/markdown.ts +++ b/blocksuite/affine/block-list/src/adapters/markdown.ts @@ -1,9 +1,9 @@ import { ListBlockSchema } from '@blocksuite/affine-model'; import { + AdapterTextUtils, BlockMarkdownAdapterExtension, type BlockMarkdownAdapterMatcher, type MarkdownAST, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import type { DeltaInsert } from '@blocksuite/inline'; import { nanoid } from '@blocksuite/store'; @@ -75,8 +75,8 @@ export const listBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher = { walkerContext.getNodeContext('affine:list:parent') === o.parent && currentTNode.type === 'list' && currentTNode.ordered === (o.node.props.type === 'numbered') && - TextUtils.isNullish(currentTNode.children[0].checked) === - TextUtils.isNullish( + AdapterTextUtils.isNullish(currentTNode.children[0].checked) === + AdapterTextUtils.isNullish( o.node.props.type === 'todo' ? (o.node.props.checked as boolean) : undefined @@ -129,8 +129,8 @@ export const listBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher = { currentTNode.type === 'listItem' && previousTNode?.type === 'list' && previousTNode.ordered === (o.node.props.type === 'numbered') && - TextUtils.isNullish(currentTNode.checked) === - TextUtils.isNullish( + AdapterTextUtils.isNullish(currentTNode.checked) === + AdapterTextUtils.isNullish( o.node.props.type === 'todo' ? (o.node.props.checked as boolean) : undefined diff --git a/blocksuite/affine/block-surface-ref/src/portal/note.ts b/blocksuite/affine/block-surface-ref/src/portal/note.ts index c560eeaa2..2beacca90 100644 --- a/blocksuite/affine/block-surface-ref/src/portal/note.ts +++ b/blocksuite/affine/block-surface-ref/src/portal/note.ts @@ -118,7 +118,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) { query: this.query, readonly: true, }); - const previewSpec = SpecProvider.getInstance().getSpec('page:preview'); + const previewSpec = SpecProvider.getInstance().getSpec('preview:page'); return new BlockStdScope({ store: doc, extensions: previewSpec.value.slice(), diff --git a/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts b/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts index dea698f7c..507c49fce 100644 --- a/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts +++ b/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts @@ -240,7 +240,7 @@ export class SurfaceRefBlockComponent extends BlockComponent { const cellId = `${row.rowId}:${column.columnId}`; const text = rowTextLists[i]?.[j]; cells[cellId] = { - text: TextUtils.createText(text ?? ''), + text: AdapterTextUtils.createText(text ?? ''), }; } } diff --git a/blocksuite/affine/components/src/rich-text/inline/adapters/html/inline-delta.ts b/blocksuite/affine/components/src/rich-text/inline/adapters/html/inline-delta.ts index 840d3cf94..b2b2b4c2f 100644 --- a/blocksuite/affine/components/src/rich-text/inline/adapters/html/inline-delta.ts +++ b/blocksuite/affine/components/src/rich-text/inline/adapters/html/inline-delta.ts @@ -1,7 +1,7 @@ import type { InlineHtmlAST } from '@blocksuite/affine-shared/adapters'; import { + AdapterTextUtils, InlineDeltaToHtmlAdapterExtension, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import { ThemeProvider } from '@blocksuite/affine-shared/services'; @@ -90,7 +90,7 @@ export const referenceDeltaToHtmlAdapterMatcher = const { configs } = context; const title = configs.get(`title:${reference.pageId}`); - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(reference.pageId), reference.params ?? Object.create(null) diff --git a/blocksuite/affine/components/src/rich-text/inline/adapters/markdown/inline-delta.ts b/blocksuite/affine/components/src/rich-text/inline/adapters/markdown/inline-delta.ts index 10729b320..ee66081c8 100644 --- a/blocksuite/affine/components/src/rich-text/inline/adapters/markdown/inline-delta.ts +++ b/blocksuite/affine/components/src/rich-text/inline/adapters/markdown/inline-delta.ts @@ -1,7 +1,7 @@ import { + AdapterTextUtils, FOOTNOTE_DEFINITION_PREFIX, InlineDeltaToMarkdownAdapterExtension, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import type { PhrasingContent } from 'mdast'; import type RemarkMath from 'remark-math'; @@ -74,7 +74,7 @@ export const referenceDeltaToMarkdownAdapterMatcher = const { configs } = context; const title = configs.get(`title:${reference.pageId}`); const params = reference.params ?? {}; - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(reference.pageId), params diff --git a/blocksuite/affine/components/src/rich-text/inline/adapters/plain-text/inline-delta.ts b/blocksuite/affine/components/src/rich-text/inline/adapters/plain-text/inline-delta.ts index 09a9bdb7b..7a10c98f7 100644 --- a/blocksuite/affine/components/src/rich-text/inline/adapters/plain-text/inline-delta.ts +++ b/blocksuite/affine/components/src/rich-text/inline/adapters/plain-text/inline-delta.ts @@ -1,7 +1,7 @@ import { + AdapterTextUtils, InlineDeltaToPlainTextAdapterExtension, type TextBuffer, - TextUtils, } from '@blocksuite/affine-shared/adapters'; import type { ExtensionType } from '@blocksuite/store'; @@ -20,7 +20,7 @@ export const referenceDeltaMarkdownAdapterMatch = const { configs } = context; const title = configs.get(`title:${reference.pageId}`) ?? ''; - const url = TextUtils.generateDocUrl( + const url = AdapterTextUtils.generateDocUrl( configs.get('docLinkBaseUrl') ?? '', String(reference.pageId), reference.params ?? Object.create(null) diff --git a/blocksuite/affine/fragment-frame-panel/src/index.ts b/blocksuite/affine/fragment-frame-panel/src/index.ts index c4351250d..807739d4f 100644 --- a/blocksuite/affine/fragment-frame-panel/src/index.ts +++ b/blocksuite/affine/fragment-frame-panel/src/index.ts @@ -1,2 +1 @@ export * from './frame-panel'; -export * from './tool'; diff --git a/blocksuite/affine/model/src/utils/types.ts b/blocksuite/affine/model/src/utils/types.ts index ef8fe53e9..4f72dd9a7 100644 --- a/blocksuite/affine/model/src/utils/types.ts +++ b/blocksuite/affine/model/src/utils/types.ts @@ -1,3 +1,11 @@ +import type { GfxModel } from '@blocksuite/block-std/gfx'; + +import type { + BrushElementModel, + ConnectorElementModel, + GroupElementModel, +} from '../elements'; + export type EmbedCardStyle = | 'horizontal' | 'horizontalThin' @@ -17,3 +25,8 @@ export type LinkPreviewData = { image: string | null; title: string | null; }; + +export type Connectable = Exclude< + GfxModel, + ConnectorElementModel | BrushElementModel | GroupElementModel +>; diff --git a/blocksuite/affine/shared/src/adapters/html/delta-converter.ts b/blocksuite/affine/shared/src/adapters/html/delta-converter.ts index dce670ac7..c607f8578 100644 --- a/blocksuite/affine/shared/src/adapters/html/delta-converter.ts +++ b/blocksuite/affine/shared/src/adapters/html/delta-converter.ts @@ -14,7 +14,7 @@ import { type InlineDeltaMatcher, } from '../types/adapter.js'; import type { HtmlAST, InlineHtmlAST } from '../types/hast.js'; -import { TextUtils } from '../utils/text.js'; +import { AdapterTextUtils } from '../utils/text.js'; export type InlineDeltaToHtmlAdapterMatcher = InlineDeltaMatcher; @@ -119,7 +119,7 @@ export class HtmlDeltaConverter extends DeltaASTConverter< options: DeltaASTConverterOptions = Object.create(null) ): DeltaInsert[] { return this._spreadAstToDelta(ast, options).reduce((acc, cur) => { - return TextUtils.mergeDeltas(acc, cur); + return AdapterTextUtils.mergeDeltas(acc, cur); }, [] as DeltaInsert[]); } diff --git a/blocksuite/affine/shared/src/adapters/middlewares/doc-link.ts b/blocksuite/affine/shared/src/adapters/middlewares/doc-link.ts new file mode 100644 index 000000000..9ee244cc8 --- /dev/null +++ b/blocksuite/affine/shared/src/adapters/middlewares/doc-link.ts @@ -0,0 +1,44 @@ +import type { TransformerMiddleware } from '@blocksuite/store'; + +const customDocLinkBaseUrlMiddleware = ( + baseUrl: string, + collectionId: string +): TransformerMiddleware => { + return ({ adapterConfigs }) => { + const docLinkBaseUrl = baseUrl + ? `${baseUrl}/workspace/${collectionId}` + : ''; + adapterConfigs.set('docLinkBaseUrl', docLinkBaseUrl); + }; +}; + +export const docLinkBaseURLMiddlewareBuilder = ( + baseUrl: string, + collectionId: string +) => { + let middleware = customDocLinkBaseUrlMiddleware(baseUrl, collectionId); + return { + get: () => middleware, + set: (url: string) => { + middleware = customDocLinkBaseUrlMiddleware(url, collectionId); + }, + }; +}; + +const defaultDocLinkBaseURLMiddlewareBuilder = (collectionId: string) => + docLinkBaseURLMiddlewareBuilder( + typeof window !== 'undefined' ? window.location.origin : '.', + collectionId + ); + +export const docLinkBaseURLMiddleware = (collectionId: string) => + defaultDocLinkBaseURLMiddlewareBuilder(collectionId).get(); + +export const setDocLinkBaseURLMiddleware = (collectionId: string) => + defaultDocLinkBaseURLMiddlewareBuilder(collectionId).set; + +export const embedSyncedDocMiddleware = + (type: 'content'): TransformerMiddleware => + ({ adapterConfigs }) => { + adapterConfigs.set('embedSyncedDocExportType', type); + }; diff --git a/blocksuite/affine/shared/src/adapters/middlewares/file-name.ts b/blocksuite/affine/shared/src/adapters/middlewares/file-name.ts new file mode 100644 index 000000000..01fe47c4c --- /dev/null +++ b/blocksuite/affine/shared/src/adapters/middlewares/file-name.ts @@ -0,0 +1,23 @@ +import type { TransformerMiddleware } from '@blocksuite/store'; + +export const fileNameMiddleware = + (fileName?: string): TransformerMiddleware => + ({ slots }) => { + slots.beforeImport.on(payload => { + if (payload.type !== 'page') { + return; + } + if (!fileName) { + return; + } + payload.snapshot.meta.title = fileName; + payload.snapshot.blocks.props.title = { + '$blocksuite:internal:text$': true, + delta: [ + { + insert: fileName, + }, + ], + }; + }); + }; diff --git a/blocksuite/affine/shared/src/adapters/middlewares/index.ts b/blocksuite/affine/shared/src/adapters/middlewares/index.ts index c576d4a83..131fa6b1f 100644 --- a/blocksuite/affine/shared/src/adapters/middlewares/index.ts +++ b/blocksuite/affine/shared/src/adapters/middlewares/index.ts @@ -1,4 +1,8 @@ export * from './code'; export * from './copy'; +export * from './doc-link'; +export * from './file-name'; export * from './paste'; +export * from './replace-id'; export * from './surface-ref-to-embed'; +export * from './title'; diff --git a/blocksuite/blocks/src/_common/transformers/middlewares.ts b/blocksuite/affine/shared/src/adapters/middlewares/replace-id.ts similarity index 69% rename from blocksuite/blocks/src/_common/transformers/middlewares.ts rename to blocksuite/affine/shared/src/adapters/middlewares/replace-id.ts index 2300beb06..fa6f02a9b 100644 --- a/blocksuite/blocks/src/_common/transformers/middlewares.ts +++ b/blocksuite/affine/shared/src/adapters/middlewares/replace-id.ts @@ -6,13 +6,8 @@ import type { ParagraphBlockModel, SurfaceRefBlockModel, } from '@blocksuite/affine-model'; -import { DEFAULT_IMAGE_PROXY_ENDPOINT } from '@blocksuite/affine-shared/consts'; import { assertExists } from '@blocksuite/global/utils'; -import type { - DeltaOperation, - DocMeta, - TransformerMiddleware, -} from '@blocksuite/store'; +import type { DeltaOperation, TransformerMiddleware } from '@blocksuite/store'; export const replaceIdMiddleware = (idGenerator: () => string): TransformerMiddleware => @@ -203,103 +198,3 @@ export const replaceIdMiddleware = } }); }; - -export const customImageProxyMiddleware = ( - imageProxyURL: string -): TransformerMiddleware => { - return ({ adapterConfigs }) => { - adapterConfigs.set('imageProxy', imageProxyURL); - }; -}; - -const customDocLinkBaseUrlMiddleware = ( - baseUrl: string, - collectionId: string -): TransformerMiddleware => { - return ({ adapterConfigs }) => { - const docLinkBaseUrl = baseUrl - ? `${baseUrl}/workspace/${collectionId}` - : ''; - adapterConfigs.set('docLinkBaseUrl', docLinkBaseUrl); - }; -}; - -export const titleMiddleware = - (metas: DocMeta[]): TransformerMiddleware => - ({ slots, adapterConfigs }) => { - slots.beforeExport.on(() => { - for (const meta of metas) { - adapterConfigs.set('title:' + meta.id, meta.title); - } - }); - }; - -export const docLinkBaseURLMiddlewareBuilder = ( - baseUrl: string, - collectionId: string -) => { - let middleware = customDocLinkBaseUrlMiddleware(baseUrl, collectionId); - return { - get: () => middleware, - set: (url: string) => { - middleware = customDocLinkBaseUrlMiddleware(url, collectionId); - }, - }; -}; - -const defaultDocLinkBaseURLMiddlewareBuilder = (collectionId: string) => - docLinkBaseURLMiddlewareBuilder( - typeof window !== 'undefined' ? window.location.origin : '.', - collectionId - ); - -export const docLinkBaseURLMiddleware = (collectionId: string) => - defaultDocLinkBaseURLMiddlewareBuilder(collectionId).get(); - -export const setDocLinkBaseURLMiddleware = (collectionId: string) => - defaultDocLinkBaseURLMiddlewareBuilder(collectionId).set; - -const imageProxyMiddlewareBuilder = () => { - let middleware = customImageProxyMiddleware(DEFAULT_IMAGE_PROXY_ENDPOINT); - return { - get: () => middleware, - set: (url: string) => { - middleware = customImageProxyMiddleware(url); - }, - }; -}; - -const defaultImageProxyMiddlewarBuilder = imageProxyMiddlewareBuilder(); - -export const setImageProxyMiddlewareURL = defaultImageProxyMiddlewarBuilder.set; - -export const defaultImageProxyMiddleware = - defaultImageProxyMiddlewarBuilder.get(); - -export const embedSyncedDocMiddleware = - (type: 'content'): TransformerMiddleware => - ({ adapterConfigs }) => { - adapterConfigs.set('embedSyncedDocExportType', type); - }; - -export const fileNameMiddleware = - (fileName?: string): TransformerMiddleware => - ({ slots }) => { - slots.beforeImport.on(payload => { - if (payload.type !== 'page') { - return; - } - if (!fileName) { - return; - } - payload.snapshot.meta.title = fileName; - payload.snapshot.blocks.props.title = { - '$blocksuite:internal:text$': true, - delta: [ - { - insert: fileName, - }, - ], - }; - }); - }; diff --git a/blocksuite/affine/shared/src/adapters/middlewares/title.ts b/blocksuite/affine/shared/src/adapters/middlewares/title.ts new file mode 100644 index 000000000..4ad24cc1f --- /dev/null +++ b/blocksuite/affine/shared/src/adapters/middlewares/title.ts @@ -0,0 +1,11 @@ +import type { DocMeta, TransformerMiddleware } from '@blocksuite/store'; + +export const titleMiddleware = + (metas: DocMeta[]): TransformerMiddleware => + ({ slots, adapterConfigs }) => { + slots.beforeExport.on(() => { + for (const meta of metas) { + adapterConfigs.set('title:' + meta.id, meta.title); + } + }); + }; diff --git a/blocksuite/affine/shared/src/adapters/utils/text.ts b/blocksuite/affine/shared/src/adapters/utils/text.ts index ce9c5da60..7ee92da5b 100644 --- a/blocksuite/affine/shared/src/adapters/utils/text.ts +++ b/blocksuite/affine/shared/src/adapters/utils/text.ts @@ -86,7 +86,7 @@ function generateDocUrl( return url; } -export const TextUtils = { +export const AdapterTextUtils = { mergeDeltas, isNullish, createText, diff --git a/blocksuite/affine/shared/src/utils/spec/spec-provider.ts b/blocksuite/affine/shared/src/utils/spec/spec-provider.ts index c0e9120a5..64adabe5f 100644 --- a/blocksuite/affine/shared/src/utils/spec/spec-provider.ts +++ b/blocksuite/affine/shared/src/utils/spec/spec-provider.ts @@ -3,10 +3,17 @@ import type { ExtensionType } from '@blocksuite/store'; import { SpecBuilder } from './spec-builder.js'; +type SpecId = + | 'store' + | 'page' + | 'edgeless' + | 'preview:page' + | 'preview:edgeless'; + export class SpecProvider { static instance: SpecProvider; - private readonly specMap = new Map(); + private readonly specMap = new Map(); private constructor() {} @@ -17,17 +24,17 @@ export class SpecProvider { return SpecProvider.instance; } - addSpec(id: string, spec: ExtensionType[]) { + addSpec(id: SpecId, spec: ExtensionType[]) { if (!this.specMap.has(id)) { this.specMap.set(id, spec); } } - clearSpec(id: string) { + clearSpec(id: SpecId) { this.specMap.delete(id); } - extendSpec(id: string, newSpec: ExtensionType[]) { + extendSpec(id: SpecId, newSpec: ExtensionType[]) { const existingSpec = this.specMap.get(id); if (!existingSpec) { console.error(`Spec not found for ${id}`); @@ -36,26 +43,17 @@ export class SpecProvider { this.specMap.set(id, [...existingSpec, ...newSpec]); } - getSpec(id: string) { + getSpec(id: SpecId) { const spec = this.specMap.get(id); assertExists(spec, `Spec not found for ${id}`); return new SpecBuilder(spec); } - hasSpec(id: string) { + hasSpec(id: SpecId) { return this.specMap.has(id); } - cloneSpec(id: string, targetId: string) { - const existingSpec = this.specMap.get(id); - if (!existingSpec) { - console.error(`Spec not found for ${id}`); - return; - } - this.specMap.set(targetId, [...existingSpec]); - } - - omitSpec(id: string, targetSpec: ExtensionType) { + omitSpec(id: SpecId, targetSpec: ExtensionType) { const existingSpec = this.specMap.get(id); if (!existingSpec) { console.error(`Spec not found for ${id}`); @@ -68,7 +66,7 @@ export class SpecProvider { ); } - replaceSpec(id: string, targetSpec: ExtensionType, newSpec: ExtensionType) { + replaceSpec(id: SpecId, targetSpec: ExtensionType, newSpec: ExtensionType) { const existingSpec = this.specMap.get(id); if (!existingSpec) { console.error(`Spec not found for ${id}`); diff --git a/blocksuite/affine/widget-drag-handle/src/helpers/preview-helper.ts b/blocksuite/affine/widget-drag-handle/src/helpers/preview-helper.ts index 5c63c2865..9aa8a6bdd 100644 --- a/blocksuite/affine/widget-drag-handle/src/helpers/preview-helper.ts +++ b/blocksuite/affine/widget-drag-handle/src/helpers/preview-helper.ts @@ -103,7 +103,7 @@ export class PreviewHelper { const query = this._calculateQuery(blockIds as string[], mode); const store = widget.doc.doc.getStore({ query }); const previewSpec = SpecProvider.getInstance().getSpec( - isEdgeless ? 'edgeless:preview' : 'page:preview' + isEdgeless ? 'preview:edgeless' : 'preview:page' ); const settingSignal = signal({ ...editorSetting }); const extensions = [ diff --git a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts index 3971fcb39..313d1dcc7 100644 --- a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts @@ -3,7 +3,10 @@ import { InlineDeltaToHtmlAdapterExtensions, } from '@blocksuite/affine-components/rich-text'; import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model'; -import { HtmlAdapter } from '@blocksuite/affine-shared/adapters'; +import { + embedSyncedDocMiddleware, + HtmlAdapter, +} from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import type { BlockSnapshot, @@ -14,7 +17,6 @@ import { AssetsManager, MemoryBlobCRUD } from '@blocksuite/store'; import { describe, expect, test } from 'vitest'; import { defaultBlockHtmlAdapterMatchers } from '../../_common/adapters/html/block-matcher.js'; -import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js'; import { createJob } from '../utils/create-job.js'; import { nanoidReplacement } from '../utils/nanoid-replacement.js'; diff --git a/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts index d39474c0d..8313e0ee3 100644 --- a/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts @@ -7,7 +7,10 @@ import { NoteDisplayMode, TableModelFlavour, } from '@blocksuite/affine-model'; -import { MarkdownAdapter } from '@blocksuite/affine-shared/adapters'; +import { + embedSyncedDocMiddleware, + MarkdownAdapter, +} from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import type { BlockSnapshot, @@ -19,7 +22,6 @@ import { AssetsManager, MemoryBlobCRUD } from '@blocksuite/store'; import { describe, expect, test } from 'vitest'; import { defaultBlockMarkdownAdapterMatchers } from '../../_common/adapters/markdown/block-matcher.js'; -import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js'; import { createJob } from '../utils/create-job.js'; import { nanoidReplacement } from '../utils/nanoid-replacement.js'; diff --git a/blocksuite/blocks/src/__tests__/adapters/plain-text.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/plain-text.unit.spec.ts index 2552034b2..e7038b2cb 100644 --- a/blocksuite/blocks/src/__tests__/adapters/plain-text.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/plain-text.unit.spec.ts @@ -1,6 +1,9 @@ import { InlineDeltaToPlainTextAdapterExtensions } from '@blocksuite/affine-components/rich-text'; import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model'; -import { PlainTextAdapter } from '@blocksuite/affine-shared/adapters'; +import { + embedSyncedDocMiddleware, + PlainTextAdapter, +} from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import type { BlockSnapshot, @@ -10,7 +13,6 @@ import type { import { describe, expect, test } from 'vitest'; import { defaultBlockPlainTextAdapterMatchers } from '../../_common/adapters/plain-text/block-matcher.js'; -import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js'; import { createJob } from '../utils/create-job.js'; const container = new Container(); diff --git a/blocksuite/blocks/src/__tests__/utils/create-job.ts b/blocksuite/blocks/src/__tests__/utils/create-job.ts index 328cb1350..6586647d3 100644 --- a/blocksuite/blocks/src/__tests__/utils/create-job.ts +++ b/blocksuite/blocks/src/__tests__/utils/create-job.ts @@ -1,3 +1,4 @@ +import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image'; import { FeatureFlagService } from '@blocksuite/affine-shared/services'; import { Schema, @@ -6,7 +7,6 @@ import { } from '@blocksuite/store'; import { TestWorkspace } from '@blocksuite/store/test'; -import { defaultImageProxyMiddleware } from '../../_common/transformers/middlewares.js'; import { AffineSchemas } from '../../schemas.js'; declare global { diff --git a/blocksuite/blocks/src/_common/transformers/index.ts b/blocksuite/blocks/src/_common/transformers/index.ts deleted file mode 100644 index 11253674f..000000000 --- a/blocksuite/blocks/src/_common/transformers/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export { HtmlTransformer } from './html.js'; -export { MarkdownTransformer } from './markdown.js'; -export { - customImageProxyMiddleware, - defaultImageProxyMiddleware, - docLinkBaseURLMiddleware, - docLinkBaseURLMiddlewareBuilder, - embedSyncedDocMiddleware, - replaceIdMiddleware, - setImageProxyMiddlewareURL, - titleMiddleware, -} from './middlewares.js'; -export { NotionHtmlTransformer } from './notion-html.js'; -export { createAssetsArchive, download } from './utils.js'; -export { ZipTransformer } from './zip.js'; diff --git a/blocksuite/blocks/src/_common/types.ts b/blocksuite/blocks/src/_common/types.ts deleted file mode 100644 index 9b00589ae..000000000 --- a/blocksuite/blocks/src/_common/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { - BrushElementModel, - ConnectorElementModel, - GroupElementModel, -} from '@blocksuite/affine-model'; -import type { GfxModel } from '@blocksuite/block-std/gfx'; - -export type Connectable = Exclude< - GfxModel, - ConnectorElementModel | BrushElementModel | GroupElementModel ->; diff --git a/blocksuite/blocks/src/_specs/common.ts b/blocksuite/blocks/src/_specs/common.ts index b5ae2d8d9..be108c981 100644 --- a/blocksuite/blocks/src/_specs/common.ts +++ b/blocksuite/blocks/src/_specs/common.ts @@ -56,6 +56,11 @@ import { import type { ExtensionType } from '@blocksuite/store'; import { AdapterFactoryExtensions } from '../_common/adapters/extension.js'; +import { + HtmlAdapterExtension, + MarkdownAdapterExtension, + NotionHtmlAdapterExtension, +} from './preset/adapters.js'; export const CommonBlockSpecs: ExtensionType[] = [ DocDisplayMetaService, @@ -110,4 +115,8 @@ export const StoreExtensions: ExtensionType[] = [ LinkPreviewerService, FileSizeLimitService, ImageStoreSpec, + + HtmlAdapterExtension, + MarkdownAdapterExtension, + NotionHtmlAdapterExtension, ].flat(); diff --git a/blocksuite/blocks/src/_specs/preset/adapters.ts b/blocksuite/blocks/src/_specs/preset/adapters.ts new file mode 100644 index 000000000..02c151080 --- /dev/null +++ b/blocksuite/blocks/src/_specs/preset/adapters.ts @@ -0,0 +1,31 @@ +import { + HtmlInlineToDeltaAdapterExtensions, + InlineDeltaToHtmlAdapterExtensions, + InlineDeltaToMarkdownAdapterExtensions, + MarkdownInlineToDeltaAdapterExtensions, + NotionHtmlInlineToDeltaAdapterExtensions, +} from '@blocksuite/affine-components/rich-text'; +import type { ExtensionType } from '@blocksuite/store'; + +import { + defaultBlockHtmlAdapterMatchers, + defaultBlockMarkdownAdapterMatchers, + defaultBlockNotionHtmlAdapterMatchers, +} from '../../_common/adapters'; + +export const HtmlAdapterExtension: ExtensionType[] = [ + ...HtmlInlineToDeltaAdapterExtensions, + ...defaultBlockHtmlAdapterMatchers, + ...InlineDeltaToHtmlAdapterExtensions, +]; + +export const MarkdownAdapterExtension: ExtensionType[] = [ + ...MarkdownInlineToDeltaAdapterExtensions, + ...defaultBlockMarkdownAdapterMatchers, + ...InlineDeltaToMarkdownAdapterExtensions, +]; + +export const NotionHtmlAdapterExtension: ExtensionType[] = [ + ...NotionHtmlInlineToDeltaAdapterExtensions, + ...defaultBlockNotionHtmlAdapterMatchers, +]; diff --git a/blocksuite/blocks/src/_specs/preset/edgeless-specs.ts b/blocksuite/blocks/src/_specs/preset/edgeless-specs.ts index ae3986350..f97a2d772 100644 --- a/blocksuite/blocks/src/_specs/preset/edgeless-specs.ts +++ b/blocksuite/blocks/src/_specs/preset/edgeless-specs.ts @@ -1,9 +1,9 @@ import { EdgelessFrameManager, FrameOverlay, + PresentTool, } from '@blocksuite/affine-block-frame'; import { ConnectionOverlay } from '@blocksuite/affine-block-surface'; -import { PresentTool } from '@blocksuite/affine-fragment-frame-panel'; import type { ExtensionType } from '@blocksuite/store'; import { EdgelessRootBlockSpec } from '../../root-block/edgeless/edgeless-root-spec.js'; diff --git a/blocksuite/blocks/src/_specs/register-specs.ts b/blocksuite/blocks/src/_specs/register-specs.ts index 8595d747b..29ca74e9c 100644 --- a/blocksuite/blocks/src/_specs/register-specs.ts +++ b/blocksuite/blocks/src/_specs/register-specs.ts @@ -1,6 +1,6 @@ import { SpecProvider } from '@blocksuite/affine-shared/utils'; -import { CommonBlockSpecs, StoreExtensions } from './common.js'; +import { StoreExtensions } from './common.js'; import { EdgelessEditorBlockSpecs } from './preset/edgeless-specs.js'; import { PageEditorBlockSpecs } from './preset/page-specs.js'; import { @@ -10,15 +10,14 @@ import { export function registerSpecs() { SpecProvider.getInstance().addSpec('store', StoreExtensions); - SpecProvider.getInstance().addSpec('common', CommonBlockSpecs); SpecProvider.getInstance().addSpec('page', PageEditorBlockSpecs); SpecProvider.getInstance().addSpec('edgeless', EdgelessEditorBlockSpecs); SpecProvider.getInstance().addSpec( - 'page:preview', + 'preview:page', PreviewPageEditorBlockSpecs ); SpecProvider.getInstance().addSpec( - 'edgeless:preview', + 'preview:edgeless', PreviewEdgelessEditorBlockSpecs ); } diff --git a/blocksuite/blocks/src/index.ts b/blocksuite/blocks/src/index.ts index eafc99426..0b31e8a9c 100644 --- a/blocksuite/blocks/src/index.ts +++ b/blocksuite/blocks/src/index.ts @@ -7,7 +7,6 @@ import { splitElements } from './root-block/edgeless/utils/clipboard-utils.js'; import { isCanvasElement } from './root-block/edgeless/utils/query.js'; export * from './_common/adapters/index.js'; -export * from './_common/transformers/index.js'; export * from './_specs/index.js'; export { EdgelessTemplatePanel } from './root-block/edgeless/components/toolbar/template/template-panel.js'; export type { @@ -93,31 +92,7 @@ export { export * from '@blocksuite/affine-fragment-frame-panel'; export * from '@blocksuite/affine-fragment-outline'; export * from '@blocksuite/affine-model'; -export { - AttachmentAdapter, - AttachmentAdapterFactoryExtension, - AttachmentAdapterFactoryIdentifier, - codeBlockWrapMiddleware, - FetchUtils, - HtmlAdapter, - HtmlAdapterFactoryExtension, - HtmlAdapterFactoryIdentifier, - ImageAdapter, - ImageAdapterFactoryExtension, - ImageAdapterFactoryIdentifier, - MarkdownAdapter, - MarkdownAdapterFactoryExtension, - MarkdownAdapterFactoryIdentifier, - MixTextAdapter, - MixTextAdapterFactoryExtension, - MixTextAdapterFactoryIdentifier, - NotionTextAdapter, - NotionTextAdapterFactoryExtension, - NotionTextAdapterFactoryIdentifier, - PlainTextAdapter, - PlainTextAdapterFactoryExtension, - PlainTextAdapterFactoryIdentifier, -} from '@blocksuite/affine-shared/adapters'; +export * from '@blocksuite/affine-shared/adapters'; export * from '@blocksuite/affine-shared/commands'; export { HighlightSelection } from '@blocksuite/affine-shared/selection'; export * from '@blocksuite/affine-shared/services'; diff --git a/blocksuite/blocks/src/root-block/clipboard/page-clipboard.ts b/blocksuite/blocks/src/root-block/clipboard/page-clipboard.ts index 162c4a032..2cdbaed15 100644 --- a/blocksuite/blocks/src/root-block/clipboard/page-clipboard.ts +++ b/blocksuite/blocks/src/root-block/clipboard/page-clipboard.ts @@ -1,6 +1,7 @@ import { deleteTextCommand } from '@blocksuite/affine-components/rich-text'; import { pasteMiddleware, + replaceIdMiddleware, surfaceRefToEmbed, } from '@blocksuite/affine-shared/adapters'; import { @@ -17,7 +18,6 @@ import type { UIEventHandler } from '@blocksuite/block-std'; import { DisposableGroup } from '@blocksuite/global/utils'; import type { BlockSnapshot, Store } from '@blocksuite/store'; -import { replaceIdMiddleware } from '../../_common/transformers/middlewares'; import { ReadOnlyClipboard } from './readonly-clipboard'; /** diff --git a/blocksuite/blocks/src/root-block/clipboard/readonly-clipboard.ts b/blocksuite/blocks/src/root-block/clipboard/readonly-clipboard.ts index f6c31fa23..78b6aee18 100644 --- a/blocksuite/blocks/src/root-block/clipboard/readonly-clipboard.ts +++ b/blocksuite/blocks/src/root-block/clipboard/readonly-clipboard.ts @@ -1,3 +1,4 @@ +import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image'; import { AttachmentAdapter, copyMiddleware, @@ -5,6 +6,7 @@ import { ImageAdapter, MixTextAdapter, NotionTextAdapter, + titleMiddleware, } from '@blocksuite/affine-shared/adapters'; import { copySelectedModelsCommand, @@ -14,10 +16,6 @@ import { import type { BlockComponent, UIEventHandler } from '@blocksuite/block-std'; import { DisposableGroup } from '@blocksuite/global/utils'; -import { - defaultImageProxyMiddleware, - titleMiddleware, -} from '../../_common/transformers/middlewares.js'; import { ClipboardAdapter } from './adapter.js'; /** diff --git a/blocksuite/blocks/src/root-block/edgeless/components/frame/frame-preview.ts b/blocksuite/blocks/src/root-block/edgeless/components/frame/frame-preview.ts index 43b4ac469..18da693c2 100644 --- a/blocksuite/blocks/src/root-block/edgeless/components/frame/frame-preview.ts +++ b/blocksuite/blocks/src/root-block/edgeless/components/frame/frame-preview.ts @@ -81,7 +81,7 @@ export class FramePreview extends WithDisposable(ShadowlessElement) { private _previewDoc: Store | null = null; private readonly _previewSpec = - SpecProvider.getInstance().getSpec('edgeless:preview'); + SpecProvider.getInstance().getSpec('preview:edgeless'); private readonly _updateFrameViewportWH = () => { const [, , w, h] = deserializeXYWH(this.frame.xywh); diff --git a/blocksuite/blocks/src/root-block/edgeless/edgeless-keyboard.ts b/blocksuite/blocks/src/root-block/edgeless/edgeless-keyboard.ts index ac50402ce..e6ee79179 100644 --- a/blocksuite/blocks/src/root-block/edgeless/edgeless-keyboard.ts +++ b/blocksuite/blocks/src/root-block/edgeless/edgeless-keyboard.ts @@ -31,11 +31,6 @@ import { import { IS_MAC } from '@blocksuite/global/env'; import { Bound, getCommonBound } from '@blocksuite/global/utils'; -import { - getNearestTranslation, - isElementOutsideViewport, - isSingleMindMapNode, -} from '../../_common/edgeless/mindmap/index.js'; import { PageKeyboardManager } from '../keyboard/keyboard-manager.js'; import type { EdgelessRootBlockComponent } from './edgeless-root-block.js'; import { CopilotTool } from './gfx-tool/copilot-tool.js'; @@ -48,6 +43,11 @@ import { } from './utils/consts.js'; import { deleteElements } from './utils/crud.js'; import { getNextShapeType } from './utils/hotkey-utils.js'; +import { + getNearestTranslation, + isElementOutsideViewport, + isSingleMindMapNode, +} from './utils/mindmap.js'; import { isCanvasElement } from './utils/query.js'; import { mountConnectorLabelEditor, diff --git a/blocksuite/blocks/src/root-block/edgeless/edgeless-root-block.ts b/blocksuite/blocks/src/root-block/edgeless/edgeless-root-block.ts index 7273ef207..871ba4dd1 100644 --- a/blocksuite/blocks/src/root-block/edgeless/edgeless-root-block.ts +++ b/blocksuite/blocks/src/root-block/edgeless/edgeless-root-block.ts @@ -45,12 +45,12 @@ import { css, html } from 'lit'; import { query } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { isSingleMindMapNode } from '../../_common/edgeless/mindmap/index.js'; import type { EdgelessRootBlockWidgetName } from '../types.js'; import { EdgelessClipboardController } from './clipboard/clipboard.js'; import type { EdgelessSelectedRectWidget } from './components/rects/edgeless-selected-rect.js'; import { EdgelessPageKeyboardManager } from './edgeless-keyboard.js'; import type { EdgelessRootService } from './edgeless-root-service.js'; +import { isSingleMindMapNode } from './utils/mindmap.js'; import { isCanvasElement } from './utils/query.js'; import { mountShapeTextEditor } from './utils/text.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool-ext/mind-map-ext/mind-map-ext.ts b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool-ext/mind-map-ext/mind-map-ext.ts index 52d3adb89..b99fadff2 100644 --- a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool-ext/mind-map-ext/mind-map-ext.ts +++ b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool-ext/mind-map-ext/mind-map-ext.ts @@ -19,7 +19,7 @@ import { } from '@blocksuite/block-std/gfx'; import type { Bound, IVec } from '@blocksuite/global/utils'; -import { isSingleMindMapNode } from '../../../../../_common/edgeless/mindmap/index.js'; +import { isSingleMindMapNode } from '../../../utils/mindmap.js'; import { isMindmapNode } from '../../../utils/query.js'; import { DefaultModeDragType, DefaultToolExt, type DragState } from '../ext.js'; import { calculateResponseArea } from './drag-utils.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool.ts b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool.ts index 5517c52dc..5cd26a66b 100644 --- a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool.ts +++ b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/default-tool.ts @@ -53,9 +53,9 @@ import { } from '@blocksuite/global/utils'; import { effect } from '@preact/signals-core'; -import { isSingleMindMapNode } from '../../../_common/edgeless/mindmap/index.js'; import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js'; import { prepareCloneData } from '../utils/clone-utils.js'; +import { isSingleMindMapNode } from '../utils/mindmap.js'; import { calPanDelta } from '../utils/panning-utils.js'; import { isCanvasElement, isEdgelessTextBlock } from '../utils/query.js'; import type { EdgelessSnapManager } from '../utils/snap-manager.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts b/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts index 4afb1140a..3a6a7033a 100644 --- a/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts +++ b/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts @@ -1,7 +1,7 @@ import { isNoteBlock } from '@blocksuite/affine-block-surface'; +import type { Connectable } from '@blocksuite/affine-model'; import type { GfxModel } from '@blocksuite/block-std/gfx'; -import type { Connectable } from '../../../_common/types.js'; import type { EdgelessRootBlockComponent } from '../index.js'; import { isConnectable } from './query.js'; diff --git a/blocksuite/blocks/src/_common/edgeless/mindmap/index.ts b/blocksuite/blocks/src/root-block/edgeless/utils/mindmap.ts similarity index 100% rename from blocksuite/blocks/src/_common/edgeless/mindmap/index.ts rename to blocksuite/blocks/src/root-block/edgeless/utils/mindmap.ts diff --git a/blocksuite/blocks/src/root-block/edgeless/utils/query.ts b/blocksuite/blocks/src/root-block/edgeless/utils/query.ts index 5f4a12ad1..980460e55 100644 --- a/blocksuite/blocks/src/root-block/edgeless/utils/query.ts +++ b/blocksuite/blocks/src/root-block/edgeless/utils/query.ts @@ -2,6 +2,7 @@ import type { CanvasElementWithText } from '@blocksuite/affine-block-surface'; import { type AttachmentBlockModel, type BookmarkBlockModel, + type Connectable, ConnectorElementModel, type EdgelessTextBlockModel, type EmbedBlockModel, @@ -32,8 +33,6 @@ import type { PointLocation } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils'; import type { BlockModel } from '@blocksuite/store'; -import type { Connectable } from '../../../_common/types'; - export function isMindmapNode(element: GfxBlockElementModel | GfxModel | null) { return element?.group instanceof MindmapElementModel; } diff --git a/blocksuite/blocks/src/root-block/index.ts b/blocksuite/blocks/src/root-block/index.ts index 3625b4b4c..dcf49ca3a 100644 --- a/blocksuite/blocks/src/root-block/index.ts +++ b/blocksuite/blocks/src/root-block/index.ts @@ -11,6 +11,7 @@ export * from './page/page-root-spec.js'; export * from './preview/preview-root-block.js'; export * from './root-config.js'; export { RootService } from './root-service.js'; +export * from './transformers/index.js'; export * from './types.js'; export * from './utils/index.js'; export * from './widgets/index.js'; diff --git a/blocksuite/blocks/src/root-block/root-service.ts b/blocksuite/blocks/src/root-block/root-service.ts index 4f0501134..2f6ea8818 100644 --- a/blocksuite/blocks/src/root-block/root-service.ts +++ b/blocksuite/blocks/src/root-block/root-service.ts @@ -8,22 +8,11 @@ import { import type { BlockComponent } from '@blocksuite/block-std'; import { BlockService } from '@blocksuite/block-std'; -import { - HtmlTransformer, - MarkdownTransformer, - ZipTransformer, -} from '../_common/transformers/index.js'; import type { RootBlockComponent } from './types.js'; export abstract class RootService extends BlockService { static override readonly flavour = RootBlockSchema.model.flavour; - transformers = { - markdown: MarkdownTransformer, - html: HtmlTransformer, - zip: ZipTransformer, - }; - get selectedBlocks() { let result: BlockComponent[] = []; this.std.command diff --git a/blocksuite/blocks/src/_common/transformers/html.ts b/blocksuite/blocks/src/root-block/transformers/html.ts similarity index 90% rename from blocksuite/blocks/src/_common/transformers/html.ts rename to blocksuite/blocks/src/root-block/transformers/html.ts index 0857f3e15..4502bd2f5 100644 --- a/blocksuite/blocks/src/_common/transformers/html.ts +++ b/blocksuite/blocks/src/root-block/transformers/html.ts @@ -1,20 +1,16 @@ +import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image'; import { - HtmlInlineToDeltaAdapterExtensions, - InlineDeltaToHtmlAdapterExtensions, -} from '@blocksuite/affine-components/rich-text'; -import { HtmlAdapter } from '@blocksuite/affine-shared/adapters'; + docLinkBaseURLMiddleware, + fileNameMiddleware, + HtmlAdapter, + titleMiddleware, +} from '@blocksuite/affine-shared/adapters'; +import { SpecProvider } from '@blocksuite/affine-shared/utils'; import { Container } from '@blocksuite/global/di'; import { sha } from '@blocksuite/global/utils'; import type { Store, Workspace } from '@blocksuite/store'; import { extMimeMap, Transformer } from '@blocksuite/store'; -import { defaultBlockHtmlAdapterMatchers } from '../adapters/html/block-matcher.js'; -import { - defaultImageProxyMiddleware, - docLinkBaseURLMiddleware, - fileNameMiddleware, - titleMiddleware, -} from './middlewares.js'; import { createAssetsArchive, download, Unzip } from './utils.js'; type ImportHTMLToDocOptions = { @@ -28,16 +24,14 @@ type ImportHTMLZipOptions = { imported: Blob; }; -const container = new Container(); -[ - ...HtmlInlineToDeltaAdapterExtensions, - ...defaultBlockHtmlAdapterMatchers, - ...InlineDeltaToHtmlAdapterExtensions, -].forEach(ext => { - ext.setup(container); -}); - -const provider = container.provider(); +function getProvider() { + const container = new Container(); + const exts = SpecProvider.getInstance().getSpec('store').value; + exts.forEach(ext => { + ext.setup(container); + }); + return container.provider(); +} /** * Exports a doc to HTML format. @@ -46,6 +40,7 @@ const provider = container.provider(); * @returns A Promise that resolves when the export is complete. */ async function exportDoc(doc: Store) { + const provider = getProvider(); const job = new Transformer({ schema: doc.schema, blobCRUD: doc.blobSync, @@ -101,6 +96,7 @@ async function importHTMLToDoc({ html, fileName, }: ImportHTMLToDocOptions) { + const provider = getProvider(); const job = new Transformer({ schema: collection.schema, blobCRUD: collection.blobSync, @@ -135,6 +131,7 @@ async function importHTMLToDoc({ * @returns A Promise that resolves to an array of IDs of the newly created docs. */ async function importHTMLZip({ collection, imported }: ImportHTMLZipOptions) { + const provider = getProvider(); const unzip = new Unzip(); await unzip.load(imported); diff --git a/blocksuite/blocks/src/root-block/transformers/index.ts b/blocksuite/blocks/src/root-block/transformers/index.ts new file mode 100644 index 000000000..a25831dbb --- /dev/null +++ b/blocksuite/blocks/src/root-block/transformers/index.ts @@ -0,0 +1,5 @@ +export { HtmlTransformer } from './html.js'; +export { MarkdownTransformer } from './markdown.js'; +export { NotionHtmlTransformer } from './notion-html.js'; +export { createAssetsArchive, download } from './utils.js'; +export { ZipTransformer } from './zip.js'; diff --git a/blocksuite/blocks/src/_common/transformers/markdown.ts b/blocksuite/blocks/src/root-block/transformers/markdown.ts similarity index 92% rename from blocksuite/blocks/src/_common/transformers/markdown.ts rename to blocksuite/blocks/src/root-block/transformers/markdown.ts index eb2a84be7..b31eefea0 100644 --- a/blocksuite/blocks/src/_common/transformers/markdown.ts +++ b/blocksuite/blocks/src/root-block/transformers/markdown.ts @@ -1,33 +1,27 @@ +import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image'; import { - InlineDeltaToMarkdownAdapterExtensions, - MarkdownInlineToDeltaAdapterExtensions, -} from '@blocksuite/affine-components/rich-text'; -import { MarkdownAdapter } from '@blocksuite/affine-shared/adapters'; + docLinkBaseURLMiddleware, + fileNameMiddleware, + MarkdownAdapter, + titleMiddleware, +} from '@blocksuite/affine-shared/adapters'; +import { SpecProvider } from '@blocksuite/affine-shared/utils'; import { Container } from '@blocksuite/global/di'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { assertExists, sha } from '@blocksuite/global/utils'; import type { Store, Workspace } from '@blocksuite/store'; import { extMimeMap, Transformer } from '@blocksuite/store'; -import { defaultBlockMarkdownAdapterMatchers } from '../adapters/index.js'; -import { - defaultImageProxyMiddleware, - docLinkBaseURLMiddleware, - fileNameMiddleware, - titleMiddleware, -} from './middlewares.js'; import { createAssetsArchive, download, Unzip } from './utils.js'; -const container = new Container(); -[ - ...MarkdownInlineToDeltaAdapterExtensions, - ...defaultBlockMarkdownAdapterMatchers, - ...InlineDeltaToMarkdownAdapterExtensions, -].forEach(ext => { - ext.setup(container); -}); - -const provider = container.provider(); +function getProvider() { + const container = new Container(); + const exts = SpecProvider.getInstance().getSpec('store').value; + exts.forEach(ext => { + ext.setup(container); + }); + return container.provider(); +} type ImportMarkdownToBlockOptions = { doc: Store; @@ -52,6 +46,7 @@ type ImportMarkdownZipOptions = { * @returns A Promise that resolves when the export is complete */ async function exportDoc(doc: Store) { + const provider = getProvider(); const job = new Transformer({ schema: doc.schema, blobCRUD: doc.blobSync, @@ -111,6 +106,7 @@ async function importMarkdownToBlock({ markdown, blockId, }: ImportMarkdownToBlockOptions) { + const provider = getProvider(); const job = new Transformer({ schema: doc.schema, blobCRUD: doc.blobSync, @@ -156,6 +152,7 @@ async function importMarkdownToDoc({ markdown, fileName, }: ImportMarkdownToDocOptions) { + const provider = getProvider(); const job = new Transformer({ schema: collection.schema, blobCRUD: collection.blobSync, @@ -192,6 +189,7 @@ async function importMarkdownZip({ collection, imported, }: ImportMarkdownZipOptions) { + const provider = getProvider(); const unzip = new Unzip(); await unzip.load(imported); diff --git a/blocksuite/blocks/src/_common/transformers/notion-html.ts b/blocksuite/blocks/src/root-block/transformers/notion-html.ts similarity index 91% rename from blocksuite/blocks/src/_common/transformers/notion-html.ts rename to blocksuite/blocks/src/root-block/transformers/notion-html.ts index c5aa2b387..88e69d23c 100644 --- a/blocksuite/blocks/src/_common/transformers/notion-html.ts +++ b/blocksuite/blocks/src/root-block/transformers/notion-html.ts @@ -1,11 +1,10 @@ -import { NotionHtmlInlineToDeltaAdapterExtensions } from '@blocksuite/affine-components/rich-text'; +import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image'; import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters'; +import { SpecProvider } from '@blocksuite/affine-shared/utils'; import { Container } from '@blocksuite/global/di'; import { sha } from '@blocksuite/global/utils'; import { extMimeMap, Transformer, type Workspace } from '@blocksuite/store'; -import { defaultBlockNotionHtmlAdapterMatchers } from '../adapters/notion-html/block-matcher.js'; -import { defaultImageProxyMiddleware } from './middlewares.js'; import { Unzip } from './utils.js'; type ImportNotionZipOptions = { @@ -13,15 +12,14 @@ type ImportNotionZipOptions = { imported: Blob; }; -const container = new Container(); -[ - ...NotionHtmlInlineToDeltaAdapterExtensions, - ...defaultBlockNotionHtmlAdapterMatchers, -].forEach(ext => { - ext.setup(container); -}); - -const provider = container.provider(); +function getProvider() { + const container = new Container(); + const exts = SpecProvider.getInstance().getSpec('store').value; + exts.forEach(ext => { + ext.setup(container); + }); + return container.provider(); +} /** * Imports a Notion zip file into the BlockSuite collection. @@ -40,6 +38,7 @@ async function importNotionZip({ collection, imported, }: ImportNotionZipOptions) { + const provider = getProvider(); const pageIds: string[] = []; let isWorkspaceFile = false; let hasMarkdown = false; diff --git a/blocksuite/blocks/src/_common/transformers/utils.ts b/blocksuite/blocks/src/root-block/transformers/utils.ts similarity index 100% rename from blocksuite/blocks/src/_common/transformers/utils.ts rename to blocksuite/blocks/src/root-block/transformers/utils.ts diff --git a/blocksuite/blocks/src/_common/transformers/zip.ts b/blocksuite/blocks/src/root-block/transformers/zip.ts similarity index 97% rename from blocksuite/blocks/src/_common/transformers/zip.ts rename to blocksuite/blocks/src/root-block/transformers/zip.ts index dd5fca07a..fdae39236 100644 --- a/blocksuite/blocks/src/_common/transformers/zip.ts +++ b/blocksuite/blocks/src/root-block/transformers/zip.ts @@ -1,9 +1,12 @@ +import { + replaceIdMiddleware, + titleMiddleware, +} from '@blocksuite/affine-shared/adapters'; import { sha } from '@blocksuite/global/utils'; import type { DocSnapshot, Store, Workspace } from '@blocksuite/store'; import { extMimeMap, getAssetName, Transformer } from '@blocksuite/store'; import { download, Unzip, Zip } from '../transformers/utils.js'; -import { replaceIdMiddleware, titleMiddleware } from './middlewares.js'; async function exportDocs(collection: Workspace, docs: Store[]) { const zip = new Zip(); diff --git a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts index d5210ab27..196de2199 100644 --- a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts +++ b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts @@ -12,9 +12,9 @@ import type { Workspace } from '@blocksuite/store'; import { html, LitElement, type PropertyValues } from 'lit'; import { query, state } from 'lit/decorators.js'; -import { HtmlTransformer } from '../../../../_common/transformers/html.js'; -import { MarkdownTransformer } from '../../../../_common/transformers/markdown.js'; -import { NotionHtmlTransformer } from '../../../../_common/transformers/notion-html.js'; +import { HtmlTransformer } from '../../../transformers/html.js'; +import { MarkdownTransformer } from '../../../transformers/markdown.js'; +import { NotionHtmlTransformer } from '../../../transformers/notion-html.js'; import { styles } from './styles.js'; export type OnSuccessHandler = ( diff --git a/blocksuite/integration-test/src/__tests__/main/snapshot.spec.ts b/blocksuite/integration-test/src/__tests__/main/snapshot.spec.ts index f44287375..da513bb78 100644 --- a/blocksuite/integration-test/src/__tests__/main/snapshot.spec.ts +++ b/blocksuite/integration-test/src/__tests__/main/snapshot.spec.ts @@ -1,5 +1,4 @@ -import { BlockServiceIdentifier } from '@blocksuite/block-std'; -import type { PageRootService, SurfaceBlockModel } from '@blocksuite/blocks'; +import { type SurfaceBlockModel, ZipTransformer } from '@blocksuite/blocks'; import type { PointLocation } from '@blocksuite/global/utils'; import { beforeEach, expect, test } from 'vitest'; @@ -25,13 +24,7 @@ const fieldChecker: Record boolean> = { const skipFields = new Set(['_lastXYWH']); const snapshotTest = async (snapshotUrl: string, elementsCount: number) => { - const pageService = window.editor.host!.std.getOptional( - BlockServiceIdentifier('affine:page') - ) as PageRootService; - if (!pageService) { - throw new Error('page service not found'); - } - const transformer = pageService.transformers.zip; + const transformer = ZipTransformer; const snapshotFile = await fetch(snapshotUrl) .then(res => res.blob()) diff --git a/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts b/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts index f656355d7..9f65195d2 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts @@ -209,7 +209,7 @@ export class AISlidesRenderer extends WithDisposable(LitElement) { ${new BlockStdScope({ store: this._doc, extensions: - SpecProvider.getInstance().getSpec('edgeless:preview').value, + SpecProvider.getInstance().getSpec('preview:edgeless').value, }).render()}
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts index 181b17807..350ed3986 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts @@ -245,10 +245,10 @@ export const extendEdgelessPreviewSpec = (function () { return _extension; } else { _extension && - SpecProvider.getInstance().omitSpec('edgeless:preview', _extension); + SpecProvider.getInstance().omitSpec('preview:edgeless', _extension); _extension = getThemeExtension(framework); _framework = framework; - SpecProvider.getInstance().extendSpec('edgeless:preview', [_extension]); + SpecProvider.getInstance().extendSpec('preview:edgeless', [_extension]); return _extension; } }; diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts index 7fa31ceb7..e8f0a73c5 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts @@ -29,14 +29,17 @@ const CustomSpecs: ExtensionType[] = [ getFontConfigExtension(), ].flat(); -function patchPreviewSpec(id: string, specs: ExtensionType[]) { +function patchPreviewSpec( + id: 'preview:edgeless' | 'preview:page', + specs: ExtensionType[] +) { const specProvider = SpecProvider.getInstance(); specProvider.extendSpec(id, specs); } export function effects() { // Patch edgeless preview spec for blocksuite surface-ref and embed-synced-doc - patchPreviewSpec('edgeless:preview', CustomSpecs); + patchPreviewSpec('preview:edgeless', CustomSpecs); } export function getPagePreviewThemeExtension(framework: FrameworkProvider) { @@ -98,7 +101,7 @@ export function createPageModePreviewSpecs( framework: FrameworkProvider ): SpecBuilder { const specProvider = SpecProvider.getInstance(); - const pagePreviewSpec = specProvider.getSpec('page:preview'); + const pagePreviewSpec = specProvider.getSpec('preview:page'); // Enable theme extension, doc display meta extension and peek view service const peekViewService = framework.get(PeekViewService); pagePreviewSpec.extend([ diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/edgeless/snapshot.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/edgeless/snapshot.tsx index a63e3e870..10ccba20a 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/edgeless/snapshot.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/edgeless/snapshot.tsx @@ -92,7 +92,7 @@ export const EdgelessSnapshot = (props: Props) => { const editorHost = new BlockStdScope({ store: doc, extensions: [ - ...SpecProvider.getInstance().getSpec('edgeless:preview').value, + ...SpecProvider.getInstance().getSpec('preview:edgeless').value, getThemeExtension(framework), ], }).render();