Skip to content

Conversation

@ja-y-son
Copy link
Contributor

@ja-y-son ja-y-son commented Dec 8, 2025

Introduce customelementregistry global attribute for elements as discussed in whatwg/dom#1413

(See WHATWG Working Mode: Changes for more details.)


/custom-elements.html ( diff )
/dom.html ( diff )
/index.html ( diff )
/indices.html ( diff )
/infrastructure.html ( diff )
/parsing.html ( diff )

@ja-y-son
Copy link
Contributor Author

ja-y-son commented Dec 8, 2025

@annevk Here's the PR for the new custom element registry attribute.

<code data-x="attr-customelementregistry">customelementregistry</code> attribute exists;
otherwise let <var>registry</var> be the result of
<span data-x="look up a custom element registry">looking up a custom element registry</span>
given <var>intendedParent</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need the same kind of complexity we need as for shadow roots for the same kind of scenario we discussed for them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I followed here. Could you elaborate on the complexity we need for this attribute that you mentioned above?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a separate "keep custom element registry null" flag for whatwg/dom#1423 (comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added keep custom element registry null concept for the element attribute aligning with the shadowroot counterpart. Also updated whatwg/dom#1437 to include the concept.

@Jamesernator
Copy link
Contributor

This should probably have serialization steps similar to shouldAppendRegistryAttribute for shadowrootcustomelementregistry as well.

@ja-y-son
Copy link
Contributor Author

@Jamesernator @annevk
I thought about the serialization steps, but when I read through these lines in serializing an element, I thought all attributes are serialized automatically. Am I missing something here?

For each attribute that the element has, append a U+0020 SPACE character, the attribute's serialized name as described below, a U+003D EQUALS SIGN character (=), a U+0022 QUOTATION MARK character ("), the attribute's value, escaped as described below in attribute mode, and a second U+0022 QUOTATION MARK character (").

@Jamesernator
Copy link
Contributor

Jamesernator commented Dec 10, 2025

I thought about the serialization steps, but when I read through these lines in serializing an element, I thought all attributes are serialized automatically. Am I missing something here?

Sure, but calling .createElement('x-foo', { customElementRegistry: nonGlobalRegistry }) doesn't actually set that attribute (besides it could just be removed after as well).

This actually pretty similar to the is attribute in element serialization steps too, in that an element's "is" value is not actually reflected as an attribute. Also like the is attribute we might opt not to emit it if there is already a customelementregistry attribute.

@ja-y-son
Copy link
Contributor Author

I see what you mean. Then here's an open question on serialization if we expect the attribute to be serialized on element using scoped registry I want to verify here:

<div customelementregistry><foo><bar></bar></foo></div>

const host = document.querySelector('div');
const registry = new CustomElementRegistry();
registry.initialize(host);

In this case, initialize will give foo and bar scoped registry. When we're serializing host, are we expecting to see customelementregistry attribute on foo and bar as well? It feels a bit odd since they didn't have those attribute at the first place.

@Jamesernator
Copy link
Contributor

In this case, initialize will give foo and bar scoped registry.

That depends how foo and bar were created, if they were parsed from the main document then their custom element registry would be the global one anyway so .initialize would be an effective no-op on them.

However if they didn't have a registry then yes I'd expect the change in registry would result in a change in serialization (just like any other DOM change).

@ja-y-son
Copy link
Contributor Author

ja-y-son commented Dec 11, 2025

I believe the intended behavior of cusomelementregistry attribute is that the element with such attribute and the subtree of the element should all get null registry. The foo and bar in above example should get scoped registry, and it sounds like we do want the attribute serialized for foo and bar.

What if we don’t do the initialize and left foo and bar’s registry null? Should they get the attribute during serialization as well in this case?

@Jamesernator
Copy link
Contributor

Jamesernator commented Dec 12, 2025

I believe the intended behavior of cusomelementregistry attribute is that the element with such attribute and the subtree of the element should all get null registry.

Actually that makes sense, it seems fine to avoid serializing the attribute if the registry is the same as the parent element.

What if we don’t do the initialize and left foo and bar’s registry null? Should they get the attribute during serialization as well in this case?

So I think the serialization is somewhat non-trivial, and we should also carefully consider the possibility of some kind of "declarative custom element registry" in future, with that in mind I think we should go along some lines of:

↓parent \ child→ global registry custom registry 1 custom registry 2 null
global registry no attribute attribute attribute
custom registry 1 ??? no attribute !!!attribute !!!attribute
null ??? !!!attribute !!!no attribute

Ideally we should have some story for global registry as a child of a scoped registry (??? in the table), as both it's not clear how to serialize it, and people transitioning to scoped registries will likely come across places where they need to opt-out.

As a bikeshed perhaps just:

<div customelementregistry="">
    <x-foo></x-foo>
    <div customelementregisty="global">
        <x-foo></x-foo>
    </div>
</div>

Now in the chart I've put !!! in front of entries that, while all could be omitted, may have impacts on a possible future declarative custom element registries. e.g. If in future we have something like:

<customelementregistry specifier="named">
    <define>....</define>
</customelementregistry>

<div customelementregistry="named">
    <div customelementregistry=""></div>
</div>

then those entries with !!! may need special consideration for how it would interact with such a possible feature.

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.

3 participants