Skip to content

Commit 8ef6f9f

Browse files
committed
Add scopedRegistry property
1 parent e3a8506 commit 8ef6f9f

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

proposals/Scoped-Custom-Element-Registries.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,25 @@ This poses a limitation for authors trying to use the constructor to create new
121121

122122
## Interaction with Declarative Shadow DOM
123123

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.
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 `shadowrootmode` attribute.
125125

126126
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.
127127

128128
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:
129129

130130
```html
131-
<template shadowroot="open" shadowrootregistry="">
132-
<some-scoped-element></some-scoped-element>
133-
</template>
131+
<my-element>
132+
<template shadowrootmode="open" shadowrootregistry="">
133+
<some-scoped-element></some-scoped-element>
134+
</template>
135+
</my-element>
134136
```
135137

136-
When the host is defined and upgrades with an existing shadow root, it can assign the registry:
138+
The shadow root created by this HTML will have a `null` registry, and be in a "awaiting scoped registry" state that allows the registry to be set once after creation.
139+
140+
To identify this "no registry, but awaiting one" state, ShadowRoot will have a `scopedRegistry` boolean property. `scopedRegistry` will set to `true` for all ShadowRoots with a scoped registry, or awaiting a scoped registry. Code can tell that ShadowRoot has an assignable `registry` property if `root.registry === null && root.scopedRegistry === true`.
141+
142+
Host elements with declarative scoped registries can assign the correct registry during upgrades, like so:
137143

138144
```ts
139145
const registry = new CustomElementRegistry();
@@ -143,17 +149,21 @@ class MyElement extends HTMLElement {
143149
constructor() {
144150
super();
145151
this.#internals = this.attachInternals();
146-
if (this.#internals.shadowRoot) {
147-
this.#internals.shadowRoot.registry = registry;
152+
let shadowRoot = this.#internals.shadowRoot;
153+
if (shadowRoot !== null) {
154+
if (shadowRoot.registry === null &&
155+
shadowRoot.scopedRegistry) {
156+
this.#internals.shadowRoot.registry = registry;
157+
} else {
158+
console.error(`Expected shadowRoot.scopedRegistry to be true`);
159+
}
148160
} else {
149161
this.attachShadow({mode: 'open', registry});
150162
}
151163
}
152164
}
153165
```
154166

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-
157167
## API
158168

159169
### CustomElementRegistry

0 commit comments

Comments
 (0)