Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Custom elements: "Jonas" vs "Dmitry"

The Jonas proposal is to have a normal JavaScript subclass:

class MyElement extends HTMLElement {
  constructor(htmlElementConstructorOptions, ...extraArgs) {
    // initialization code here, potentially using extraArgs for non-parser cases

The catch is that while parsing you need to do bookkeeping when you encounter custom elements (those with a dash) and then construct and insert them at a later point. This does not quite explain the platform:

  • If you iterate over the tree before such synchronization it will look weird.
  • Mutation observers will tell a rather interesting story that does not match what the parser does today.
  • Does not support asynchronous loading of custom element constructors.

The alternative is the Dmitry proposal which proposes a two-tier constructor. An element is constructed and inserted as normal and later "upgraded" to get the appropriate internal slots:

class MyElement extends HTMLElement {
  [Element.create](...extraArgs) {
    // initialization code here, potentially using extraArgs for non-parser cases

This also does not quite explain the platform:

  • Requires instantiating the internal slots through Element.create rather than the constructor.
  • Requires mutating the prototype of objects at the time of invoking Element.create.
  • Requires an extension to JavaScript (Reflect.isDefaultConstructor) that has not been vetted by TC39.

However, it has been argued that we could possibly retrofit existing elements to follow a similar design, making elements self-consistent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment