fix: cross-chat data corruption and tiptap editor access errors (#20266)

* fix: prevent cross-chat corruption and editor access errors

* fix: safety check in Messages.svelte and cleanup in RichTextInput
This commit is contained in:
G30
2025-12-31 17:40:35 +04:00
committed by GitHub
parent 5a556b00c3
commit 252a983091
2 changed files with 34 additions and 7 deletions
+4
View File
@@ -346,6 +346,10 @@
};
const saveMessage = async (messageId, message) => {
if (!history.messages?.[messageId]) {
return;
}
history.messages[messageId] = message;
await updateChat();
};
+30 -7
View File
@@ -416,7 +416,7 @@
};
export const setText = (text: string) => {
if (!editor) return;
if (!editor || !editor.view) return;
text = text.replaceAll('\n\n', '\n');
// reset the editor content
@@ -448,11 +448,13 @@
}
selectNextTemplate(editor.view.state, editor.view.dispatch);
// Ensure the editor is still valid before trying to focus
focus();
};
export const insertContent = (content) => {
if (!editor) return;
if (!editor || !editor.view) return;
const { state, view } = editor;
const { schema, tr } = state;
@@ -466,7 +468,7 @@
};
export const replaceVariables = (variables) => {
if (!editor) return;
if (!editor || !editor.view) return;
const { state, view } = editor;
const { doc } = state;
@@ -509,11 +511,16 @@
};
export const focus = () => {
if (editor) {
if (editor && editor.view) {
// Check if the editor is destroyed
if (editor.isDestroyed) {
return;
}
try {
editor.view?.focus();
editor.view.focus();
// Scroll to the current selection
editor.view?.dispatch(editor.view.state.tr.scrollIntoView());
editor.view.dispatch(editor.view.state.tr.scrollIntoView());
} catch (e) {
// sometimes focusing throws an error, ignore
console.warn('Error focusing editor', e);
@@ -743,7 +750,7 @@
})
]
: []),
...(richText && showFormattingToolbar
...(richText && showFormattingToolbar
? [
BubbleMenu.configure({
element: bubbleMenuElement,
@@ -753,6 +760,14 @@
placement: 'top',
theme: 'transparent',
offset: [0, 2]
},
shouldShow: ({ editor, view, state, oldState, from, to }) => {
// safety check
if (!editor || !editor.view || editor.isDestroyed) {
return false;
}
// default logic
return from !== to;
}
}),
FloatingMenu.configure({
@@ -763,6 +778,14 @@
placement: floatingMenuPlacement,
theme: 'transparent',
offset: [-12, 4]
},
shouldShow: ({ editor, view, state, oldState }) => {
// safety check
if (!editor || !editor.view || editor.isDestroyed) {
return false;
}
// default logic
return editor.isActive('paragraph');
}
})
]