diff --git a/libs/tiptap-editor/src/index.ts b/libs/tiptap-editor/src/index.ts index 9267e1d..87feabe 100644 --- a/libs/tiptap-editor/src/index.ts +++ b/libs/tiptap-editor/src/index.ts @@ -5,6 +5,7 @@ import { TaskItem, TaskList } from '@tiptap/extension-list'; import { TableKit } from '@tiptap/extension-table'; import { Markdown } from '@tiptap/markdown'; import StarterKit from '@tiptap/starter-kit'; +import { CodeBlockNodeView, ON_RUN_CODE_STORAGE_KEY } from './code-block-view'; import { lowlight } from './highlight'; import { SlashCommand } from './slash-command'; import { TaskInputRule } from './task-input-rule'; @@ -38,6 +39,9 @@ class EditorOptions { onReady?: () => void; // 上传状态事件(error/success/removed + counts),替代 window.__tiptap_uploads 轮询 onUploadEvent?: (event: UploadEvent) => void; + // 编辑器内运行代码回调:Rust 注入,NodeView 点击「运行」时经 editor.storage 转发。 + // opts: { language, source };返回格式化结果字符串(Rust 拼好 stdout/stderr/状态)。 + onRunCode?: (opts: { language: string; source: string }) => Promise; } // wasm-bindgen 生成的 glue 用裸标识符 `new EditorOptions()` 从全局解析, // IIFE 的 name 只能挂一个全局(TiptapEditor),这里手动把 EditorOptions 也挂到 window 上。 @@ -103,7 +107,11 @@ class TiptapEditorInstance { codeBlock: false, }), Markdown, - CodeBlockLowlight.configure({ lowlight }), + CodeBlockLowlight.configure({ lowlight }).extend({ + addNodeView() { + return ({ node, editor }) => new CodeBlockNodeView({ node, editor }); + }, + }), TableKit, UploadImage, TaskList, @@ -169,6 +177,12 @@ class TiptapEditorInstance { this.coordinator; } + // 把 onRunCode 回调挂到 editor.storage,供 CodeBlockNodeView 读取(仿 upload-coordinator 范式)。 + if (this.options.onRunCode) { + (this.editor.storage as unknown as Record)[ON_RUN_CODE_STORAGE_KEY] = + this.options.onRunCode; + } + // 通知宿主编辑器已就绪(替代 window.__tiptap_ready 轮询) this.options.onReady?.(); }