-
Notifications
You must be signed in to change notification settings - Fork 40
T/460 Selection rendering breaks composition #861
base: master
Are you sure you want to change the base?
Conversation
… by mutations after composed text is inserted.
@@ -177,6 +185,10 @@ export default class Renderer { | |||
* removed as long selection is in the text node which needed it at first. | |||
*/ | |||
render() { | |||
if ( this.isComposing ) { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like asking for serious troubles with collaboration. If you allow changing the view, but prevent changes in DOM, you may have a very different state of view and DOM if another user changed the same part of the document. Mutations calculate a diff between DOM and view and if there is something from the OT in the view it will be marked to be removed since it does not appear in the DOM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can say that it's an edge case, but it is exactly the same edge case you want to fix with this return (OT and composition in the same block). It means that to prevent breaking composition, you breaks OT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure it need some tests with collaboration begore merging this PR because it can causes more bad than good.
Have you tested how it would work with OT / collaborative editing? I am worried it will not work properly. Consider following scenario:
Your model is:
I think this has to be handled more cautiously. Some ideas (pretty wild so I don't know whether they are good):
|
Thanks for pointing that out, I was wondering about issues connected to OT. What is the proper way to test OT for such cases, do we already have some integration/manual tests for similar cases? |
You can test it directly by faking composition start (set Then you would have to somehow fire typing, though. I don't remember how |
Ok, first I will write some unit/integration test (using operations as @scofalik suggested) to check how it works with composition. |
A question (without checking much of the code) – does this PR blocks the entire rendering? Looking at some comments, I'd say that we should make it more precise from the day one by blocking changing only a certain container's content. |
@Reinmar, yes it blocks the entire rendering. Blocking only the container (or part of it) in which the composition takes place may help to solve some cases with OT, however probably not all. |
Although... I can imagine such situation:
If we block rendering in that first <p>a[bc]def</p>
<p>f</p> Mind the duplicated "f". After more thinking I guess that blocking rendering smaller bits of content may lead to really weird situations ;|. So I'm not sure anymore if we shouldn't start with blocking everything. |
I don't know. Right now I can see only these issues with weird things happening around the blocked container. @scofalik may be able to imagine how (and if) this would have any effect on OT. I think not. The model will actually be live. The problems may be |
I think that we should do as much as we can not to break anything, but when there is no other way, for changes we can not predict/handle, I think that it's better to break composition then OT. These will be edge cases, I hope, but if the composition will be broken, then it broken composition. If the OT is broken, it can be broken editor (or all connected editors in the worst scenario). I think, still, we can handle, most obvious scenarios. But blocking rendering should go in pair with handing observers well when the view totally changed. You can not predict what kind of changes occurred in the meantime. It mostly meant that you need to handle mutations, but I can also imagine some bugs with selection observer, hope other observers will be fine. This is why I think that less we block, safer we are. Again, if part of the not blocked rendering will break composition, then only composition is broken, but if we will have a crash because of the not handled mutation/selection/whatever observer of the blocked element, then everything is broken. I would start from the smallest possible part, so blocking changing content of the text node. Then we can handle inserting a new text node if composition creates it. Then breaking text block, moving it, etc. Or not, we can decide that if someone else breaks the block, it's too big change to prevent and the composition should be broken. For handling typing in the same block, you still need to somehow save changes in the view, which are not rendered. I believe it's doable. For instance:
|
And, as I think about it, selection need to be handled as well. If I end composition by moving the selection to the end of |
Also, note that renderer role is to compare view and DOM and not render nodes which does not need to be rendered (to not break composition). So elements which are the same in the view and DOM should not be touched. It, most probably, does not mean that we do not need renderer blocking, but as long as it can prevent some bugs, we should improve renderers nodes comparing, so render as few as possible. |
BTW, we can also improve how the text nodes are updated. In w3c/editing#149 I commented that:
I don't know if this applies to all browsers but if we want to go this way that OT is more important, then this would be the way to go. BUT do note that composition can't have the lowest priority for us. E.g. if you want to render selections of other users in the text node in which someone is typing... you'll break the composition every time some other user moved the selection in that text node. This, in some situations, will not be an edge case, but a really popular scenario. It'd render composing text impossible which would be a huge issue. |
Final words – I guess we know a bit more about the scope and complexity of this problem now. It looks to me that it may be a killer issue so we should consider trying to find some quick wins and leave the rest for the future. What I'd like to now first is:
|
You did not get my point. I did not say that we should not prevent rendering anything, like the selection of other users. Or that it is not important. I said that we can not introduce changes which prevent breaking composition but crash editor instead. We need to be very careful and be sure that every introduced change is well tested and will not cause more harm than good. |
Looks tough indeed. I start checking for failing 1 user scenarios while using composition. Checked MacOS accent balloon and Spanish accent composition for now. MacOS accent scenarios
Only failing scenarios are listed below Chrome FF - All OK Safari Spanish-ISO scenarios
Only failing scenarios are listed below Chrome - All OK FF Safari 3. Broken:
4. Broken:
To sum up, there is 1 issue in Chrome, 1 in FF and 4 in Safari. |
This is odd. Perhaps our handler for the filler kicks in and tries to handle the arrow keys. This is the only place where we listen to keys. |
May be that our dirty unsafe key hack fails here :( |
My 5 cents: of course blocking rendering does not crash OT directly. What PJ (and me) meant by crashing OT is more crashing collaborative editing, because of reasons that we already discussed. |
Checked some scenarios with Hiragana too. Only a few but I think it is enough to give some general picture. The scenarios contains just a key sequences as it is the easiest way to describe it and the reproduce.
Only failing scenarios are listed below Chrome FF Safari I think it will be good to check which of the failing cases could be solved by blocking rendering during composition and or using |
I think that first, we should check why these cases are failing. It might be simple a bug in the renderer which renders more than it needs and may be fixed. |
I can see that the arrow keys break text input again. I think that this is the same issue as with what you described previously – that in e.g. Safari you can't use arrows to navigate the accent tooltip. I'd check this first. And it may not be related to rendering but to how we handle the filler. |
@Reinmar if by Looks more like the rendering issue, every time the arrow is pressed, the content of text node changes (the different accent is inserted) and rendering ( |
Yep -> https://github.com/ckeditor/ckeditor5-typing/issues/82 |
As for #861 (comment) - while navigating with arrow keys inside balloon panel the selection changes so the renderer updates it ( I was also able to check how it works with |
We have two options here:
|
Yep, we'd need to use the diff function and diff results grouping. I was worried about performance impact, but I guess we'll use it only when updating existing text node (which is rather rare action). When rendering for the first time we'll be of course creating new text nodes so it should be fine. |
The two Safari issues (Spanish-ISO 3. and 4.) described in #861 (comment) are caused by the Safari auto correction mechanism so it is not releted to this issue. With auto correction off, it works fine. |
I agree with both. For content, we should do our best to improve renderer comparison, so the renderer will see that the view and the DOM are the same and do not need rendering, since, at the moment all other options seems to be very painful. For selection, we should try it too, but preventing selection rendering seems to be far less dangerous than contents. |
Yep, we had performance problems with diff. It appears when you compare 2 totally different collections (strings). The time needed to calculate the diff is linear if collections are the same and grows exponentially with the length of the different texts. There was an idea to improve the diff function so if the difference is too big to calculate it quickly (something like 30 different characters), we overwrite the whole string. |
But do you think that it may be any performance issue if we use diffing only on strings which we know that got changed? This only affects typing and other kinds of text insertion which happen only a couple of times per second. |
If one paste a long text into the paragraph we may get a serious browser freeze (more than 10 sec). It might not be that bad, but the performance, in this case, needs to be tested in the first place. I remember we experienced it already, and it was not around 500 ms, but more than 10 sec. But then we used a linear model and calculated a diff on the whole model, so in this case in might be not that bad. |
Reported autocorrection issue (#861 (comment)): https://github.com/ckeditor/ckeditor5-typing/issues/85. |
In case of selection during composition (MacOS accent panel) it is: https://github.com/ckeditor/ckeditor5-typing/issues/86. |
It looks like https://github.com/ckeditor/ckeditor5-typing/issues/86 also fixed most issues with Hiragana composition in Chrome (3. - 6.) mentioned above. And so for the above scenarios the remaining issues are: MacOS accent scenarios Spanish-ISO scenarios Hiragana
All IME related found issues: https://github.com/ckeditor/ckeditor5-typing/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20IME |
@pjasiun, as I told you, we don't close unmerged PRs if they have some value. I've been looking for this PR now, knowing that it was somewhere there previously, and I couldn't find it. Hence, I'm reopening it. |
Went through scenarios from #861 (comment) and #861 (comment) once again: MacOS accent
Only this one is still reproducible on Chrome.
The Safari one visible above related to key navigation inside accent panel was fixed. Spanish-ISOBoth:
were fixed. Hiragana
Still reproducible in Chrome and Safari, looks like Bold is the issue here as described in https://github.com/ckeditor/ckeditor5-typing/issues/89. And on Firefox only 7. case fails, seems to be related to the same issue. The rest of reported cases were fixed. |
Went once again through scenarios which are still reproducible (#861 (comment)) because of https://github.com/ckeditor/ckeditor5-engine/issues/1417. MacOS accent
Only this one is still reproducible on Chrome. I extracted this issue to https://github.com/ckeditor/ckeditor5-typing/issues/147 so it is easier to track it. HiraganaThere is only problem with Safari when:
I suspect it is caused by the fact that when we navigate through composition panel, selection leaves text node (in which composition takes place) which causes inline filler to be removed and it breaks composition. Extracted to https://github.com/ckeditor/ckeditor5-typing/issues/148 so it is easier to track. |
Fix: Rendering is suspended during composition. Closes ckeditor/ckeditor5#3742.
Additional information
The fix introduces
CompositionObserver
which listens to native composition events. If composition is in progress therenderer
will not update the DOM.