[WICG/webcomponents] Please, PLEASE, do not allow custom elements to be upgraded in scoped `ShadowRoot` registries. (Issue #960)

Needing to handle pre-upgrade properties and values for custom elements whose instances are used before they are upgraded requires hideous difficult-to-read code.

Pre-upgrade values are the _bane_ of custom elements, if not a nightmare. They are the single most difficult aspect of writing custom elements and I keep seeing people encounter issues with **all the time**.

Even after _years_ of writing custom elements, I still encounter issues myself.

---

I think it would be much better if we did something like the following ideas:

- when calling `scopedRegistry.define('some-element', SomeClass)`, an error is thrown and the call fails if any elements with the name `some-element` already exist in the ShadowRoot
- using `cloneNode()` on a template that contains custom elements should throw an error when an element would be created without being upgraded
  - Perhaps `cloneNode()` can accept a new arg that allows specifying which registry to using during the clone process, f.e. `cloneNode({ deep: false, registry: scopedRegistry })`
- `document.createElement` would have a new `registry` option, although the existing without such option can't be changed. Framework authors can opt into doing `document.createElement(..., {registry: someRegistry})` (and similar with `cloneNode`) in which case errors can be thrown on undefined elements.
- An alternative to `shadowRoot.innerHTML` should throw if the parsing encounters an unknown custom element
- We should provide new APIs that encourage good defaults. For example, `ShadowRoot.createElement()` should throw on unknown elements, and we can add APIs like `ShadowRoot.cloneElement(elementToClone)` (also `element.scope.cloneElement(element)`) to clone elements with the error-throwing defaults (as alternative to `cloneNode`), etc
- To simplify things, we can add a new option to `attachShadow`, f.e. `el.attachShadow({ allowUnknown: false })` that will cause all of a the `ShadowRoot`'s APIs (even existing ones like `innerHTML` that we otherwise can't break) to throw errors when they'd otherwise create unknown elements. 
- I'm not sure what to do with declarative shadow roots, but my hunch is that their processing would remain the same, including instantiating unknown elements, but an error would be thrown the moment a developer tries to access them (using any old APIs with new options, old APIs under the new attachShadow allowUnknown:false option, or new ShadowRoot APIs).
  - For example, parsing could create the ShadowRoots including their sub trees, but something like `shadowRoot.querySelector()` or `shadowRoot.firstElementChild` would throw if they were to return an unknown element.
  - If the user doesn't touch any APIs that would return a non-upgraded element, no error is thrown, therefore rendering still works, and any pre-existing Document or ShadowRoot APIs would continue to be backwards compatible.
- etc

By "unknown element" I mean any element that has a hyphen in its named that would otherwise be a custom element if the registry it participates in had the defined class for that name.

In other words, apart from top level `customElements` and existing `document` and `ShadowRoot` APIs which we can't break, it should otherwise be impossible to get an instance of a custom element that is not upgraded; errors should always be thrown in any possible case that creates unknown element instances; and all current APIs should gain an option that allows them to throw any time they would create an unknown element.

---

This would _**greatly**_, I mean **_vastly_**, improve the developer experience for custom element authors, and even for authors of major well-known frameworks that, to this day (Jul 3, 2022), I see dealing with this stuff. In fact, authors of major frameworks

I can't tell you how much time I've spent dealing with pre-upgrade issues! The cost of that lost time is at least in the thousands, but more importantly it's an _annoying_ and _frustrating_ thing I don't want to spend any time on at all.


---

@justinfagnani The [explainer](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md) does not mention any changes that are similar to what I described above; there is a potential here to greatly reduce developer code complexity.

---

Related:

https://github.com/WICG/webcomponents/issues/922

https://github.com/WICG/webcomponents/issues/923

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

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

Received on Sunday, 3 July 2022 16:02:39 UTC