diff --git a/frontend/src/components/input/editor/TipTap.vue b/frontend/src/components/input/editor/TipTap.vue index 6bfdb3186..32c4c5f0c 100644 --- a/frontend/src/components/input/editor/TipTap.vue +++ b/frontend/src/components/input/editor/TipTap.vue @@ -301,6 +301,10 @@ const internalMode = ref('preview') const isEditing = computed(() => internalMode.value === 'edit' && props.isEditEnabled) const contentHasChanged = ref(false) +// TipTap crashes when inserting an image into an empty editor. +// To work around this, we're inserting an element first, then insert the image, then remove the element. +const UPLOAD_PLACEHOLDER_ELEMENT = '

UPLOAD_PLACEHOLDER

' + let lastSavedState = '' watch( @@ -542,18 +546,30 @@ onBeforeUnmount(() => editor.value?.destroy()) const uploadInputRef = ref(null) function uploadAndInsertFiles(files: File[] | FileList) { - if (typeof props.uploadCallback !== 'undefined') { + if (typeof props.uploadCallback === 'undefined') { throw new Error('Can\'t add files here') } props.uploadCallback(files).then(urls => { urls?.forEach(url => { + if (editor.value?.isEmpty) { + editor.value + ?.chain() + .focus() + .insertContent(UPLOAD_PLACEHOLDER_ELEMENT) + .run() + } editor.value ?.chain() .focus() .setImage({src: url}) .run() }) + + const html = editor.value?.getHTML().replace(UPLOAD_PLACEHOLDER_ELEMENT, '') ?? '' + + editor.value?.commands.setContent(html, false) + bubbleSave() }) }