ckeditor / ckeditor5

Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.
https://ckeditor.com/ckeditor-5
Other
9.35k stars 3.68k forks source link

setData() resets cursor position (even if new data is identical to current data) #759

Closed thedavidmeister closed 6 years ago

thedavidmeister commented 6 years ago

🐞 Is this a bug report or feature request? (choose one)

not sure

πŸ’» Version of CKEditor

alpha2

πŸ“‹ Steps to reproduce

  1. call setData on initialised editor

βœ… Expected result

if new data === existing data, then nothing should happen.

if new data contains the current cursor position (based on some kind of diff logic) then data should update but cursor should not move.

❎ Actual result

cursor always moves to start of WYSIWYG when setData() is called

πŸ“ƒ Other details that might be useful

https://codepen.io/anon/pen/WdXgjN?editors=1111

pjasiun commented 6 years ago

The problem with diff is that it's computationally very demanding. It should be used carefully. If there will be a long, different content, the browser can freeze on such setData.

On the other hand, simple === will fail on any whitespaces or filtered-out attributes.

This is why I'm against having such feature available by default.

Reinmar commented 6 years ago

This can be an editor's plugin or something but it should not be a part of the code. There are two reasons for that:

Anyway, I'm curious what's the use case for this behaviour.

. If there will be a long, different content, the browser can freeze on such setData.

I think that there's a quite simple solution to this problem, which is computationally cheap:

  1. Store selection (as a normal Selection instance).
  2. Set new data.
  3. Create new positions based on the old positions' paths but with new roots.
  4. Check if those positions still make sense in the new document.
  5. If so, set the new document's selection to these positions.
thedavidmeister commented 6 years ago

@Reinmar @pjasiun so i don't know enough about this but i thought a goal of ckeditor 5 was real time collaboration - sounds like setData is the wrong tool for that job, so how should i be inserting new content coming over the wire from other collaborators? (obviously the cursors can't all reset position whenever somebody types)

Reinmar commented 6 years ago

Real-time collaboration requires more than just updating one editor's content with the new content taken from another editor. This would make the editor unusable when two users are typing simultaneously. They'd just override each other's content all the time because most letter insertions will happen at the same time (taken network latency).

Therefore, one of (many) aspects of real-time collaboration is conflict resolution. In a text editing conflicts happen all the time so you need not only an algorithm which allows you to ensure eventual consistency (like CRDT), but also resolve conflicts between operations which overlap. For this, we use the OT (Operational Transformation) algorithms.

Every change in the editor must be applied to the model as an operation. These operations can then be sent further and after conflicts are resolved between operations which "happened at the same time" (air quotes because it's not about a point in time but about maintaining the same order) they can be applied to other clients.

Then, after this works, there are topics like displaying selections of other users, reconnection, writing features in a collab-safe way, etc.

Reinmar commented 6 years ago

I'm closing this ticket as we agreed that real-time collab editing is not a valid use case for setData() and that additional behaviour can be achieved from "outside" of the editor.

thedavidmeister commented 6 years ago

@Reinmar could you point me at the docs for these operations?

Reinmar commented 6 years ago

I'm afraid that I don't know where to point you really. We're talking here about some research and papers that we consumed initially and then 4 years of our work which would easily make for couple other papers. The resulting API is just the surface of the problem and without a deep understanding of the problem, its documentation (which is out there in the code) will not be of a much help. Do we plan to write an extensive documentation for this? I don't think so. There are multiple reasons why this won't happen:

In other words, the editor acts as a framework when you want to implement your own editors with your own features. But when talking about so complex and multi-layered topics as real-time collab editing, we feel that it is more right to propose products and high-level components, not libraries. We’ve seen too many times that lower-level components don’t really help people who mistakenly tend to break things on the integration level which then backfires at us.

That's why we ended up offering Letters next to CKEditor 5. The product that we propose (Letters) is built on top of CKEditor 5 Framework, which proves that all the necessary features, which are required for implementing collaboration are included in this Open Source project.

thedavidmeister commented 6 years ago

ok sure, letters certainly looks interesting - will have to keep an eye on it and the final pricing

Reinmar commented 6 years ago

For those of you who haven't seen the news – we released CKEditor 5 Collaboration Features which you can enable in CKEditor 5 in your application. You can check out the demo in https://docs.ckeditor.com/ckeditor5/latest/features/collaboration/overview.html.

thedavidmeister commented 6 years ago

ooooooooh

DhruvikLadWappzo commented 2 months ago

@Reinmar @pjasiun so i don't know enough about this but i thought a goal of ckeditor 5 was real time collaboration - sounds like setData is the wrong tool for that job, so how should i be inserting new content coming over the wire from other collaborators? (obviously the cursors can't all reset position whenever somebody types)

You're right, I have same issue