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

Here's an idea that seems to work, although I'm not sure it can be implemented.

If scoped registries were to define a sub-class of the passed component, adding to it a reference to the registry, it would allow the HTMLElement constructor to identify the registry on which the component is registered. 

```
let preSuperCalled = false;
let preSuperComponent;
let postSuperCalled = false;
let postSuperComponent;

const $registry = Symbol('[[Registry]]');

class CustomElementRegistry {
  #registry = {}

  constructor(name) {
    this.registryName = name;
  }

  define(name, Component) {
    if (customElements === this) {
      this.#registry[name] = Component;
    } else {
      this.#registry[name] = class extends Component {
        static [$registry] = registry;
      }
    }
  }

  get(name) {
    return this.#registry[name];
  }
}

const customElements = new CustomElementRegistry('global');

// HTMLElement has a default registry field
class HTMLElement {
  static [$registry] = customElements;

  constructor(name) {
    console.log(`Component "${name}" on registry "${this.constructor[$registry].registryName}"`);
  }
}

class ReentryByDirectCall extends HTMLElement {
  constructor(name) {
    if (!preSuperCalled) {
      preSuperCalled = true;
      preSuperComponent = new ReentryByDirectCall('pre-component');
    }
    super(name);

    if (!postSuperCalled) {
      postSuperCalled = true;
      postSuperComponent = new ReentryByDirectCall('post-component');
    }
  }
}

customElements.define('test-element', ReentryByDirectCall);

let registry = new CustomElementRegistry('custom');

registry.define('shadow-test-element', ReentryByDirectCall);

new (registry.get('shadow-test-element'))('shadow-custom-component');
```

[Working codepen.](https://codepen.io/chalbert/pen/QWVGjOW?editors=0012)

This works for components created from constructor both pre and post super() call.

------ 

The downside would be that if the constructor is accessed from within a custom-scoped component, it will not be the original constructor but the subclassed one. Or maybe that could become a feature as it could be useful to know if a custom element is used on the global registry or a custom one.

Looking forward to using scoped registries!

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

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

Received on Sunday, 26 February 2023 13:57:00 UTC