Re: [WICG/webcomponents] [scoped-registries] Interaction with HTML element's overridden constructor steps (Issue #969)

> > This isn't a thing in the current proposal. Calling constructors is only supported for the global registry
> 
> It comes back to what I was saying, unless you are sure your component will be exposed globally, using constructors is not safe anymore.

Maybe we're having a mis-communication here. I'm saying that it's not unsafe, it's specifically disallowed.

When you call `new MyElement()` an instance will be created in the global scope if MyElement is registered there, otherwise it will throw. This is true today, so constructors are no more or less unsafe than they are now.

The example you have is incomplete because it doesn't show registrations. Today for this to work, you'll need:

```ts
class A extends HTMLElement {}
customElements.define('x-a', A);

class B extends HTMLElement {
 connectedCallback() {
     this.appendChild(new A());
  }
}
customElements.define('x-b', B);
export { A, B };
```

This will work today and when scoped registries are added. Scoped registries cannot break this currently working code.

If you want it to use scoped registries, you still need registrations, and again, because calling constructors _never_ uses a scoped registry, you need to use one of the scoped element creation APIs:

```ts
class A extends HTMLElement {}
const registry = new CustomElementsRegistry();
registry.define('x-a', A);

class B extends HTMLElement {
  constructor() {
    this.attachShadow({mode: 'open', registry});
  }
  connectedCallback() {
    this.appendChild(this.shadowRoot.createElement('x-a'));
  }
}
// global registration for <x-b> is optional
customElements.define('x-b', B);
export { A, B };
```

> Wouldn't it be a good practice for libraries not to assume their component is globally defined, nor the actual tag it is defined under?

Yes, this is the practice that scoped registries are trying to enable, and the solution is for a parent element to choose the tag name that it registers dependencies under and use that tag name to create instances.

Again, we did consider an API where `CustomElements.define()` would return a scoped constructor. Based on feedback from the group, we decided to not add that in the first version and instead have constructors only work for the global scope. If we want to revisit that decision, I think that is a slightly different discussion than re-entrancy.

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

Message ID: <WICG/webcomponents/issues/969/1458648830@github.com>

Received on Tuesday, 7 March 2023 18:39:09 UTC