diff --git a/blocksuite/affine/block-code/src/code-block-spec.ts b/blocksuite/affine/block-code/src/code-block-spec.ts index 5ddb5da56f..1e2a28d608 100644 --- a/blocksuite/affine/block-code/src/code-block-spec.ts +++ b/blocksuite/affine/block-code/src/code-block-spec.ts @@ -1,7 +1,7 @@ import { BlockViewExtension, FlavourExtension, - WidgetViewMapExtension, + WidgetViewExtension, } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/store'; import { literal, unsafeStatic } from 'lit/static-html.js'; @@ -14,13 +14,17 @@ import { import { CodeBlockService } from './code-block-service.js'; import { AFFINE_CODE_TOOLBAR_WIDGET } from './code-toolbar/index.js'; +export const codeToolbarWidget = WidgetViewExtension( + 'affine:code', + AFFINE_CODE_TOOLBAR_WIDGET, + literal`${unsafeStatic(AFFINE_CODE_TOOLBAR_WIDGET)}` +); + export const CodeBlockSpec: ExtensionType[] = [ FlavourExtension('affine:code'), CodeBlockService, BlockViewExtension('affine:code', literal`affine-code`), - WidgetViewMapExtension('affine:code', { - codeToolbar: literal`${unsafeStatic(AFFINE_CODE_TOOLBAR_WIDGET)}`, - }), + codeToolbarWidget, CodeBlockInlineManagerExtension, CodeBlockUnitSpecExtension, CodeBlockAdapterExtensions, diff --git a/blocksuite/affine/block-image/src/image-spec.ts b/blocksuite/affine/block-image/src/image-spec.ts index 515280a3e8..79387e3a90 100644 --- a/blocksuite/affine/block-image/src/image-spec.ts +++ b/blocksuite/affine/block-image/src/image-spec.ts @@ -1,7 +1,7 @@ import { BlockViewExtension, FlavourExtension, - WidgetViewMapExtension, + WidgetViewExtension, } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/store'; import { literal } from 'lit/static-html.js'; @@ -10,6 +10,12 @@ import { ImageBlockAdapterExtensions } from './adapters/extension.js'; import { ImageProxyService } from './image-proxy-service.js'; import { ImageBlockService, ImageDropOption } from './image-service.js'; +export const imageToolbarWidget = WidgetViewExtension( + 'affine:image', + 'imageToolbar', + literal`affine-image-toolbar-widget` +); + export const ImageBlockSpec: ExtensionType[] = [ FlavourExtension('affine:image'), ImageBlockService, @@ -22,9 +28,7 @@ export const ImageBlockSpec: ExtensionType[] = [ return literal`affine-image`; }), - WidgetViewMapExtension('affine:image', { - imageToolbar: literal`affine-image-toolbar-widget`, - }), + imageToolbarWidget, ImageDropOption, ImageBlockAdapterExtensions, ].flat(); diff --git a/blocksuite/affine/block-surface-ref/src/index.ts b/blocksuite/affine/block-surface-ref/src/index.ts index 33e9135377..6903b745d8 100644 --- a/blocksuite/affine/block-surface-ref/src/index.ts +++ b/blocksuite/affine/block-surface-ref/src/index.ts @@ -1,9 +1,6 @@ export * from './commands.js'; export * from './surface-ref-block.js'; export * from './surface-ref-block-edgeless.js'; -export { - EdgelessSurfaceRefBlockSpec, - PageSurfaceRefBlockSpec, -} from './surface-ref-spec.js'; +export * from './surface-ref-spec.js'; export * from './types.js'; export * from './utils.js'; diff --git a/blocksuite/affine/block-surface-ref/src/surface-ref-spec.ts b/blocksuite/affine/block-surface-ref/src/surface-ref-spec.ts index b6cd7c180d..99d0426e39 100644 --- a/blocksuite/affine/block-surface-ref/src/surface-ref-spec.ts +++ b/blocksuite/affine/block-surface-ref/src/surface-ref-spec.ts @@ -1,17 +1,21 @@ import { BlockViewExtension, FlavourExtension, - WidgetViewMapExtension, + WidgetViewExtension, } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/store'; import { literal } from 'lit/static-html.js'; +export const surfaceRefToolbarWidget = WidgetViewExtension( + 'affine:surface-ref', + 'surfaceToolbar', + literal`affine-surface-ref-toolbar` +); + export const PageSurfaceRefBlockSpec: ExtensionType[] = [ FlavourExtension('affine:surface-ref'), BlockViewExtension('affine:surface-ref', literal`affine-surface-ref`), - WidgetViewMapExtension('affine:surface-ref', { - surfaceToolbar: literal`affine-surface-ref-toolbar`, - }), + surfaceRefToolbarWidget, ]; export const EdgelessSurfaceRefBlockSpec: ExtensionType[] = [ diff --git a/blocksuite/blocks/src/_specs/preset/mobile-patch.ts b/blocksuite/blocks/src/_specs/preset/mobile-patch.ts index 042440c8d5..34f516f5d6 100644 --- a/blocksuite/blocks/src/_specs/preset/mobile-patch.ts +++ b/blocksuite/blocks/src/_specs/preset/mobile-patch.ts @@ -9,15 +9,9 @@ import { type BlockStdScope, ConfigIdentifier, LifeCycleWatcher, - WidgetViewMapIdentifier, - type WidgetViewMapType, } from '@blocksuite/block-std'; import type { Container } from '@blocksuite/global/di'; -import { AFFINE_EMBED_CARD_TOOLBAR_WIDGET } from '../../root-block/widgets/embed-card-toolbar/embed-card-toolbar.js'; -import { AFFINE_FORMAT_BAR_WIDGET } from '../../root-block/widgets/format-bar/format-bar.js'; -import { AFFINE_SLASH_MENU_WIDGET } from '../../root-block/widgets/slash-menu/index.js'; - export class MobileSpecsPatches extends LifeCycleWatcher { static override key = 'mobile-patches'; @@ -54,48 +48,6 @@ export class MobileSpecsPatches extends LifeCycleWatcher { } satisfies CodeBlockConfig; }); } - - // Disable root level widgets for mobile. - { - const rootWidgetViewMapIdentifier = - WidgetViewMapIdentifier('affine:page'); - - const prev = di.getFactory(rootWidgetViewMapIdentifier); - - di.override(rootWidgetViewMapIdentifier, provider => { - const ignoreWidgets = [ - AFFINE_FORMAT_BAR_WIDGET, - AFFINE_EMBED_CARD_TOOLBAR_WIDGET, - AFFINE_SLASH_MENU_WIDGET, - ]; - - const newMap = { ...prev?.(provider) }; - - ignoreWidgets.forEach(widget => { - if (widget in newMap) delete newMap[widget]; - }); - - return newMap; - }); - } - - // Disable block level toolbar widgets for mobile. - { - di.override( - WidgetViewMapIdentifier('affine:code'), - (): WidgetViewMapType => ({}) - ); - - di.override( - WidgetViewMapIdentifier('affine:image'), - (): WidgetViewMapType => ({}) - ); - - di.override( - WidgetViewMapIdentifier('affine:surface-ref'), - (): WidgetViewMapType => ({}) - ); - } } override mounted() { diff --git a/blocksuite/blocks/src/root-block/common-specs/index.ts b/blocksuite/blocks/src/root-block/common-specs/index.ts new file mode 100644 index 0000000000..a49c9739e4 --- /dev/null +++ b/blocksuite/blocks/src/root-block/common-specs/index.ts @@ -0,0 +1,50 @@ +import { FileDropExtension } from '@blocksuite/affine-components/drop-indicator'; +import { + DNDAPIExtension, + DocModeService, + EmbedOptionService, + PageViewportServiceExtension, + ThemeService, +} from '@blocksuite/affine-shared/services'; +import { FlavourExtension } from '@blocksuite/block-std'; +import type { ExtensionType } from '@blocksuite/store'; + +import { ExportManagerExtension } from '../../_common/export-manager/export-manager'; +import { RootBlockAdapterExtensions } from '../adapters/extension'; +import { + docRemoteSelectionWidget, + dragHandleWidget, + embedCardToolbarWidget, + formatBarWidget, + innerModalWidget, + linkedDocWidget, + modalWidget, + scrollAnchoringWidget, + slashMenuWidget, + viewportOverlayWidget, +} from './widgets'; + +export const CommonSpecs: ExtensionType[] = [ + FlavourExtension('affine:page'), + DocModeService, + ThemeService, + EmbedOptionService, + ExportManagerExtension, + PageViewportServiceExtension, + DNDAPIExtension, + FileDropExtension, + ...RootBlockAdapterExtensions, + + modalWidget, + innerModalWidget, + slashMenuWidget, + linkedDocWidget, + dragHandleWidget, + embedCardToolbarWidget, + formatBarWidget, + docRemoteSelectionWidget, + viewportOverlayWidget, + scrollAnchoringWidget, +]; + +export * from './widgets'; diff --git a/blocksuite/blocks/src/root-block/common-specs/widgets.ts b/blocksuite/blocks/src/root-block/common-specs/widgets.ts new file mode 100644 index 0000000000..b6076d1cdf --- /dev/null +++ b/blocksuite/blocks/src/root-block/common-specs/widgets.ts @@ -0,0 +1,64 @@ +import { AFFINE_DRAG_HANDLE_WIDGET } from '@blocksuite/affine-widget-drag-handle'; +import { AFFINE_DOC_REMOTE_SELECTION_WIDGET } from '@blocksuite/affine-widget-remote-selection'; +import { AFFINE_SCROLL_ANCHORING_WIDGET } from '@blocksuite/affine-widget-scroll-anchoring'; +import { WidgetViewExtension } from '@blocksuite/block-std'; +import { literal, unsafeStatic } from 'lit/static-html.js'; + +import { AFFINE_EMBED_CARD_TOOLBAR_WIDGET } from '../widgets/embed-card-toolbar/embed-card-toolbar.js'; +import { AFFINE_FORMAT_BAR_WIDGET } from '../widgets/format-bar/format-bar.js'; +import { AFFINE_INNER_MODAL_WIDGET } from '../widgets/inner-modal/inner-modal.js'; +import { AFFINE_LINKED_DOC_WIDGET } from '../widgets/linked-doc/config.js'; +import { AFFINE_MODAL_WIDGET } from '../widgets/modal/modal.js'; +import { AFFINE_SLASH_MENU_WIDGET } from '../widgets/slash-menu/index.js'; +import { AFFINE_VIEWPORT_OVERLAY_WIDGET } from '../widgets/viewport-overlay/viewport-overlay.js'; + +export const modalWidget = WidgetViewExtension( + 'affine:page', + AFFINE_MODAL_WIDGET, + literal`${unsafeStatic(AFFINE_MODAL_WIDGET)}` +); +export const innerModalWidget = WidgetViewExtension( + 'affine:page', + AFFINE_INNER_MODAL_WIDGET, + literal`${unsafeStatic(AFFINE_INNER_MODAL_WIDGET)}` +); +export const slashMenuWidget = WidgetViewExtension( + 'affine:page', + AFFINE_SLASH_MENU_WIDGET, + literal`${unsafeStatic(AFFINE_SLASH_MENU_WIDGET)}` +); +export const linkedDocWidget = WidgetViewExtension( + 'affine:page', + AFFINE_LINKED_DOC_WIDGET, + literal`${unsafeStatic(AFFINE_LINKED_DOC_WIDGET)}` +); +export const dragHandleWidget = WidgetViewExtension( + 'affine:page', + AFFINE_DRAG_HANDLE_WIDGET, + literal`${unsafeStatic(AFFINE_DRAG_HANDLE_WIDGET)}` +); +export const embedCardToolbarWidget = WidgetViewExtension( + 'affine:page', + AFFINE_EMBED_CARD_TOOLBAR_WIDGET, + literal`${unsafeStatic(AFFINE_EMBED_CARD_TOOLBAR_WIDGET)}` +); +export const formatBarWidget = WidgetViewExtension( + 'affine:page', + AFFINE_FORMAT_BAR_WIDGET, + literal`${unsafeStatic(AFFINE_FORMAT_BAR_WIDGET)}` +); +export const docRemoteSelectionWidget = WidgetViewExtension( + 'affine:page', + AFFINE_DOC_REMOTE_SELECTION_WIDGET, + literal`${unsafeStatic(AFFINE_DOC_REMOTE_SELECTION_WIDGET)}` +); +export const viewportOverlayWidget = WidgetViewExtension( + 'affine:page', + AFFINE_VIEWPORT_OVERLAY_WIDGET, + literal`${unsafeStatic(AFFINE_VIEWPORT_OVERLAY_WIDGET)}` +); +export const scrollAnchoringWidget = WidgetViewExtension( + 'affine:page', + AFFINE_SCROLL_ANCHORING_WIDGET, + literal`${unsafeStatic(AFFINE_SCROLL_ANCHORING_WIDGET)}` +); diff --git a/blocksuite/blocks/src/root-block/edgeless/edgeless-root-spec.ts b/blocksuite/blocks/src/root-block/edgeless/edgeless-root-spec.ts index 93770e0e1c..dd4502bde6 100644 --- a/blocksuite/blocks/src/root-block/edgeless/edgeless-root-spec.ts +++ b/blocksuite/blocks/src/root-block/edgeless/edgeless-root-spec.ts @@ -1,40 +1,18 @@ -import { FileDropExtension } from '@blocksuite/affine-components/drop-indicator'; -import { - DNDAPIExtension, - DocModeService, - EmbedOptionService, - PageViewportServiceExtension, - ThemeService, -} from '@blocksuite/affine-shared/services'; -import { AFFINE_DRAG_HANDLE_WIDGET } from '@blocksuite/affine-widget-drag-handle'; import { AFFINE_EDGELESS_AUTO_CONNECT_WIDGET } from '@blocksuite/affine-widget-edgeless-auto-connect'; import { AFFINE_FRAME_TITLE_WIDGET } from '@blocksuite/affine-widget-frame-title'; -import { - AFFINE_DOC_REMOTE_SELECTION_WIDGET, - AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET, -} from '@blocksuite/affine-widget-remote-selection'; -import { AFFINE_SCROLL_ANCHORING_WIDGET } from '@blocksuite/affine-widget-scroll-anchoring'; +import { AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET } from '@blocksuite/affine-widget-remote-selection'; import { BlockServiceWatcher, BlockViewExtension, - FlavourExtension, - WidgetViewMapExtension, + WidgetViewExtension, } from '@blocksuite/block-std'; import { ToolController } from '@blocksuite/block-std/gfx'; import type { ExtensionType } from '@blocksuite/store'; import { literal, unsafeStatic } from 'lit/static-html.js'; -import { ExportManagerExtension } from '../../_common/export-manager/export-manager.js'; -import { RootBlockAdapterExtensions } from '../adapters/extension.js'; +import { CommonSpecs } from '../common-specs/index.js'; import { AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET } from '../widgets/edgeless-zoom-toolbar/index.js'; import { EDGELESS_ELEMENT_TOOLBAR_WIDGET } from '../widgets/element-toolbar/index.js'; -import { AFFINE_EMBED_CARD_TOOLBAR_WIDGET } from '../widgets/embed-card-toolbar/embed-card-toolbar.js'; -import { AFFINE_FORMAT_BAR_WIDGET } from '../widgets/format-bar/format-bar.js'; -import { AFFINE_INNER_MODAL_WIDGET } from '../widgets/inner-modal/inner-modal.js'; -import { AFFINE_LINKED_DOC_WIDGET } from '../widgets/linked-doc/config.js'; -import { AFFINE_MODAL_WIDGET } from '../widgets/modal/modal.js'; -import { AFFINE_SLASH_MENU_WIDGET } from '../widgets/slash-menu/index.js'; -import { AFFINE_VIEWPORT_OVERLAY_WIDGET } from '../widgets/viewport-overlay/viewport-overlay.js'; import { NOTE_SLICER_WIDGET } from './components/note-slicer/index.js'; import { EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET } from './components/presentation/edgeless-navigator-black-background.js'; import { EDGELESS_DRAGGING_AREA_WIDGET } from './components/rects/edgeless-dragging-area-rect.js'; @@ -42,68 +20,56 @@ import { EDGELESS_SELECTED_RECT_WIDGET } from './components/rects/edgeless-selec import { EDGELESS_TOOLBAR_WIDGET } from './components/toolbar/edgeless-toolbar.js'; import { EdgelessRootService } from './edgeless-root-service.js'; -export const edgelessRootWidgetViewMap = { - [AFFINE_MODAL_WIDGET]: literal`${unsafeStatic(AFFINE_MODAL_WIDGET)}`, - [AFFINE_INNER_MODAL_WIDGET]: literal`${unsafeStatic(AFFINE_INNER_MODAL_WIDGET)}`, - [AFFINE_SLASH_MENU_WIDGET]: literal`${unsafeStatic( - AFFINE_SLASH_MENU_WIDGET - )}`, - [AFFINE_LINKED_DOC_WIDGET]: literal`${unsafeStatic( - AFFINE_LINKED_DOC_WIDGET - )}`, - [AFFINE_DRAG_HANDLE_WIDGET]: literal`${unsafeStatic( - AFFINE_DRAG_HANDLE_WIDGET - )}`, - [AFFINE_EMBED_CARD_TOOLBAR_WIDGET]: literal`${unsafeStatic( - AFFINE_EMBED_CARD_TOOLBAR_WIDGET - )}`, - [AFFINE_FORMAT_BAR_WIDGET]: literal`${unsafeStatic( - AFFINE_FORMAT_BAR_WIDGET - )}`, - [AFFINE_DOC_REMOTE_SELECTION_WIDGET]: literal`${unsafeStatic( - AFFINE_DOC_REMOTE_SELECTION_WIDGET - )}`, - [AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET]: literal`${unsafeStatic( - AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET - )}`, - [AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET]: literal`${unsafeStatic( - AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET - )}`, - [AFFINE_FRAME_TITLE_WIDGET]: literal`${unsafeStatic(AFFINE_FRAME_TITLE_WIDGET)}`, - [EDGELESS_ELEMENT_TOOLBAR_WIDGET]: literal`${unsafeStatic(EDGELESS_ELEMENT_TOOLBAR_WIDGET)}`, - [AFFINE_VIEWPORT_OVERLAY_WIDGET]: literal`${unsafeStatic( - AFFINE_VIEWPORT_OVERLAY_WIDGET - )}`, - [AFFINE_EDGELESS_AUTO_CONNECT_WIDGET]: literal`${unsafeStatic( - AFFINE_EDGELESS_AUTO_CONNECT_WIDGET - )}`, - [AFFINE_SCROLL_ANCHORING_WIDGET]: literal`${unsafeStatic(AFFINE_SCROLL_ANCHORING_WIDGET)}`, - [EDGELESS_DRAGGING_AREA_WIDGET]: literal`${unsafeStatic(EDGELESS_DRAGGING_AREA_WIDGET)}`, - [NOTE_SLICER_WIDGET]: literal`${unsafeStatic(NOTE_SLICER_WIDGET)}`, - [EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET]: literal`${unsafeStatic(EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET)}`, - [EDGELESS_SELECTED_RECT_WIDGET]: literal`${unsafeStatic(EDGELESS_SELECTED_RECT_WIDGET)}`, - [EDGELESS_TOOLBAR_WIDGET]: literal`${unsafeStatic(EDGELESS_TOOLBAR_WIDGET)}`, -}; - -const EdgelessCommonExtension: ExtensionType[] = [ - FlavourExtension('affine:page'), - EdgelessRootService, - DocModeService, - ThemeService, - EmbedOptionService, - ExportManagerExtension, - ToolController, - DNDAPIExtension, - PageViewportServiceExtension, - RootBlockAdapterExtensions, - FileDropExtension, -].flat(); - -export const EdgelessRootBlockSpec: ExtensionType[] = [ - ...EdgelessCommonExtension, - BlockViewExtension('affine:page', literal`affine-edgeless-root`), - WidgetViewMapExtension('affine:page', edgelessRootWidgetViewMap), -]; +export const edgelessRemoteSelectionWidget = WidgetViewExtension( + 'affine:page', + AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET, + literal`${unsafeStatic(AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET)}` +); +export const edgelessZoomToolbarWidget = WidgetViewExtension( + 'affine:page', + AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET, + literal`${unsafeStatic(AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET)}` +); +export const frameTitleWidget = WidgetViewExtension( + 'affine:page', + AFFINE_FRAME_TITLE_WIDGET, + literal`${unsafeStatic(AFFINE_FRAME_TITLE_WIDGET)}` +); +export const elementToolbarWidget = WidgetViewExtension( + 'affine:page', + EDGELESS_ELEMENT_TOOLBAR_WIDGET, + literal`${unsafeStatic(EDGELESS_ELEMENT_TOOLBAR_WIDGET)}` +); +export const autoConnectWidget = WidgetViewExtension( + 'affine:page', + AFFINE_EDGELESS_AUTO_CONNECT_WIDGET, + literal`${unsafeStatic(AFFINE_EDGELESS_AUTO_CONNECT_WIDGET)}` +); +export const edgelessDraggingAreaWidget = WidgetViewExtension( + 'affine:page', + EDGELESS_DRAGGING_AREA_WIDGET, + literal`${unsafeStatic(EDGELESS_DRAGGING_AREA_WIDGET)}` +); +export const noteSlicerWidget = WidgetViewExtension( + 'affine:page', + NOTE_SLICER_WIDGET, + literal`${unsafeStatic(NOTE_SLICER_WIDGET)}` +); +export const edgelessNavigatorBlackBackgroundWidget = WidgetViewExtension( + 'affine:page', + EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET, + literal`${unsafeStatic(EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET)}` +); +export const edgelessSelectedRectWidget = WidgetViewExtension( + 'affine:page', + EDGELESS_SELECTED_RECT_WIDGET, + literal`${unsafeStatic(EDGELESS_SELECTED_RECT_WIDGET)}` +); +export const edgelessToolbarWidget = WidgetViewExtension( + 'affine:page', + EDGELESS_TOOLBAR_WIDGET, + literal`${unsafeStatic(EDGELESS_TOOLBAR_WIDGET)}` +); class EdgelessLocker extends BlockServiceWatcher { static override readonly flavour = 'affine:page'; @@ -119,6 +85,27 @@ class EdgelessLocker extends BlockServiceWatcher { } } +const EdgelessCommonExtension: ExtensionType[] = [ + CommonSpecs, + ToolController, + EdgelessRootService, +].flat(); + +export const EdgelessRootBlockSpec: ExtensionType[] = [ + ...EdgelessCommonExtension, + BlockViewExtension('affine:page', literal`affine-edgeless-root`), + edgelessRemoteSelectionWidget, + edgelessZoomToolbarWidget, + frameTitleWidget, + elementToolbarWidget, + autoConnectWidget, + edgelessDraggingAreaWidget, + noteSlicerWidget, + edgelessNavigatorBlackBackgroundWidget, + edgelessSelectedRectWidget, + edgelessToolbarWidget, +]; + export const PreviewEdgelessRootBlockSpec: ExtensionType[] = [ ...EdgelessCommonExtension, BlockViewExtension('affine:page', literal`affine-edgeless-root-preview`), diff --git a/blocksuite/blocks/src/root-block/index.ts b/blocksuite/blocks/src/root-block/index.ts index 717426e17a..3625b4b4c8 100644 --- a/blocksuite/blocks/src/root-block/index.ts +++ b/blocksuite/blocks/src/root-block/index.ts @@ -1,5 +1,6 @@ export * from './adapters/markdown.js'; export * from './clipboard/index.js'; +export * from './common-specs/index.js'; export * from './edgeless/edgeless-root-spec.js'; export * from './edgeless/index.js'; export { TemplateJob } from './edgeless/services/template.js'; diff --git a/blocksuite/blocks/src/root-block/page/page-root-spec.ts b/blocksuite/blocks/src/root-block/page/page-root-spec.ts index 126d0c5073..263d1b6ef7 100644 --- a/blocksuite/blocks/src/root-block/page/page-root-spec.ts +++ b/blocksuite/blocks/src/root-block/page/page-root-spec.ts @@ -1,83 +1,34 @@ -import { FileDropExtension } from '@blocksuite/affine-components/drop-indicator'; -import { - DNDAPIExtension, - DocModeService, - EmbedOptionService, - PageViewportServiceExtension, - ThemeService, -} from '@blocksuite/affine-shared/services'; -import { AFFINE_DRAG_HANDLE_WIDGET } from '@blocksuite/affine-widget-drag-handle'; -import { AFFINE_DOC_REMOTE_SELECTION_WIDGET } from '@blocksuite/affine-widget-remote-selection'; -import { AFFINE_SCROLL_ANCHORING_WIDGET } from '@blocksuite/affine-widget-scroll-anchoring'; -import { - BlockViewExtension, - FlavourExtension, - WidgetViewMapExtension, -} from '@blocksuite/block-std'; +import { BlockViewExtension, WidgetViewExtension } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/store'; import { literal, unsafeStatic } from 'lit/static-html.js'; -import { ExportManagerExtension } from '../../_common/export-manager/export-manager.js'; -import { RootBlockAdapterExtensions } from '../adapters/extension.js'; -import { AFFINE_EMBED_CARD_TOOLBAR_WIDGET } from '../widgets/embed-card-toolbar/embed-card-toolbar.js'; -import { AFFINE_FORMAT_BAR_WIDGET } from '../widgets/format-bar/format-bar.js'; -import { AFFINE_INNER_MODAL_WIDGET } from '../widgets/inner-modal/inner-modal.js'; +import { CommonSpecs } from '../common-specs/index.js'; import { AFFINE_KEYBOARD_TOOLBAR_WIDGET } from '../widgets/keyboard-toolbar/index.js'; -import { AFFINE_LINKED_DOC_WIDGET } from '../widgets/linked-doc/config.js'; -import { AFFINE_MODAL_WIDGET } from '../widgets/modal/modal.js'; import { AFFINE_PAGE_DRAGGING_AREA_WIDGET } from '../widgets/page-dragging-area/page-dragging-area.js'; -import { AFFINE_SLASH_MENU_WIDGET } from '../widgets/slash-menu/index.js'; -import { AFFINE_VIEWPORT_OVERLAY_WIDGET } from '../widgets/viewport-overlay/viewport-overlay.js'; import { PageRootService } from './page-root-service.js'; -export const pageRootWidgetViewMap = { - [AFFINE_KEYBOARD_TOOLBAR_WIDGET]: literal`${unsafeStatic(AFFINE_KEYBOARD_TOOLBAR_WIDGET)}`, - [AFFINE_MODAL_WIDGET]: literal`${unsafeStatic(AFFINE_MODAL_WIDGET)}`, - [AFFINE_INNER_MODAL_WIDGET]: literal`${unsafeStatic(AFFINE_INNER_MODAL_WIDGET)}`, - [AFFINE_SLASH_MENU_WIDGET]: literal`${unsafeStatic( - AFFINE_SLASH_MENU_WIDGET - )}`, - [AFFINE_LINKED_DOC_WIDGET]: literal`${unsafeStatic( - AFFINE_LINKED_DOC_WIDGET - )}`, - [AFFINE_DRAG_HANDLE_WIDGET]: literal`${unsafeStatic( - AFFINE_DRAG_HANDLE_WIDGET - )}`, - [AFFINE_EMBED_CARD_TOOLBAR_WIDGET]: literal`${unsafeStatic( - AFFINE_EMBED_CARD_TOOLBAR_WIDGET - )}`, - [AFFINE_FORMAT_BAR_WIDGET]: literal`${unsafeStatic( - AFFINE_FORMAT_BAR_WIDGET - )}`, - [AFFINE_DOC_REMOTE_SELECTION_WIDGET]: literal`${unsafeStatic( - AFFINE_DOC_REMOTE_SELECTION_WIDGET - )}`, - [AFFINE_PAGE_DRAGGING_AREA_WIDGET]: literal`${unsafeStatic( - AFFINE_PAGE_DRAGGING_AREA_WIDGET - )}`, - [AFFINE_VIEWPORT_OVERLAY_WIDGET]: literal`${unsafeStatic( - AFFINE_VIEWPORT_OVERLAY_WIDGET - )}`, - [AFFINE_SCROLL_ANCHORING_WIDGET]: literal`${unsafeStatic(AFFINE_SCROLL_ANCHORING_WIDGET)}`, -}; +export const keyboardToolbarWidget = WidgetViewExtension( + 'affine:page', + AFFINE_KEYBOARD_TOOLBAR_WIDGET, + literal`${unsafeStatic(AFFINE_KEYBOARD_TOOLBAR_WIDGET)}` +); + +export const pageDraggingAreaWidget = WidgetViewExtension( + 'affine:page', + AFFINE_PAGE_DRAGGING_AREA_WIDGET, + literal`${unsafeStatic(AFFINE_PAGE_DRAGGING_AREA_WIDGET)}` +); const PageCommonExtension: ExtensionType[] = [ - FlavourExtension('affine:page'), + CommonSpecs, PageRootService, - DocModeService, - ThemeService, - EmbedOptionService, - PageViewportServiceExtension, -]; + pageDraggingAreaWidget, +].flat(); export const PageRootBlockSpec: ExtensionType[] = [ ...PageCommonExtension, BlockViewExtension('affine:page', literal`affine-page-root`), - WidgetViewMapExtension('affine:page', pageRootWidgetViewMap), - ExportManagerExtension, - DNDAPIExtension, - RootBlockAdapterExtensions, - FileDropExtension, + keyboardToolbarWidget, ].flat(); export const PreviewPageRootBlockSpec: ExtensionType[] = [ diff --git a/blocksuite/framework/block-std/src/extension/widget-view-map.ts b/blocksuite/framework/block-std/src/extension/widget-view-map.ts index 7574f95857..b71f16e430 100644 --- a/blocksuite/framework/block-std/src/extension/widget-view-map.ts +++ b/blocksuite/framework/block-std/src/extension/widget-view-map.ts @@ -1,32 +1,40 @@ import type { ExtensionType } from '@blocksuite/store'; -import { WidgetViewMapIdentifier } from '../identifier.js'; -import type { WidgetViewMapType } from '../spec/type.js'; +import { WidgetViewIdentifier } from '../identifier.js'; +import type { WidgetViewType } from '../spec/type.js'; /** - * Create a widget view map extension. + * Create a widget view extension. * - * @param flavour The flavour of the block that the widget view map is for. - * @param widgetViewMap A map of widget names to widget view lit literal. + * @param flavour The flavour of the block that the widget view is for. + * @param id The id of the widget view. + * @param view The widget view lit literal. * - * A widget view map is to provide a map of widgets to a block. - * For every target block, it's view will be rendered with the widget views. + * A widget view is to provide a widget view for a block. + * For every target block, it's view will be rendered with the widget view. * * @example * ```ts - * import { WidgetViewMapExtension } from '@blocksuite/block-std'; + * import { WidgetViewExtension } from '@blocksuite/block-std'; * - * const MyWidgetViewMapExtension = WidgetViewMapExtension('my-flavour', { - * 'my-widget': literal`my-widget-view` - * }); + * const MyWidgetViewExtension = WidgetViewExtension('my-flavour', 'my-widget', literal`my-widget-view`); */ -export function WidgetViewMapExtension( +export function WidgetViewExtension( flavour: string, - widgetViewMap: WidgetViewMapType + id: string, + view: WidgetViewType ): ExtensionType { return { setup: di => { - di.addImpl(WidgetViewMapIdentifier(flavour), () => widgetViewMap); + if (flavour.includes('|') || id.includes('|')) { + console.error(`Register view failed:`); + console.error( + `flavour or id cannot include '|', flavour: ${flavour}, id: ${id}` + ); + return; + } + const key = `${flavour}|${id}`; + di.addImpl(WidgetViewIdentifier(key), view); }, }; } diff --git a/blocksuite/framework/block-std/src/identifier.ts b/blocksuite/framework/block-std/src/identifier.ts index 571d509c38..32d0aa0722 100644 --- a/blocksuite/framework/block-std/src/identifier.ts +++ b/blocksuite/framework/block-std/src/identifier.ts @@ -4,7 +4,7 @@ import type { Command } from './command/index.js'; import type { EventOptions, UIEventHandler } from './event/index.js'; import type { BlockService, LifeCycleWatcher } from './extension/index.js'; import type { BlockStdScope } from './scope/index.js'; -import type { BlockViewType, WidgetViewMapType } from './spec/type.js'; +import type { BlockViewType, WidgetViewType } from './spec/type.js'; export const BlockServiceIdentifier = createIdentifier('BlockService'); @@ -20,8 +20,8 @@ export const ConfigIdentifier = export const BlockViewIdentifier = createIdentifier('BlockView'); -export const WidgetViewMapIdentifier = - createIdentifier('WidgetViewMap'); +export const WidgetViewIdentifier = + createIdentifier('WidgetView'); export const LifeCycleWatcherIdentifier = createIdentifier('LifeCycleWatcher'); diff --git a/blocksuite/framework/block-std/src/spec/type.ts b/blocksuite/framework/block-std/src/spec/type.ts index 6aa0a157fc..1ca5536dfa 100644 --- a/blocksuite/framework/block-std/src/spec/type.ts +++ b/blocksuite/framework/block-std/src/spec/type.ts @@ -2,4 +2,4 @@ import type { BlockModel } from '@blocksuite/store'; import type { StaticValue } from 'lit/static-html.js'; export type BlockViewType = StaticValue | ((model: BlockModel) => StaticValue); -export type WidgetViewMapType = Record; +export type WidgetViewType = StaticValue; diff --git a/blocksuite/framework/block-std/src/view/element/lit-host.ts b/blocksuite/framework/block-std/src/view/element/lit-host.ts index 5ac1518f69..d94fc575d8 100644 --- a/blocksuite/framework/block-std/src/view/element/lit-host.ts +++ b/blocksuite/framework/block-std/src/view/element/lit-host.ts @@ -17,7 +17,7 @@ import { html, type StaticValue, unsafeStatic } from 'lit/static-html.js'; import type { CommandManager } from '../../command/index.js'; import type { UIEventDispatcher } from '../../event/index.js'; -import { WidgetViewMapIdentifier } from '../../identifier.js'; +import { WidgetViewIdentifier } from '../../identifier.js'; import type { RangeManager } from '../../range/index.js'; import type { BlockStdScope } from '../../scope/block-std-scope.js'; import { PropTypes, requiredProperties } from '../decorators/index.js'; @@ -56,22 +56,21 @@ export class EditorHost extends SignalWatcher( console.warn(`Cannot find render flavour ${flavour}.`); return html`${nothing}`; } - const widgetViewMap = this.std.getOptional( - WidgetViewMapIdentifier(flavour) + + const widgetViews = this.std.provider.getAll(WidgetViewIdentifier); + const widgets = widgetViews.entries().reduce( + (mapping, [key, tag]) => { + const [widgetFlavour, id] = key.split('|'); + if (widgetFlavour === flavour) { + const template = html`<${tag} ${unsafeStatic(WIDGET_ID_ATTR)}=${id}>`; + mapping[id] = template; + } + return mapping; + }, + {} as Record ); const tag = typeof view === 'function' ? view(model) : view; - const widgets: Record = widgetViewMap - ? Object.entries(widgetViewMap).reduce((mapping, [key, tag]) => { - const template = html`<${tag} ${unsafeStatic(WIDGET_ID_ATTR)}=${key}>`; - - return { - ...mapping, - [key]: template, - }; - }, {}) - : {}; - return html`<${tag} ${unsafeStatic(BLOCK_ID_ATTR)}=${model.id} .widgets=${widgets} @@ -144,13 +143,22 @@ export class EditorHost extends SignalWatcher( const view = this.std.getView(rootModel.flavour); if (!view) return result; - const widgetViewMap = this.std.getOptional( - WidgetViewMapIdentifier(rootModel.flavour) + const widgetViews = this.std.provider.getAll( + WidgetViewIdentifier(rootModel.flavour) + ); + const widgetTags = Object.entries(widgetViews).reduce( + (mapping, [key, tag]) => { + const [widgetFlavour, id] = key.split('|'); + if (widgetFlavour === rootModel.flavour) { + mapping[id] = tag; + } + return mapping; + }, + {} as Record ); - const widgetTags = Object.values(widgetViewMap ?? {}); const elementsTags: StaticValue[] = [ typeof view === 'function' ? view(rootModel) : view, - ...widgetTags, + ...Object.values(widgetTags), ]; await Promise.all( elementsTags.map(tag => { diff --git a/blocksuite/playground/apps/starter/main.ts b/blocksuite/playground/apps/starter/main.ts index c262e8873d..7c4cc7264f 100644 --- a/blocksuite/playground/apps/starter/main.ts +++ b/blocksuite/playground/apps/starter/main.ts @@ -1,9 +1,6 @@ import '../../style.css'; -import { - WidgetViewMapExtension, - WidgetViewMapIdentifier, -} from '@blocksuite/block-std'; +import * as blockStd from '@blocksuite/block-std'; import * as blocks from '@blocksuite/blocks'; import { CommunityCanvasTextFonts, @@ -52,8 +49,8 @@ async function main() { blocks, global: { utils: globalUtils }, editor, + blockStd: blockStd, identifiers: { - WidgetViewMapIdentifier, QuickSearchProvider, DocModeProvider, RefNodeSlotsProvider, @@ -65,7 +62,6 @@ async function main() { ], extensions: { FontConfigExtension: FontConfigExtension(CommunityCanvasTextFonts), - WidgetViewMapExtension, }, mockServices: { mockDocModeService, diff --git a/blocksuite/tests-legacy/slash-menu.spec.ts b/blocksuite/tests-legacy/slash-menu.spec.ts index 345f07988c..311949935a 100644 --- a/blocksuite/tests-legacy/slash-menu.spec.ts +++ b/blocksuite/tests-legacy/slash-menu.spec.ts @@ -794,13 +794,11 @@ test.describe('slash menu with customize menu', () => { { setup: di => { di.override( - window.$blocksuite.identifiers.WidgetViewMapIdentifier( - 'affine:page' + window.$blocksuite.blockStd.WidgetViewIdentifier( + 'affine:page|affine-slash-menu-widget' ), // @ts-ignore - () => ({ - 'affine-slash-menu-widget': fakeLiteral`affine-custom-slash-menu`, - }) + fakeLiteral`affine-custom-slash-menu` ); }, }, @@ -869,13 +867,11 @@ test.describe('slash menu with customize menu', () => { { setup: di => di.override( - window.$blocksuite.identifiers.WidgetViewMapIdentifier( - 'affine:page' + window.$blocksuite.blockStd.WidgetViewIdentifier( + 'affine:page|affine-slash-menu-widget' ), // @ts-ignore - () => ({ - 'affine-slash-menu-widget': fakeLiteral`affine-custom-slash-menu`, - }) + fakeLiteral`affine-custom-slash-menu` ), }, ]; diff --git a/blocksuite/tests-legacy/utils/declare-test-window.ts b/blocksuite/tests-legacy/utils/declare-test-window.ts index 5b37a687ad..8e4564f319 100644 --- a/blocksuite/tests-legacy/utils/declare-test-window.ts +++ b/blocksuite/tests-legacy/utils/declare-test-window.ts @@ -5,11 +5,7 @@ import type { QuickSearchProvider, ThemeProvider, } from '@blocksuite/affine-shared/services'; -import type { - EditorHost, - WidgetViewMapExtension, - WidgetViewMapIdentifier, -} from '@blocksuite/block-std'; +import type { EditorHost } from '@blocksuite/block-std'; import type { RefNodeSlotsProvider, TestUtils } from '@blocksuite/blocks'; import type { AffineEditorContainer } from '@blocksuite/presets'; import type { @@ -32,8 +28,8 @@ declare global { utils: typeof import('@blocksuite/global/utils'); }; editor: typeof import('@blocksuite/presets'); + blockStd: typeof import('@blocksuite/block-std'); identifiers: { - WidgetViewMapIdentifier: typeof WidgetViewMapIdentifier; QuickSearchProvider: typeof QuickSearchProvider; DocModeProvider: typeof DocModeProvider; ThemeProvider: typeof ThemeProvider; @@ -41,9 +37,6 @@ declare global { ParseDocUrlService: typeof ParseDocUrlProvider; }; defaultExtensions: () => ExtensionType[]; - extensions: { - WidgetViewMapExtension: typeof WidgetViewMapExtension; - }; mockServices: { mockDocModeService: typeof DocModeService; }; diff --git a/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts b/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts index 6ad115b1eb..82b9fd381f 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts @@ -1,6 +1,6 @@ import { BlockServiceWatcher, - WidgetViewMapIdentifier, + WidgetViewExtension, } from '@blocksuite/affine/block-std'; import { AFFINE_AI_PANEL_WIDGET, @@ -14,10 +14,8 @@ import { EdgelessCopilotWidget, EdgelessElementToolbarWidget, EdgelessRootBlockSpec, - edgelessRootWidgetViewMap, ImageBlockSpec, PageRootBlockSpec, - pageRootWidgetViewMap, ParagraphBlockService, ParagraphBlockSpec, } from '@blocksuite/affine/blocks'; @@ -63,25 +61,22 @@ function getAIPageRootWatcher(framework: FrameworkProvider) { return AIPageRootWatcher; } +const aiPanelWidget = WidgetViewExtension( + 'affine:page', + AFFINE_AI_PANEL_WIDGET, + literal`${unsafeStatic(AFFINE_AI_PANEL_WIDGET)}` +); + +const edgelessCopilotWidget = WidgetViewExtension( + 'affine:page', + AFFINE_EDGELESS_COPILOT_WIDGET, + literal`${unsafeStatic(AFFINE_EDGELESS_COPILOT_WIDGET)}` +); + export function createAIPageRootBlockSpec( framework: FrameworkProvider ): ExtensionType[] { - return [ - ...PageRootBlockSpec, - getAIPageRootWatcher(framework), - { - setup: di => { - di.override(WidgetViewMapIdentifier('affine:page'), () => { - return { - ...pageRootWidgetViewMap, - [AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic( - AFFINE_AI_PANEL_WIDGET - )}`, - }; - }); - }, - }, - ]; + return [...PageRootBlockSpec, aiPanelWidget, getAIPageRootWatcher(framework)]; } function getAIEdgelessRootWatcher(framework: FrameworkProvider) { @@ -123,22 +118,9 @@ export function createAIEdgelessRootBlockSpec( ): ExtensionType[] { return [ ...EdgelessRootBlockSpec, + aiPanelWidget, + edgelessCopilotWidget, getAIEdgelessRootWatcher(framework), - { - setup: di => { - di.override(WidgetViewMapIdentifier('affine:page'), () => { - return { - ...edgelessRootWidgetViewMap, - [AFFINE_EDGELESS_COPILOT_WIDGET]: literal`${unsafeStatic( - AFFINE_EDGELESS_COPILOT_WIDGET - )}`, - [AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic( - AFFINE_AI_PANEL_WIDGET - )}`, - }; - }); - }, - }, ]; } diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx index 9dd5e0a870..eb73dee114 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx @@ -17,7 +17,15 @@ import { toURLSearchParams } from '@affine/core/modules/navigation'; import { PeekViewService } from '@affine/core/modules/peek-view/services/peek-view'; import { WorkspaceService } from '@affine/core/modules/workspace'; import track from '@affine/track'; -import type { DocMode } from '@blocksuite/affine/blocks'; +import { + codeToolbarWidget, + type DocMode, + embedCardToolbarWidget, + formatBarWidget, + imageToolbarWidget, + slashMenuWidget, + surfaceRefToolbarWidget, +} from '@blocksuite/affine/blocks'; import { DocTitle, EdgelessEditor, @@ -173,6 +181,12 @@ const usePatchSpecs = (mode: DocMode) => { builder.extend([patchForAttachmentEmbedViews(reactToLit)]); } if (BUILD_CONFIG.isMobileEdition) { + builder.omit(formatBarWidget); + builder.omit(embedCardToolbarWidget); + builder.omit(slashMenuWidget); + builder.omit(codeToolbarWidget); + builder.omit(imageToolbarWidget); + builder.omit(surfaceRefToolbarWidget); builder.extend([patchForMobile()].flat()); } if (BUILD_CONFIG.isElectron) {