refactor: move utils and cleanup test helpers (#10261)

This commit is contained in:
Saul-Mirone
2025-02-18 14:03:51 +00:00
parent faf6e2c79f
commit 2f04e3180c
22 changed files with 38 additions and 111 deletions

View File

@@ -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();
[

View File

@@ -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();
[

View File

@@ -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();
[

View File

@@ -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', () => {

View File

@@ -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)));
}

View File

@@ -1,2 +0,0 @@
export * from '../types.js';
export * from './query.js';

View File

@@ -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));
}

View File

@@ -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();

View File

@@ -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';

View File

@@ -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;
}

View File

@@ -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';

View File

@@ -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,

View File

@@ -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';

View File

@@ -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;

View File

@@ -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);

View File

@@ -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<Viewport>(),
};
}