From 30577403c6014b9bf8a2ac6561719b559c87c194 Mon Sep 17 00:00:00 2001 From: maggch Date: Wed, 19 Nov 2025 18:37:46 +0800 Subject: [PATCH] fix(editor): preserve consecutive whitespace in comments in TipTap Ensure multiple spaces in comment content are no longer collapsed when editing/saving by: - Adding SetContentOptions with parseOptions.preserveWhitespace = 'full' - Applying those options to all setContent calls (initial load, exit edit mode, post-upload cleanup) - Enabling preserveWhitespace in editor parseOptions Previously, repeated spaces were normalized away after setContent(false), causing comments with deliberate spacing to be altered unexpectedly. No behavioral changes beyond whitespace retention; renders identical except space fidelity. --- frontend/src/components/input/editor/TipTap.vue | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/input/editor/TipTap.vue b/frontend/src/components/input/editor/TipTap.vue index 473d3a2af..7aefd14fd 100644 --- a/frontend/src/components/input/editor/TipTap.vue +++ b/frontend/src/components/input/editor/TipTap.vue @@ -145,7 +145,7 @@ import {eventToHotkeyString} from '@github/hotkey' import EditorToolbar from './EditorToolbar.vue' import StarterKit from '@tiptap/starter-kit' -import {Extension, mergeAttributes} from '@tiptap/core' +import {Extension, mergeAttributes, type SetContentOptions} from '@tiptap/core' import {EditorContent, type Extensions, useEditor, VueNodeViewRenderer} from '@tiptap/vue-3' import {Plugin, PluginKey} from '@tiptap/pm/state' import {marked} from 'marked' @@ -213,6 +213,12 @@ const tiptapInstanceRef = ref(null) const {t} = useI18n() +const defaultSetContentOptions: SetContentOptions = { + parseOptions: { + preserveWhitespace: 'full', + }, +} + const CustomTableCell = TableCell.extend({ addAttributes() { return { @@ -539,6 +545,9 @@ const editor = useEditor({ onUpdate: () => { bubbleNow() }, + parseOptions: { + preserveWhitespace: 'full', + }, }) watch( @@ -583,7 +592,7 @@ function bubbleSave() { } function exitEditMode() { - editor.value?.commands.setContent(lastSavedState, false) + editor.value?.commands.setContent(lastSavedState, defaultSetContentOptions) if (isEditing.value) { internalMode.value = 'preview' } @@ -630,7 +639,7 @@ function uploadAndInsertFiles(files: File[] | FileList) { const html = editor.value?.getHTML().replace(UPLOAD_PLACEHOLDER_ELEMENT, '') ?? '' - editor.value?.commands.setContent(html, false) + editor.value?.commands.setContent(html, defaultSetContentOptions) bubbleSave() }) @@ -689,7 +698,7 @@ onBeforeUnmount(() => { function setModeAndValue(value: string) { internalMode.value = isEditorContentEmpty(value) ? 'edit' : 'preview' - editor.value?.commands.setContent(value, false) + editor.value?.commands.setContent(value, defaultSetContentOptions) }