w3c / uievents

UI Events
https://w3c.github.io/uievents/
Other
147 stars 52 forks source link

Cancelable/default action for keydown, composition*, beforeinput, textInput, input #361

Open zcorpan opened 10 months ago

zcorpan commented 10 months ago

While trying to figure out what spec text to propose for the textInput event (#353) I found that the spec doesn't seem to match implementations for the default action for the keydown, composition*, beforeinput, textInput, input events, and whether/when they're cancelable.

Demo: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/12161

For example, https://w3c.github.io/uievents/#keydown says

If the key is associated with a character, the default action MUST be to dispatch a beforeinput event followed by an input event.

However, in Chrome, Safari and Firefox, if you cancel a beforeinput event, no input event is fired.

Chrome and Safari support textInput, and if you cancel that event, no input event is fired.

So, assuming the correct event order for typing a single non-composing character in a text field is:

  1. keydown
  2. keypress
  3. beforeinput
  4. textInput
  5. input
  6. keyup

...the default actions should be:

event default action
keydown fire keypress
keypress fire beforeinput
beforeinput fire textInput
textInput update DOM; fire input
input none
keyup none

During composition I think beforeinput isn't cancelable as implemented (try typing ¨ in the demo), and keypress isn't fired.

The spec also says that compositionupdate and compositionend are not cancelable, but in Chrome and Safari they are. In Firefox they are not cancelable, and compositionstart is also not cancelable.

zcorpan commented 8 months ago

I forgot about keypress.

https://software.hixie.ch/utilities/js/live-dom-viewer/saved/12264

The spec says:

The keypress event type MUST be dispatched after the beforeinput event and before the input event associated with the same key.

https://w3c.github.io/uievents/#keypress-event-order

However Chrome, Safari, Firefox all fire keypress right after keydown when typing "a" in <input> or contenteditable element.