Mousetrap.js doesn’t properly stop callbacks for events originating from a shadow DOM

I’m experimenting with shadow DOM in a Discourse plugin I’m writing and noticed that mousetrap.js is not stopping callbacks for events that originate in the shadow DOM. For example, pressing u in an input element triggers the Discourse shortcut for history back navigation; thus, stopping me from filling out any forms.

I’m mainly adding this as a reference for people running into this in the future because it’s unlikely this can be fixed in Discourse without replacing mousetrap.js (except for monkey-patching the file).

  • Upstream issue: https://github.com/ccampbell/mousetrap/issues/245

  • Open pull request (stale, unfortunately): https://github.com/ccampbell/mousetrap/pull/254

  • Possible fix:

    Adding the following before the final return statement in Mousetrap.prototype.stopCallback.

    // Events originating from a shadow DOM are re-targetted; thus, `e.target` is not always
    // the initial event source. If the first element in the event’s composed path is not
    // the target, it has a different initial event source than `element`.
    if ('composedPath' in e && typeof e.composedPath === 'function') {
      var initialEventTarget = e.composedPath()[0];
      if (initialEventTarget !== e.target) {
        element = initialEventTarget;
      }
    }
    
4 Likes

It would be great if you could get this fixed upstream. That would make our lives a lot easier, because we use yarn for that dependency and we’d like to avoid monkey patching. Please feel free to ping us or create a PR to update our dependency when a new version with the fix has been released.

5 Likes

I asked whether they want a new pull request because I don’t want to just hijack the existing pull request although it is stale for three years. We’ll see.

3 Likes

I submitted a pull request upstream: https://github.com/ccampbell/mousetrap/pull/438

4 Likes

Oh, I just noticed that we are using a fork of mousetrap because we had to apply a patch that hasn’t been merged yet. :see_no_evil:

So, yeah, I guess you could send the pull request to our fork if there’s no reaction in the upstream project in a reasonable timeframe.

3 Likes

@kleinfreund FYI, I have merged the upstream changes on our fork of mousetrap should you wish to revisit the PR above.

2 Likes

I talked to the maintainer and asked whether they’re willing to review a pull request getting everything into order so that my initial pull request can get merged without failing tests. So I’m currently waiting for the review on those preparations. This would hopefully lay the groundwork for Discourse using the original repository as a depedency instead of maintaining a fork. I’ll get back to you once there is any relevant news.

Update: The pull request was merged and a follow-up pull request to address the issue at hand was submitted:

https://github.com/ccampbell/mousetrap/pull/445

7 Likes

The issue described in the original post is fixed in Mousetrap.js.

Since the issue that leads to Discourse maintaining a fork of Mousetrap is not addressed, yet, it would be nice if someone could update discourse/mousetrap to include the recent changes to ccampbell/mousetrap.

3 Likes

Thanks for the nudge @kleinfreund, our fork is updated and the update has been applied to core: https://github.com/discourse/discourse/commit/44523320771cfff692730d1066f95da2bb2bdb1e

5 Likes