Skip to content

Hotkeys are fired when trying to type into a text field inside a custom element #123

Open

Description

@kolaente

When typing in an input (textarea, input tag, editable, …) which is itself placed inside of a custom html element, the hotkey is still fired. That's because the isFormField handler checks only the target element, which is this case is the custom element. It should instead use the explicitOriginalTarget property, since that contains the actual input element.

Here's a minimal reproduction: https://jsfiddle.net/zm7etdh3/

Activity

  1. kolaente commented on Mar 12, 2024

    @kolaente
    Author

    My initial attemt for a fix:

    diff --git a/dist/index.js b/dist/index.js
    index b6e6e0a6864cb00bc085b8d4503a705cb3bc8404..91a107f0e562f68baac0f71f83cef93f0178076d 100644
    --- a/dist/index.js
    +++ b/dist/index.js
    @@ -368,10 +368,10 @@ const sequenceTracker = new SequenceTracker({
     function keyDownHandler(event) {
         if (event.defaultPrevented)
             return;
    -    if (!(event.target instanceof Node))
    +    const target = (event.explicitOriginalTarget || event.originalTarget) || event.target;
    +    if (!(target instanceof Node))
             return;
    -    if (isFormField(event.target)) {
    -        const target = event.target;
    +    if (isFormField(target)) {
             if (!target.id)
                 return;
             if (!target.ownerDocument.querySelector(`[data-hotkey-scope="${target.id}"]`))
    @@ -385,7 +385,6 @@ function keyDownHandler(event) {
         sequenceTracker.registerKeypress(event);
         currentTriePosition = newTriePosition;
         if (newTriePosition instanceof Leaf) {
    -        const target = event.target;
             let shouldFire = false;
             let elementToFire;
             const formField = isFormField(target);

    Unfortunately, this works only in Firefox, because the explicitOriginalTarget does not exist in Chromium based browser. I haven't found an equivalent.

    What do you think about disabling hotkeys altogether when the keydown event originated from a custom element?

  2. keithamus commented on Mar 12, 2024

    @keithamus
    Contributor

    We could change the check to something like event.composedPath().some(isFormField) - that would work for open shadowroots, but not closed ones.

  3. kolaente commented on Mar 12, 2024

    @kolaente
    Author

    Isn't the shadow root open anyways when the event target is the custom element?

  4. keithamus commented on Mar 12, 2024

    @keithamus
    Contributor

    If you change the mode: 'open' to mode: 'closed' then it won’t be, and the composedPath will exclude items from the ShadowDOM, but that’s probably fine - there isn’t much we can do about it.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions