Skip to content
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

Target range in device independent events #39

Closed
kojiishi opened this issue Jan 10, 2015 · 11 comments
Closed

Target range in device independent events #39

kojiishi opened this issue Jan 10, 2015 · 11 comments
Milestone

Comments

@kojiishi
Copy link

@BenjamP mentioned the co-editing scenario in the issue #18, and that makes me wonder maybe we should have a target range in device independent events.

Currently, we translate, say, a keyboard event Ctrl+B to a device independent event Bold, and it executes against the current selection. But if an editor wants to bold anywhere other than the current selection, the options are either to do it by own, or move the selection tentatively and move it back. The latter is likely to results in bad UX, and also could introduce weird bugs.

The proposal is, instead, Ctrl+B is translated to Bold this range with the targetRange set to the selection.

We can't then re-use execCommand or exiting code as is, but I assume we won't, so this change should not add a lot of work. Or is it only for Blink and WebKit?

@kojiishi
Copy link
Author

Let me re-state this issue, as I figured it's better to describe the issue first before diving into a solution proposal.

On two documents co-editing web services, I see a same symptom happening; whenever someone makes edits, my un-committed IME string is committed automatically. This makes these services completely unusable for IME users.

While this is just a bug in the two services, I believe our API design has a flaw for such a bug to be easily slipped in. My guess is that, since operations are designed around selection, they save the selection by getRangeAt, move the selection, do the operation someone else did, then get the selection back by addRange. Unfortunately, this does not work because browsers have unexposed internal states associated with selections, such as un-committed IME string or information to resolve ambiguity of range-to-visual mapping.

Possible solution proposals are:

  1. Define device independent events against a range, and when device events translate to device independent events, associate the current selection with the device independent events.
  2. Add APIs to make saving/restoring of selections possible, including browser-internal states that are not exposed via APIs.

@rniwa
Copy link
Contributor

rniwa commented Jan 12, 2015

I think being able to specify a specific range to apply a device independent "behavior" makes sense.

@teleclimber
Copy link

That's an interesting observation.

It seems to me that just adjusting the API isn't enough to ensure a bug-free editor for IME users. I am concerned that there are other things that might cause the UA to lose its internal state wrt IMEs. Perhaps DOM manipulations in the same region?

Furthermore, even with a better API design there is no way to guarantee that devs are not playing loose with selections. Seeing as these internal states are completely hidden and silent, there is no way for an editor dev to even check if it's ok to touch anything. I think devs treat selections as something they can remember, change, and restore without consequence. And this is often needed when we want to let the user interact with another part of the UI or we need to do a DOM manipulation that might knock out the Selection.

I am not sure what the right solution is but it seems to me this should be taken into account in the IME discussion #34.

@kojiishi
Copy link
Author

IME is likely to require this issue to be resolved, but I'm guessing this issue affects more, and "how more" is what I'd like to ask you all.

When creating editors, do you ever want to save the selection to move it temporary, do something and then restore? Co-authoring is one likely case I found, and IME is one likely victim by doing so. But there are several information browsers keep internally along with the selection. Examples are:

There may be more, and we may add more in future. All these will be lost if you getRangeAt to save and then addRange later to restore. I hope you understand that solving this issue is more important than just for IME.

So, is it real, not only my guess, that editors want to modify other than selections, or want to save/restore selections for whatever reasons?

@teleclimber
Copy link

When creating editors, do you ever want to save the selection to move it temporary, do something and then restore?

I don't "want to" and I try to avoid it, but there are situations that leave me unable to do it any other way. Take for example the case where my user creates a hyperlink. I will create a little popup toolbar that allows user to edit the url. But the moment the url input element gets the caret, the selection in the document has disappeared. Therefore I would "save" the selection based on what the Selection api gives me, then restore it when user is done editing url. There are ugly hacky workarounds that would leave the selection in place but I'd much prefer if the Selection could be saved and set without losing important state.

Sometimes it's also necessary to adjust the Selection because it is in an illegal place (with respect to my editor's logic).

Maybe not necessary for cE=typing, but the style last deleted/typed is also stored, so that when you delete all of bold words and then start typing, bold is applied.

Agreed this one is irrelevant for cE=typing.

So, is it real, not only my guess, that editors want to modify other than selections, or want to save/restore selections for whatever reasons?

Yes. I can't imagine writing an editor where I can't change the Selection.

I think the larger problem here is that the Selection API is a writable API, but there are internal states attached to Selections that aren't reflected in the API. How can this ever be problem free? If I have a writable API I am going to assume I can read and write to my heart's content. If there are hidden consequences to writing the API they should at the very least be documented, probably standardized, and ideally made writable too.

@kojiishi
Copy link
Author

Thanks for your comment, and confirmation of needing save/restore.

I think the larger problem here is that the Selection API is a writable API, but there are internal states attached to Selections that aren't reflected in the API. How can this ever be problem free? If I have a writable API I am going to assume I can read and write to my heart's content. If there are hidden consequences to writing the API they should at the very least be documented, probably standardized, and ideally made writable too.

I think this is a separate issue. We're open source, we can expose what we keep as an internal state at a moment. But I'd like to discuss what to expose by what's needed, and what can be interoperable, not by what one implementation has. If exposing one of them can make editors better, I'd be very happy to discuss that. But I'm not positive to expose all what all browsers have internally.

Even if we exposed everything, save/restore is a separate story. You probably don't want to save 40 properties and restore, and it may be 41 tomorrow.

Save/restore can assure you to temporary change and restore selection without breaking anything including future, while we could discuss separately what other properties can make editors better.

@rniwa
Copy link
Contributor

rniwa commented Jan 20, 2015

Being able to save & restore the selection seems like a useful feature. Going back to the original topic of this issue, the question then becomes whether we want something that represents the full state of selection at the time of a device independent event was created/fired.

@kojiishi
Copy link
Author

Save/restore selections is now split into w3c/selection-api#42.

Going back to the original topic of this issue, the question then becomes whether we want something that represents the full state of selection at the time of a device independent event was created/fired.

Hm, yeah, you're right, I was underestimating that. While it still looks a nice design to me, it's probably too much work compared to the benefits once save/restore is in place.

Please close as won't fix if you agree.

@BenjamP
Copy link

BenjamP commented Jan 28, 2015

So back to the original question: do we want to have a targetRange or just use the Selection? Does anyone have a use-case for needing a targetRange? The point about co-editing a document doesn't really apply because the co-editor is not the user. It should instead be seen as a change from the server, which should not fire Device Independent Events.

@BenjamP
Copy link

BenjamP commented Feb 23, 2015

Maybe the best reason to include the range in the event is because the selection might change, and the event would still need to know what it was.

@johanneswilm
Copy link
Contributor

Hey, looking at this now. Does any of this still apply, @teleclimber @kojiishi ?

As I understand @BenjamP's last comments, the selection shouldn't need to change when applying changes that come from the server. It should normally not invalidate the selection either -- unless of course the change was in the same text node that the local user is trying to add IME characters in, in which it's probably correct to cancel the IME composition handling anyway. Given that selection saving/restoring is handled by the selection APi, do we still need this issue? Please reopen if we do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants