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 5d3869bd3a..a8b7fcb41a 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 3ed5f5cd48..a978d1982b 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 cd81dac2a9..59ab7c22ac 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 eafa6b52a1..796a67ac3b 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 2df2e154e2..c8b6c7291d 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 00600120de..3aac6d2163 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 5c10b24381..32f9438ec3 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 4adaa45b65..4f3971956a 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 ad411d3fbf..83d33a4e52 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 94b5ef70c3..eff5f4e0ee 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 8b98f3e362..4dcb66f6c7 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 bd9bc4032c..47ddf70e69 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 c560eeaa26..2beacca903 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 dea698f7cc..507c49fcee 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 840d3cf948..b2b2b4c2f1 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 10729b3207..ee66081c80 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 09a9bdb7bd..7a10c98f7a 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 c4351250d7..807739d4f7 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 ef8fe53e95..4f72dd9a78 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 dce670ac78..c607f8578e 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 0000000000..9ee244cc8a --- /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 0000000000..01fe47c4c1 --- /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 c576d4a835..131fa6b1f0 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 2300beb068..fa6f02a9b3 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 0000000000..4ad24cc1ff --- /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 ce9c5da607..7ee92da5bb 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 c0e9120a54..64adabe5f2 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 5c63c28658..9aa8a6bdd3 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 3971fcb39f..313d1dcc79 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 d39474c0de..8313e0ee3d 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 2552034b2f..e7038b2cb1 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 328cb13503..6586647d3a 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 11253674fd..0000000000 --- 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 9b00589ae9..0000000000 --- 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 b5ae2d8d9a..be108c9816 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 0000000000..02c1510808 --- /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 ae39863504..f97a2d7726 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 8595d747b3..29ca74e9cb 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 eafc99426a..0b31e8a9c0 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 162c4a032e..2cdbaed15f 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 f6c31fa233..78b6aee186 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 43b4ac469e..18da693c2c 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 ac50402ce4..e6ee791794 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 7273ef2073..871ba4dd12 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 52d3adb89c..b99fadff27 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 5517c52dc8..5cd26a66b9 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 4afb1140aa..3a6a7033af 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 5f4a12ad19..980460e55c 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 3625b4b4c8..dcf49ca3ac 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 4f0501134b..2f6ea88181 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 0857f3e15e..4502bd2f5f 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 0000000000..a25831dbbe --- /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 eb2a84be74..b31eefea01 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 c5aa2b387d..88e69d23cd 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 dd5fca07ad..fdae392360 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 d5210ab270..196de21997 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 f442873751..da513bb789 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 f656355d77..9f65195d2b 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 181b178071..350ed3986b 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 7fa31ceb77..e8f0a73c5d 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 a63e3e870c..10ccba20a6 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();