Apple's updated feedback on Custom Elements and Shadow DOM

# Maciej Stachowiak (8 months ago)

A while back we sent a consolidated pile of feedback on the Web Components family of specs. In preparation for tomorrow's F2F, here is an update on our positions. We've also changed the bugzilla links to point to relevant github issues instead.

We're only covering Custom Elements (the main expected topic), and also Shadow DOM (in case that gets discussed too).

I. ==== Custom Elements ====

A. ES6 classes / Upgrade / Synchronous Constructors
    1. In general, we support the "synchronous constructors" approach to the "prototype swizzling" approach, as the lesser evil. While tricky to implement correctly, it makes a lot more sense and fits more naturally into the language. We are willing to do the work to make it feasible.
    2. Custom elements should support initialization using an ES6 class constructo instead of a separate callback. <[https://github.com/w3c/webcomponents/issues/139](https://github.com/w3c/webcomponents/issues/139) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=28541](https://www.w3.org/Bugs/Public/show_bug.cgi?id=28541)>>
    3. We don’t think upgrading should be supported. The tradeoffs of different options have been much-discussed. <[https://github.com/w3c/webcomponents/issues/134](https://github.com/w3c/webcomponents/issues/134) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=28544](https://www.w3.org/Bugs/Public/show_bug.cgi?id=28544)>>
    4. Specifically, we don't really like the "Optional Upgrades, Optional Constructors" proposal (seems like it's the worst of both worlds in terms of complexity and weirdness) or the "Parser-Created Classes" proposal (not clear how this even solves the problem).

B. Insertion/Removal Callbacks
    1. We think the current attached/detached callbacks should be removed. They don’t match core DOM concepts and insert/remove is a more natural bracket. The primitives should be insertedIntoDocument / removedFromDocument and inserted / removed. If you care about whether your document is rendered, look at its defaultView property. <[https://github.com/w3c/webcomponents/issues/286](https://github.com/w3c/webcomponents/issues/286)>
    2. We think inserted/removed callbacks should be added, for alignment with DOM. <[https://github.com/w3c/webcomponents/issues/222](https://github.com/w3c/webcomponents/issues/222)>

C. Inheritance for Built-ins
    1. We think support for inheritance from built-in elements (other than HTMLElement/SVGElement) should be omitted from a cross-browser v1. It raises complex implementation issues. <[https://github.com/w3c/webcomponents/issues/133](https://github.com/w3c/webcomponents/issues/133) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=28547](https://www.w3.org/Bugs/Public/show_bug.cgi?id=28547)>>

D. Syntactic Sugar / Developer Ergonomics
    1. We think it would be useful (perhaps post-v1) to make it simpler to create a custom element that is always instantiated with a shadow DOM from a template. Right now, this common use case requires script and a template in separate places, and a few lines of confusing boilerplate code. <[https://github.com/w3c/webcomponents/issues/135](https://github.com/w3c/webcomponents/issues/135) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=28546](https://www.w3.org/Bugs/Public/show_bug.cgi?id=28546)>>
    2. We think at some point (perhaps post-V1), there should be a convenient declarative syntax that combines script and a template to define a custom element. JavaScript frameworks on top of web components provide something like this. Perhaps with field experience we can make a standardized common syntax. <[https://github.com/w3c/webcomponents/issues/136](https://github.com/w3c/webcomponents/issues/136)>

E. Renaming the API
    1. We’re still not wholly sold on document.registerElement as a name. We like document.define or document.defineElement. At minimum, we’d like the WG to decide on the name instead of just leaving it at the editor’s initial decision. We can probably live with this not changing though. <[https://github.com/w3c/webcomponents/issues/140](https://github.com/w3c/webcomponents/issues/140) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=24087](https://www.w3.org/Bugs/Public/show_bug.cgi?id=24087)>>
    2. If anything about Custom Elements is changed incompatibly, we suggest renaming document.registerElement (whether to one of our suggestions or another). This is to avoid compat problems with content written for Chrome’s shipping implementation. This will almost certainly be true if we switch from createdCallback to constructors as the initializers.

II. ==== Shadow DOM ====

A. Closed vs. Open.
    1. A closed/open flag has been added to createShadowRoot(). It seems this has been done. We are ok with the syntax. <[https://github.com/w3c/webcomponents/issues/100](https://github.com/w3c/webcomponents/issues/100)>
    2. The behavior of closed mode should be actually defined. We hope this does not need much justification. We think this is critical for v1. <[https://github.com/w3c/webcomponents/issues/100](https://github.com/w3c/webcomponents/issues/100)>
    3. We wanted closed mode to be the default but we are ok with having no default, as was decided at the last F2F.

B. Multiple Generations of Shadow DOM
    1. We are glad to see that multiple generations of Shadow DOM has been removed per F2F agreement.
    2. After further consideration, we are even more convinced that the "named slot" proposal is the way to go for distribution for v1. Original proposal here: <[https://github.com/w3c/webcomponents/wiki/Proposal-for-changes-to-manage-Shadow-DOM-content-distribution](https://github.com/w3c/webcomponents/wiki/Proposal-for-changes-to-manage-Shadow-DOM-content-distribution) <[https://github.com/w3c/webcomponents/wiki/Proposal-for-changes-to-manage-Shadow-DOM-content-distribution](https://github.com/w3c/webcomponents/wiki/Proposal-for-changes-to-manage-Shadow-DOM-content-distribution)>> Some detailed algorithms written out here: <[https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md)> Github issue here: <[https://github.com/w3c/webcomponents/issues/138](https://github.com/w3c/webcomponents/issues/138)>

C. Imperative Distribution API
    1. We think the imperative distribution API may be worth doing, but we're no longer confident that it is important for v1. <[https://github.com/w3c/webcomponents/issues/60](https://github.com/w3c/webcomponents/issues/60) <[https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429](https://www.w3.org/Bugs/Public/show_bug.cgi?id=18429)>>

D. Event Retargeting
    1. We agree with making it optional (opt-in or opt-out). We don’t feel that strongly, but many web developers have asked for this. The default should likely match the default for open vs. closed (no retargeting by default if open by default). It seems like the issue is marked for v2, but we thought we'd all agreed to do something here for v1? <[https://github.com/w3c/webcomponents/issues/89](https://github.com/w3c/webcomponents/issues/89)>

E. Renaming the API
    1. If any strongly incompatible changes are made, we suggest renaming createShadowRoot. This is to avoid compat problems with content written for Chrome’s shipping implementation. We are not sure if this will be required, but named slots may force it if adopted.
Contact us to advertise here
# Domenic Denicola (8 months ago)

Thanks very much for your feedback Maciej! I know we'll be talking a lot more tomorrow, but one point in particular confused me:

From: Maciej Stachowiak [mailto:[email protected]]

  1. Specifically, we don't really like the "Optional Upgrades, Optional Constructors" proposal (seems like it's the worst of both worlds in terms of complexity and weirdness) or the "Parser-Created Classes" proposal (not clear how this even solves the problem).

Specifically with regard to the latter, what is unclear about how it solves the problem? It completely gets rid of upgrades, which I thought you would be in favor of.

The former is, as you noted, a compromise solution, that brings in the best of both worlds (from some perspectives) and the worst of them (from others).

# Maciej Stachowiak (8 months ago)

On Jul 20, 2015, at 10:29 PM, Domenic Denicola d@domenic.me wrote:

Thanks very much for your feedback Maciej! I know we'll be talking a lot more tomorrow, but one point in particular confused me:

From: Maciej Stachowiak [mailto:[email protected]]

  1. Specifically, we don't really like the "Optional Upgrades, Optional Constructors" proposal (seems like it's the worst of both worlds in terms of complexity and weirdness) or the "Parser-Created Classes" proposal (not clear how this even solves the problem).

Specifically with regard to the latter, what is unclear about how it solves the problem? It completely gets rid of upgrades, which I thought you would be in favor of.

The former is, as you noted, a compromise solution, that brings in the best of both worlds (from some perspectives) and the worst of them (from others).

Sorry that this was unclear.

From our (many Apple folks') perspective, the biggest problem with the "prototype swizzling" solution is that it doesn't allow natural use of ES6 classes, in particular with initialization happening through the constructor. It seems like parser-created classes do not solve that problem, since initialization happens before the class is even defined. It also does not solve the secondary problem of FOUC, or the related flash of non-interactive content. It does seem to solve the secondary problem of modifying prototype chains after the fact and in some sense changing the "class identity" of elements.

By my best understanding of the anti "synchronous constructors" position, I think there are two key concerns - the need to run arbitrary user code at possibly inconvenient moments of parsing or cloning; and the fact that elements can't be upgraded to a fancier version after the fact if they are parsed before a relevant library loads. It does seem to solve both those problems.

Does that sound right to you?

If so, it is not much more appealing than "prototype swizzling" to us, since our biggest concern is allowing natural use of ES6 classes.

Regards, Maciej

(The "we" in this case includes at least myself, Ryosuke Niwa, Sam Weinig, and Gavin Barraclough who composed this position statement today; but others at Apple have also expressed similar vies in the past.)

# Domenic Denicola (8 months ago)

From: Maciej Stachowiak [mailto:[email protected]]

Does that sound right to you?

If so, it is not much more appealing than "prototype swizzling" to us, since our biggest concern is allowing natural use of ES6 classes.

Got it, thanks. So it really does sound like it comes down to

class XFoo extends HTMLElement { constructor() { super(); // init code here } }

vs.

class XFoo extends HTMLElement { Element.created { // init code here } }

which I guess we covered in the past at lists.w3.org/Archives/Public/public-webapps/2015JanMar/0283.html as being a general instance of the inversion of control design pattern, which I still don't really understand Apple's objection to. I suppose we can leave that for tomorrow.

Want more features?

Request early access to our private beta of readable email premium.