diff --git a/packages/lexical-yjs/src/SyncCursors.ts b/packages/lexical-yjs/src/SyncCursors.ts index a34c7538409..d493515f51d 100644 --- a/packages/lexical-yjs/src/SyncCursors.ts +++ b/packages/lexical-yjs/src/SyncCursors.ts @@ -26,7 +26,7 @@ import { createRelativePositionFromTypeIndex, } from 'yjs'; -import {Provider} from '.'; +import {Provider, UserState} from '.'; import {CollabDecoratorNode} from './CollabDecoratorNode'; import {CollabElementNode} from './CollabElementNode'; import {CollabLineBreakNode} from './CollabLineBreakNode'; @@ -295,50 +295,75 @@ function updateCursor( } } -export function $syncLocalCursorPosition( - binding: Binding, - provider: Provider, -): void { - const awareness = provider.awareness; - const localState = awareness.getLocalState(); +type AnyCollabNode = + | CollabDecoratorNode + | CollabElementNode + | CollabTextNode + | CollabLineBreakNode; - if (localState === null) { - return; - } +export function getAnchorAndFocusCollabNodesForUserState( + binding: Binding, + userState: UserState, +) { + const {anchorPos, focusPos} = userState; - const anchorPos = localState.anchorPos; - const focusPos = localState.focusPos; + let anchorCollabNode: AnyCollabNode | null = null; + let anchorOffset = 0; + let focusCollabNode: AnyCollabNode | null = null; + let focusOffset = 0; if (anchorPos !== null && focusPos !== null) { const anchorAbsPos = createAbsolutePosition(anchorPos, binding); const focusAbsPos = createAbsolutePosition(focusPos, binding); if (anchorAbsPos !== null && focusAbsPos !== null) { - const [anchorCollabNode, anchorOffset] = getCollabNodeAndOffset( + [anchorCollabNode, anchorOffset] = getCollabNodeAndOffset( anchorAbsPos.type, anchorAbsPos.index, ); - const [focusCollabNode, focusOffset] = getCollabNodeAndOffset( + [focusCollabNode, focusOffset] = getCollabNodeAndOffset( focusAbsPos.type, focusAbsPos.index, ); + } + } - if (anchorCollabNode !== null && focusCollabNode !== null) { - const anchorKey = anchorCollabNode.getKey(); - const focusKey = focusCollabNode.getKey(); + return { + anchorCollabNode, + anchorOffset, + focusCollabNode, + focusOffset, + }; +} - const selection = $getSelection(); +export function $syncLocalCursorPosition( + binding: Binding, + provider: Provider, +): void { + const awareness = provider.awareness; + const localState = awareness.getLocalState(); - if (!$isRangeSelection(selection)) { - return; - } - const anchor = selection.anchor; - const focus = selection.focus; + if (localState === null) { + return; + } - $setPoint(anchor, anchorKey, anchorOffset); - $setPoint(focus, focusKey, focusOffset); - } + const {anchorCollabNode, anchorOffset, focusCollabNode, focusOffset} = + getAnchorAndFocusCollabNodesForUserState(binding, localState); + + if (anchorCollabNode !== null && focusCollabNode !== null) { + const anchorKey = anchorCollabNode.getKey(); + const focusKey = focusCollabNode.getKey(); + + const selection = $getSelection(); + + if (!$isRangeSelection(selection)) { + return; } + const anchor = selection.anchor; + const focus = selection.focus; + + $setPoint(anchor, anchorKey, anchorOffset); + $setPoint(focus, focusKey, focusOffset); } } @@ -413,7 +438,7 @@ export function syncCursorPositions( if (clientID !== localClientID) { visitedClientIDs.add(clientID); - const {anchorPos, focusPos, name, color, focusing} = awareness; + const {name, color, focusing} = awareness; let selection = null; let cursor = cursors.get(clientID); @@ -423,41 +448,30 @@ export function syncCursorPositions( cursors.set(clientID, cursor); } - if (anchorPos !== null && focusPos !== null && focusing) { - const anchorAbsPos = createAbsolutePosition(anchorPos, binding); - const focusAbsPos = createAbsolutePosition(focusPos, binding); - - if (anchorAbsPos !== null && focusAbsPos !== null) { - const [anchorCollabNode, anchorOffset] = getCollabNodeAndOffset( - anchorAbsPos.type, - anchorAbsPos.index, - ); - const [focusCollabNode, focusOffset] = getCollabNodeAndOffset( - focusAbsPos.type, - focusAbsPos.index, - ); - - if (anchorCollabNode !== null && focusCollabNode !== null) { - const anchorKey = anchorCollabNode.getKey(); - const focusKey = focusCollabNode.getKey(); - selection = cursor.selection; - - if (selection === null) { - selection = createCursorSelection( - cursor, - anchorKey, - anchorOffset, - focusKey, - focusOffset, - ); - } else { - const anchor = selection.anchor; - const focus = selection.focus; - anchor.key = anchorKey; - anchor.offset = anchorOffset; - focus.key = focusKey; - focus.offset = focusOffset; - } + if (focusing) { + const {anchorCollabNode, anchorOffset, focusCollabNode, focusOffset} = + getAnchorAndFocusCollabNodesForUserState(binding, awareness); + + if (anchorCollabNode !== null && focusCollabNode !== null) { + const anchorKey = anchorCollabNode.getKey(); + const focusKey = focusCollabNode.getKey(); + selection = cursor.selection; + + if (selection === null) { + selection = createCursorSelection( + cursor, + anchorKey, + anchorOffset, + focusKey, + focusOffset, + ); + } else { + const anchor = selection.anchor; + const focus = selection.focus; + anchor.key = anchorKey; + anchor.offset = anchorOffset; + focus.key = focusKey; + focus.offset = focusOffset; } } } diff --git a/packages/lexical-yjs/src/index.ts b/packages/lexical-yjs/src/index.ts index 62b5fbbe8fc..bed89d65e6a 100644 --- a/packages/lexical-yjs/src/index.ts +++ b/packages/lexical-yjs/src/index.ts @@ -111,7 +111,10 @@ export function setLocalStateFocus( localState.focusing = focusing; awareness.setLocalState(localState); } -export {syncCursorPositions} from './SyncCursors'; +export { + getAnchorAndFocusCollabNodesForUserState, + syncCursorPositions, +} from './SyncCursors'; export { syncLexicalUpdateToYjs, syncYjsChangesToLexical,