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

Event order between "compositionend" and "input" #202

Open
masayuki-nakano opened this issue Apr 21, 2018 · 29 comments
Open

Event order between "compositionend" and "input" #202

masayuki-nakano opened this issue Apr 21, 2018 · 29 comments

Comments

@masayuki-nakano
Copy link

masayuki-nakano commented Apr 21, 2018

Currently, UI Events declares event order of "compositionend" and "input" as:

  1. beforeinput
  2. (compositionupdate)
  3. input
  4. compositionend
  5. (no input)

At https://w3c.github.io/uievents/#events-composition-input-events

However, Firefox and Edge's order is:

  1. (beforeinput not yet supported on them)
  2. (compositionupdate)
  3. (no input)
  4. compositionend
  5. input

I.e., "input" event is fired after "compositionend".

On the other hand, Chrome and Safari dispatches as the spec declared.

I tried to make Firefox take the same event order as the draft in https://bugzilla.mozilla.org/show_bug.cgi?id=1305387. However, after changing the order, I needed following change in some places even in Firefox's UI: https://hg.mozilla.org/try/rev/9dbba7ff1d6f7f72a33dccc93fdda60f04d9942e

Then, I feel that the event order of Chrome, Safari and the spec does not make sense for web application developers. The reason is, if all browsers use the event order of Firefox and Edge, isComposing value of "input" event becomes false. So, if a web application needs to do something at every input except during composition, web application needs to listen to only input event if it's run on Firefox or Edge. I.e., can be implemented like:

foo.addEventListener("input", (event) => {
  if (event.isComposing) {
    // Nothing to do during composition
    return;
  }
  // Do something what you need.
});

On the other hand, it's run on Chrome or Safari, needs to be implemented like:

function onInput() {
  // Do something what you need.
}
foo.addEventListener("input", (event) => {
  if (event.isComposing) {
    // Nothing to do during composition
    return;
  }
  onInput();
});
foo.addEventListener("compositionend", (event) => {
  // Need to run "input" event handler here because "input" event whose isComposing is false
  // won't be fired until user inputs something without IME later. 
  onInput();
});

I believe that the behavior of Chrome, Safari and UI Events may make web applications not aware of IME.

From point of view of browser developer, this behavior is easier to implement actually since browser does not check whether it's followed by compositionend event when it tries to fire "input" event at every composition change. However, usefulness for web application developers must be more important than easier to implement by browsers.

What do you think, @garykac ?

@masayuki-nakano
Copy link
Author

So, I think that isComposing of "beforeinput" followed by "compositionend" should be true, but isComposing of "input" event caused by committing composition should be false.

@Jessidhia
Copy link

The problem with this is that you cannot detect anymore whether the input that caused compositionend to happen was itself done while composing.

@birtles
Copy link
Contributor

birtles commented Jun 26, 2018

The problem with this is that you cannot detect anymore whether the input that caused compositionend to happen was itself done while composing.

Is there a particular use case you have in mind where you need to make this distinction?

@masayuki-nakano
Copy link
Author

Another possible solution is, UI Events would change the declaration of InputEvent.isComposing.

It's currently declared as "true if the input event occurs as part of a composition session, i.e., after a compositionstart event and before the corresponding compositionend event.", however, if it's declared as the value of input events which are fired for committing composition is set to false, web apps need to check only input events whose isComposing is false (like running on Firefox and Edge).

@birtles
Copy link
Contributor

birtles commented Jul 24, 2018

@Kovensky What do you think of the proposal that we match the order of WebKit/Blink (and now the spec) but make the last input event before the compositionend event, have isComposing be set to false?

I think that would allow making the distinction you mentioned and, like @masayuki-nakano mentions, would mean that for many apps that want to ignore input during composition, they can simply ignore input events when isComposing is true without having to track state using compositionstart and compositionend.

@garykac?

@Jessidhia
Copy link

I remember having issues with Japanese IME input because the Enter key is typically what is used to trigger compositionend, but if it comes with isComposing: false, I can no longer tell if that Enter key was used to exit composition or to actually write a new line.

This was a few months ago, though, I don't remember if/how that was dealt with.

@birtles
Copy link
Contributor

birtles commented Jul 25, 2018

That's a fair point. I hadn't thought about multi-line input so much.

So with the proposal to make isComposing false for the last input event before the (last?) compositionend the author:

  • will no longer need to track compositionstart / compositionend in order to ignore inputs while composing, but
  • will need to track compositionstart / compositionend in order to differentiate between an input that commits part of the composition, and an input that is not part of composition.

Does that sound right?

(I'm actually a bit confused now about if this proposal works in light of multiple compositionend events. The IMEs I use on Linux and Windows don't allow committing part of a composition string so I never get more than one compositionend event.)

@masayuki-nakano
Copy link
Author

Currently, DOM composition events do not support of committing a part of composition. In such case, Firefox commits existing composition first, then, restart composition with new range.

Brian, you can check this behavior even with MS-IME.

  1. Open preferences dialog
  2. Press key assign from "Microsoft IME" to "ATOK"
  3. Type something which may cause 2 or more clauses.
  4. Type Space bar to convert.
  5. Type ArrowDown key.

And also, new line key handling is not defined under UI Events unfortunately. In most cases, Enter key press during composition of Japanese IME just commits composition. However, for example, Enter key press during composition of Korean IME causes both committing composition and inserting a new line. If all browsers support beforeinput, the new line input can be represented with it which should be fired immediately after compositionend. However, now, Firefox dispatches a set of key events (i.e., keydown, keypress and keyup events) after compositionend on Windows, and dispatches only keypress event after compositionend on macOS. So, this issue should be out of scope of this.

@birtles
Copy link
Contributor

birtles commented Aug 3, 2018

Currently, DOM composition events do not support of committing a part of composition. In such case, Firefox commits existing composition first, then, restart composition with new range.

Oh, I see. The spec seems to suggest there should be no extra compositionstart:

Note that while every composition only has one compositionstart event, it may have several compositionend events.

But I notice neither Chrome nor Firefox do that.

For my reference I am testing using this pen: https://codepen.io/birtles/pen/pZwNPx

Following the stems from Masayuki for MS-IME:

  1. Open preferences dialog
  2. Press key assign from "Microsoft IME" to "ATOK"
  3. Type something which may cause 2 or more clauses.
  4. Type Space bar to convert.
  5. Type ArrowDown key.

I get in Firefox:

compositionstart (value: )
input (value: k, isComposing: true)
input (value: こ, isComposing: true)
input (value: こr, isComposing: true)
input (value: これ, isComposing: true)
input (value: これh, isComposing: true)
input (value: これは, isComposing: true)
input (value: これはt, isComposing: true)
input (value: これはて, isComposing: true)
input (value: これはてs, isComposing: true)
input (value: これはてす, isComposing: true)
input (value: これはてすt, isComposing: true)
input (value: これはてすと, isComposing: true)
input (value: これはテスト, isComposing: true)
compositionend (value: これは)
input (value: これは, isComposing: false)
compositionstart (value: これは)
input (value: これはテスト, isComposing: true)
compositionend (value: これはテスト)
input (value: これはテスト, isComposing: false)

In Chrome:

compositionstart (value: )
input (value: k, isComposing: true)
input (value: k, isComposing: true)
input (value: こ, isComposing: true)
input (value: こ, isComposing: true)
input (value: こr, isComposing: true)
input (value: こr, isComposing: true)
input (value: これ, isComposing: true)
input (value: これ, isComposing: true)
input (value: これ, isComposing: true)
input (value: これh, isComposing: true)
input (value: これh, isComposing: true)
input (value: これは, isComposing: true)
input (value: これは, isComposing: true)
input (value: これはt, isComposing: true)
input (value: これはて, isComposing: true)
input (value: これはて, isComposing: true)
input (value: これはてs, isComposing: true)
input (value: これはてs, isComposing: true)
input (value: これはてす, isComposing: true)
input (value: これはてす, isComposing: true)
input (value: これはてすt, isComposing: true)
input (value: これはてすt, isComposing: true)
input (value: これはてすと, isComposing: true)
input (value: これはてすと, isComposing: true)
input (value: これはテスト, isComposing: true)
input (value: これは, isComposing: true)
compositionend (value: これは)
compositionstart (value: これは)
input (value: これはテスト, isComposing: true)
input (value: これはテスト, isComposing: true)
compositionend (value: これはテスト)

Edge:

compositionstart (value: )
input (value: k, isComposing: undefined)
input (value: こ, isComposing: undefined)
input (value: こr, isComposing: undefined)
input (value: これ, isComposing: undefined)
input (value: これh, isComposing: undefined)
input (value: これは, isComposing: undefined)
input (value: これはt, isComposing: undefined)
input (value: これはて, isComposing: undefined)
input (value: これはてs, isComposing: undefined)
input (value: これはてす, isComposing: undefined)
input (value: これはてすt, isComposing: undefined)
input (value: これはてすと, isComposing: undefined)
input (value: これはテスト, isComposing: undefined)
compositionend (value: これはテスト)

If some Korean IMEs allow Enter to do double-duty as committing a composition and entering a newline then it sounds like distinguishing between the two actions is a separate matter as you say. If beforeinput lets authors recognize a genuine newline (I didn't quite understand this part but would love to know how this work) then that's even better.

So it sounds like the proposal to make the last input event before the compositionend event have isComposing be set to false could work.

@garykac
Copy link
Member

garykac commented Aug 7, 2018

Sorry for the delays responding on that issue. I've been finishing other things up and am just now starting to be able to spend more time on UIEvents.

To summarize my understanding:

  • Some web apps want to be able to ignore the intermediate input events generated during composition, but they want the final input event (effectively, they want to consider the composition as a single input action).
  • Currently this requires that the web dev listen to compositionend to know that the previous input event was the final one.
  • Proposal is to make this easier for devs by setting isComposing to false for this final input event (just for the last one before compositionend).
  • Possible concern: for web apps that want to distinguish between a final Enter that ends composition and one that adds a newline.

Regarding that last concern, I just tested this on Chrome Win and Mac with Korean and Japanese IMEs and noticed the following events after pressing Enter to accept the composition:

  • Japanese:
    • Chrome Win/Mac sends keydown / beforeinput / c-update / input / c-end / keyup to close the composition
      • The inputType for the input event is insertCompositionText
    • Firefox Windows sends c-end / input / keyup to close the composition. (inputType is not set)
    • Edge Windows sends only c-end to close the composition. (inputType is not set)
  • Korean:
    • Chrome Win/Mac sends c-update / input / c-end to close the composition and follows it with keydown / keypress / beforeinput / input / keyup for the Enter key to add a newline
      • The first inputType is insertCompositionText
    • The second inputType is insertParagraph
    • Firefox Windows sends c-end / input followed by keydown / keypress / input / keyup. (inputType is not set)
    • Edge Windows sends c-end followed up keydown / keypress / input / keyup. (inputType is not set)
  • Note: tested using https://w3c.github.io/uievents/tools/key-event-viewer-ce.html

So (from this limited testing), I don't think there's a problem with distinguishing the final Enter of a composition from the newline (esp. when inputType is set).

As for the proposal, other than it makes the spec description more complex, I don't see serious problems with it. But I also don't have a sense of how serious the original problem is.

The tradeoff we're making is between:

  • Making the spec's description more complex: "isComposing is set when composing, EXCEPT when..." (ugh)
  • Making things slightly harder for devs who need to ignore input events during composition (since they have to add an event handler for compositionend).

But it doesn't seem (to me) like it's very common to need to distinguish between input events that are inside or outside composition. The vast majority of devs won't care. The one case I can think of where someone might want to do this is for devs writing rich text editors, but I don't consider it a problem if they have to write a bit more code to get things done - they're probably handling compositionend already.

Unless there's a real dev need to fix this, I'd rather keep the definition for isComposing simple.

Note that while every composition only has one compositionstart event, it may have several compositionend events.

I was wondering where this came from (it's not in the UIEvents spec) and finally found it as a non-normative note in Input Events spec (in Step 5) (https://www.w3.org/TR/input-events-2/).

AIUI, that is wrong. compositionstart and compositionend are supposed to be matching pairs. I'm not aware of any situation where there should be multiple compositionend events in a single composition session.

The UIEvents spec says (https://www.w3.org/TR/uievents/#events-compositionevents):

Conceptually, a composition session consists of one compositionstart event, one or more compositionupdate events, and one compositionend event, with the value of the data attribute persisting between each stage of this event chain during each session.

@birtles
Copy link
Contributor

birtles commented Aug 8, 2018

Thanks for following up on this!

The tradeoff we're making is between:

  • Making the spec's description more complex: "isComposing is set when composing, EXCEPT when..." (ugh)
  • Making things slightly harder for devs who need to ignore input events during composition (since they have to add an event handler for compositionend).

That priority of constituencies here surely means we should choose the latter (i.e. devs > spec writers).

But it doesn't seem (to me) like it's very common to need to distinguish between input events that are inside or outside composition. The vast majority of devs won't care.

I disagree. @masayuki-nakano has already indicated that it is common to make this distinction in Firefox source. In my work on Web apps too, I frequently need to make this distinction. Some common examples include:

  • If you are triggering a search as the user types, you don't normally want to do that search until the string has been committed since, in the case of Japanese, you'll be searching on the hiragana instead of the kanji so it will likely be wasted work and distracting to the user.
  • If you're doing validation on data as it is typed, it's quite common that the uncommitted string will be invalid while the committed string will be valid and you don't want to annoy the user with "data invalid" UI while they're still composing. (As a concrete example, consider an app that checks an input station name is valid. While the string is uncommitted it will likely be incomplete or in hiragana but once committed it will typically be valid.)
  • If you're doing auto-save based on user input, it would likely be wasted work to save before the string is committed.

@masayuki-nakano
Copy link
Author

  • Making the spec's description more complex: "isComposing is set when composing, EXCEPT when..." (ugh)

How about: "isComposing is true when the text is still composing by composition" or something similar? I'm trying to say, when isComposing is true, its data may be updated/replaced during current composition. So, the data hasn't been fixed yet.

  • Making things slightly harder for devs who need to ignore input events during composition (since they have to add an event handler for compositionend).

I have no idea what the use-case of ignoring all input caused by composition. I suggested current isComposing but I intended to make input event useful for suggesting use-case because I didn't realize the event order difference between browsers (input vs. compositionend).

@garykac
Copy link
Member

garykac commented Aug 15, 2018

The tradeoff we're making is between:

Making the spec's description more complex: "isComposing is set when composing, EXCEPT when..." (ugh)
Making things slightly harder for devs who need to ignore input events during composition (since they have to add an event handler for compositionend).

That priority of constituencies here surely means we should choose the latter (i.e. devs > spec writers).

I phrased that poorly. My concern is not for the spec writer (who only has to write it once), but for anyone who has to read the spec. A more complex spec is more complex for anyone who has to read it or any follow-on documentation (like MDN) that are based on the spec.

But it doesn't seem (to me) like it's very common to need to distinguish between input events that are inside or outside composition. The vast majority of devs won't care.

I disagree. @masayuki-nakano has already indicated that it is common to make this distinction in Firefox source.

But needing to make this distinction in FF code isn't a good reason to expose this to the web platform.

In my work on Web apps too, I frequently need to make this distinction. Some common examples include:

  • If you are triggering a search as the user types, you don't normally want to do that search until the string has been committed since, in the case of Japanese, you'll be searching on the hiragana instead of the kanji so it will likely be wasted work and distracting to the user.
  • If you're doing validation on data as it is typed, it's quite common that the uncommitted string will be invalid while the committed string will be valid and you don't want to annoy the user with "data invalid" UI while they're still composing. (As a concrete example, consider an app that checks an input station name is valid. While the string is uncommitted it will likely be incomplete or in hiragana but once committed it will typically be valid.)
  • If you're doing auto-save based on user input, it would likely be wasted work to save before the string is committed.

These are compelling examples. Thanks for taking the time to write them up. These are good cases for motivating this change.

Would it be sufficient to phrase this as something like:
"During composition, the isComposing attribute should be true for all input events except for the final one that updates the DOM."

AUIU, if the user cancels composition, the final input would be a delete to remove the previous
candidate. I think this is fine. I can't think of any other cases that might be problematic.

Does the final beforeinput event need to have isComposing set in the same manner? My instinct is "yes, it should", but I'm open to arguments why is doesn't need to be.

@birtles
Copy link
Contributor

birtles commented Aug 16, 2018

Thanks for following up on this.

But it doesn't seem (to me) like it's very common to need to distinguish between input events that are inside or outside composition. The vast majority of devs won't care.

I disagree. @masayuki-nakano has already indicated that it is common to make this distinction in Firefox source.

But needing to make this distinction in FF code isn't a good reason to expose this to the web platform.

Yes, sorry, by FF code I meant Firefox front-end code, i.e. the JS used for the FF user interface. While it's not entirely representative of typical Web content, for the purposes of handling input events I think it's reasonably close.

Would it be sufficient to phrase this as something like:
"During composition, the isComposing attribute should be true for all input events except for the final one that updates the DOM."

I'm not familiar with the correct terminology here but that seems to match the intention at least. @masayuki-nakano does this sound right? The idea behind this language is that it then covers the cancel case too.

Does the final beforeinput event need to have isComposing set in the same manner? My instinct is "yes, it should", but I'm open to arguments why is doesn't need to be.

@masayuki-nakano what do you think about this? ↑

@masayuki-nakano
Copy link
Author

Yes, sorry, by FF code I meant Firefox front-end code, i.e. the JS used for the FF user interface. While it's not entirely representative of typical Web content, for the purposes of handling input events I think it's reasonably close.

Firefox's front-end is one of the biggest web-applications in the world even though it uses some special API to access sensitive area. So, I believe that if some spec changes make Firefox's front-end more complicated, that means that web apps in the world are also made complicated if they need to implement similar feature.

Does the final beforeinput event need to have isComposing set in the same manner? My instinct is "yes, it should", but I'm open to arguments why is doesn't need to be.

@masayuki-nakano what do you think about this? ↑

Honestly, I'm still not sure, I'm still thinking this...

From a point of view of web browser, browser has not been handled native commit event yet at dispatching beforeinput event. I.e., there is a composition in the editor. So, setting false to isComposing of beforeinput may make sense.

On the other hand, beforeinput is not useful event if there were no inputType attribute value since web apps cannot know what will happen without the attribute. So, in other words, I have no idea how web apps use only isComposing information of beforeinput.

So, most important thing is, which value can prevent bugs of web apps...

@birtles
Copy link
Contributor

birtles commented Aug 21, 2018

Today Masayuki and I discussed whether or not beforeinput should also set isComposing to false on the last event before updating the DOM. I'll summarize what I recall and Masayuki can correct me where I'm wrong.

Argument for making isComposing true:

  • I think Masayuki was originally concerned that setting it to false would lead to bugs in Web apps. For example, while in a Japanese IME the final composition string is typically equal to the committed string, in Chinese IMEs it can differ (e.g. the string being composed might be all alphabetic and at the moment it is committed, it is converted to Chinese characters).

    If Web apps are waiting for isComposing === false and then taking some action that results in the DOM being updated and the composition canceled then they might arrive at a state where the string being composed remains, and not the final string that should have been committed.

    (I'm a bit vague about this concern but hopefully Masayuki can clarify this point.)

Argument for making isComposing false:

  • beforeinput and input are a conceptual set, so if input has isComposing === false then conceptually one would expect the corresponding beforeinput event to also have isComposing === false.

  • Despite the concern mentioned above, given that the beforeinput events with inputType === 'insertFromComposition' are cancelable, there's probably no extra harm having apps trigger other actions at this point--at least from the UA's point of view, they need to be able to safely handle canceling at this point anyway.

@masayuki-nakano
Copy link
Author

(I'm a bit vague about this concern but hopefully Masayuki can clarify this point.)

No, you understand my arguing points perfectly.

So, beforeinput is NOT useful only with the fact that it's fired since beforeinput is fired before the change affects the value of focused editor. So, inputType is really important for beforeinput event listeners. I.e., I have no idea how important that isComposing is referred by beforeinput listeners. If a event listener listens both input and beforeinput events, isComposing of beforeinput may be referred. However, I have no idea what such listeners need to do.

@Jessidhia
Copy link

I ran into this again, but this time not even with input or beforeinput events, but with keydown events which is supposed to fire even earlier than beforeinput (need to watch the state of modifier keys so input events are not low level enough).

In Safari, compositionend fires even before the keydown with the Enter that commits the IME input is fired, which causes isComposing to be wrong there too. The only way I have to tell if that Enter key was actually an input to the IME is to look at the deprecated which property and check if it's 229 or 13.

@birtles birtles mentioned this issue Sep 5, 2018
@birtles
Copy link
Contributor

birtles commented Sep 5, 2018

@Kovensky I'm not sure I understand what you're suggesting here. Are you endorsing the importance of this issue or suggesting a particular value of isComposing?

@Jessidhia
Copy link

It is the importance of this issue, although this kinda looks like a Safari bug instead. The value of isComposing is true, by definition, before compositionend; the problem here is that Safari is emitting compositionend way before when it's supposed to be emitted. It's not even just that it's before input, it's happening even before keydown.

@johanneswilm
Copy link

But it doesn't seem (to me) like it's very common to need to distinguish between input events that are inside or outside composition. The vast majority of devs won't care.

Most web apps don't do text editing at all, and those 99% won't care, I agree. But what we need to look at are the 1% (or less) of devs working on editing apps. Without such editing apps, there is no content on the web so even if the percentage is low, it does matter for the web overall.

Those web apps doing text editing need to be concerned with the difference between composing and non-composing as they are prohibited from changing the DOM around the composition while it takes place. So as long as that is clearly communicated in some way, I think everything is fine.

If Web apps are waiting for isComposing === false and then taking some action that results in the DOM being updated and the composition canceled then they might arrive at a state where the string being composed remains, and not the final string that should have been committed.

If isComposing is set to false, while it really should be true and it does cause IMEs to be canceled half-way, then the web apps will stop checking that attribute and will be looking for some other indication of whether the composition has finished.

That is not really ideal as we are then moving away from the idea that you can build an editor by listening to beforeinput events and go back to the kind of patchwork that editors need to go through today.

@johanneswilm
Copy link

Some web apps want to be able to ignore the intermediate input events generated during composition, but they want the final input event (effectively, they want to consider the composition as a single input action).

I believe when we originally wrote the level 2 input events spec, our information was that the last input event may not give us information about the contents and placement of the entire composition string. And also at that start, when a composition is initiated on a pre-existing string, we would not know where that string is. This is why we added the cancelable beforeinput events with inputtypes deleteByComposition (before composition) and insertFromComposition (after composition).

Without those events, as in level 1, the only important piece of information we can listen for is when the composition has finished. Once that has happened, we diff the DOM and find out what has changed, based on that make a guess on what the user wanted to enter/delete, and then act upon that.

So unless something has changed so that one can always know where the entire string was placed based on the information of the last input event during composition and what has changed, I don't know if this is of much help to webapps.

@masayuki-nakano
Copy link
Author

Even if browser only supports Input Events Level 1 (like Firefox and Chrome), input events during composition has insertCompositionText as inputType value. Therefore, even if InputEvent.isComposing is set to false during composition, web apps can distinguish whether every change is caused by IME or not.

@aaclayton
Copy link

I came across this as a problem for my own use case where I discovered that Safari/Chrome were triggering compositionend before keydown including for the ENTER keypress which concluded composition - resulting in a KeyboardEvent where the code is "Enter" and isComposing is false - but that enter keypress was - in fact - used to conclude a composition.

I don't have the level of expertise to contribute towards a solution here, but it seems that there was some productive conversation in this thread which dried out and didn't end up leading anywhere. Is this viewed as a non-issue? What should developers be doing to avoid triggering incorrect events on keyboard events which are actually due to international character composition?

@birtles
Copy link
Contributor

birtles commented May 7, 2020

Yes, it would be good to reach consensus on this. I believe we were proposing to change the value of isComposing for input events (and perhaps beforeinput) but that will depend on how willing Chrome/Safari are to make that change.

For what it's worth I also often encounter this issue, e.g. this code which is precisely the sort of code Masayuki mentioned at this beginning of this issue.

@dandclark
Copy link

It seems like there are good arguments here for Chromium and Safari converging to Firefox's behavior and updating the spec accordingly.

@mustaqahmed, would you be the right owner for this for Chrome, or do you know who could make that call?

@annevk is this something you'd be able to comment on for Safari?

@annevk
Copy link
Member

annevk commented Jun 16, 2023

How often are these events used? I'd be a bit worried about web compatibility, but perhaps with Chromium and WebKit changing this around the same time that can be mitigated somewhat.

cc @whsieh

@mustaqahmed
Copy link
Member

@garykac: do you know who could answer the Chrome question above?

@birtles
Copy link
Contributor

birtles commented Jun 17, 2023

How often are these events used?

Pretty often. Apart from the issues linked to this one, there are plenty of blogs of people stumbling due to this, e.g.:

Just trying to distinguish an Enter keypress to commit a selection from a regular Enter keypress (e.g. to close a modal) is really hard in Safari. (The most reliable way being to use the deprecated keyCode property.)

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

9 participants