Skip to content

Commit

Permalink
Add missing isLayoutReady check in useMultiRootEditor
Browse files Browse the repository at this point in the history
  • Loading branch information
Mati365 committed Jun 14, 2024
1 parent 9b55c68 commit 096ee26
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
15 changes: 14 additions & 1 deletion demo-multiroot-react-19/src/ContextMultiRootEditorDemo.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import React from 'react';
import React, { useEffect, useState } from 'react';

import { useMultiRootEditor, type MultiRootHookProps, CKEditorContext } from '../../src';
import MultiRootEditor from './MultiRootEditor';

export default function ContextMultiRootEditorDemo(): JSX.Element {
const [ isLayoutReady, setLayoutReady ] = useState( false );

useEffect( () => {
const timer = setTimeout( () => {
setLayoutReady( true );
}, 100 );

return () => {
clearTimeout( timer );
};
}, [] );

return (
<>
{ /* @ts-expect-error: Caused by linking to parent project and conflicting react types */ }
<CKEditorContext
isLayoutReady={ isLayoutReady }
context={ MultiRootEditor.Context as any }
contextWatchdog={ MultiRootEditor.ContextWatchdog as any }
>
Expand Down
10 changes: 8 additions & 2 deletions src/useMultiRootEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
EventInfo
} from 'ckeditor5';

import { ContextWatchdogContext } from './ckeditorcontext';
import { ContextWatchdogContext, isContextWatchdogReadyToUse } from './ckeditorcontext';
import { EditorWatchdogAdapter } from './ckeditor';

import type { EditorSemaphoreMountResult } from './lifecycle/LifeCycleEditorSemaphore';
Expand Down Expand Up @@ -87,6 +87,12 @@ const useMultiRootEditor = ( props: MultiRootHookProps ): MultiRootHookReturns =
useEffect( () => {
const semaphoreElement = semaphoreElementRef.current;

// Check if parent context is ready (only if it is provided).
if ( context && !isContextWatchdogReadyToUse( context ) ) {
return;
}

// Check if hook internal state or attributes are not ready yet.
if ( !semaphoreElement || props.isLayoutReady === false ) {
return;
}
Expand Down Expand Up @@ -128,7 +134,7 @@ const useMultiRootEditor = ( props: MultiRootHookProps ): MultiRootHookReturns =
forceAssignFakeEditableElements();
semaphore.release( false );
};
}, [ props.id, props.isLayoutReady ] );
}, [ props.id, props.isLayoutReady, context?.status ] );

/**
* Returns the editor configuration.
Expand Down
20 changes: 18 additions & 2 deletions tests/useMultiRootEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,33 @@ describe( 'useMultiRootEditor', () => {

it( 'should initialize the MultiRootEditor instance with context', async () => {
const contextWatchdog = new ContextWatchdog( TestMultiRootEditor.Context );
contextWatchdog.create();
await contextWatchdog.create();

const useContextSpy = sinon.stub( React, 'useContext' );
useContextSpy.withArgs( ContextWatchdogContext ).returns( contextWatchdog );
useContextSpy.withArgs( ContextWatchdogContext ).returns( {
status: 'initialized',
watchdog: contextWatchdog
} );

const { result, waitFor } = renderHook( () => useMultiRootEditor( editorProps ) );

await waitFor( () => {
expect( result.current.editor ).to.be.instanceof( TestMultiRootEditor );
} );
} );

it( 'should not initialize the MultiRootEditor instance with context when watchdog is not initialized', async () => {
const useContextSpy = sinon.stub( React, 'useContext' );
useContextSpy.withArgs( ContextWatchdogContext ).returns( {
status: 'initializing'
} );

const { result, waitFor } = renderHook( () => useMultiRootEditor( editorProps ) );

await waitFor( () => {
expect( result.current.editor ).to.be.null;
} );
} );
} );

describe( 'toolbarElement', () => {
Expand Down

0 comments on commit 096ee26

Please sign in to comment.