From 4da00eba0d1d15acd4c8a2e9ea78fac75c9db8dd Mon Sep 17 00:00:00 2001 From: donteatfriedrice Date: Sat, 12 Apr 2025 01:56:24 +0000 Subject: [PATCH] fix(editor): cut and paste surface-ref to same doc should remain surface-ref (#11639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close [BS-3107](https://linear.app/affine-design/issue/BS-3107/剪切-surface-ref-block-会变成指向当前文档的link-card) --- .../middlewares/surface-ref-to-embed.ts | 14 ++- .../blocksuite/clipboard/clipboard.spec.ts | 111 +++++++++++------- 2 files changed, 79 insertions(+), 46 deletions(-) diff --git a/blocksuite/affine/shared/src/adapters/middlewares/surface-ref-to-embed.ts b/blocksuite/affine/shared/src/adapters/middlewares/surface-ref-to-embed.ts index 6a96d07aae..2ccff6426b 100644 --- a/blocksuite/affine/shared/src/adapters/middlewares/surface-ref-to-embed.ts +++ b/blocksuite/affine/shared/src/adapters/middlewares/surface-ref-to-embed.ts @@ -11,12 +11,16 @@ export const surfaceRefToEmbed = } }); slots.beforeImport.subscribe(payload => { + // only handle surface-ref block snapshot if ( - pageId && - payload.type === 'block' && - payload.snapshot.flavour === 'affine:surface-ref' && - !std.store.hasBlock(payload.snapshot.id) - ) { + payload.type !== 'block' || + payload.snapshot.flavour !== 'affine:surface-ref' + ) + return; + + // turn into embed-linked-doc if the current doc is different from the pageId of the surface-ref block + const isNotSameDoc = pageId !== std.store.doc.id; + if (pageId && isNotSameDoc) { // The blockId of the original surface-ref block const blockId = payload.snapshot.id; payload.snapshot.id = std.workspace.idGenerator(); diff --git a/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts b/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts index 538287fa9d..d04f9186e8 100644 --- a/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts +++ b/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts @@ -9,6 +9,7 @@ import { } from '@affine-test/kit/utils/editor'; import { copyByKeyboard, + cutByKeyboard, pasteByKeyboard, pressEnter, } from '@affine-test/kit/utils/keyboard'; @@ -174,56 +175,84 @@ test.describe('paste in multiple blocks text selection', () => { }); }); -test('paste surface-ref block to another doc as embed-linked-doc block', async ({ - page, -}) => { - await clickEdgelessModeButton(page); - const container = locateEditorContainer(page); - await container.click(); +test.describe('surface-ref block', () => { + async function setupSurfaceRefBlock(page: Page) { + await clickEdgelessModeButton(page); + const container = locateEditorContainer(page); + await container.click(); - // add a shape - await page.keyboard.press('s'); - // click to add a shape - await container.click({ position: { x: 100, y: 300 } }); - await page.waitForTimeout(50); - // add a frame - await page.keyboard.press('f'); - await page.waitForTimeout(50); + // add a shape + await page.keyboard.press('s'); + await container.click({ position: { x: 100, y: 300 } }); + await page.waitForTimeout(50); - // click on the frame title to trigger the change frame button toolbar - const frameTitle = page.locator('affine-frame-title'); - await frameTitle.click(); - await page.waitForTimeout(50); + // add a frame + await page.keyboard.press('f'); + await page.waitForTimeout(50); - const toolbar = page.locator('affine-toolbar-widget editor-toolbar'); + // click on the frame title to trigger the change frame button toolbar + const frameTitle = page.locator('affine-frame-title'); + await frameTitle.click(); + await page.waitForTimeout(50); - const insertIntoPageButton = toolbar.getByLabel('Insert into Page'); - await insertIntoPageButton.click(); + const toolbar = page.locator('affine-toolbar-widget editor-toolbar'); + const insertIntoPageButton = toolbar.getByLabel('Insert into Page'); + await insertIntoPageButton.click(); - await clickPageModeButton(page); - await waitForEditorLoad(page); - await container.click(); + await clickPageModeButton(page); + await waitForEditorLoad(page); + await container.click(); - // copy surface-ref block - const surfaceRefBlock = page.locator('affine-surface-ref'); - await surfaceRefBlock.click(); - await page.waitForSelector('affine-surface-ref .focused'); - await copyByKeyboard(page); + return { container }; + } - // paste to another doc - await clickNewPageButton(page, 'page2'); - await pressEnter(page); + test('paste surface-ref block to another doc as embed-linked-doc block', async ({ + page, + }) => { + await setupSurfaceRefBlock(page); - // paste the surface-ref block - await pasteByKeyboard(page); - await page.waitForTimeout(50); + // copy surface-ref block + const surfaceRefBlock = page.locator('affine-surface-ref'); + await surfaceRefBlock.click(); + await page.waitForSelector('affine-surface-ref .focused'); + await copyByKeyboard(page); - const embedLinkedDocBlock = page.locator('affine-embed-linked-doc-block'); - await expect(embedLinkedDocBlock).toBeVisible(); - const embedLinkedDocBlockTitle = embedLinkedDocBlock.locator( - '.affine-embed-linked-doc-content-title-text' - ); - await expect(embedLinkedDocBlockTitle).toHaveText('Clipboard Test'); + // paste to another doc + await clickNewPageButton(page, 'page2'); + await pressEnter(page); + + // paste the surface-ref block + await pasteByKeyboard(page); + await page.waitForTimeout(50); + + const embedLinkedDocBlock = page.locator('affine-embed-linked-doc-block'); + await expect(embedLinkedDocBlock).toBeVisible(); + const embedLinkedDocBlockTitle = embedLinkedDocBlock.locator( + '.affine-embed-linked-doc-content-title-text' + ); + await expect(embedLinkedDocBlockTitle).toHaveText('Clipboard Test'); + }); + + test('cut and paste surface-ref block to same doc should remain surface-ref block', async ({ + page, + }) => { + const { container } = await setupSurfaceRefBlock(page); + + // cut surface-ref block + const surfaceRefBlock = page.locator('affine-surface-ref'); + await surfaceRefBlock.click(); + await page.waitForSelector('affine-surface-ref .focused'); + await cutByKeyboard(page); + + // focus on the editor + await container.click(); + + // paste the surface-ref block + await pasteByKeyboard(page); + await page.waitForTimeout(50); + await expect(surfaceRefBlock).toHaveCount(1); + await expect(surfaceRefBlock).toBeVisible(); + }); }); test.describe('paste to code block', () => {