Re: [w3c/webcomponents] Should custom elements be adoptable if so, how? (#512)

Let's try to drive a resolution on this. I see a few possibilities.

### Proposals

#### Throw when adopting

This would make adopting a custom element throw.

The spec remains as-is for uncustomized elements (no proto swizzling), and some browsers presumably continue to not comply with it.

The main downside of this is that it's not clear whether it's safe to introduce throwing into adoption. I believe some browsers perform adoption frequently (e.g. while printing?) and won't be expecting failure.

#### Stay custom with same definition

Adopting a custom element leaves it with a custom element state of "custom". It carries with it its original custom element definition and prototype.

The spec remains as-is for uncustomized elements (no proto swizzling), and some browsers presumably continue to not comply with it.

In the future we could perhaps introduce an adoptedCallback. This is a good idea anyway to allow custom elements to have "adoption steps". (Although only one built-in element, `<template>`, uses these.) It also allows the non-compliant browsers to rationalize their behavior by saying that the default adoptedCallback equivalent for built-in elements does proto-swizzling, even if the spec does not mention that.

#### Downgrade, then maybe upgrade

Adopting a custom element "downgrades" it to have a custom element state of "undefined." It then might become inserted into a document (perhaps immediately), which might cause an upgrade, if a definition with the matching name appears in the new document. That upgrade will necessarily proto-swizzle to the new definition's prototype, and run the new definition's constructor on the (already constructed oncee) object.

With this in place we could either:
 - Leave the spec as-is for uncustomized elements (no proto swizzling).
 - Change the spec to proto-swizzle uncustomized elements (including "downgraded" custom elements, which would proto-swizzle to the new document's HTMLElement, with subsequent upgrades potentially causing another proto-swizzle).

My understanding is that some browsers will not comply with either of these two options. And both seem consistent. So if we were to go this route I guess we'd probably leave the spec as-is for uncustomized elements out of inertia.

I am not sure introducing an adoptedCallback makes sense in this world, as it's unclear whose responsibility the adoption would be: the original definition, or the new definition (or both!?). In general the idea of adoptedCallback as a way of accomplishing something similar to built-in elements' "adoption steps" doesn't make sense here because in this world the two element definitions are largely unrelated, so it's not like it's the same type of "thing" and you just need to run some steps on some internal state. Indeed, after adoption the element will have two separate sets of internal state, one from each definition.

### Thoughts and conclusions

We have to pick one of these (or something new nobody thought of; let me know). Right now the spec specifies "Downgrade, then maybe upgrade."

One might think that the simplest position is "Throw when adopting," but I am not sure. It seems like that has its own unique challenges which might make it worse.

My personal preference at this point in time is "Stay custom with same definition". It seems self-consistent, and matches the built-ins. It has an extensibility point for adoptedCallback in the future. It even has a rationalization built in for the noncompliant browsers that I think avoids any future compatibility constraints. Anyway, "Downgrade, then maybe upgrade" seems increasingly bad the more I look at it.

Do others find this convincing?

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

Received on Wednesday, 15 June 2016 18:43:17 UTC