修复富文本编辑 删除报错问题

This commit is contained in:
北枳 2025-08-14 20:47:12 +08:00
parent d08140f537
commit e60ec8b61a
2 changed files with 70 additions and 19 deletions

View File

@ -312,15 +312,17 @@ export class TextToShotAdapter {
public static fromRoleToText(paragraphs: Paragraph[]): string { public static fromRoleToText(paragraphs: Paragraph[]): string {
let text = ''; let text = '';
paragraphs.forEach(paragraph => { paragraphs.forEach(paragraph => {
paragraph.content.forEach(node => { if (paragraph?.content) {
if (node.type === 'highlightText') { paragraph.content.forEach(node => {
text += node.attrs.text; if (node.type === 'highlightText') {
} else if (node.type === 'text') { text += node.attrs.text;
text += node.text; } else if (node.type === 'text') {
} else if (node.type === 'characterToken') { text += node.text;
text += node.attrs.name; } else if (node.type === 'characterToken') {
} text += node.attrs.name;
}); }
});
}
}); });
return text; return text;
} }

View File

@ -13,35 +13,84 @@ export default function MainEditor({ content, onChangeContent }: MainEditorProps
const [renderContent, setRenderContent] = useState<any[]>(content); const [renderContent, setRenderContent] = useState<any[]>(content);
useEffect(() => { useEffect(() => {
onChangeContent?.(renderContent);; onChangeContent?.(renderContent);
}, [renderContent]); }, [renderContent]);
const editor = useEditor({ const editor = useEditor({
extensions: [ extensions: [
StarterKit, StarterKit.configure({
paragraph: {
HTMLAttributes: {
class: 'paragraph'
}
},
}),
HighlightTextExtension, HighlightTextExtension,
], ],
content: { type: 'doc', content: renderContent }, content: {
type: 'doc',
content: renderContent.length === 0 ? [{ type: 'paragraph', content: [] }] : renderContent
},
editorProps: { editorProps: {
attributes: { attributes: {
class: 'prose prose-invert max-w-none focus:outline-none' class: 'prose prose-invert max-w-none focus:outline-none'
},
handleDOMEvents: {
keydown: (view, event) => {
// 如果内容为空且按下删除键或退格键,阻止默认行为
if (
(event.key === 'Backspace' || event.key === 'Delete') &&
editor?.isEmpty
) {
event.preventDefault();
return true;
}
return false;
}
} }
}, },
immediatelyRender: false,
onCreate: ({ editor }) => { onCreate: ({ editor }) => {
editor.setOptions({ editable: true }) editor.setOptions({ editable: true });
}, },
onUpdate: ({ editor }) => { onUpdate: ({ editor }) => {
const json = editor.getJSON(); try {
flushSync(() => { const json = editor.getJSON();
setRenderContent(json.content); // 确保至少有一个空段落
}); const safeContent = json.content.length === 0
? [{ type: 'paragraph', content: [] }]
: json.content;
flushSync(() => {
setRenderContent(safeContent);
});
} catch (error) {
console.error('Editor update error:', error);
}
}, },
immediatelyRender: false, // 解决 SSR 水合问题
}); });
// 监听编辑器内容变化,确保始终有一个段落
useEffect(() => {
const handleEmpty = () => {
if (editor?.isEmpty) {
editor.commands.setContent([{
type: 'paragraph',
content: []
}]);
}
};
editor?.on('update', handleEmpty);
return () => {
editor?.off('update', handleEmpty);
};
}, [editor]);
if (!editor) { if (!editor) {
return null return null;
} }
return ( return (
<EditorContent editor={editor} /> <EditorContent editor={editor} />
); );