There has been revived interest in standardizing shadow DOM and custom elements across all browsers. To that end we had a bunch of discussion online, met in April to discuss shadow DOM, and met earlier this month to discuss custom elements (custom elements minutes). There is agreement around shadow DOM now. host.attachShadow()
will give you a ShadowRoot
instance. And <slot>
elements can be used to populate the shadow tree with children from the host. The shadow DOM specification will remain largely unchanged otherwise. Hayato is working on updates.
This is great, we can start implementing these changes in Gecko and ship them. Other browsers plan on doing the same.
Custom elements however is somewhat more astray. Here are some of the pain points:
Can we execute JavaScript at creation-time? This would explain how builtin elements are created and would provide JavaScript with a consistent world view (attributes are not yet added, children do not exist yet). It does complicate a number of algorithms in the DOM (ranges/editing) that are already very hard to reason about and have been the cause of security bugs.
The counter argument is that those algorithms are likely already harder than specified due to mutation events, several focus events that fire synchronously (!), and beforeunload
. The counter argument to that is that maybe we can “fix” those cases and that adding new scenarios where JavaScript can run synchronously does not help lower the complexity tax.
Do we need upgrades? With some reservation, there seemed to be agreement that custom elements definitions loaded post-parse-time were an important facet to support. That is, the parser creates instances and these are later "upgraded" with some JavaScript into their local-name matching custom element. Retaining object identity here is important as experiments show that unrelated libraries might grab references before "upgrading" happens.
Can we have upgrades and provide a consistent world view? This was the question that killed custom elements being done anytime soon. Once you accept upgrades, you accept that instances are created at a different time to when they get initialized. In this time difference observable changes happen to the tree and the wider world of DOM. If developers start depending on these differences for their own custom elements, they end up creating elements that cannot be reused, break when created through document.createElement()
, etc. (Feedback from Polymer indicated that developers of components frequently depend on attributes and children being present.)
During the meeting Maciej imagined various hacks during a break that would meet the consistency and upgrade requirements, but neither seemed workable on closer scrutiny, although an attempt will still be made. That and figuring out whether JavaScript needs to run during DOM operations will be our next set of steps. Hopefully with some more research a clearer answer for custom elements will emerge.