Skip to content

Reference Target: How to handle events fired on the reference target by related elements? #1098

Open
@alice

Description

@alice

This was raised by @jakearchibald in whatwg/html#10707 (comment):

An interesting case here:

<button popovertarget="component-a"></button>
<component-a id="component-a">
  <template shadowrootmode="closed" shadowrootreferencetarget="inner-thing">
    <div id="inner-thing" popover></div>
  </template>
</component-a>

As the owner of the button, is it weird that I don't get a toggle event on component-a, despite the popover being successfully opened?

and whatwg/html#11148 (comment):

Because the problem is referenceTarget specific, a solution tailored to referenceTarget seems ok. As in, the command event (and other related events like popover toggle) can flow through retargeted boundaries.

<component-a>
  <template shadowrootmode="closed">
    <button command="--foo" commandFor="component-b"></button>
    <component-b id="component-b">
      <template shadowrootmode="closed" shadowrootreferencetarget="inner-thing">
        <div id="inner-thing"></div>
      </template>
    </component-b>
  </template>
</component-a>

In the example above, the command would be seen within component-b's shadow root, since that's where the ultimate target is, but it would also be seen in component-a's shadow root, since it was retargeted from there.

We'd need to consider cases where retargeting was between multiple shadow roots.

[We should] work on the referenceTarget-specific issues as part of that feature work. I don't think we should solve this just for command, nor should we end up having to default to composed events everywhere due to referenceTarget.


My proposal (see also #1098 (comment)):

  • Certain events get a source, which already exists on CommandEvent. We would also need to add it to:
    • SubmitEvent, which already has submitter for the same thing, so submitter could be used as an alias
    • ToggleEvent
    • The definition of the event concept, so that it can be used in algorithms, analogous to how relatedTarget is.
  • Set source to the element which causes an event to fire on another element before firing the event; some locations for where this needs to happen are listed below.
  • Modify shadow root's get the parent algorithm to:
    1. let target be event’s path’s first struct’s invocation target;
    2. if event’s composed flag is set, return shadow root’s host;
    3. if shadow root is not the root of target, and event does not have a source or shadow root is not the root of event's source, return shadow root's host;
    4. if event has a source, and event's source's root is a shadow-including ancestor of shadow root, return the result of retargeting target against event's triggering element;
    5. otherwise, return null.

Some places we'd need to modify event initialisation:


Draft PRs:
whatwg/dom#1377
whatwg/html#11349

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