feat(editor): use code block html preview in make it real (#12418)

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

## Summary by CodeRabbit

- **New Features**
  - HTML code previews are now displayed as code blocks within notes when supported, offering improved readability and interaction.
- **Improvements**
  - Enhanced feature detection ensures HTML code block previews are only enabled in secure, compatible environments.
  - If the preview feature is unavailable, HTML content will continue to be embedded as before.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Flrande
2025-05-21 12:02:49 +00:00
parent 84667b3440
commit 322bd4f76b
3 changed files with 63 additions and 18 deletions

View File

@@ -1,3 +1,4 @@
import { CodeBlockPreviewIdentifier } from '@blocksuite/affine/blocks/code';
import { addImages } from '@blocksuite/affine/blocks/image';
import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface';
import { LightLoadingIcon } from '@blocksuite/affine/components/icons';
@@ -19,6 +20,7 @@ import {
import { TelemetryProvider } from '@blocksuite/affine/shared/services';
import type { EditorHost } from '@blocksuite/affine/std';
import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx';
import { Text } from '@blocksuite/affine/store';
import {
AFFINE_TOOLBAR_WIDGET,
type AffineToolbarWidget,
@@ -490,15 +492,34 @@ function responseToMakeItReal(host: EditorHost, ctx: AIContext) {
aiPanel.hide();
host.store.transact(() => {
host.store.addBlock(
'affine:embed-html',
{
html,
design: 'ai:makeItReal', // as tag
xywh: bounds.serialize(),
},
surface.id
const ifUseCodeBlock = host.std.getOptional(
CodeBlockPreviewIdentifier('html')
);
if (ifUseCodeBlock) {
const note = host.store.addBlock(
'affine:note',
{
xywh: bounds.serialize(),
},
host.store.root
);
host.store.addBlock(
'affine:code',
{ text: new Text(html), language: 'html', preview: true },
note
);
} else {
host.store.addBlock(
'affine:embed-html',
{
html,
design: 'ai:makeItReal', // as tag
xywh: bounds.serialize(),
},
surface.id
);
}
});
}

View File

@@ -1,3 +1,4 @@
import { CodeBlockPreviewIdentifier } from '@blocksuite/affine/blocks/code';
import { addSiblingImageBlocks } from '@blocksuite/affine/blocks/image';
import {
getSurfaceBlock,
@@ -117,17 +118,37 @@ function responseToMakeItReal(host: EditorHost, ctx: AIContext, place: Place) {
const htmlBound = new Bound(x, y + PADDING, width || 800, height || 600);
const html = preprocessHtml(aiPanel.answer);
host.store.transact(() => {
host.store.addBlock(
'affine:embed-html',
{
html,
design: 'ai:makeItReal', // as tag
xywh: htmlBound.serialize(),
},
surface.id
const ifUseCodeBlock = host.std.getOptional(
CodeBlockPreviewIdentifier('html')
);
const frameBound = expandBound(htmlBound, PADDING);
addSurfaceRefBlock(host, frameBound, place);
if (ifUseCodeBlock) {
const note = host.store.addBlock(
'affine:note',
{
xywh: htmlBound.serialize(),
},
host.store.root
);
host.store.addBlock(
'affine:code',
{ text: new Text(html), language: 'html', preview: true },
note
);
const frameBound = expandBound(htmlBound, PADDING);
addSurfaceRefBlock(host, frameBound, place);
} else {
host.store.addBlock(
'affine:embed-html',
{
html,
design: 'ai:makeItReal', // as tag
xywh: htmlBound.serialize(),
},
surface.id
);
const frameBound = expandBound(htmlBound, PADDING);
addSurfaceRefBlock(host, frameBound, place);
}
});
}

View File

@@ -38,6 +38,9 @@ export class CodeBlockPreviewViewExtension extends ViewExtensionProvider {
framework.get(FeatureFlagService).flags.enable_code_block_html_preview.$
.value;
if (!flag) return;
if (!window.crossOriginIsolated) return;
context.register(CodeBlockHtmlPreview);
}
}