diff --git a/blocksuite/affine/blocks/code/package.json b/blocksuite/affine/blocks/code/package.json index 5af3375d3d..833a10f7db 100644 --- a/blocksuite/affine/blocks/code/package.json +++ b/blocksuite/affine/blocks/code/package.json @@ -11,6 +11,7 @@ "license": "MIT", "dependencies": { "@blocksuite/affine-components": "workspace:*", + "@blocksuite/affine-gfx-turbo-renderer": "workspace:*", "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-inline-link": "workspace:*", "@blocksuite/affine-inline-preset": "workspace:*", @@ -35,7 +36,8 @@ }, "exports": { ".": "./src/index.ts", - "./effects": "./src/effects.ts" + "./effects": "./src/effects.ts", + "./turbo-painter": "./src/turbo/code-painter.worker.ts" }, "files": [ "src", diff --git a/blocksuite/affine/blocks/code/src/index.ts b/blocksuite/affine/blocks/code/src/index.ts index dc06c61a67..4de4cf592b 100644 --- a/blocksuite/affine/blocks/code/src/index.ts +++ b/blocksuite/affine/blocks/code/src/index.ts @@ -3,3 +3,5 @@ export * from './code-block'; export * from './code-block-config'; export * from './code-block-spec'; export * from './code-toolbar'; +export * from './turbo/code-layout-handler'; +export * from './turbo/code-painter.worker'; diff --git a/blocksuite/affine/blocks/code/src/turbo/code-layout-handler.ts b/blocksuite/affine/blocks/code/src/turbo/code-layout-handler.ts new file mode 100644 index 0000000000..3a43ba2b85 --- /dev/null +++ b/blocksuite/affine/blocks/code/src/turbo/code-layout-handler.ts @@ -0,0 +1,71 @@ +import type { Rect } from '@blocksuite/affine-gfx-turbo-renderer'; +import { + BlockLayoutHandlerExtension, + BlockLayoutHandlersIdentifier, +} from '@blocksuite/affine-gfx-turbo-renderer'; +import type { Container } from '@blocksuite/global/di'; +import type { EditorHost, GfxBlockComponent } from '@blocksuite/std'; +import { clientToModelCoord, type ViewportRecord } from '@blocksuite/std/gfx'; +import type { BlockModel } from '@blocksuite/store'; + +import type { CodeLayout } from './code-painter.worker'; + +export class CodeLayoutHandlerExtension extends BlockLayoutHandlerExtension { + readonly blockType = 'affine:code'; + + static override setup(di: Container) { + di.addImpl( + BlockLayoutHandlersIdentifier('code'), + CodeLayoutHandlerExtension + ); + } + + override queryLayout( + model: BlockModel, + host: EditorHost, + viewportRecord: ViewportRecord + ): CodeLayout | null { + const component = host.std.view.getBlock(model.id) as GfxBlockComponent; + if (!component) return null; + + const codeBlockElement = component.querySelector( + '.affine-code-block-container' + ); + if (!codeBlockElement) return null; + + const { zoom, viewScale } = viewportRecord; + const codeLayout: CodeLayout = { + type: 'affine:code', + blockId: model.id, + rect: { x: 0, y: 0, w: 0, h: 0 }, + }; + + // Get the bounding rect of the code block + const clientRect = codeBlockElement.getBoundingClientRect(); + if (!clientRect) return null; + + // Convert client coordinates to model coordinates + const [modelX, modelY] = clientToModelCoord(viewportRecord, [ + clientRect.x, + clientRect.y, + ]); + + codeLayout.rect = { + x: modelX, + y: modelY, + w: clientRect.width / zoom / viewScale, + h: clientRect.height / zoom / viewScale, + }; + + return codeLayout; + } + + calculateBound(layout: CodeLayout) { + const rect: Rect = layout.rect; + + return { + rect, + subRects: [rect], + }; + } +} diff --git a/blocksuite/affine/blocks/code/src/turbo/code-painter.worker.ts b/blocksuite/affine/blocks/code/src/turbo/code-painter.worker.ts new file mode 100644 index 0000000000..9b929a3152 --- /dev/null +++ b/blocksuite/affine/blocks/code/src/turbo/code-painter.worker.ts @@ -0,0 +1,53 @@ +import type { + BlockLayout, + BlockLayoutPainter, + WorkerToHostMessage, +} from '@blocksuite/affine-gfx-turbo-renderer'; +import { BlockLayoutPainterExtension } from '@blocksuite/affine-gfx-turbo-renderer/painter'; + +export interface CodeLayout extends BlockLayout { + type: 'affine:code'; +} + +function isCodeLayout(layout: BlockLayout): layout is CodeLayout { + return layout.type === 'affine:code'; +} + +class CodeLayoutPainter implements BlockLayoutPainter { + paint( + ctx: OffscreenCanvasRenderingContext2D, + layout: BlockLayout, + layoutBaseX: number, + layoutBaseY: number + ): void { + if (!isCodeLayout(layout)) { + const message: WorkerToHostMessage = { + type: 'paintError', + error: 'Invalid layout format', + blockType: 'affine:code', + }; + self.postMessage(message); + return; + } + + // Get the layout dimensions + const x = layout.rect.x - layoutBaseX; + const y = layout.rect.y - layoutBaseY; + const width = layout.rect.w; + const height = layout.rect.h; + + // Simple white rectangle for now + ctx.fillStyle = 'white'; + ctx.fillRect(x, y, width, height); + + // Add a border to visualize the code block + ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)'; + ctx.lineWidth = 1; + ctx.strokeRect(x, y, width, height); + } +} + +export const CodeLayoutPainterExtension = BlockLayoutPainterExtension( + 'affine:code', + CodeLayoutPainter +); diff --git a/blocksuite/affine/blocks/code/tsconfig.json b/blocksuite/affine/blocks/code/tsconfig.json index e5046f026e..0132fbfea1 100644 --- a/blocksuite/affine/blocks/code/tsconfig.json +++ b/blocksuite/affine/blocks/code/tsconfig.json @@ -8,6 +8,7 @@ "include": ["./src"], "references": [ { "path": "../../components" }, + { "path": "../../gfx/turbo-renderer" }, { "path": "../../inlines/latex" }, { "path": "../../inlines/link" }, { "path": "../../inlines/preset" }, diff --git a/packages/frontend/core/src/blocksuite/extensions/turbo-painter.worker.ts b/packages/frontend/core/src/blocksuite/extensions/turbo-painter.worker.ts index d8767fd39d..4ee5a1dd0b 100644 --- a/packages/frontend/core/src/blocksuite/extensions/turbo-painter.worker.ts +++ b/packages/frontend/core/src/blocksuite/extensions/turbo-painter.worker.ts @@ -1,3 +1,4 @@ +import { CodeLayoutPainterExtension } from '@blocksuite/affine/blocks/code'; import { ListLayoutPainterExtension } from '@blocksuite/affine/blocks/list'; import { NoteLayoutPainterExtension } from '@blocksuite/affine/blocks/note'; import { ParagraphLayoutPainterExtension } from '@blocksuite/affine/blocks/paragraph'; @@ -7,4 +8,5 @@ new ViewportLayoutPainter([ ParagraphLayoutPainterExtension, ListLayoutPainterExtension, NoteLayoutPainterExtension, + CodeLayoutPainterExtension, ]); diff --git a/packages/frontend/core/src/blocksuite/extensions/turbo-renderer.ts b/packages/frontend/core/src/blocksuite/extensions/turbo-renderer.ts index 70478278ca..4b27de2669 100644 --- a/packages/frontend/core/src/blocksuite/extensions/turbo-renderer.ts +++ b/packages/frontend/core/src/blocksuite/extensions/turbo-renderer.ts @@ -1,4 +1,5 @@ import { getWorkerUrl } from '@affine/env/worker'; +import { CodeLayoutHandlerExtension } from '@blocksuite/affine/blocks/code'; import { ListLayoutHandlerExtension } from '@blocksuite/affine/blocks/list'; import { NoteLayoutHandlerExtension } from '@blocksuite/affine/blocks/note'; import { ParagraphLayoutHandlerExtension } from '@blocksuite/affine/blocks/paragraph'; @@ -17,6 +18,7 @@ export function patchTurboRendererExtension() { ParagraphLayoutHandlerExtension, ListLayoutHandlerExtension, NoteLayoutHandlerExtension, + CodeLayoutHandlerExtension, TurboRendererConfigFactory({ options: { zoomThreshold: 1, diff --git a/tools/utils/src/workspace.gen.ts b/tools/utils/src/workspace.gen.ts index 54fdca6484..b3bdb73ec4 100644 --- a/tools/utils/src/workspace.gen.ts +++ b/tools/utils/src/workspace.gen.ts @@ -111,6 +111,7 @@ export const PackageList = [ name: '@blocksuite/affine-block-code', workspaceDependencies: [ 'blocksuite/affine/components', + 'blocksuite/affine/gfx/turbo-renderer', 'blocksuite/affine/inlines/latex', 'blocksuite/affine/inlines/link', 'blocksuite/affine/inlines/preset', diff --git a/yarn.lock b/yarn.lock index 962f910057..3bb06d344d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2450,6 +2450,7 @@ __metadata: resolution: "@blocksuite/affine-block-code@workspace:blocksuite/affine/blocks/code" dependencies: "@blocksuite/affine-components": "workspace:*" + "@blocksuite/affine-gfx-turbo-renderer": "workspace:*" "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-inline-link": "workspace:*" "@blocksuite/affine-inline-preset": "workspace:*" @@ -20555,13 +20556,13 @@ __metadata: linkType: hard "eslint-config-prettier@npm:^10.0.0": - version: 10.1.1 - resolution: "eslint-config-prettier@npm:10.1.1" + version: 10.1.2 + resolution: "eslint-config-prettier@npm:10.1.2" peerDependencies: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: 10/e78e195a4f19e0de9bf655648bb3433877d6a5368537f1b1049976b74180844a00dd7c1ba3144e3da6e8b6864f8dcdfcda6c7338a537883fcf5b212ef6dcd0e0 + checksum: 10/7b096cbb75ff57cee933451e9c8bd2926688bc603a7d74c3d89b2bd57324cb0346c7e95ac24b17ef2dd2050bb870602c032368f11bf57c2962210418a99caf3f languageName: node linkType: hard @@ -22992,8 +22993,8 @@ __metadata: linkType: hard "http-proxy-middleware@npm:^2.0.7": - version: 2.0.8 - resolution: "http-proxy-middleware@npm:2.0.8" + version: 2.0.9 + resolution: "http-proxy-middleware@npm:2.0.9" dependencies: "@types/http-proxy": "npm:^1.17.8" http-proxy: "npm:^1.18.1" @@ -23005,13 +23006,13 @@ __metadata: peerDependenciesMeta: "@types/express": optional: true - checksum: 10/77f54a73ca97fc453d535d9dee702392348505909105bf8868ddcc799903e553bfe5180aaec6e022bf23685072df6b0f91a0884331c2c3245ccf61ad1647fa27 + checksum: 10/4ece416a91d52e96f8136c5f4abfbf7ac2f39becbad21fa8b158a12d7e7d8f808287ff1ae342b903fd1f15f2249dee87fabc09e1f0e73106b83331c496d67660 languageName: node linkType: hard "http-proxy-middleware@npm:^3.0.3": - version: 3.0.4 - resolution: "http-proxy-middleware@npm:3.0.4" + version: 3.0.5 + resolution: "http-proxy-middleware@npm:3.0.5" dependencies: "@types/http-proxy": "npm:^1.17.15" debug: "npm:^4.3.6" @@ -23019,7 +23020,7 @@ __metadata: is-glob: "npm:^4.0.3" is-plain-object: "npm:^5.0.0" micromatch: "npm:^4.0.8" - checksum: 10/3e0f4ae61b62ba14ac6821f5208b5590ac5ec4a1a0cfbd5e643ca7b75540dabab2d83b81ad046bdf06365ba15cb7e237aaa2836398922f6777ee82f90393d704 + checksum: 10/83c1956be6451a5f4a2f3c7b3d84085dbd47e1efb5bb684c1ed668a6606c18c7c07be823b0dbba1326955b64cf88de2672492940b0b48d140215fbdb06105c9a languageName: node linkType: hard @@ -32930,9 +32931,9 @@ __metadata: linkType: hard "undici@npm:^7.1.0": - version: 7.7.0 - resolution: "undici@npm:7.7.0" - checksum: 10/629861f30411f43b276163a9aa3f6b74b70a6fb911f3389220524bfb149003771447ec6779f3d49f8a9cf54f9aa09b5b5c1b35521c25344df48e4f4aae1e21aa + version: 7.8.0 + resolution: "undici@npm:7.8.0" + checksum: 10/bbd1fd9e63f0842196fc0210ffb36c29eed2841f1499e149718b96e52e195afe3ccaaa2da76aae4253cd5cc58a26b20836f7a98db11f335b594009603cc72eec languageName: node linkType: hard