Skip to content

[DRAFT] Propagate events into the event's source's tree where appropriate. #1377

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alice
Copy link

@alice alice commented Jun 3, 2025

When an event is triggered by a source in a different tree from the target, propagate events into the source's tree
(where appropriate) so that event listeners can be added in that tree without needing to have access into the
target's tree.

  • Add the concept of a "source" for an Event.
  • Modify shadow root's "get the parent" algorithm such that events propagate into the event's source's tree where appropriate.

whatwg/html#11349 pulls the event source concept into the HTML spec.

See WICG/webcomponents#1098 for more information and worked examples.


Preview | Diff

- Add the concept of a "source" for an Event.
- Modify shadow root's "get the parent" algorithm such that events
propagate into the event's source's tree where appropriate.
@keithamus
Copy link

This concept of re-despatching on the host might have confusing consequences for developers, who will be able to observe events pointed at a target that would commonly dispatch those events, but weren't the source of this event. For example:

<button id=b>Hover me</button>
<div id=popoverA popover>
  <template shadowrootmode=open>
    <div id=popoverB popover>
    </div>
  </template>
</div>
<script>
let popoverB = popoverA.shadowRoot.querySelector('#popoverB');
b.addEventListener('mouseover', () => {
  popoverB.showPopover({source:b});
});
b.addEventListener('mouseout', () => {
  popoverB.hidePopover({source:b});
});
</script>

AIUI, In this example, when popoverB is shown it will dispatch a beforetoggle (and toggle) event on popoverB, with a source of b. The event will then also dispatch on popoverA, despite the fact that popoverA isn't being shown. Further to that, the event being dispatched on popoverA would be otherwise identical to an event that popoverA might dispatch - for example the target, source, isTrusted, composed fields etc would all be the same.

This feels like it could make it extremely difficult for developers to ascertain when an event has been dispatched because a host element has/is changed/changing state, or whether one of its shadow descendants happened to do change state and the source element is causing it to re-despatch.

I think for this to move forward it would probably need some kind of additional property on Events, like .wasOriginallyDespatchedInTheTargetsShadowButNowIsBeingRedespatchedInThisTreeBecauseYourSourceElementMightWantToKnowAboutIt. Though I'm not sold on the name; maybe it can be workshopped.

@alice
Copy link
Author

alice commented Jun 5, 2025

@jakearchibald Any thoughts?

I would note only that the same is presumably true for composed events?

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

Successfully merging this pull request may close these issues.

2 participants