Skip to content

Commit a675ff4

Browse files
committed
1 parent d406ee2 commit a675ff4

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

packages/blocks/src/root-block/clipboard/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export class PageClipboard {
132132
this._std.command
133133
.chain()
134134
.try(cmd => [
135-
cmd.getTextSelection().deleteText(),
135+
cmd.getTextSelection(),
136136
cmd
137137
.getSelectedModels()
138138
.clearAndSelectFirstModel()

packages/blocks/src/root-block/clipboard/middlewares/paste.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
2+
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
23

4+
import { REFERENCE_NODE } from '@blocksuite/affine-components/rich-text';
35
import {
46
ParseDocUrlProvider,
57
type ParseDocUrlService,
@@ -154,10 +156,19 @@ class PasteTr {
154156
private _mergeSingle = () => {
155157
this._updateFlavour();
156158
const { firstDelta } = this._getDeltas();
157-
this.pointState.text.applyDelta([
158-
{ retain: this.pointState.point.index },
159-
...firstDelta,
160-
]);
159+
const { index, length } = this.pointState.point;
160+
161+
// Pastes a link
162+
if (length && firstDelta.length === 1 && firstDelta[0].attributes?.link) {
163+
this.pointState.text.format(index, length, firstDelta[0].attributes);
164+
} else {
165+
const ops: DeltaOperation[] = [{ retain: index }];
166+
if (length) ops.push({ delete: length });
167+
ops.push(...firstDelta);
168+
169+
this.pointState.text.applyDelta(ops);
170+
}
171+
161172
this.snapshot.content.splice(0, 1);
162173
this._updateSnapshot();
163174
};
@@ -424,7 +435,14 @@ class PasteTr {
424435
return { ...op };
425436
}
426437

427-
const reference = { pageId, type: 'LinkedPage' };
438+
const reference: AffineTextAttributes['reference'] = {
439+
pageId,
440+
type: 'LinkedPage',
441+
};
442+
// Title alias
443+
if (op.insert && op.insert !== REFERENCE_NODE && op.insert !== link) {
444+
reference.title = op.insert;
445+
}
428446

429447
const extractedParams = extractSearchParams(link);
430448
const isLinkedBlock = extractedParams
@@ -446,7 +464,7 @@ class PasteTr {
446464
return {
447465
...op,
448466
attributes: { reference },
449-
insert: ' ',
467+
insert: REFERENCE_NODE,
450468
};
451469
});
452470
return [newDelta, transformed];

tests/clipboard/clipboard.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,48 @@ test(scoped`pasting internal url with params`, async ({ page }) => {
276276
await expect(page.locator('affine-reference')).toContainText('test page');
277277
});
278278

279+
test(
280+
scoped`pasting an external URL from clipboard to automatically creating a link from selection`,
281+
async ({ page }) => {
282+
await enterPlaygroundRoom(page);
283+
await initEmptyParagraphState(page);
284+
await focusTitle(page);
285+
await type(page, 'test page');
286+
287+
await focusRichText(page);
288+
await type(page, 'title alias');
289+
await setSelection(page, 1, 6, 1, 11);
290+
291+
await pasteContent(page, {
292+
'text/plain': 'https://affine.pro/',
293+
});
294+
await expect(page.locator('affine-link')).toContainText('alias');
295+
}
296+
);
297+
298+
test(
299+
scoped`pasting an internal URL from clipboard to automatically creating a link from selection`,
300+
async ({ page }) => {
301+
await enterPlaygroundRoom(page);
302+
await initEmptyParagraphState(page);
303+
await focusTitle(page);
304+
await type(page, 'test page');
305+
306+
await focusRichText(page);
307+
await type(page, 'title alias');
308+
await setSelection(page, 1, 6, 1, 11);
309+
310+
const docId = await getCurrentEditorDocId(page);
311+
await mockParseDocUrlService(page, {
312+
'http://workspace/doc-id': docId,
313+
});
314+
await pasteContent(page, {
315+
'text/plain': 'http://workspace/doc-id',
316+
});
317+
await expect(page.locator('affine-reference')).toContainText('alias');
318+
}
319+
);
320+
279321
test(scoped`paste parent block`, async ({ page }) => {
280322
test.info().annotations.push({
281323
type: 'issue',

0 commit comments

Comments
 (0)