Details
-
Bug
-
Resolution: Fixed
-
Major
-
16.10.18
-
None
-
Chrome 150
-
Integration
-
Unknown
-
N/A
-
N/A
-
Description
In some cases when the document is modified by another participant in the CKEditor realtime editing session, the cursor position is lost and jumps back to the start of the document. The conditions for that seem to include that while the editor is out of focus (e.g., because the user is on another tab), the content is shortened by another participant such that the text of the element with the cursor is now shorter than the previous cursor position offset. Then, when regaining focus, the restoring of the cursor positions fails and it jumps back to the start of the document. This only reproduces on Chrome because the mechanism for the failure in CKEditor has a bypass for Gecko-based browsers. In the integration tests, this reproduces in the localUndoRedo test in org.xwiki.realtime.wysiwyg.test.ui.RealtimeWYSIWYGEditorIT since the upgrade to Chrome 150. I haven't managed manually reproducing this but in theory this should be reproducible.
Explanation of the root cause by Claude Code on the failure seen in the integration test, found by putting extensive debug logging around the various places in the code:
CKEditor locks the selection when the editing area loses focus. In a realtime session the tab is unfocused while remote changes arrive, so the locked selection goes stale — a remote edit shortens the text node it points at. _applySelection then calls editable.$.focus(), CKEditor's focus handler runs unlockSelection() → selectRanges(<stale>) → setStart(node, 19) on a 17-char node → IndexSizeError. Thrown from a synchronously-dispatched DOM listener, so it's "Uncaught" and never reaches restoreSelection's try/catch; CKEditor's selection is left inconsistent and the caret drops to offset 0. Everything downstream then faithfully propagates that wrong caret into the undo history and back out — so ] gets typed at the start.