- From: Domenic Denicola <notifications@github.com>
- Date: Wed, 13 Jul 2016 09:30:49 -0700
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc:
- Message-ID: <w3c/webcomponents/issues/512/232410812@github.com>
OK, @dominiccooney pointed out a problem with "stay custom with same definition" semantics, and now I am not sure we are on the right path here. ### The problem A common pattern is for people to use a `<template>` to instantiate their element's contents. However, this pattern fails with our current setup for custom element registries and our proposed setup for adopting. Consider: ```html <!DOCTYPE html> <template id="xfoo"> <x-bar>hello</x-bar> </template> <script> "use strict"; customElements.define("x-bar", class XBar extends HTMLElement { ... }); const template = document.querySelector("template#xfoo"); class XFoo extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.shadowRoot.appendChild(template.content.cloneNode(true)); } } customElements.define("x-foo", XFoo); </script> ``` The problem is, template contents belong to a special browsing context-less Document. Thus, any elements created inside the template contents are never custom (step 2 of [look up a custom element definition](https://html.spec.whatwg.org/multipage/scripting.html#look-up-a-custom-element-definition) returns null). Cloning the template contents doesn't change that. And then, per the proposed adoption semantics in this thread, when we append the resulting document fragment, the cloned non-custom elements will carry their non-customness with them into XFoo's shadowRoot---not at all what we intended. I hope we can all agree this is a problem? This kind of template + custom elements + shadow DOM scenario has been part of the web components story for as long as I have been involved, and it seems like we accidentally broke it. (Or at least, discovered that it wasn't on very solid footing.) ### Proposed solutions @dominiccooney and I came up with several solutions, trying to take into account the various opinions expressed in this thread about defaults, added concepts, and more. - "Auto downgrade": this is essentially the old "downgrade, then upgrade" from https://github.com/w3c/webcomponents/issues/512#issuecomment-226281431. This has the drawback of running a constructor twice. However, `adoptedCallback()` has the potential of allowing some kind of teardown/reset of state, which could help... - "Manual downgrade": we keep the "stay custom with same definition" semantics by default, but elements which wish to work with `<template>` can use some new API, say `customElements.downgrade(element)`, inside their `adoptedCallback()`. - "Branching adoption": when adopting elements, if the element already has a custom element definition, keep it. However, if it does not have one, then look up the potential custom element definition in the destination document, and if such a definition exists, assign it. This prevents running any constructors twice, and solves the template problem (as well as the similar-but-less-common `responseXML` and `DOMParser` problems). - There's a variant of this where we branch based on whether the source document had a browsing context, instead of based on whether the being-adopted element had a custom element definition. The difference being that "has a browsing context" would only catch the template/responseXML/DOMParser cases, whereas "has a custom element definition" would also allow moving elements between "normal" documents and the element "lighting up" if only the destination document has a definition. Of these I am warming up to "branching adoption"... The "has a browsing context" version even seems somewhat principled. I guess we conceptualize that as "elements get a chance to become custom the first time their node document has a browsing context", which is either at creation, or at adoption. I'm really sorry to retread this after we already went through the discussion and seemingly settled on a good solution. But I think we missed something big, and fixing it will be worth it! --- 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-232410812
Received on Wednesday, 13 July 2016 16:31:34 UTC