🐛(frontend) check tiptap editor in dom

When zooming in and out quickly, the editor
instance may not be fully mounted, leading to
errors when accessing its document. This commit
adds checks to ensure the editor and its view
are mounted before attempting to access the
document, preventing potential runtime errors.
This commit is contained in:
Anthony LC
2025-12-10 10:09:20 +01:00
parent 90651a8ea6
commit 99131dc917
5 changed files with 30 additions and 7 deletions

View File

@@ -87,7 +87,9 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
const { isDesktop } = useResponsiveStore();
const { isSynced: isConnectedToCollabServer } = useProviderStore();
const refEditorContainer = useRef<HTMLDivElement>(null);
const canSeeComment = doc.abilities.comment && isDesktop;
const canSeeComment = doc.abilities.comment;
// Determine if comments should be visible in the UI
const showComments = canSeeComment && isDesktop;
useSaveDoc(doc.id, provider.document, isConnectedToCollabServer);
const { i18n } = useTranslation();
@@ -207,7 +209,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
ref={refEditorContainer}
$css={css`
${cssEditor};
${cssComments(canSeeComment, currentUserAvatarUrl)}
${cssComments(showComments, currentUserAvatarUrl)}
`}
>
{errorAttachment && (
@@ -225,7 +227,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
formattingToolbar={false}
slashMenu={false}
theme="light"
comments={canSeeComment}
comments={showComments}
aria-label={t('Document editor')}
>
<BlockNoteSuggestionMenu />

View File

@@ -7,6 +7,11 @@ export const useHeadings = (editor: DocsBlockNoteEditor) => {
const { setHeadings, resetHeadings } = useHeadingStore();
useEffect(() => {
// Check if editor and its view are mounted before accessing document
if (!editor || !editor._tiptapEditor?.view?.dom) {
return;
}
setHeadings(editor);
let timeoutId: NodeJS.Timeout;

View File

@@ -7,6 +7,11 @@ export const useShortcuts = (
el: HTMLDivElement | null,
) => {
useEffect(() => {
// Check if editor and its view are mounted
if (!editor || !editor._tiptapEditor?.view?.dom || !el) {
return;
}
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === '@' && editor?.isFocused()) {
const selection = window.getSelection();
@@ -32,10 +37,6 @@ export const useShortcuts = (
}
};
if (!el) {
return;
}
el.addEventListener('keydown', handleKeyDown);
return () => {

View File

@@ -95,6 +95,11 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => {
);
useEffect(() => {
// Check if editor and its view are mounted before accessing document
if (!editor || !editor._tiptapEditor?.view?.dom) {
return;
}
const imagesBlocks = editor?.document.filter(
(block) =>
block.type === 'image' && block.props.url.includes(ANALYZE_URL),
@@ -110,6 +115,11 @@ export const useUploadStatus = (editor: DocsBlockNoteEditor) => {
* block to show analyzing status
*/
useEffect(() => {
// Check if editor and its view are mounted before setting up handlers
if (!editor || !editor._tiptapEditor?.view?.dom) {
return;
}
editor.onUploadEnd((blockId) => {
if (!blockId) {
return;

View File

@@ -28,6 +28,11 @@ export interface UseHeadingStore {
export const useHeadingStore = create<UseHeadingStore>((set, get) => ({
headings: [],
setHeadings: (editor) => {
// Check if editor and its view are mounted before accessing document
if (!editor || !editor._tiptapEditor?.view?.dom) {
return;
}
const headingBlocks = editor?.document
.filter(
(block) =>