Skip to content

Commit e3a8506

Browse files
committed
Describe interaction with declarative shadow DOM
1 parent 60c9f68 commit e3a8506

1 file changed

Lines changed: 39 additions & 7 deletions

File tree

proposals/Scoped-Custom-Element-Registries.md

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,41 @@ As a result, it must limit constructors by default to only looking up registrati
119119

120120
This poses a limitation for authors trying to use the constructor to create new elements associated to scoped registries but not registered as global. More flexibility can be analyzed post MVP, for now, a user-land abstraction can help by keeping track of the constructor and its respective registry.
121121

122+
## Interaction with Declarative Shadow DOM
123+
124+
[Declarative shadow DOM](https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md) allows HTML to construct shadow roots for elements from `<template>` elements with a `shadowroot` attribute.
125+
126+
Since these shadow roots are not created by a host calling `attachShadow()`, the host doesn't have a chance to pass in a scoped custom element registry. If a host is using a scoped registry, we need to force the declarative shadow root to not use the global registry and instead leave custom elements un-upgraded until the host can create and assign the correct registry.
127+
128+
To do this we add a `shadowrootregistry` attribute, according to the [declarative shadow root explainer section on additional `attachShadow()` options](https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#additional-arguments-for-attachshadow). This attribute causes the declarative shadow root to have no registry associated with it at all:
129+
130+
```html
131+
<template shadowroot="open" shadowrootregistry="">
132+
<some-scoped-element></some-scoped-element>
133+
</template>
134+
```
135+
136+
When the host is defined and upgrades with an existing shadow root, it can assign the registry:
137+
138+
```ts
139+
const registry = new CustomElementRegistry();
140+
141+
class MyElement extends HTMLElement {
142+
#internals = null;
143+
constructor() {
144+
super();
145+
this.#internals = this.attachInternals();
146+
if (this.#internals.shadowRoot) {
147+
this.#internals.shadowRoot.registry = registry;
148+
} else {
149+
this.attachShadow({mode: 'open', registry});
150+
}
151+
}
152+
}
153+
```
154+
155+
Having `ShadowRoot.prototype.registry` be settable raises the question of whether it can change over time once being set. To simplify the semantics we can restrict this to only being settable once. If it's already defined, setting is disallowed.
156+
122157
## API
123158

124159
### CustomElementRegistry
@@ -143,6 +178,10 @@ ShadowRoot adds element creation APIs that were previously only available on Doc
143178

144179
These are added to provide a root and possible registry to look up a custom element definition.
145180

181+
ShadowRoot also adds a `registry` property:
182+
183+
* `registry`: `CustomElementRegistry`
184+
146185
## Open Questions
147186

148187
### Adopted elements and Scoped Registry
@@ -154,13 +193,6 @@ There are concern about what happens when an element with a custom registry move
154193
3. create a new callback that can receive the new registry when moved. This is problematic as well because what happen when the registries are coming from another library, already created by someone else?
155194
4. find ways for implementers to preserve the original registry (ideal).
156195

157-
### Intersection with Declarative Shadow Root
158-
159-
Although these two proposals are in early stages, we need to solve the intersection semantics. There are two main issues:
160-
161-
1. if a declarative shadow root is created, elements inside that shadow should not be upgraded with the global registry. a possible solution is to add a new attribute, similar to `mode` to indicate to the parser that a custom registry is going to be eventually associated to this shadow.
162-
2. if the component is planning to reuse the instance of the declarative shadow root (which is ideal), how can the component associate that instance with a registry? this indicates that maybe the association between ShadowRoot and CustomElementRegistry cannot be defined via `attachShadow()`, and instead, something like `ElementInternals` is much more flexible.
163-
164196
## Alternatives to allowing multiple definitions
165197

166198
### More robust registration patterns

0 commit comments

Comments
 (0)