From 2f04e3180c186dcd2ab6f8768998d88bc642042d Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Tue, 18 Feb 2025 14:03:51 +0000 Subject: [PATCH] refactor: move utils and cleanup test helpers (#10261) --- .../affine/block-image/src/image-spec.ts | 2 +- .../src/utils/dom/has-classname-in-list.ts | 6 ++ .../affine/shared/src/utils/dom/index.ts | 1 + .../src/__tests__/adapters/html.unit.spec.ts | 2 +- .../__tests__/adapters/markdown.unit.spec.ts | 2 +- .../adapters/notion-html.unit.spec.ts | 2 +- .../adapters/notion-text.unit.spec.ts | 2 +- .../utils/nanoid-replacement.ts} | 15 ----- blocksuite/blocks/src/_common/utils/index.ts | 2 - blocksuite/blocks/src/_common/utils/query.ts | 59 ------------------- blocksuite/blocks/src/_specs/common.ts | 9 ++- blocksuite/blocks/src/index.ts | 1 - .../edgeless/clipboard/clipboard.ts | 11 +++- .../root-block/edgeless/gfx-tool/note-tool.ts | 2 +- .../edgeless/gfx-tool/shape-tool.ts | 2 +- .../src/root-block/edgeless/utils/crud.ts | 2 +- .../src/root-block/edgeless/utils/query.ts | 2 +- .../src/root-block/page/page-root-block.ts | 13 ++-- .../src/root-block/page/page-root-service.ts | 6 -- blocksuite/playground/apps/env.d.ts | 2 - .../apps/starter/utils/collection.ts | 3 +- .../tests-legacy/utils/declare-test-window.ts | 3 +- 22 files changed, 38 insertions(+), 111 deletions(-) create mode 100644 blocksuite/affine/shared/src/utils/dom/has-classname-in-list.ts rename blocksuite/blocks/src/{_common/test-utils/test-utils.ts => __tests__/utils/nanoid-replacement.ts} (79%) delete mode 100644 blocksuite/blocks/src/_common/utils/index.ts delete mode 100644 blocksuite/blocks/src/_common/utils/query.ts diff --git a/blocksuite/affine/block-image/src/image-spec.ts b/blocksuite/affine/block-image/src/image-spec.ts index 79387e3a9..945715315 100644 --- a/blocksuite/affine/block-image/src/image-spec.ts +++ b/blocksuite/affine/block-image/src/image-spec.ts @@ -33,4 +33,4 @@ export const ImageBlockSpec: ExtensionType[] = [ ImageBlockAdapterExtensions, ].flat(); -export const ImageStoreSpec: ExtensionType[] = [ImageProxyService].flat(); +export const ImageStoreSpec: ExtensionType[] = [ImageProxyService]; diff --git a/blocksuite/affine/shared/src/utils/dom/has-classname-in-list.ts b/blocksuite/affine/shared/src/utils/dom/has-classname-in-list.ts new file mode 100644 index 000000000..0b08cf720 --- /dev/null +++ b/blocksuite/affine/shared/src/utils/dom/has-classname-in-list.ts @@ -0,0 +1,6 @@ +/** + * Return `true` if the element has class name in the class list. + */ +export function hasClassNameInList(element: Element, classList: string[]) { + return classList.some(className => element.classList.contains(className)); +} diff --git a/blocksuite/affine/shared/src/utils/dom/index.ts b/blocksuite/affine/shared/src/utils/dom/index.ts index 2c2e1c47f..260a677a2 100644 --- a/blocksuite/affine/shared/src/utils/dom/index.ts +++ b/blocksuite/affine/shared/src/utils/dom/index.ts @@ -1,4 +1,5 @@ export * from './checker.js'; +export * from './has-classname-in-list.js'; export * from './point-to-block.js'; export * from './point-to-range.js'; export * from './query.js'; diff --git a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts index 14e38ddd3..3971fcb39 100644 --- a/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts @@ -14,9 +14,9 @@ import { AssetsManager, MemoryBlobCRUD } from '@blocksuite/store'; import { describe, expect, test } from 'vitest'; import { defaultBlockHtmlAdapterMatchers } from '../../_common/adapters/html/block-matcher.js'; -import { nanoidReplacement } from '../../_common/test-utils/test-utils.js'; import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js'; import { createJob } from '../utils/create-job.js'; +import { nanoidReplacement } from '../utils/nanoid-replacement.js'; const container = new Container(); [ diff --git a/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts index 975db9528..d39474c0d 100644 --- a/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/markdown.unit.spec.ts @@ -19,9 +19,9 @@ import { AssetsManager, MemoryBlobCRUD } from '@blocksuite/store'; import { describe, expect, test } from 'vitest'; import { defaultBlockMarkdownAdapterMatchers } from '../../_common/adapters/markdown/block-matcher.js'; -import { nanoidReplacement } from '../../_common/test-utils/test-utils.js'; import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js'; import { createJob } from '../utils/create-job.js'; +import { nanoidReplacement } from '../utils/nanoid-replacement.js'; const container = new Container(); [ diff --git a/blocksuite/blocks/src/__tests__/adapters/notion-html.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/notion-html.unit.spec.ts index eb97c4c55..51d2b62c0 100644 --- a/blocksuite/blocks/src/__tests__/adapters/notion-html.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/notion-html.unit.spec.ts @@ -10,8 +10,8 @@ import { import { describe, expect, test } from 'vitest'; import { defaultBlockNotionHtmlAdapterMatchers } from '../../_common/adapters/notion-html/block-matcher.js'; -import { nanoidReplacement } from '../../_common/test-utils/test-utils.js'; import { createJob } from '../utils/create-job.js'; +import { nanoidReplacement } from '../utils/nanoid-replacement.js'; const container = new Container(); [ diff --git a/blocksuite/blocks/src/__tests__/adapters/notion-text.unit.spec.ts b/blocksuite/blocks/src/__tests__/adapters/notion-text.unit.spec.ts index 311ffa077..dd9a53174 100644 --- a/blocksuite/blocks/src/__tests__/adapters/notion-text.unit.spec.ts +++ b/blocksuite/blocks/src/__tests__/adapters/notion-text.unit.spec.ts @@ -3,8 +3,8 @@ import { NotionTextAdapter } from '@blocksuite/affine-shared/adapters'; import type { SliceSnapshot } from '@blocksuite/store'; import { describe, expect, test } from 'vitest'; -import { nanoidReplacement } from '../../_common/test-utils/test-utils.js'; import { createJob } from '../utils/create-job.js'; +import { nanoidReplacement } from '../utils/nanoid-replacement.js'; describe('notion-text to snapshot', () => { test('basic', () => { diff --git a/blocksuite/blocks/src/_common/test-utils/test-utils.ts b/blocksuite/blocks/src/__tests__/utils/nanoid-replacement.ts similarity index 79% rename from blocksuite/blocks/src/_common/test-utils/test-utils.ts rename to blocksuite/blocks/src/__tests__/utils/nanoid-replacement.ts index 981e5be70..b0a4b6a1c 100644 --- a/blocksuite/blocks/src/_common/test-utils/test-utils.ts +++ b/blocksuite/blocks/src/__tests__/utils/nanoid-replacement.ts @@ -1,20 +1,5 @@ -import { - mergeToCodeModel, - transformModel, -} from '@blocksuite/affine-shared/utils'; import type { BlockSnapshot, SliceSnapshot } from '@blocksuite/store'; -class DocTestUtils { - // block model operations (data layer) - mergeToCodeModel = mergeToCodeModel; - - transformModel = transformModel; -} - -export class TestUtils { - docTestUtils = new DocTestUtils(); -} - export function nanoidReplacement(snapshot: BlockSnapshot | SliceSnapshot) { return JSON.parse(nanoidReplacementString(JSON.stringify(snapshot))); } diff --git a/blocksuite/blocks/src/_common/utils/index.ts b/blocksuite/blocks/src/_common/utils/index.ts deleted file mode 100644 index 8e95d3152..000000000 --- a/blocksuite/blocks/src/_common/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../types.js'; -export * from './query.js'; diff --git a/blocksuite/blocks/src/_common/utils/query.ts b/blocksuite/blocks/src/_common/utils/query.ts deleted file mode 100644 index 0c0ef8389..000000000 --- a/blocksuite/blocks/src/_common/utils/query.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { EditorHost } from '@blocksuite/block-std'; -import type { BlockModel } from '@blocksuite/store'; - -import type { RootBlockComponent } from '../../index.js'; - -/** - * This function is used to build model's "normal" block path. - * If this function does not meet your needs, you may need to build path manually to satisfy your needs. - * You should not modify this function. - */ -export function buildPath(model: BlockModel | null): string[] { - const path: string[] = []; - let current = model; - while (current) { - path.unshift(current.id); - current = current.doc.getParent(current); - } - return path; -} - -export function getRootByEditorHost( - editorHost: EditorHost -): RootBlockComponent | null { - return ( - getPageRootByEditorHost(editorHost) ?? - getEdgelessRootByEditorHost(editorHost) - ); -} - -/** If it's not in the page mode, it will return `null` directly */ -export function getPageRootByEditorHost(editorHost: EditorHost) { - return editorHost.querySelector('affine-page-root'); -} - -/** If it's not in the edgeless mode, it will return `null` directly */ -export function getEdgelessRootByEditorHost(editorHost: EditorHost) { - return editorHost.querySelector('affine-edgeless-root'); -} - -/** - * Get block component by model. - * Note that this function is used for compatibility only, and may be removed in the future. - * - * @deprecated - */ -export function getBlockComponentByModel( - editorHost: EditorHost, - model: BlockModel | null -) { - if (!model) return null; - return editorHost.view.getBlock(model.id); -} - -/** - * Return `true` if the element has class name in the class list. - */ -export function hasClassNameInList(element: Element, classList: string[]) { - return classList.some(className => element.classList.contains(className)); -} diff --git a/blocksuite/blocks/src/_specs/common.ts b/blocksuite/blocks/src/_specs/common.ts index 478bf5183..b5ae2d8d9 100644 --- a/blocksuite/blocks/src/_specs/common.ts +++ b/blocksuite/blocks/src/_specs/common.ts @@ -71,11 +71,12 @@ export const CommonBlockSpecs: ExtensionType[] = [ BookmarkBlockSpec, EmbedExtensions, AttachmentBlockSpec, - AdapterFactoryExtensions, CodeBlockSpec, ImageBlockSpec, ParagraphBlockSpec, DefaultOpenDocExtension, + FontLoaderService, + AdapterFactoryExtensions, ].flat(); export const PageFirstPartyBlockSpecs: ExtensionType[] = [ @@ -83,7 +84,6 @@ export const PageFirstPartyBlockSpecs: ExtensionType[] = [ NoteBlockSpec, PageSurfaceBlockSpec, PageSurfaceRefBlockSpec, - FontLoaderService, ].flat(); export const EdgelessFirstPartyBlockSpecs: ExtensionType[] = [ @@ -94,11 +94,9 @@ export const EdgelessFirstPartyBlockSpecs: ExtensionType[] = [ EdgelessSurfaceRefBlockSpec, FrameBlockSpec, EdgelessTextBlockSpec, - FontLoaderService, ].flat(); export const StoreExtensions: ExtensionType[] = [ - FeatureFlagService, BlockSelectionExtension, TextSelectionExtension, SurfaceSelectionExtension, @@ -107,8 +105,9 @@ export const StoreExtensions: ExtensionType[] = [ ImageSelectionExtension, DatabaseSelectionExtension, TableSelectionExtension, + + FeatureFlagService, LinkPreviewerService, FileSizeLimitService, - ImageStoreSpec, ].flat(); diff --git a/blocksuite/blocks/src/index.ts b/blocksuite/blocks/src/index.ts index c3fa0c2fb..760282e44 100644 --- a/blocksuite/blocks/src/index.ts +++ b/blocksuite/blocks/src/index.ts @@ -8,7 +8,6 @@ import { isCanvasElement } from './root-block/edgeless/utils/query.js'; export * from './_common/adapters/index.js'; export { type NavigatorMode } from './_common/edgeless/frame/consts.js'; -export * from './_common/test-utils/test-utils.js'; export * from './_common/transformers/index.js'; export { type AbstractEditor } from './_common/types.js'; export * from './_specs/index.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/clipboard/clipboard.ts b/blocksuite/blocks/src/root-block/edgeless/clipboard/clipboard.ts index a0f7e9388..f5d172ed9 100644 --- a/blocksuite/blocks/src/root-block/edgeless/clipboard/clipboard.ts +++ b/blocksuite/blocks/src/root-block/edgeless/clipboard/clipboard.ts @@ -69,13 +69,13 @@ import { import DOMPurify from 'dompurify'; import * as Y from 'yjs'; -import { getRootByEditorHost } from '../../../_common/utils/query.js'; import { ClipboardAdapter } from '../../clipboard/adapter.js'; import { PageClipboard } from '../../clipboard/index.js'; import { decodeClipboardBlobs, encodeClipboardBlobs, } from '../../clipboard/utils.js'; +import type { RootBlockComponent } from '../../types.js'; import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js'; import { edgelessElementsBoundFromRawData } from '../utils/bound-utils.js'; import { createNewPresentationIndexes } from '../utils/clipboard-utils.js'; @@ -1439,3 +1439,12 @@ function tryGetSvgFromClipboard(clipboardData: DataTransfer) { const file = new File([blob], 'pasted-image.svg', { type: 'image/svg+xml' }); return file; } + +function getRootByEditorHost( + editorHost: EditorHost +): RootBlockComponent | null { + const model = editorHost.doc.root; + if (!model) return null; + const root = editorHost.view.getBlock(model.id); + return root as RootBlockComponent | null; +} diff --git a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/note-tool.ts b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/note-tool.ts index 9c26c01ee..fe1cc5de3 100644 --- a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/note-tool.ts +++ b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/note-tool.ts @@ -6,12 +6,12 @@ import { } from '@blocksuite/affine-model'; import { EditPropsStore } from '@blocksuite/affine-shared/services'; import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types'; +import { hasClassNameInList } from '@blocksuite/affine-shared/utils'; import type { PointerEventState } from '@blocksuite/block-std'; import { BaseTool } from '@blocksuite/block-std/gfx'; import { Point } from '@blocksuite/global/utils'; import { effect } from '@preact/signals-core'; -import { hasClassNameInList } from '../../../_common/utils/index.js'; import { EXCLUDING_MOUSE_OUT_CLASS_LIST } from '../utils/consts.js'; import { DraggingNoteOverlay, NoteOverlay } from '../utils/tool-overlay.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/shape-tool.ts b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/shape-tool.ts index dd4953713..996a82f54 100644 --- a/blocksuite/blocks/src/root-block/edgeless/gfx-tool/shape-tool.ts +++ b/blocksuite/blocks/src/root-block/edgeless/gfx-tool/shape-tool.ts @@ -9,13 +9,13 @@ import { TelemetryProvider, ThemeProvider, } from '@blocksuite/affine-shared/services'; +import { hasClassNameInList } from '@blocksuite/affine-shared/utils'; import type { PointerEventState } from '@blocksuite/block-std'; import { BaseTool } from '@blocksuite/block-std/gfx'; import type { IBound } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils'; import { effect } from '@preact/signals-core'; -import { hasClassNameInList } from '../../../_common/utils/index.js'; import { EXCLUDING_MOUSE_OUT_CLASS_LIST, SHAPE_OVERLAY_HEIGHT, diff --git a/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts b/blocksuite/blocks/src/root-block/edgeless/utils/crud.ts index fa5041932..4afb1140a 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 { GfxModel } from '@blocksuite/block-std/gfx'; -import type { Connectable } from '../../../_common/utils/index.js'; +import type { Connectable } from '../../../_common/types.js'; import type { EdgelessRootBlockComponent } from '../index.js'; import { isConnectable } from './query.js'; diff --git a/blocksuite/blocks/src/root-block/edgeless/utils/query.ts b/blocksuite/blocks/src/root-block/edgeless/utils/query.ts index 509f92f0c..fa97b9481 100644 --- a/blocksuite/blocks/src/root-block/edgeless/utils/query.ts +++ b/blocksuite/blocks/src/root-block/edgeless/utils/query.ts @@ -33,7 +33,7 @@ import type { PointLocation } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils'; import type { BlockModel } from '@blocksuite/store'; -import type { Connectable } from '../../../_common/utils/index.js'; +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/page/page-root-block.ts b/blocksuite/blocks/src/root-block/page/page-root-block.ts index 5a29f664c..a5365069f 100644 --- a/blocksuite/blocks/src/root-block/page/page-root-block.ts +++ b/blocksuite/blocks/src/root-block/page/page-root-block.ts @@ -28,7 +28,6 @@ import { css, html } from 'lit'; import { query } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { buildPath } from '../../_common/utils/index.js'; import { PageClipboard } from '../clipboard/index.js'; import type { PageRootBlockWidgetName } from '../index.js'; import { PageKeyboardManager } from '../keyboard/keyboard-manager.js'; @@ -269,13 +268,13 @@ export class PageRootBlockComponent extends BlockComponent< ); if (!sel) return; let model: BlockModel | null = null; - let path: string[] = buildPath(this.doc.getBlockById(sel.blockId)); - while (path.length > 0 && !model) { - const m = this.doc.getBlockById(path[path.length - 1]); - if (m && m.flavour === 'affine:note') { - model = m; + let current = this.doc.getBlockById(sel.blockId); + while (current && !model) { + if (current.flavour === 'affine:note') { + model = current; + } else { + current = this.doc.getParent(current); } - path = path.slice(0, -1); } if (!model) return; const prevNote = this.doc.getPrev(model); diff --git a/blocksuite/blocks/src/root-block/page/page-root-service.ts b/blocksuite/blocks/src/root-block/page/page-root-service.ts index 8e6a87349..9ca385bb3 100644 --- a/blocksuite/blocks/src/root-block/page/page-root-service.ts +++ b/blocksuite/blocks/src/root-block/page/page-root-service.ts @@ -1,13 +1,7 @@ import { RootBlockSchema } from '@blocksuite/affine-model'; -import type { Viewport } from '@blocksuite/affine-shared/types'; -import { Slot } from '@blocksuite/global/utils'; import { RootService } from '../root-service.js'; export class PageRootService extends RootService { static override readonly flavour = RootBlockSchema.model.flavour; - - slots = { - viewportUpdated: new Slot(), - }; } diff --git a/blocksuite/playground/apps/env.d.ts b/blocksuite/playground/apps/env.d.ts index e57cd6a56..65ebbd076 100644 --- a/blocksuite/playground/apps/env.d.ts +++ b/blocksuite/playground/apps/env.d.ts @@ -1,5 +1,4 @@ import type { EditorHost } from '@blocksuite/block-std'; -import type { TestUtils } from '@blocksuite/blocks'; import type { AffineEditorContainer } from '@blocksuite/presets'; import type { BlockSchema, Blocks, Workspace, Transformer } from '@blocksuite/store'; import type { z } from 'zod'; @@ -20,7 +19,6 @@ declare global { job: Transformer; Y: typeof Y; std: typeof std; - testUtils: TestUtils; host: EditorHost; testWorker: Worker; diff --git a/blocksuite/playground/apps/starter/utils/collection.ts b/blocksuite/playground/apps/starter/utils/collection.ts index 3fb4f9aa7..4e9708aab 100644 --- a/blocksuite/playground/apps/starter/utils/collection.ts +++ b/blocksuite/playground/apps/starter/utils/collection.ts @@ -1,4 +1,4 @@ -import { AffineSchemas, SpecProvider, TestUtils } from '@blocksuite/blocks'; +import { AffineSchemas, SpecProvider } from '@blocksuite/blocks'; import { nanoid, Schema, Transformer } from '@blocksuite/store'; import { createAutoIncrementIdGenerator, @@ -73,7 +73,6 @@ export function createStarterDocCollection() { }, }); window.Y = Y; - window.testUtils = new TestUtils(); return collection; } diff --git a/blocksuite/tests-legacy/utils/declare-test-window.ts b/blocksuite/tests-legacy/utils/declare-test-window.ts index 8e4564f31..d1a1edfe4 100644 --- a/blocksuite/tests-legacy/utils/declare-test-window.ts +++ b/blocksuite/tests-legacy/utils/declare-test-window.ts @@ -6,7 +6,7 @@ import type { ThemeProvider, } from '@blocksuite/affine-shared/services'; import type { EditorHost } from '@blocksuite/block-std'; -import type { RefNodeSlotsProvider, TestUtils } from '@blocksuite/blocks'; +import type { RefNodeSlotsProvider } from '@blocksuite/blocks'; import type { AffineEditorContainer } from '@blocksuite/presets'; import type { BlockModel, @@ -47,7 +47,6 @@ declare global { debugMenu: HTMLElement; editor: AffineEditorContainer; host: EditorHost; - testUtils: TestUtils; job: Transformer; } }