fix(editor): prevent errors when moving a block to its own position (#9887)

This commit is contained in:
L-Sun
2025-01-24 12:55:55 +00:00
parent 4b553d153a
commit 351816b343
2 changed files with 61 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import { expect, test, vi } from 'vitest';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import * as Y from 'yjs';
import type { BlockModel, Store } from '../model/index.js';
import { Schema } from '../schema/index.js';
import { createAutoIncrementIdGenerator } from '../test/index.js';
import { TestWorkspace } from '../test/test-workspace.js';
@@ -267,3 +268,40 @@ test('local readonly', () => {
expect(doc2?.readonly).toBeTruthy();
expect(doc3?.readonly).toBeFalsy();
});
describe('move blocks', () => {
type Context = { doc: Store; page: BlockModel; notes: BlockModel[] };
beforeEach((context: Context) => {
const options = createTestOptions();
const collection = new TestWorkspace(options);
collection.meta.initialize();
const doc = collection.createDoc({ id: 'home' });
doc.load();
const pageId = doc.addBlock('affine:page');
const page = doc.getBlock(pageId)!.model;
const noteIds = doc.addBlocks(
[1, 2, 3].map(i => ({
flavour: 'affine:note',
blockProps: { id: `${i}` },
})),
page
);
const notes = noteIds.map(id => doc.getBlock(id)!.model);
context.doc = doc;
context.page = page;
context.notes = notes;
});
test('move block to itself', ({ doc, page, notes }: Context) => {
const noteIds = notes.map(({ id }) => id);
doc.moveBlocks([notes[0]], page, notes[0], true);
expect(page.children.map(({ id }) => id)).toEqual(noteIds);
doc.moveBlocks([notes[0]], page, notes[0], false);
expect(page.children.map(({ id }) => id)).toEqual(noteIds);
});
});

View File

@@ -264,6 +264,28 @@ export class DocCRUD {
targetSibling: string | null = null,
shouldInsertBeforeSibling = true
) {
if (
blocksToMove.length > 1 &&
targetSibling &&
blocksToMove.includes(targetSibling)
) {
console.error(
'Cannot move blocks when the target sibling is in the blocks to move'
);
return;
}
if (blocksToMove.length === 1 && targetSibling === blocksToMove[0]) {
return;
}
if (blocksToMove.includes(newParent)) {
console.error(
'Cannot move blocks when the new parent is in the blocks to move'
);
return;
}
// A map to store parent block and their respective child blocks
const childBlocksPerParent = new Map<string, string[]>();