diff --git a/blocksuite/framework/std/src/clipboard/clipboard.ts b/blocksuite/framework/std/src/clipboard/clipboard.ts
index 8661fe949b..1dc789dd17 100644
--- a/blocksuite/framework/std/src/clipboard/clipboard.ts
+++ b/blocksuite/framework/std/src/clipboard/clipboard.ts
@@ -76,6 +76,7 @@ export class Clipboard extends LifeCycleWatcher {
const byPriority = Array.from(this._adapters).sort(
(a, b) => b.priority - a.priority
);
+
for (const { adapter, mimeType } of byPriority) {
const item = getItem(mimeType);
if (Array.isArray(item)) {
@@ -170,7 +171,9 @@ export class Clipboard extends LifeCycleWatcher {
index?: number
) => {
const data = event.clipboardData;
- if (!data) return;
+ if (!data) {
+ return;
+ }
try {
const json = this.readFromClipboard(data);
@@ -187,7 +190,7 @@ export class Clipboard extends LifeCycleWatcher {
);
}
return slice;
- } catch {
+ } catch (error) {
const getDataByType = this._getDataByType(data);
const slice = await this._getSnapshotByPriority(
type => getDataByType(type),
@@ -195,7 +198,6 @@ export class Clipboard extends LifeCycleWatcher {
parent,
index
);
-
return slice;
}
};
@@ -292,9 +294,7 @@ export class Clipboard extends LifeCycleWatcher {
if (image) {
const type = 'image/png';
-
delete items[type];
-
if (typeof image === 'string') {
clipboardItems[type] = new Blob([image], { type });
} else if (image instanceof Blob) {
@@ -314,7 +314,7 @@ export class Clipboard extends LifeCycleWatcher {
if (hasInnerHTML || isEmpty) {
const type = 'text/html';
const snapshot = lz.compressToEncodedURIComponent(JSON.stringify(items));
- const html = `
${innerHTML}
`;
+ const html = `${innerHTML}
`;
clipboardItems[type] = new Blob([html], { type });
}
diff --git a/blocksuite/framework/std/src/event/control/clipboard.ts b/blocksuite/framework/std/src/event/control/clipboard.ts
index 2993a61178..be681a5f3c 100644
--- a/blocksuite/framework/std/src/event/control/clipboard.ts
+++ b/blocksuite/framework/std/src/event/control/clipboard.ts
@@ -28,7 +28,6 @@ export class ClipboardControl {
const clipboardEventState = new ClipboardEventState({
event,
});
-
this._dispatcher.run(
'paste',
this._createContext(event, clipboardEventState)
diff --git a/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts b/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts
index e4aaae7563..d4b65c643a 100644
--- a/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts
+++ b/tests/affine-local/e2e/blocksuite/clipboard/clipboard.spec.ts
@@ -474,6 +474,79 @@ test.describe('paste in readonly mode', () => {
});
});
+test.describe('cross document clipboard regression', () => {
+ test('copy and paste paragraph content between docs', async ({ page }) => {
+ const container = locateEditorContainer(page);
+ await container.click();
+
+ const sourceText = "Cross-doc paste can't fail again";
+ await type(page, sourceText);
+
+ const { blockIds } = await getParagraphIds(page);
+ await setSelection(page, blockIds[0], 0, blockIds[0], sourceText.length);
+
+ await copyByKeyboard(page);
+
+ await clickNewPageButton(page, 'Clipboard Destination');
+ await waitForEditorLoad(page);
+
+ const destination = locateEditorContainer(page);
+ await destination.click();
+
+ await pasteByKeyboard(page);
+ await page.waitForTimeout(100);
+
+ const pastedTexts = await page.locator(paragraphLocator).allTextContents();
+ expect(pastedTexts.some(text => text.includes(sourceText))).toBe(true);
+ });
+
+ test('copied content remains available to external clipboard consumers', async ({
+ page,
+ }) => {
+ const container = locateEditorContainer(page);
+ await container.click();
+
+ const textForExternal = 'External clipboard visibility check';
+ await type(page, textForExternal);
+
+ const { blockIds } = await getParagraphIds(page);
+ await setSelection(
+ page,
+ blockIds[0],
+ 0,
+ blockIds[0],
+ textForExternal.length
+ );
+
+ await copyByKeyboard(page);
+
+ const plainText = await page.evaluate(() => navigator.clipboard.readText());
+
+ expect(plainText).toBe(textForExternal);
+ });
+
+ test('copy and paste within a single document still duplicates content', async ({
+ page,
+ }) => {
+ const container = locateEditorContainer(page);
+ await container.click();
+
+ const intraDocText = 'Same doc paste regression guard';
+ await type(page, intraDocText);
+
+ const { blockIds } = await getParagraphIds(page);
+ await setSelection(page, blockIds[0], 0, blockIds[0], intraDocText.length);
+
+ await copyByKeyboard(page);
+
+ await pressEnter(page);
+ await pasteByKeyboard(page);
+ await page.waitForTimeout(100);
+
+ await verifyParagraphContent(page, 1, intraDocText);
+ });
+});
+
test('should copy single image from edgeless and paste to page', async ({
page,
}) => {