Compare commits

...

1 Commits

Author SHA1 Message Date
Naiyuan Qing
ad023c2bb3 fix(editor): trim trailing whitespace from getMarkdown() output
ProseMirror always keeps an empty paragraph at the document end (schema
requires "block+"), which getMarkdown() serializes as trailing "\n\n".
Without trimming, each save→reload cycle adds an extra empty line.

Centralize the trim in ContentEditor (both onUpdate callback and ref
getMarkdown), removing redundant .replace() calls from comment-input,
reply-input, and comment-card.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:36:49 +08:00
4 changed files with 10 additions and 12 deletions

View File

@@ -109,7 +109,11 @@ const ContentEditor = forwardRef<ContentEditorRef, ContentEditorProps>(
if (!onUpdateRef.current) return;
if (debounceRef.current) clearTimeout(debounceRef.current);
debounceRef.current = setTimeout(() => {
onUpdateRef.current?.(ed.getMarkdown());
// Trim trailing whitespace: ProseMirror always keeps an empty
// paragraph at the document end (schema: "block+"), which
// getMarkdown() serializes as trailing "\n\n". Without trimming,
// each save→reload cycle would add an extra empty line.
onUpdateRef.current?.(ed.getMarkdown().replace(/(\n\s*)+$/, ""));
}, debounceMs);
},
onBlur: () => {
@@ -175,7 +179,7 @@ const ContentEditor = forwardRef<ContentEditorRef, ContentEditorProps>(
}, [editor, editable, defaultValue]);
useImperativeHandle(ref, () => ({
getMarkdown: () => editor?.getMarkdown() ?? "",
getMarkdown: () => editor?.getMarkdown().replace(/(\n\s*)+$/, "") ?? "",
clearContent: () => {
editor?.commands.clearContent();
},

View File

@@ -131,10 +131,7 @@ function CommentRow({
const saveEdit = async () => {
if (cancelledRef.current) return;
const trimmed = editEditorRef.current
?.getMarkdown()
?.replace(/(\n\s*)+$/, "")
.trim();
const trimmed = editEditorRef.current?.getMarkdown()?.trim();
if (!trimmed || trimmed === (entry.content ?? "").trim()) {
setEditing(false);
return;
@@ -300,10 +297,7 @@ function CommentCard({
const saveEdit = async () => {
if (cancelledRef.current) return;
const trimmed = editEditorRef.current
?.getMarkdown()
?.replace(/(\n\s*)+$/, "")
.trim();
const trimmed = editEditorRef.current?.getMarkdown()?.trim();
if (!trimmed || trimmed === (entry.content ?? "").trim()) {
setEditing(false);
return;

View File

@@ -23,7 +23,7 @@ function CommentInput({ issueId, onSubmit }: CommentInputProps) {
};
const handleSubmit = async () => {
const content = editorRef.current?.getMarkdown()?.replace(/(\n\s*)+$/, "").trim();
const content = editorRef.current?.getMarkdown()?.trim();
if (!content || submitting) return;
setSubmitting(true);
try {

View File

@@ -56,7 +56,7 @@ function ReplyInput({
};
const handleSubmit = async () => {
const content = editorRef.current?.getMarkdown()?.replace(/(\n\s*)+$/, "").trim();
const content = editorRef.current?.getMarkdown()?.trim();
if (!content || submitting) return;
setSubmitting(true);
try {