marcstraube / marcstraube/zappzarapp-node-browser-utils

fix(keyboard): ignoreEditableTargets misses inputs inside open Shadow DOM

Open
#166 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Summary

ignoreEditableTargets (added in #164) reads event.target to decide whether focus is in an editable element. For events that cross an open Shadow DOM boundary, the browser retargets event.target to the shadow host, so a document-bound shortcut listener sees the host element — not the <input> the user is typing in. The shortcut can therefore still fire (and preventDefault) while typing into an input nested inside a web component's shadow root.

Reproduction (real browser)

<my-editor>
  #shadow-root (open)
    <input>
</my-editor>

With ShortcutManager.on(KeyboardShortcut.key('r'), rotate, { ignoreEditableTargets: true }):

  • typing r in the <input>event.target at the document listener is <my-editor>isEditableTarget returns false → the shortcut fires. Expected: skipped.

Proposed fix

Resolve the deepest target via event.composedPath()[0] instead of event.target in the dispatch path before calling isEditableTarget. In the non-shadow case composedPath()[0] === event.target, so the change is behavior-neutral there.

Caveats to handle:

  • Closed shadow roots: composedPath() excludes their internal nodes and yields the host — the best obtainable signal; document the residual gap.
  • noUncheckedIndexedAccess: composedPath()[0] is typed EventTarget | undefined; widen isEditableTarget's parameter accordingly (the instanceof Element guard already handles undefined).

Why this is a separate issue

It cannot be covered by the current happy-dom unit tests — happy-dom does not retarget shadow-boundary events (it already exposes the inner <input> as event.target), so the bug is neither reproducible nor coverable there. Closing this properly needs real-browser test infrastructure (e.g. Playwright), which the repo does not yet have. Adding that harness is part of the work here.

Acceptance criteria

  • A bare-key shortcut with ignoreEditableTargets: true does not fire while typing in an <input> nested in an open shadow root.
  • No regression for light-DOM editable-target detection.
  • Real-browser test coverage for the shadow-DOM case.

Context

Documented as a known limitation in documentation/keyboard.md. Follow-up to #164.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ignoreEditableTargets dispatch path and isEditableTarget implementation, then review documentation/keyboard.md and the existing happy-dom tests. Add the real-browser test infrastructure described in the issue and verify the shadow-DOM, light-DOM, and closed-shadow-root acceptance criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, testing-qa, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.