Skip to content
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

Add Scoped Custom Element Registries #1341

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

annevk
Copy link
Member

@annevk annevk commented Dec 17, 2024

Please do not comment directly on this PR unless asked. It's a big change and we want to keep it manageable. Use #1339 instead.

HTML PR: whatwg/html#10869.

Tests: web-platform-tests/wpt#50790.

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


Preview | Diff

annevk added a commit to whatwg/html that referenced this pull request Dec 17, 2024
Do not comment directly on this PR while it is in draft state. Use #10854 instead.

DOM PR: whatwg/dom#1341.

Tests: ...
@annevk annevk marked this pull request as ready for review December 19, 2024 09:51
@annevk annevk added topic: custom elements Relates to custom elements (as defined in DOM and HTML) addition/proposal New features or enhancements topic: shadow Relates to shadow trees (as defined in DOM) topic: nodes labels Dec 19, 2024
@annevk annevk force-pushed the annevk/scoped-custom-element-registries branch from 66f3a02 to dacf095 Compare December 19, 2024 10:05
annevk added a commit to whatwg/html that referenced this pull request Dec 19, 2024
@annevk annevk force-pushed the annevk/scoped-custom-element-registries branch from dacf095 to 7e04bae Compare February 21, 2025 09:40
annevk added a commit to whatwg/html that referenced this pull request Feb 21, 2025
@annevk annevk linked an issue Feb 26, 2025 that may be closed by this pull request
@annevk annevk linked an issue Feb 26, 2025 that may be closed by this pull request
4 tasks
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Feb 28, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Feb 28, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this pull request Feb 28, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this pull request Feb 28, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Mar 1, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860

UltraBlame original commit: 4a4c1689ebd912108057f71fa24393009d4ab18a
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Mar 1, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925

UltraBlame original commit: 78ef3074b0082c9e95d840a8010b34661973a847
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Mar 1, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860

UltraBlame original commit: 4a4c1689ebd912108057f71fa24393009d4ab18a
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Mar 1, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925

UltraBlame original commit: 78ef3074b0082c9e95d840a8010b34661973a847
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Mar 1, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860

UltraBlame original commit: 4a4c1689ebd912108057f71fa24393009d4ab18a
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Mar 1, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925

UltraBlame original commit: 78ef3074b0082c9e95d840a8010b34661973a847
jamienicol pushed a commit to jamienicol/gecko that referenced this pull request Mar 5, 2025
…nly (and invert its value), a=testonly

Automatic update from web-platform-tests
DOM: rename importNode()'s deep to selfOnly (and invert its value)

Part of whatwg/dom#1341.

--

wpt-commits: 5bcf44cb07a74e284893af96926d932ec09705e7
wpt-pr: 50860
jamienicol pushed a commit to jamienicol/gecko that referenced this pull request Mar 5, 2025
…ith scoped registries, a=testonly

Automatic update from web-platform-tests
DOM: createElement and createElementNS with scoped registries

For whatwg/dom#1341.
--

wpt-commits: a52f97983743aae5fdd5172c9938b47743dc7146
wpt-pr: 50925
annevk added a commit to whatwg/html that referenced this pull request Mar 6, 2025
otherwise null.
</dl>

<p>The <dfn attribute for=DocumentOrShadowRoot><code>customElementRegistry</code></dfn> getter steps

Choose a reason for hiding this comment

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

Are there setter steps for shadow roots with keep custom element registry null set to true?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, you have to use the initialize() API.

<p><a for=/>Shadow roots</a> have an associated
<dfn for=ShadowRoot>keep custom element registry null</dfn> (a boolean). It is initially false.

<p class=note>This can only ever be true in combination with declarative shadow roots. And it only

Choose a reason for hiding this comment

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

Are there any cases where we want to be able to programmatically create shadow roots that emulate declarative shadow roots with a null registry?

I think this might be the first instance where we can't imperatively make a shadow root that matches a declarative shadow root. That should be an issue for polyfilling (true polyfills after some browsers have shipped) things for DSD.

For instance, to polyfill this feature, we would need to prevent declarative shadow roots from using the global registry. So we would have to emit on the server templates with an alternate shadowrootmode attribute, and imperatively instantiate the shadow roots, and record the fact that it had shadowrootcustomelementregistry attribute.

If a future feature required a similar technique, then either we'd need to be able to set this option when creating the shadow root or be able to set a shadow root's registry to null.

Copy link
Member Author

Choose a reason for hiding this comment

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

You already can't create all declarative shadow roots. Only declarative shadow roots have the declarative bit set, for instance.

Copy link
Member

@foolip foolip left a comment

Choose a reason for hiding this comment

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

Note to self: editorial review done up the "Elements have an associated" bit.

@@ -2830,9 +2830,22 @@ before a <var>child</var>, with an optional <i>suppress observers flag</i>, run
<li><p>Run the <a>insertion steps</a> with <var>inclusiveDescendant</var>.

<li>
<p>If <var>inclusiveDescendant</var> is <a>connected</a>:
<p>If <var>inclusiveDescendant</var> is <a>connected</a> and is an <a for=/>element</a>:
Copy link
Member

Choose a reason for hiding this comment

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

In order to simplify the conditions, how about a "If inclusiveDescendant is not connected, continue." step before this?

null, then set <var>inclusiveDescendant</var>'s <a for=Element>custom element registry</a> to
the result of <b>looking up a custom element registry</b> given
<var>inclusiveDescendant</var>'s <a for=tree>parent</a>.
<!-- XXX xref -->
Copy link
Member

Choose a reason for hiding this comment

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

Is the idea to land both PRs and then wait until HTML is scraped into Bikeshed's data files before updating DOM to fix these refs?

How about adding to <pre class=anchors> or something to get it right when it first lands?

Comment on lines +2867 to +2868
<li><p>If <li><var>inclusiveDescendant</var>'s <a for=ShadowRoot>custom element registry</a>
is null and <li><var>inclusiveDescendant</var>'s
Copy link
Member

Choose a reason for hiding this comment

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

Accidental list items here:

Suggested change
<li><p>If <li><var>inclusiveDescendant</var>'s <a for=ShadowRoot>custom element registry</a>
is null and <li><var>inclusiveDescendant</var>'s
<li><p>If <var>inclusiveDescendant</var>'s <a for=ShadowRoot>custom element registry</a>
is null and <var>inclusiveDescendant</var>'s

are:

<ol>
<li><p class="XXX">Handle the document node case.
Copy link
Member

Choose a reason for hiding this comment

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

I know this is unfinished, but how will this work, what's it for? Documents don't have a custom element registry now, and initialize() doesn't accept a Document argument.

Comment on lines +4610 to +4611
<dfn export for="clone a node"><var>parent</var></dfn> (default null), and null or a
{{CustomElementRegistry}} object <dfn export for="clone a node"><var>fallbackRegistry</var></dfn>
Copy link
Member

Choose a reason for hiding this comment

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

Similar to the style suggestion in the HTML PR:

Suggested change
<dfn export for="clone a node"><var>parent</var></dfn> (default null), and null or a
{{CustomElementRegistry}} object <dfn export for="clone a node"><var>fallbackRegistry</var></dfn>
<dfn export for="clone a node"><var>parent</var></dfn> (default null), and a
{{CustomElementRegistry}}-or-null <dfn export for="clone a node"><var>fallbackRegistry</var></dfn>

<ol>
<li><p>Let <var>registry</var> be null.

<li><li>Let <var>is</var> be null.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<li><li>Let <var>is</var> be null.
<li><p>Let <var>is</var> be null.


<ol>
<li><p>If <var>options</var>["{{ElementCreationOptions/customElementRegistry}}"]
<a for=map>exists</a>, then set <var>registry</var> to it.
Copy link
Member

Choose a reason for hiding this comment

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

I haven't seen this short and sweet "set x to it" style before, but I like it!

<var>is</var> to it.
</ol>

<li><p>If <var>registry</var> is non-null and <var>is</var> is non-null, then <a>throw</a> a
Copy link
Member

Choose a reason for hiding this comment

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

Move this inside the if statement since it's impossible otherwise?

<var>node</var>'s <a for=tree>descendants</a>.

<p>If <var>options</var>'s {{ImportNodeOptions/customElementRegistry}} can be used to set the
Copy link
Member

Choose a reason for hiding this comment

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

The leading "If" seems like copypasta. This isn't great either but some change is needed:

Suggested change
<p>If <var>options</var>'s {{ImportNodeOptions/customElementRegistry}} can be used to set the
<p><var>options</var>'s {{ImportNodeOptions/customElementRegistry}} can be used to set the

@@ -6094,12 +6232,26 @@ It is initially set to false.</p>
<p><a for=/>Shadow roots</a> have an associated <dfn for=ShadowRoot>serializable</dfn> (a boolean).
It is initially set to false.</p>

<p><a for=/>Shadow roots</a> have an associated <dfn for=ShadowRoot>custom element registry</dfn>
Copy link
Member

Choose a reason for hiding this comment

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

Say that it is initially null?

Copy link
Member

@foolip foolip left a comment

Choose a reason for hiding this comment

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

Editorial review done.

@@ -6499,6 +6678,26 @@ null), and boolean <var>synchronousCustomElements</var> (default false):
<li><p>Return <var>result</var>.
</ol>

<p>To <dfn>create an element internal</dfn> given a <a for=/>document</a> <var>document</var>, an
Copy link
Member

Choose a reason for hiding this comment

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

I actually am not sure what effect the noexport attribute has, but it's used elsewhere in DOM for spec-internal stuff, so:

Suggested change
<p>To <dfn>create an element internal</dfn> given a <a for=/>document</a> <var>document</var>, an
<p>To <dfn noexport>create an element internal</dfn> given a <a for=/>document</a> <var>document</var>, an

Also, I first thought this might be related to ElementInternals, so a name like "internal create element steps" or "inner create element steps" would help avoid that. Not a big deal though.


<li><p>Assert: <var>result</var>'s <a for=Element>custom element state</a> and
<a for=Element>custom element definition</a> are initialized.
<li><p><a for=map>Set</a> the <a>surrounding agent</a>'s
Copy link
Member

Choose a reason for hiding this comment

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

It's very hard to follow the diff here inside "create an element", so for any other reviews, I think the main things are:

  • Refactoring to use a "creating an element internal" helper, which takes the registry as an argument.
  • A bunch of steps nested one more level under "Run these steps while catching any exceptions", ending with the added "Set result’s custom element registry to registry."

Basically searching for "registry" within the steps shows the interesting stuff.

And I can't find anything wrong :)

a boolean <var>serializable</var>, a boolean <var>delegatesFocus</var>, and a string
<var>slotAssignment</var>:
a boolean <var>serializable</var>, a boolean <var>delegatesFocus</var>, a string
<var>slotAssignment</var>, and null or a {{CustomElementRegistry}} object <var>registry</var>:
Copy link
Member

Choose a reason for hiding this comment

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

If you like this style, here it is again:

Suggested change
<var>slotAssignment</var>, and null or a {{CustomElementRegistry}} object <var>registry</var>:
<var>slotAssignment</var>, and a {{CustomElementRegistry}}-or-null <var>registry</var>:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: custom elements Relates to custom elements (as defined in DOM and HTML) topic: nodes topic: shadow Relates to shadow trees (as defined in DOM)
Development

Successfully merging this pull request may close these issues.

Revamped Scoped Custom Element Registries (DOM side) Revamped Scoped Custom Element Registries
3 participants