facebook / lexical

Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.
https://lexical.dev
MIT License
19.65k stars 1.67k forks source link

Bug: Listeners fire on initialization with CollaborationPlugin #4517

Open GermanJablo opened 1 year ago

GermanJablo commented 1 year ago

When the CollaborationPlugin handles changing documents by receiving a different id, the listeners fire. Of course, listeners should not fire on document initialization/change. I've noticed that this doesn't happen with the OnChangePlugin, because it checks that the previous editorState is not null, apparently to avoid this situation:

return editor.registerUpdateListener(
  ({ editorState, dirtyElements, dirtyLeaves, prevEditorState, tags }) => {
    if (prevEditorState.isEmpty()) return;
    // ...
  }
);

Ideally, this should be the default behavior. But the problem is that even if you wanted to, you couldn't imitate this trick with the other listeners, since updateListener is the only one that receives prevEditorState as callback.

Lexical version: 0.9.1

Steps To Reproduce

  1. npm run dev
  2. In another terminal, npm run collab-server
  3. In the browser, click on the buttons to change the document, and you will see that content changed appears in the console.

Link to code example: https://github.com/EgonBolton/collab

The current behavior

The listeners are fired, as seen in the console.

The expected behavior

I think the listeners should not fire in this case.

GermanJablo commented 1 year ago

UPDATE: merged the two messages above, improved the problem explanation and got the repro to work (can't be codesandbox for collab server to work)

GermanJablo commented 1 year ago

UPDATE 2: I have done the repro on a fork branch of lexical: https://github.com/EgonBolton/lexical/tree/collab-final

This makes it easier to debug CollabPlugin. The steps are the same: npm run dev and npm run collab-server.

I've also been able to track where the two updates that fire the listeners are and I've put console.logs in those places: