Skip to content

Reference Target: Rethinking attribute reflection for invalid reference targets #1114

Open

Description

@alice

In #1071 there was some consensus that getters for IDL attributes which refer to an element with an invalid reference target should return null:

<label id="example-label" for="fancy-input">Example</label>
<fancy-input id="fancy-input">
  <template
   shadowrootmode="closed"
    shadowrootreferencetarget="real-input"
  >
    <div>
      <!-- In this example, there is nothing with the ID "real-input" in the shadow tree -->
    </div>
  </template>
</fancy-input>

<script>
const label = document.getElementById('example-label');
console.log(label.control); // << What does this log?

When writing the relevant spec language, I assumed this also referred to settable IDL attributes like popovertarget, i.e.:

<button popoverTarget="myPopover">Open popover</button>
<my-popover id="myPopover">
  <template
      shadowRootMode="closed"
      shadowRootReferenceTarget="BROKEN">
    <div popover>The real popover target</div>
  </template>
</my-popover>
console.log(button.popoverTarget);  // logs null

The getter steps are:

Let candidate be the result of running this's get the attr-associated element.

Return the result of retargeting candidate against this.

where get the attr-associated-element requires resolving the reference target:

The steps to resolve the reference target on an element element are:

  1. If element does not have a shadow root, or element's shadow root's reference target is null, return element.

  2. Let referenceTargetValue be the value of element's shadow root's reference target.

  3. Let candidate be the first element in element's shadow root whose ID matches referenceTargetValue.

  4. If no such element exists, return null.

  5. Return the result of resolving the reference target on candidate.

meaning that if the reference target is invalid, the getter would return null, even if the attr-associated element not taking reference target into account was non-null.

However, after the discussion in whatwg/html#11577, particularly around validation, I'm wondering whether it might make sense to have a shallower algorithm for the IDL attribute getters, essentially equivalent to the current algorithm.

Activity

  1. annevk commented on Oct 10, 2025

    @annevk
    Collaborator

    I think developer tools should expose "validity" (I think this term is rather confusing, but I can't immediately think of something better).

    I wonder to what extent it's useful for web developers in API form. And even then we couldn't tell them much due to encapsulation. Arguably telling them anything violates encapsulation to some extent.

    Making the getter more often return the value you passed to the setter seems like a win to me as well.

    The caveat to all this is that generally HTML getters do return the computed value where possible. But I think in this case we can't usefully return the computed value due to encapsulation and custom element initialization being dynamic. So I think that argues for returning the maybe shadow host always.

  2. alice commented on Oct 11, 2025

    @alice
    MemberAuthor

    I think developer tools should expose "validity" (I think this term is rather confusing, but I can't immediately think of something better).

    I think developer tools should definitely have a way of exposing the computed attr-associated element which is used internally, at the very least. Might that be enough for expressing "validity" in this instance, or do you also think we need a coarser, squiggly-line/other error indicator type of UI?

    The caveat to all this is that generally HTML getters do return the computed value where possible.

    I think you could make an argument that this is as much (or as little) the computed value as something like el.htmlFor is. I think most getters which return elements and pre-date element reflection are read-only?

  3. annevk commented on Oct 13, 2025

    @annevk
    Collaborator

    If you know the computed element that's prolly sufficient. (I have forgotten as to whether the computed element can be nonsensical, but even then you can probably quickly determine why that would not work.)


    Those which return elements are typically read-only, but I was talking about getters more generally.

  4. dandclark commented on May 19, 2026

    @dandclark
    Contributor

    I don't have strong feelings on this either way, but a piece of precedent that I think points in the direction of returning null for invalid reference targets is that the getters already do the validation that the attr-associated element is a descendant of any of the element's shadow-including ancestors:

    <button popoverTarget="myPopover">Open popover</button>
    <my-popover id="myPopover">
      <template shadowRootMode="open">
        <div popover>The real popover target</div>
      </template>
    </my-popover>
    <script>
      const button = document.querySelector("button");
      const div = document.querySelector("my-popover").shadowRoot.querySelector("div[popover]");
      button.popoverTargetElement = div; // Won't be a real association; div is not a descendant of any of button's shadow-including ancestors
      button.popoverTargetElement; // logs null
    </script>

    Following the reference target to see if it's valid seems similar to me.

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