Re: [WICG/webcomponents] [scoped-registries] Concerns about non-construction of scoped elements (Issue #987)

I really think we need to clarify the potential problem first before searching for a solution.

The proposal is designed as is in part to prevent breaking existing pages and components.

So:
- Globally registered constructors will create elements in the global scope, as they do today
- Constructors not registered globally will throw, as they do today. This is especially important because a constructor could be registered globally after attempted calls, and that behavior must match.
- Registering a constructor in a scoped registry will not prevent it from being registered in the global registry, so using scoped registries will not change the behavior of code using the global registry
- Inheritance of registries through the DOM hierarchy was removed form the proposal to ensure that components using the global registry aren't effected by an ancestor using scoped registries.

> > The only thing the absence of a constructor prevents is calling new ComponentA(), it doesn't prevent creating the element at all.
> 
> I'm aware of that. My point is:
> 
> Libraries can create components from constructor on global registry. A component working on the global registry won't necessarily work on a scoped registry, or could stop working in the future, unless it has been specifically designed not to use constructors.

If a library creates components with the global registry today, it will continue to work with no behavior changes, regardless of what any scoped registry does.

But this is where I'd need the risk clarified with some concrete examples. What does it mean for a library to "work on a scoped registry"?

I see two possibilities:

Are you talking about a library that calls constructors it imports? In that case it will work the same in the presences of scoped registries. Constructors you import from a module will (most likely) be either globally registered or not registered at all. I think it would be pretty unusual to export a pre-scoped constructor, though it's possible to create today (see next example).

Or, are you talking about a library that accepts arbitrary constructors and called `new` on them? Something like:

```ts
const makeElement = (ctor) => new ctor();
```

While possible, I haven't really seen this in the wild, however for this to work with scoped registries, then the caller will have to do something like:

```ts
const registry = new CustomElementRegistry();
registry.define('my-element', MyElement);
class MyScopedElement extends MyElement {
  constructor() {
    return registry.createElement('my-element');
  }
}

makeElement(MyScopedElement);
```

(I believe this will work, can you confirm in your prototype @xiaochengh?)

Yes, this is awkward, because we intentionally left open the question of how to handle scoped constructor. One of the original options was to have `define()` return a scoped constructor to make this simpler:

```ts
const registry = new CustomElementRegistry();
const MyScopedElement = registry.define('my-element', MyElement);

makeElement(MyScopedElement);
```

I think this is still an interesting option, but we didn't want to block the proposal on this given that we can add it after.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/987#issuecomment-1509440592
You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/issues/987/1509440592@github.com>

Received on Saturday, 15 April 2023 01:02:56 UTC