refactor(editor): cleanup dead code (#12072)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Simplified and removed several internal AI block extension files and utility functions, streamlining the codebase and reducing unused features.
  - Updated logic to access editor modes and controllers directly, removing reliance on DOM queries and certain abstractions.
  - Reduced and restructured effect type declarations for improved clarity.

- **Bug Fixes**
  - Improved type safety in the editor component by explicitly typing queried elements.

- **Chores**
  - Removed obsolete exports and internal functions with no impact on user-facing functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Saul-Mirone
2025-04-30 05:26:39 +00:00
parent 0d6c595adf
commit d856911144
12 changed files with 49 additions and 361 deletions
+17 -170
View File
@@ -1,92 +1,24 @@
import { effects as blockAttachmentEffects } from '@blocksuite/affine-block-attachment/effects';
import { effects as blockBookmarkEffects } from '@blocksuite/affine-block-bookmark/effects';
import { effects as blockCalloutEffects } from '@blocksuite/affine-block-callout/effects';
import { effects as blockCodeEffects } from '@blocksuite/affine-block-code/effects';
import { effects as blockDataViewEffects } from '@blocksuite/affine-block-data-view/effects';
import { effects as blockDatabaseEffects } from '@blocksuite/affine-block-database/effects';
import { effects as blockDividerEffects } from '@blocksuite/affine-block-divider/effects';
import { effects as blockEdgelessTextEffects } from '@blocksuite/affine-block-edgeless-text/effects';
import { effects as blockEmbedEffects } from '@blocksuite/affine-block-embed/effects';
import { effects as blockFrameEffects } from '@blocksuite/affine-block-frame/effects';
import { effects as blockImageEffects } from '@blocksuite/affine-block-image/effects';
import { effects as blockLatexEffects } from '@blocksuite/affine-block-latex/effects';
import { effects as blockListEffects } from '@blocksuite/affine-block-list/effects';
import { effects as blockNoteEffects } from '@blocksuite/affine-block-note/effects';
import { effects as blockParagraphEffects } from '@blocksuite/affine-block-paragraph/effects';
import { effects as blockRootEffects } from '@blocksuite/affine-block-root/effects';
import { effects as blockSurfaceEffects } from '@blocksuite/affine-block-surface/effects';
import { effects as blockSurfaceRefEffects } from '@blocksuite/affine-block-surface-ref/effects';
import { effects as blockTableEffects } from '@blocksuite/affine-block-table/effects';
import { BlockSelection } from '@blocksuite/affine-components/block-selection';
import { BlockZeroWidth } from '@blocksuite/affine-components/block-zero-width';
import { effects as componentCaptionEffects } from '@blocksuite/affine-components/caption';
import { effects as componentCardStyleDropdownMenuEffects } from '@blocksuite/affine-components/card-style-dropdown-menu';
import { effects as componentCitationEffects } from '@blocksuite/affine-components/citation';
import { effects as componentColorPickerEffects } from '@blocksuite/affine-components/color-picker';
import { effects as componentContextMenuEffects } from '@blocksuite/affine-components/context-menu';
import { effects as componentDatePickerEffects } from '@blocksuite/affine-components/date-picker';
import { effects as componentDropIndicatorEffects } from '@blocksuite/affine-components/drop-indicator';
import { effects as componentEdgelessLineStylesEffects } from '@blocksuite/affine-components/edgeless-line-styles-panel';
import { effects as componentEdgelessLineWidthEffects } from '@blocksuite/affine-components/edgeless-line-width-panel';
import { effects as componentEdgelessShapeColorPickerEffects } from '@blocksuite/affine-components/edgeless-shape-color-picker';
import { effects as componentEmbedCardModalEffects } from '@blocksuite/affine-components/embed-card-modal';
import { FilterableListComponent } from '@blocksuite/affine-components/filterable-list';
import { effects as componentHighlightDropdownMenuEffects } from '@blocksuite/affine-components/highlight-dropdown-menu';
import { IconButton } from '@blocksuite/affine-components/icon-button';
import { effects as componentLinkPreviewEffects } from '@blocksuite/affine-components/link-preview';
import { effects as componentLinkedDocTitleEffects } from '@blocksuite/affine-components/linked-doc-title';
import { effects as componentOpenDocDropdownMenuEffects } from '@blocksuite/affine-components/open-doc-dropdown-menu';
import { effects as componentPortalEffects } from '@blocksuite/affine-components/portal';
import { effects as componentSizeDropdownMenuEffects } from '@blocksuite/affine-components/size-dropdown-menu';
import { SmoothCorner } from '@blocksuite/affine-components/smooth-corner';
import { effects as componentToggleButtonEffects } from '@blocksuite/affine-components/toggle-button';
import { ToggleSwitch } from '@blocksuite/affine-components/toggle-switch';
import { effects as componentToolbarEffects } from '@blocksuite/affine-components/toolbar';
import { effects as componentTooltipContentWithShortcutEffects } from '@blocksuite/affine-components/tooltip-content-with-shortcut';
import { effects as componentViewDropdownMenuEffects } from '@blocksuite/affine-components/view-dropdown-menu';
import { effects as fragmentDocTitleEffects } from '@blocksuite/affine-fragment-doc-title/effects';
import { effects as fragmentFramePanelEffects } from '@blocksuite/affine-fragment-frame-panel/effects';
import { effects as fragmentOutlineEffects } from '@blocksuite/affine-fragment-outline/effects';
import { effects as inlineFootnoteEffects } from '@blocksuite/affine-inline-footnote/effects';
import { effects as inlineLatexEffects } from '@blocksuite/affine-inline-latex/effects';
import { effects as inlineLinkEffects } from '@blocksuite/affine-inline-link/effects';
import { effects as inlineMentionEffects } from '@blocksuite/affine-inline-mention';
import { effects as inlinePresetEffects } from '@blocksuite/affine-inline-preset/effects';
import { effects as inlineReferenceEffects } from '@blocksuite/affine-inline-reference/effects';
import { effects as richTextEffects } from '@blocksuite/affine-rich-text/effects';
import { effects as widgetDragHandleEffects } from '@blocksuite/affine-widget-drag-handle/effects';
import { effects as widgetEdgelessAutoConnectEffects } from '@blocksuite/affine-widget-edgeless-auto-connect/effects';
import { effects as widgetFrameTitleEffects } from '@blocksuite/affine-widget-frame-title/effects';
import { effects as widgetRemoteSelectionEffects } from '@blocksuite/affine-widget-remote-selection/effects';
import { effects as widgetScrollAnchoringEffects } from '@blocksuite/affine-widget-scroll-anchoring/effects';
import { effects as widgetSlashMenuEffects } from '@blocksuite/affine-widget-slash-menu/effects';
import { effects as widgetToolbarEffects } from '@blocksuite/affine-widget-toolbar/effects';
import { effects as dataViewEffects } from '@blocksuite/data-view/effects';
import { effects as stdEffects } from '@blocksuite/std/effects';
import { type effects as blockRootEffects } from '@blocksuite/affine-block-root/effects';
import { type effects as componentCaptionEffects } from '@blocksuite/affine-components/caption';
import { type effects as componentColorPickerEffects } from '@blocksuite/affine-components/color-picker';
import { type effects as componentContextMenuEffects } from '@blocksuite/affine-components/context-menu';
import { type effects as componentDatePickerEffects } from '@blocksuite/affine-components/date-picker';
import { type effects as componentDropIndicatorEffects } from '@blocksuite/affine-components/drop-indicator';
import { type effects as componentEmbedCardModalEffects } from '@blocksuite/affine-components/embed-card-modal';
import { type effects as componentHighlightDropdownMenuEffects } from '@blocksuite/affine-components/highlight-dropdown-menu';
import { type effects as componentLinkPreviewEffects } from '@blocksuite/affine-components/link-preview';
import { type effects as componentLinkedDocTitleEffects } from '@blocksuite/affine-components/linked-doc-title';
import { type effects as componentPortalEffects } from '@blocksuite/affine-components/portal';
import { type effects as componentToggleButtonEffects } from '@blocksuite/affine-components/toggle-button';
import { type effects as componentToolbarEffects } from '@blocksuite/affine-components/toolbar';
import { type effects as componentViewDropdownMenuEffects } from '@blocksuite/affine-components/view-dropdown-menu';
import { type effects as richTextEffects } from '@blocksuite/affine-rich-text/effects';
import { type effects as stdEffects } from '@blocksuite/std/effects';
export declare const _GLOBAL_:
| typeof stdEffects
| typeof dataViewEffects
| typeof richTextEffects
| typeof blockNoteEffects
| typeof blockAttachmentEffects
| typeof blockBookmarkEffects
| typeof blockFrameEffects
| typeof blockListEffects
| typeof blockParagraphEffects
| typeof blockEmbedEffects
| typeof blockSurfaceEffects
| typeof blockImageEffects
| typeof blockDatabaseEffects
| typeof blockSurfaceRefEffects
| typeof blockLatexEffects
| typeof blockEdgelessTextEffects
| typeof blockDividerEffects
| typeof blockDataViewEffects
| typeof blockCodeEffects
| typeof blockTableEffects
| typeof blockRootEffects
| typeof blockCalloutEffects
| typeof componentCaptionEffects
| typeof componentContextMenuEffects
| typeof componentDatePickerEffects
@@ -99,89 +31,4 @@ export declare const _GLOBAL_:
| typeof componentToolbarEffects
| typeof componentToggleButtonEffects
| typeof componentColorPickerEffects
| typeof componentViewDropdownMenuEffects
| typeof widgetScrollAnchoringEffects
| typeof widgetFrameTitleEffects
| typeof widgetRemoteSelectionEffects
| typeof widgetDragHandleEffects
| typeof widgetEdgelessAutoConnectEffects
| typeof widgetToolbarEffects
| typeof widgetSlashMenuEffects
| typeof fragmentDocTitleEffects
| typeof fragmentFramePanelEffects
| typeof fragmentOutlineEffects;
export function effects() {
stdEffects();
dataViewEffects();
richTextEffects();
inlineReferenceEffects();
inlinePresetEffects();
inlineLinkEffects();
inlineFootnoteEffects();
inlineLatexEffects();
inlineMentionEffects();
blockNoteEffects();
blockAttachmentEffects();
blockBookmarkEffects();
blockFrameEffects();
blockListEffects();
blockParagraphEffects();
blockEmbedEffects();
blockSurfaceEffects();
blockImageEffects();
blockDatabaseEffects();
blockSurfaceRefEffects();
blockLatexEffects();
blockEdgelessTextEffects();
blockDividerEffects();
blockDataViewEffects();
blockCodeEffects();
blockTableEffects();
blockRootEffects();
blockCalloutEffects();
componentCaptionEffects();
componentContextMenuEffects();
componentDatePickerEffects();
componentPortalEffects();
componentToolbarEffects();
componentDropIndicatorEffects();
componentToggleButtonEffects();
componentColorPickerEffects();
componentEmbedCardModalEffects();
componentLinkPreviewEffects();
componentLinkedDocTitleEffects();
componentCitationEffects();
componentCardStyleDropdownMenuEffects();
componentHighlightDropdownMenuEffects();
componentViewDropdownMenuEffects();
componentTooltipContentWithShortcutEffects();
componentSizeDropdownMenuEffects();
componentEdgelessLineWidthEffects();
componentEdgelessLineStylesEffects();
componentEdgelessShapeColorPickerEffects();
componentOpenDocDropdownMenuEffects();
widgetScrollAnchoringEffects();
widgetFrameTitleEffects();
widgetRemoteSelectionEffects();
widgetDragHandleEffects();
widgetEdgelessAutoConnectEffects();
widgetSlashMenuEffects();
widgetToolbarEffects();
fragmentDocTitleEffects();
fragmentFramePanelEffects();
fragmentOutlineEffects();
customElements.define('icon-button', IconButton);
customElements.define('smooth-corner', SmoothCorner);
customElements.define('toggle-switch', ToggleSwitch);
customElements.define('affine-filterable-list', FilterableListComponent);
customElements.define('block-zero-width', BlockZeroWidth);
customElements.define('affine-block-selection', BlockSelection);
}
| typeof componentViewDropdownMenuEffects;
@@ -44,7 +44,6 @@ import { preprocessHtml } from '../utils/html';
import { fetchImageToFile } from '../utils/image';
import {
getCopilotSelectedElems,
getEdgelessRootFromEditor,
getSurfaceElementFromEditor,
} from '../utils/selection-utils';
import type { AffineAIPanelWidget } from '../widgets/ai-panel/ai-panel';
@@ -337,12 +336,12 @@ function responseToCreateImage(host: EditorHost) {
.then(img => {
if (!img) return;
const edgelessRoot = getEdgelessRootFromEditor(host);
const { minX, minY } = bounds;
const [x, y] = edgelessRoot.service.viewport.toViewCoord(minX, minY);
const gfx = host.std.get(GfxControllerIdentifier);
const [x, y] = gfx.viewport.toViewCoord(minX, minY);
host.doc.transact(() => {
addImages(edgelessRoot.std, [img], { point: [x, y] })
addImages(host.std, [img], { point: [x, y] })
.then(blockIds => {
const imageBlockId = blockIds[0];
const imageBlock = host.doc.getBlock(imageBlockId);
@@ -490,10 +489,8 @@ function responseToMakeItReal(host: EditorHost, ctx: AIContext) {
edgelessCopilot.hideCopilotPanel();
aiPanel.hide();
const edgelessRoot = getEdgelessRootFromEditor(host);
host.doc.transact(() => {
edgelessRoot.doc.addBlock(
host.doc.addBlock(
'affine:embed-html',
{
html,
@@ -1,9 +1,5 @@
import {
AffineCodeToolbarWidget,
CodeBlockSpec,
} from '@blocksuite/affine/blocks/code';
import { AffineCodeToolbarWidget } from '@blocksuite/affine/blocks/code';
import { LifeCycleWatcher } from '@blocksuite/affine/std';
import type { ExtensionType } from '@blocksuite/affine/store';
import { setupCodeToolbarAIEntry } from '../entries/code-toolbar/setup-code-toolbar';
@@ -24,8 +20,3 @@ export class AICodeBlockWatcher extends LifeCycleWatcher {
});
}
}
export const AICodeBlockSpec: ExtensionType[] = [
...CodeBlockSpec,
AICodeBlockWatcher,
];
@@ -1,14 +0,0 @@
import { ImageBlockSpec } from '@blocksuite/affine/blocks/image';
import { ToolbarModuleExtension } from '@blocksuite/affine/shared/services';
import { BlockFlavourIdentifier } from '@blocksuite/affine/std';
import type { ExtensionType } from '@blocksuite/affine/store';
import { imageToolbarAIEntryConfig } from '../entries/image-toolbar/setup-image-toolbar';
export const AIImageBlockSpec: ExtensionType[] = [
...ImageBlockSpec,
ToolbarModuleExtension({
id: BlockFlavourIdentifier('custom:affine:image'),
config: imageToolbarAIEntryConfig(),
}),
];
@@ -1,24 +0,0 @@
import {
ParagraphBlockConfigExtension,
ParagraphBlockSpec,
} from '@blocksuite/affine/blocks/paragraph';
import type { ExtensionType } from '@blocksuite/affine/store';
export const AIParagraphBlockSpec: ExtensionType[] = [
...ParagraphBlockSpec,
ParagraphBlockConfigExtension({
getPlaceholder: model => {
const placeholders = {
text: "Type '/' for commands, 'space' for AI",
h1: 'Heading 1',
h2: 'Heading 2',
h3: 'Heading 3',
h4: 'Heading 4',
h5: 'Heading 5',
h6: 'Heading 6',
quote: '',
};
return placeholders[model.props.type];
},
}),
];
@@ -25,10 +25,8 @@ import { Slice, toDraftModel } from '@blocksuite/affine/store';
import type { ChatContextValue } from '../chat-panel/chat-context';
import {
allToCanvas,
getSelectedImagesAsBlobs,
getSelectedTextContent,
getTextContentFromBlockModels,
selectedToCanvas,
} from './selection-utils';
@@ -98,69 +96,6 @@ async function extractPageSelected(
}
}
export async function extractAllContent(
host: EditorHost
): Promise<Partial<ChatContextValue> | null> {
const docModeService = host.std.get(DocModeProvider);
const mode = docModeService.getEditorMode() || 'page';
if (mode === 'edgeless') {
return await extractEdgelessAll(host);
} else {
return await extractPageAll(host);
}
}
export async function extractEdgelessAll(
host: EditorHost
): Promise<Partial<ChatContextValue> | null> {
if (!isInsideEdgelessEditor(host)) return null;
const canvas = await allToCanvas(host);
if (!canvas) return null;
const blob: Blob | null = await new Promise(resolve =>
canvas.toBlob(resolve)
);
if (!blob) return null;
return {
images: [new File([blob], `${host.doc.id}.png`)],
};
}
export async function extractPageAll(
host: EditorHost
): Promise<Partial<ChatContextValue> | null> {
const blockModels = getNoteBlockModels(host.doc);
const text = await getTextContentFromBlockModels(
host,
blockModels,
'plain-text'
);
const markdown = await getTextContentFromBlockModels(
host,
blockModels,
'markdown'
);
const blobs = await Promise.all(
blockModels.map(async s => {
if (s.flavour !== 'affine:image') return null;
const sourceId = (s as ImageBlockModel)?.props.sourceId;
if (!sourceId) return null;
const blob = await (sourceId ? host.doc.blobSync.get(sourceId) : null);
if (!blob) return null;
return new File([blob], sourceId);
}) ?? []
);
const images = blobs.filter((blob): blob is File => !!blob);
return {
quote: text,
markdown,
images,
};
}
export async function extractMarkdownFromDoc(
doc: Store,
provider: ServiceProvider
@@ -1,17 +1,12 @@
import {
EdgelessClipboardController,
isCanvasElement,
splitElements,
} from '@blocksuite/affine/blocks/root';
import {
getSurfaceBlock,
type SurfaceBlockComponent,
} from '@blocksuite/affine/blocks/surface';
import {
DatabaseBlockModel,
type FrameBlockModel,
ImageBlockModel,
} from '@blocksuite/affine/model';
import { DatabaseBlockModel, ImageBlockModel } from '@blocksuite/affine/model';
import {
getBlockSelectionsCommand,
getImageSelectionsCommand,
@@ -36,30 +31,17 @@ import { getContentFromSlice } from '../../utils';
import type { CopilotTool } from '../tool/copilot-tool';
import { getEdgelessCopilotWidget } from './edgeless';
export function getEdgelessRootFromEditor(editor: EditorHost) {
const edgelessRoot = editor.getElementsByTagName('affine-edgeless-root')[0];
if (!edgelessRoot) {
alert('Please switch to edgeless mode');
throw new Error('Please open switch to edgeless mode');
}
return edgelessRoot;
}
export async function selectedToCanvas(host: EditorHost) {
const edgelessRoot = getEdgelessRootFromEditor(host);
return elementsToCanvas(
host,
edgelessRoot.service.selection.selectedElements
);
const gfx = host.std.get(GfxControllerIdentifier);
return elementsToCanvas(host, gfx.selection.selectedElements);
}
export async function allToCanvas(host: EditorHost) {
const edgelessRoot = getEdgelessRootFromEditor(host);
return elementsToCanvas(host, edgelessRoot.gfx.gfxElements);
const gfx = host.std.get(GfxControllerIdentifier);
return elementsToCanvas(host, gfx.gfxElements);
}
export async function elementsToCanvas(host: EditorHost, elements: GfxModel[]) {
const edgelessRoot = getEdgelessRootFromEditor(host);
const { notes, frames, shapes, images, edgelessTexts, embedSyncedDocs } =
splitElements(elements);
@@ -77,7 +59,7 @@ export async function elementsToCanvas(host: EditorHost, elements: GfxModel[]) {
}
try {
const canvas = await edgelessRoot.std
const canvas = await host.std
.get(EdgelessClipboardController)
.toCanvas(blockElements, shapes);
if (!canvas) {
@@ -90,10 +72,6 @@ export async function elementsToCanvas(host: EditorHost, elements: GfxModel[]) {
}
}
export async function selectedToPng(editor: EditorHost) {
return (await selectedToCanvas(editor))?.toDataURL('image/png');
}
export function getSelectedModels(editorHost: EditorHost) {
const [_, ctx] = editorHost.std.command.exec(getSelectedModelsCommand, {
types: ['block', 'text'],
@@ -198,10 +176,6 @@ export async function selectAboveBlocks(editorHost: EditorHost, num = 10) {
return getTextContentFromBlockModels(editorHost, selectedModels);
}
export const stopPropagation = (e: Event) => {
e.stopPropagation();
};
export function getSurfaceElementFromEditor(editor: EditorHost) {
const { doc } = editor;
const surfaceModel = getSurfaceBlock(doc);
@@ -216,24 +190,6 @@ export function getSurfaceElementFromEditor(editor: EditorHost) {
return surfaceElement;
}
export const getFirstImageInFrame = (
frame: FrameBlockModel,
editor: EditorHost
) => {
const edgelessRoot = getEdgelessRootFromEditor(editor);
const elements = edgelessRoot.service.frame.getElementsInFrameBound(
frame,
false
);
const image = elements.find(ele => {
if (!isCanvasElement(ele)) {
return ele.flavour === 'affine:image';
}
return false;
}) as ImageBlockModel | undefined;
return image?.id;
};
export const getSelections = (
host: EditorHost,
mode: 'flat' | 'highest' = 'flat'
@@ -1,8 +1,5 @@
import { registerAIEffects } from '@affine/core/blocksuite/ai/effects';
import { editorEffects } from '@affine/core/blocksuite/editors';
import type * as EffectType from '@blocksuite/affine/effects';
declare type _GLOBAL_ = typeof EffectType;
import { registerTemplates } from './register-templates';
@@ -401,7 +401,9 @@ export const BlocksuiteEdgelessEditor = forwardRef<
editorRef.current.updateComplete
.then(() => {
// make sure editor can get keyboard events on showing up
editorRef.current?.querySelector('affine-edgeless-root')?.click();
editorRef.current
?.querySelector<HTMLElement>('affine-edgeless-root')
?.click();
})
.catch(console.error);
}
@@ -3,7 +3,10 @@ import type { DefaultOpenProperty } from '@affine/core/components/doc-properties
import type { DocTitle } from '@blocksuite/affine/fragments/doc-title';
import type { DocMode, ReferenceParams } from '@blocksuite/affine/model';
import { HighlightSelection } from '@blocksuite/affine/shared/selection';
import { FeatureFlagService as BSFeatureFlagService } from '@blocksuite/affine/shared/services';
import {
DocModeProvider,
FeatureFlagService as BSFeatureFlagService,
} from '@blocksuite/affine/shared/services';
import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx';
import type { InlineEditor } from '@blocksuite/std/inline';
import { effect } from '@preact/signals-core';
@@ -293,19 +296,18 @@ export class Editor extends Entity {
unsubs.push(subscription.unsubscribe.bind(subscription));
// ----- Presenting -----
const edgelessPage = editorContainer.host?.querySelector(
'affine-edgeless-root'
);
if (!edgelessPage) {
const std = editorContainer.host?.std;
const editorMode = std?.get(DocModeProvider)?.getEditorMode();
if (!editorMode || editorMode !== 'edgeless' || !gfx) {
this.isPresenting$.next(false);
} else {
this.isPresenting$.next(
edgelessPage.gfx.tool.currentToolName$.peek() === 'frameNavigator'
gfx.tool.currentToolName$.peek() === 'frameNavigator'
);
const disposable = effect(() => {
this.isPresenting$.next(
edgelessPage.gfx.tool.currentToolName$.value === 'frameNavigator'
gfx.tool.currentToolName$.value === 'frameNavigator'
);
});
unsubs.push(disposable);
@@ -1,14 +1,14 @@
import type * as Effects from '@blocksuite/affine/effects';
import type * as ConnectorToolEffect from '@blocksuite/affine/gfx/connector';
import type * as ShapeToolEffect from '@blocksuite/affine/gfx/shape';
import type * as Effect from '@blocksuite/affine/effects';
import type * as ConnectorEffect from '@blocksuite/affine/gfx/connector';
import type * as ShapeEffect from '@blocksuite/affine/gfx/shape';
import type { EditorHost } from '@blocksuite/affine/std';
import type { Store, Transformer, Workspace } from '@blocksuite/affine/store';
import type { TestAffineEditorContainer } from '@blocksuite/integration-test';
declare const _GLOBAL_:
| typeof Effects
| typeof ConnectorToolEffect
| typeof ShapeToolEffect;
declare type _GLOBAL_ =
| typeof Effect
| typeof ConnectorEffect
| typeof ShapeEffect;
declare global {
interface Window {
+2 -3
View File
@@ -1,12 +1,11 @@
import type * as BlocksuiteEffects from '@blocksuite/affine/effects';
import '@blocksuite/affine/effects';
import type { IVec, XYWH } from '@blocksuite/affine/global/gfx';
import type { CodeBlockComponent } from '@blocksuite/affine-block-code';
import type { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
import type { BlockComponent } from '@blocksuite/std';
import { expect, type Locator, type Page } from '@playwright/test';
declare type _GLOBAL_ = typeof BlocksuiteEffects;
const EDGELESS_TOOLBAR_WIDGET = 'edgeless-toolbar-widget';
export const ZERO_WIDTH_FOR_EMPTY_LINE =
process.env.BROWSER === 'webkit' ? '\u200C' : '\u200B';