mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-04 19:15:33 +08:00
fix(editor): paste surface-ref block to another doc as embed-linked-doc block (#10274)
[BS-2155](https://linear.app/affine-design/issue/BS-2155/复制-insert-frame-group-粘贴后,应当变为-block-ref-link)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export * from './code';
|
||||
export * from './copy';
|
||||
export * from './paste';
|
||||
export * from './surface-ref-to-embed';
|
||||
|
||||
+6
-2
@@ -17,12 +17,16 @@ export const surfaceRefToEmbed =
|
||||
payload.snapshot.flavour === 'affine:surface-ref' &&
|
||||
!std.store.hasBlock(payload.snapshot.id)
|
||||
) {
|
||||
const id = payload.snapshot.id;
|
||||
// The blockId of the original surface-ref block
|
||||
const blockId = payload.snapshot.id;
|
||||
payload.snapshot.id = std.workspace.idGenerator();
|
||||
payload.snapshot.flavour = 'affine:embed-linked-doc';
|
||||
payload.snapshot.props = {
|
||||
blockId: id,
|
||||
pageId,
|
||||
params: {
|
||||
mode: 'page',
|
||||
blockIds: [blockId],
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
NoteBlockModel,
|
||||
RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { surfaceRefToEmbed } from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
BLOCK_CHILDREN_CONTAINER_PADDING_LEFT,
|
||||
EMBED_CARD_HEIGHT,
|
||||
@@ -68,7 +69,6 @@ import { PreviewHelper } from '../helpers/preview-helper.js';
|
||||
import { gfxBlocksFilter } from '../middleware/blocks-filter.js';
|
||||
import { newIdCrossDoc } from '../middleware/new-id-cross-doc.js';
|
||||
import { reorderList } from '../middleware/reorder-list';
|
||||
import { surfaceRefToEmbed } from '../middleware/surface-ref-to-embed.js';
|
||||
import {
|
||||
containBlock,
|
||||
extractIdsFromSnapshot,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { deleteTextCommand } from '@blocksuite/affine-components/rich-text';
|
||||
import {
|
||||
pasteMiddleware,
|
||||
surfaceRefToEmbed,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
clearAndSelectFirstModelCommand,
|
||||
deleteSelectedModelsCommand,
|
||||
@@ -13,6 +17,7 @@ import type { UIEventHandler } from '@blocksuite/block-std';
|
||||
import { DisposableGroup } from '@blocksuite/global/utils';
|
||||
import type { BlockSnapshot, Store } from '@blocksuite/store';
|
||||
|
||||
import { replaceIdMiddleware } from '../../_common/transformers/middlewares';
|
||||
import { ReadOnlyClipboard } from './readonly-clipboard';
|
||||
|
||||
/**
|
||||
@@ -22,6 +27,23 @@ import { ReadOnlyClipboard } from './readonly-clipboard';
|
||||
export class PageClipboard extends ReadOnlyClipboard {
|
||||
protected _init = () => {
|
||||
this._initAdapters();
|
||||
const paste = pasteMiddleware(this._std);
|
||||
// Use surfaceRefToEmbed middleware to convert surface-ref to embed-linked-doc
|
||||
// When pastina a surface-ref block to another doc
|
||||
const surfaceRefToEmbedMiddleware = surfaceRefToEmbed(this._std);
|
||||
const replaceId = replaceIdMiddleware(
|
||||
this._std.store.workspace.idGenerator
|
||||
);
|
||||
this._std.clipboard.use(paste);
|
||||
this._std.clipboard.use(surfaceRefToEmbedMiddleware);
|
||||
this._std.clipboard.use(replaceId);
|
||||
this._disposables.add({
|
||||
dispose: () => {
|
||||
this._std.clipboard.unuse(paste);
|
||||
this._std.clipboard.unuse(surfaceRefToEmbedMiddleware);
|
||||
this._std.clipboard.unuse(replaceId);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onBlockSnapshotPaste = async (
|
||||
@@ -143,3 +165,5 @@ export class PageClipboard extends ReadOnlyClipboard {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { pasteMiddleware };
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
ImageAdapter,
|
||||
MixTextAdapter,
|
||||
NotionTextAdapter,
|
||||
pasteMiddleware,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
copySelectedModelsCommand,
|
||||
@@ -17,7 +16,6 @@ import { DisposableGroup } from '@blocksuite/global/utils';
|
||||
|
||||
import {
|
||||
defaultImageProxyMiddleware,
|
||||
replaceIdMiddleware,
|
||||
titleMiddleware,
|
||||
} from '../../_common/transformers/middlewares.js';
|
||||
import { ClipboardAdapter } from './adapter.js';
|
||||
@@ -64,12 +62,7 @@ export class ReadOnlyClipboard {
|
||||
this._std.clipboard.registerAdapter('text/plain', MixTextAdapter, 70);
|
||||
this._std.clipboard.registerAdapter('*/*', AttachmentAdapter, 60);
|
||||
const copy = copyMiddleware(this._std);
|
||||
const paste = pasteMiddleware(this._std);
|
||||
this._std.clipboard.use(copy);
|
||||
this._std.clipboard.use(paste);
|
||||
this._std.clipboard.use(
|
||||
replaceIdMiddleware(this._std.store.workspace.idGenerator)
|
||||
);
|
||||
this._std.clipboard.use(
|
||||
titleMiddleware(this._std.store.workspace.meta.docMetas)
|
||||
);
|
||||
@@ -91,10 +84,6 @@ export class ReadOnlyClipboard {
|
||||
this._std.clipboard.unregisterAdapter('text/html');
|
||||
this._std.clipboard.unregisterAdapter('*/*');
|
||||
this._std.clipboard.unuse(copy);
|
||||
this._std.clipboard.unuse(paste);
|
||||
this._std.clipboard.unuse(
|
||||
replaceIdMiddleware(this._std.store.workspace.idGenerator)
|
||||
);
|
||||
this._std.clipboard.unuse(
|
||||
titleMiddleware(this._std.store.workspace.meta.docMetas)
|
||||
);
|
||||
@@ -135,4 +124,4 @@ export class ReadOnlyClipboard {
|
||||
}
|
||||
}
|
||||
|
||||
export { copyMiddleware, pasteMiddleware };
|
||||
export { copyMiddleware };
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import { pasteContent } from '@affine-test/kit/utils/clipboard';
|
||||
import {
|
||||
clickEdgelessModeButton,
|
||||
clickPageModeButton,
|
||||
locateEditorContainer,
|
||||
} from '@affine-test/kit/utils/editor';
|
||||
import {
|
||||
copyByKeyboard,
|
||||
pasteByKeyboard,
|
||||
@@ -8,6 +13,7 @@ import {
|
||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
||||
import {
|
||||
clickNewPageButton,
|
||||
getBlockSuiteEditorTitle,
|
||||
type,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
@@ -141,3 +147,62 @@ test.describe('paste in multiple blocks text selection', () => {
|
||||
await verifyParagraphContent(page, 3, 'test world');
|
||||
});
|
||||
});
|
||||
|
||||
test('paste surface-ref block to another doc as embed-linked-doc block', async ({
|
||||
page,
|
||||
}) => {
|
||||
await openHomePage(page);
|
||||
await clickNewPageButton(page, 'Clipboard Test');
|
||||
await waitForEditorLoad(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: 500 } });
|
||||
await page.waitForTimeout(50);
|
||||
// add a frame
|
||||
await page.keyboard.press('f');
|
||||
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);
|
||||
const changeFrameButton = page.locator('edgeless-change-frame-button');
|
||||
// get insert into page button which with aria-label 'Insert into Page'
|
||||
const insertIntoPageButton = changeFrameButton.locator(
|
||||
`editor-icon-button[aria-label="Insert into Page"]`
|
||||
);
|
||||
await insertIntoPageButton.click();
|
||||
|
||||
await clickPageModeButton(page);
|
||||
await page.waitForTimeout(50);
|
||||
|
||||
// copy surface-ref block
|
||||
const surfaceRefBlock = page.locator('.affine-surface-ref');
|
||||
await surfaceRefBlock.click();
|
||||
await page.waitForTimeout(50);
|
||||
await copyByKeyboard(page);
|
||||
|
||||
// paste to another doc
|
||||
await clickNewPageButton(page);
|
||||
await waitForEditorLoad(page);
|
||||
const title2 = getBlockSuiteEditorTitle(page);
|
||||
await title2.pressSequentially('page2');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForTimeout(50);
|
||||
|
||||
// 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');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user