-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The interaction between composition and updateText
/updateSelection
should be more clearly defined
#111
Comments
I agree that this behavior seems surprising, and your proposed changes are reasonable. I'm not aware of a deliberate decision having been made here, and am assuming that, like you say, the current behavior was just the most straightforward implementation. If we want to change this behavior the main issue would be that it's a breaking change to the Chromium implementation. Chromium will generally try to avoid changes that might break code in the wild without very strong justification. In building a justification, it would be good to understand better how hard it is to work around this. For the failure to update the selection position, I assume devs can work around this by just ensuring that after calling I'm tempted to try to split the difference and only change the behavior in the second and third bullet points: adjusting composition positions if However, maybe it would be confusing for developers if we change that behavior without also changing the behavior in the first bullet point (updating selection positions when |
It is extremely awkward. If your text model changes through some event that doesn't originate in the edit context during a composition, you cannot touch the edit context to sync it up, because that will cause it to emit unusable events. So you have to somehow accommodate for the fact that your edit context and your actual text model have diverged—and because they can diverge in arbitrary ways, this is very difficult to model. My current workaround consists of some crude, unsound hacks (codemirror/view@9658d5e, codemirror/view@e7d6eeb) because modeling this properly would just be too much added complexity.
Yes, but only for a case where the current behavior is not very compelling (landing the selection in a more or less arbitrary place after you call |
From meeting minutes (2024-12-12):
|
@dandclark Do you know when you'll be able to get around to drafting the spec update? (It's looking like I'm going to be turning off |
@dandclark Is CodeMirror the only known user of EditContext in DOM mode? If yes, it would seem like it shouldn't be too difficult to change. If not, do we know what workarounds other users employ? |
This is what the discussed spec change would look like: #115. There remain concerns with making this non-backwards-compatible change to the shipped Chromium implementation. The change would also affect non-DOM-mode users of EditContext, which includes Google Docs. I talked to the engineer from Docs who worked on the EditContext integration and there are definitely concerns about compatibility there. So there are a few ways to approach this. This is not really satisfying since the default behavior would not be the best behavior, so another thing that could be explored in conjunction with this is adding use counters to the Chromium implementation to detect when the proposed change would have affected pages that did not request this opt-in. If that use count is sufficiently low, the old behavior could be removed and the opt-in would become a no-op. |
@dandclark sounds good. I agree that adding a counter would be preferable as we don't have that many known users right now. Will that count only number of times a browser uses the feature or will it also include things like number of domains it is used on? |
Discussed in Editing WG on 2025-03-13:
|
While it's absolutely possible for this to regress something, it seems like the code would have to do something very specific, like set the selection before updating the text (which seems problematic when the new selection position is outside of the range of the old text) or storing the selection position in a variable before updating the text, then calling It is of course entirely possible that I'm failing to account for some other pattern. But I expect that if you can get some examples of existing EditContext code and review them for how they'd handle this change, most would continue to work or even have a bug they didn't know they had solved by the change. |
At the moment, in Chromium's implementation of
EditContext
, if you push a text/selection update into the edit context while a composition is in progress, further composition updates will continue to happen at the old selection position. See also this issue.In a situation (which I think is typical of an
EditContext
-based editor) where the editor library will push changes made to its document via sources other than the edit context into the edit context in order to keep that synced with its own document model, this is going to cause issues.I would expect updates to the edit context's text/selection model that don't directly impact the text around the composition to move the context's understanding of where the composition happens. Updates that do touch the composed text should probably abort the composition.
The current interface, where
updateText
andupdateSelection
are two separate methods, even though the data they interact with is deeply entangled, makes addressing this somewhat awkward, because a state update isn't a single atomic thing, but two imperative calls, with the context being in a bogus state in between them.I was actually surprised to see that (at least in Chrome's implementation),
updateText
does not affectselectionStart
/selectionEnd
—i.e. when the selection is at position 10 and you callupdateText(0, 6, "")
, it stays at 10 (or is clipped to the end of the document) rather than moving to position 4 along with the text that it points at. Is that an intentional decision, or something that just fell out of the most straightforward implementation? IfupdateText
did adjust the selection (which seems like it will be a welcome behavior in almost every situation), it provides more of an atomic way to push updates into the context, and may make it easier to define composition behavior in response to such an update.Given all that, my proposal would be:
updateText
affect the selection start and end, moving them bytext.length - (rangeEnd - rangeStart)
whenpos >= rangeEnd
, or torangeStart + text.length
whenpos > rangeStart && pos < rangeEnd
.updateText
is calledupdateSelection
is called with a selection that differs from the current selection, the composition should probably be abortedThe text was updated successfully, but these errors were encountered: