Skip to content

customElementRegistry.initialize should provoke custom elements to upgrade #1408

@sorvell

Description

@sorvell

What is the issue with the DOM Standard?

Calling registry.initialize should provoke custom elements to upgrade. Currently, it does not do so and this can lead to a custom element being in a confusing hard to reason about state.

The fact that custom elements can be in multiple states (e.g. defined or not, upgraded or not) is an inherent complexity, especially when compared to platform elements. It is never desirable for an element that has a valid definition to be in an un-upgraded state. To avoid this, developers must always remember to call registry.upgrade or the tree is left in a confusing state after calling registry.initialize. Consider this simple case:

<x-host id="host">
  <template shadowrootmode="open" shadowrootcustomelementregistry>
    <x-child id="child"></x-child>
  </template>
</x-host>
const registry = new CustomElementRegistry();
registry.define('x-child', XChildElement);
// child is *not* upgraded by initialize()
registry.initialize(host.shadowRoot); 
console.assert(child.customElementRegistry === registry) // true
console.assert(child.customElementRegistry.get(child.localName) !== undefined) // true
console.assert(child.isConnected === true) // true
console.assert(child.matches(':defined')) // false
// child is upgraded by upgrade()
registry.upgrade(host.shadowRoot); 
// *or* or child is upgraded by connection...
child.parentNode.append(child)
console.assert(child.matches(':defined')) // true

The confusion stems from the fact that if an element has a valid definition and is connected, before the introduction of scoped registries, a developer could expect it would be defined. Now, this is not the case, and the fact that subsequently re-connecting the element can cause it to become defined is behavior that is hard to reason about without full knowledge of the lifecycle of the element.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions