fix(core): pasted code artifact should be inserted as codeblock (#13492)

fix AI-417

#### PR Dependency Tree


* **PR #13492** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Copying code snippets now uses a rich format for improved paste
fidelity in compatible editors.
* Preserves code block formatting and language when pasted, reducing
manual cleanup.
* Continues to support plain text and HTML paste for broad
compatibility.
  * Works more reliably when moving content within the app.
  * Existing copy confirmation remains unchanged.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Peng Xiao
2025-08-15 13:28:44 +08:00
committed by GitHub
parent 9d38f79395
commit 693ae9c834

View File

@@ -3,6 +3,11 @@ import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import { ColorScheme } from '@blocksuite/affine/model';
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
import { type BlockStdScope } from '@blocksuite/affine/std';
import {
type BlockSnapshot,
nanoid,
type SliceSnapshot,
} from '@blocksuite/affine/store';
import type { NotificationService } from '@blocksuite/affine-shared/services';
import {
CodeBlockIcon,
@@ -496,6 +501,10 @@ export class CodeArtifactTool extends ArtifactTool<
</div>`;
}
get clipboard() {
return this.std?.clipboard;
}
protected override getPreviewControls() {
if (this.data.type !== 'tool-result' || !this.std || !this.data.result) {
return undefined;
@@ -506,7 +515,39 @@ export class CodeArtifactTool extends ArtifactTool<
const title = result.title;
const copyHTML = async () => {
await navigator.clipboard.writeText(htmlContent).catch(console.error);
const codeBlock: BlockSnapshot = {
type: 'block',
id: nanoid(),
flavour: 'affine:code',
version: 1,
props: {
language: 'html',
wrap: false,
caption: '',
text: {
'$blocksuite:internal:text$': true,
delta: [{ insert: htmlContent }],
},
},
children: [],
};
const sliceSnapshot: SliceSnapshot = {
type: 'slice',
content: [codeBlock],
workspaceId: 'fake-workspace-id',
pageId: 'fake-page-id',
};
await this.clipboard?.writeToClipboard(items => ({
...items,
'text/plain': htmlContent,
'text/html': htmlContent,
'BLOCKSUITE/SNAPSHOT': JSON.stringify({
snapshot: sliceSnapshot,
blobs: {},
}),
}));
this.notificationService.toast('Copied HTML to clipboard');
};