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

Input events #3

Open
jgraham opened this issue May 19, 2022 · 14 comments
Open

Input events #3

jgraham opened this issue May 19, 2022 · 14 comments

Comments

@jgraham
Copy link
Contributor

jgraham commented May 19, 2022

One area that's believed to cause significant compat problems and difficulties for writing reliable editors is differences between input events, and their order, in different browsers. As part of this investigation we should:

  • Identify the specifications covering these events, and ensure that they match the desired behaviour
  • Identify the existing testcases covering these events, and ensure they match the specifications
  • Add additional test coverage where there are known gaps

The aim is that the identified tests would be a candidate for an Interop 2023 focus area that browsers would be able to commit to.

@jgraham
Copy link
Contributor Author

jgraham commented May 19, 2022

Please let me know if the summary as written isn't right, doesn't cover something important, or covers something it shouldn't.

@jgraham
Copy link
Contributor Author

jgraham commented Jun 16, 2022

An issue we'd like to nominate for inclusion here is w3c/uievents#202 which led to https://bugzilla.mozilla.org/show_bug.cgi?id=1511157 and is related to https://bugs.chromium.org/p/chromium/issues/detail?id=929404

@jgraham
Copy link
Contributor Author

jgraham commented Jul 14, 2022

From our point of view, getting that issue resolved would be a sufficient goal for this part of the project.

@whsieh
Copy link

whsieh commented Jul 21, 2022

Another interesting issue might be aligning whether events are dispatched when deleting backwards in an empty contenteditable or text field; when focusing the textarea on https://whsieh.github.io/examples/input-events and deleting backwards in Safari, for instance, neither input nor beforeinput are dispatched (which just seems like a bug).

In both Firefox and Chrome on macOS, the beforeinput event is dispatched, but not the input event. We should probably all align on this behavior.

@hsinyi hsinyi mentioned this issue Aug 9, 2022
@masayuki-nakano
Copy link

@whsieh

Currently, Firefox does not check strictly whether Delete or Backspace will delete something or nothing because it's hard to dispatch beforeinput event at first modification of the DOM tree. That's the reason why Firefox dispatches beforeinput in the case.

On the other hand, cut, copy and paste events are always fired for making web apps possible to handle them when the user indent to do it with browser's default shortcut keys or UI (such as menu) even if the commands are not available, e.g., due to Selection is collapsed or non-editable element has focus, the reason is for making web apps may want to handle them with their own data.

For consistency with the clipboard events, dispatching only beforeinput event must be reasonable in the case, e.g., web apps may put multiple editable elements and they may want to navigate them at pressing Backspace or Delete like credit card number inputs.

And it seems that browsers should dispatch beforeinput events whose inputType is historyUndo and historyRedo even if there is no transactions in their builtin editor.

@johanneswilm
Copy link

At TPAC, the Editing Working Group decided to move the event order of composition and input events into the uievents spec. So this is currently part of the TODO list of @garykac [1]. Also, the question of whether the last beforeinput event of a composition should be cancelable is still unresolved [2]. So based on that I am not sure whether it is actually possible to present tests rights now.

[1] w3c/input-events#22 w3c/input-events#135 https://www.w3.org/2022/09/15-editing-minutes.html#a01

[2] w3c/input-events#134

@jgraham
Copy link
Contributor Author

jgraham commented Oct 20, 2022

https://wpt.fyi/results/input-events/input-events-typing.html?label=experimental&label=master&aligned&view=subtest should be updated to match the expected behaviour.

https://wpt.fyi/results/input-events?label=experimental&label=master&aligned&view=subtest has additional tests.

The composition events tests will require IME primitives.

@jgraham
Copy link
Contributor Author

jgraham commented Oct 20, 2022

Score here is still 0% until we have some tests added / updated and progress on the spec changes.

@Azmisov
Copy link

Azmisov commented Oct 25, 2022

Quirks I have observed:

  • Pressing delete key in Chrome will use beforeinput.deleteContentForward followed by input.deleteContentBackward (should match)
  • If I have a text element  text and backspace up to, but not including, the space, Chrome Android will fire beforeinput.insertCompositionText followed by input.deleteContentBackward (should match)
  • Pasting in Chrome Android seems to use a series of composition events instead of insertFromPaste
  • Safari uses insertText instead of insertReplacementText when correcting a typo
  • Delete soft vs hard line forward/backward is not consistent among browsers. ctrl+shift+backspace gives you soft delete in Firefox, hard delete in Chrome; Safari says it is a deleteHardLineBackward, but it actually behaves like a soft delete.
  • Safari delete key does a deleteContentBackward with backspace behavior
  • Changing the cursor position during composition in Safari will emit compositionend without deleteCompositionText or insertFromComposition
  • Changing the cursor position during composition in Chrome Android will stop composition, but no compositionend is emitted.
  • No browser is emitting deleteByComposition
  • Firefox compositionend occurs before the final input.insertCompositionText, with isComposing=false, whereas other browsers all do the compositionend after.
  • Manipulating DOM during composition will cancel composition in Chrome Android. In Firefox, composition continues, but events and ranges are in reference to a disconnected DOM element. I suppose more of a gap in the spec, in that its not defined what browsers should do should the DOM change. Chrome behavior is reasonable, though if I am only changing the styles of elements and the textContent and the cursor relative to that textContent is unchanged, I would think the browser should be able to continue composition without canceling; the IME doesn't care about the DOM, so if textContent is the same, I'd expect composition to be able to continue. Firefox I think is poor behavior since the cursor no longer has focus on that disconnected element; it should cancel the composition or gracefully recover if textContent were the same. At the very least, the spec could say "manipulating the DOM between (beforeinput.deleteByComposition, beforeinput.insertFromComposition) will result in undefined behavior". See my suggestions here input-events/issues/134, about a requestCompositionEnd and compositionborder, which I think can also help better define browser behavior for composition: If they wanted to manipulate DOM, they'd call e.requestCompositionEnd() first and wait until beforeinput.insertFromComposition (outside the "undefined" event range); after this event, browser then picks up updated DOM and can continue composition if needed with the possibly modified text.

I've also made an input events tester like @whsieh, see here: https://azmisov.github.io/Input-Events-Tester/. Feel free to use/fork/edit if you want. It will pretty print the DOM HTML, along with target ranges/selection embedded, and a unique id applied to each node. Can be helpful to test how browsers behave with things other than plain text (which I would say is the motivation behind InputEvents). Can be used cleanly from mobile browsers as well.

@Azmisov
Copy link

Azmisov commented Oct 25, 2022

And it seems that browsers should dispatch beforeinput events whose inputType is historyUndo and historyRedo even if there is no transactions in their builtin editor.

I agree. I recall testing Safari and it wouldn't fire historyRedo if there was nothing to redo, but I'd have to double check that. Developer may want to implement their own history, but they'd currently have to listen for key combos and sniff OS to do so (and I suppose mobile platforms may not emit a key combination and so impossible to integrate with any builtin undo/redo).

@jgraham
Copy link
Contributor Author

jgraham commented Dec 15, 2022

Although we've got some useful feedback here, it seems like there hasn't been any concrete progress writing tests or resolving interop differences. So I think the score is still 0%.

@johanneswilm
Copy link

Hey @Azmisov ,
I am trying to add some of these things to the input-events-typing.html test file. It is not IME-related things for now, but everything else

I am using this page where I am trying to reproduce your findings: https://domeventviewer.com/key-event-viewer-ce.html as well as your own input tester.

  • Pressing delete key in Chrome will use beforeinput.deleteContentForward followed by input.deleteContentBackward (should match)

I am not able to reproduce that. If there is no content after the caret, I receive a beforeinput and no input-event. If there is content after the caret, I receive both events and both have the type deleteContentForward. Could you gie instructions on what I need to do to obtain your results?

  • If I have a text element  text and backspace up to, but not including, the space, Chrome Android will fire beforeinput.insertCompositionText followed by input.deleteContentBackward (should match)

Reproduceable. Added to test.

  • Pasting in Chrome Android seems to use a series of composition events instead of insertFromPaste

I'm not able to reproduce that. I see before/input events of type insertFromPaste. Need more detail.

I am not able to test the Safari-related events for now.

@Azmisov
Copy link

Azmisov commented Dec 16, 2022

I'll go back and test it again tomorrow, or this weekend if I don't get to it

@Azmisov
Copy link

Azmisov commented Dec 16, 2022

For the first one: select 1+ characters first, then press delete.

The second insertFromPaste looks like it is actually fine. The IME has a "paste text" option which I think I was using to test. When I paste from the context menu it uses insertFromPaste though.

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

No branches or pull requests

5 participants