This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
TL;DR: Current upgrade algorithm isn't perfect but better than possible alternatives in my mind. Moved discussion from [1]. Current upgrade algorithm [2] does the upgrade only in-document elements. This means that any out-of-document element which has becomes-valid name doesn't get upgraded. For example: var outOfDocElement = document.createElement("x-foo"); document.register("x-foo", ...); // a) Here |outOfDocElement| doesn't get any upgrade. document.body.appendChild(outOfDocElement); // b) It won't be upgraded even after inserted into document. This might be confusing and inconvenient for developers so it's worth exploring better approach. Here are three alternative approaches: - A: Upgrade all elements regardless they are in the document. - B: Current algorithm + Upgrade "yet-to-be-upgraded" elements when it is inserted into the document. - C: Current algorithm + Provide document.upgrade(element) API for explicit upgrade. Approach A might be straightforward from developers' perspective. However, it requires implementations to track all unresolved elements, which is bad IMO. How about B? It seems natural extension of A. B raises an interesting question though: What does happen when a custom element, which lives in a document D1, is inserted to different document D2, which has different custom element definition on same element name? Should the element be "upgraded" to D2's definition? Or should it stay D1's definition? I think this complication comes from the idea to tie the element definition and document closures. C just exposes the upgrade algorithm to developers and let them handle it in the way they want. This might just work. But I feel it a premature fine-tuning and want to let us go without it and see what developers find. In summary, each alternative has its own caveats and current behavior is the best preferable due to its simplicity. ---- [1] https://bugs.webkit.org/show_bug.cgi?id=113362 [2] https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-element-upgrade
My initial reactions: I could live in a world where outOfDocElement is simply never upgraded; in general I'm willing to accept some resposibility for timing of actions. From this standpoint, it's all a matter of how costly each option is to implement. A. upgrade all: is probably best, but since Morrita-san says it causes trouble, I'm ready to dismiss it. B. upgrade on insertion: would probably be a good compromise. C. document.upgrade(): my sense is to avoid this complication. D. do nothing: simple may be best, as suggested. >> What does happen when a custom element, which lives in a document D1, is inserted to different document D2 << IMO, nothing at all. I suspect user wants the behavior element had in D1 to be transferred to D2. I realize this creates a weird situation wrt localName. I would rather somehow alter localName then morph the element. Another possibility is to just make it an error.
> IMO, nothing at all. That's not compatible with the prototype chain reparenting UAs do in practice when transferring elements between documents, fwiw. > Another possibility is to just make it an error. This is .... somewhat nontrivial, actually. Unless you make all adopt operations do an extra pass over the to-be-adopted tree just in case it has components in it or something.
> That's not compatible with the prototype chain reparenting UAs do in practice when transferring elements between documents, fwiw. In that case, I don't see how we avoid completely tearing down the element and then rebuilding it in the new document. IOW, shadow-dom and user initializations wil vary by registration.
I don't see it either, frankly. Pretty sure that's what happens in Gecko's current implementation, in fact.
> Pretty sure that's what happens in Gecko's current implementation, > in fact. Sorry if this is naiive, but we couldn't just throw an exception about incompatible registrations at this point?
At what point? Currently, calling adoptNode on a node adopts the entire subtree rooted at that node. Adopting part of the subtree and then throwing an exception seems like a really bad idea, because then you get a subtree of nodes which have different ownerDocuments, which can't ever really happen. In fact, it's a bad enough idea that if that situation ever happens (which it can't per spec right now, note) Gecko disconnects every single node in the subtree from all the other nodes before throwing an exception...
All I'm noticing is that you said: > extra pass over the to-be-adopted tree just in case it has components in it but then we agreed that components [custom elements] have to be detected and handled specially during adoption anyway. If you say the latter doesn't remove the necessity for the former, then I take it as read.
The point is that throwing during the middle of adoption is really bad, so you have to throw _before_ you start adopting, which means you need to prescan for custom elements or something.
Ok, thank you for zeroing in on that for me.
Wrt outOfDocument element, I realize I'm not clear on the state of elements in 'imported' documents, and elements inside of <template>. It's standard procedure for us to do things like this: <template> <x-custom></x-custom> </template> <script> otherDom.appendChild(template.createInstance()); </script> At what point is x-custom upgraded? Additionally, what if the above code is in an 'imported' document (<link rel='import'>)? I realize our polyfill(s) don't handle this at all, and our sugaring layer specifically upgrades all custom elements after they are instanced from a template. Seems like I sidestepped this problem in my own thinking. Scott
I apologize, I was imprecise above. There can be custom elements inside of 'imported' documents. Do imported documents share the element registry? If so, then I suppose there is no problem with transferring nodes from imported document, or cloning nodes from imported document, and inserting them into the main document. Presumably, template stamping is a version of subtree cloning. Nodes in a template are in a document fragment, I believe. Does the fragment share the element registry? The template may also be in a linked document, so the content may be twice removed. If the registries are not shared, then custom elements would have to be 'upgraded' on insertion into the new document. I hope that's clearer.
Dimitri was asked directly about 'sharing registries' and he said he thought 'no'. On reflection, I believe this actually is the only answer that makes sense, but it requires: B: Current algorithm + Upgrade "yet-to-be-upgraded" elements when it is inserted into the document. Examples below are given in terms of <template> because it's encapsulating document shenanigans, but I believe this is WLOG to doing it by hand. Example: <template> <x-foo></x-foo> </template> <x-foo> lives in a document fragment with no definition of x-foo, so it is 'plain'. The only chance then to upgrade x-foo is when I insert it into the main document. This is sane, because it would be wasteful to upgrade <x-foo> in the document fragment (it must be inert, after all) and in any case it would need to be 'custom-cloned' (i.e. re-initialized). I believe this would work similarly for imports.
> The only chance then to upgrade x-foo is when I insert it into the > main document. Insert, or adopt? In that situation, upgrading on adopt, as long as upgrading can't fail, would be quite easy to do. So this situation is somewhat orthogonal to what happens for nodes that already have the same ownerDocument and then get inserted somewhere.
An alternative notion has been floated that could work with answer 'A'. The idea is that when, e.g., templates are instantiated, the correct node is generated at creation time (as long as the nodes are created with the proper document owner). I believe the advantage of this idea is that upgrade is decoupled from adoption/insertion. In the general case however, cloneNode has no notion of 'target document' to make this work. I also expect users to want to migrate subtrees from imports to the main document, and expect the custom elements to generate. Sidebar: the notion of A may require that some custom elements take care to operate only on insertion, and even then only in suitable contexts. I don't claim this is a problem however, because this is a normal condition for DOM nodes. For example, <img src='foo.jpg'> tag doesn't actually hit the network to load 'foo.jpg' until it's in a suitable document context.
> For example, <img src='foo.jpg'> tag doesn't actually hit the network to load > 'foo.jpg' until it's in a suitable document context. That's a particularly bad example, because whether <img> does the load depends only on its ownerDocument and not on anything else.
(In reply to comment #2) > > IMO, nothing at all. > > That's not compatible with the prototype chain reparenting UAs do in > practice when transferring elements between documents, fwiw. > I wasn't aware of reparenting thing. Is this part of DOM standard? I tried it http://jsfiddle.net/4gxHQ/1/ and see neither Chrome and Safari does but Firefox. If Chrome adopts this reparenting behavior, B possibly can be an extension of such reparenting.
> Is this part of DOM standard? It's being discussed. > and see neither Chrome and Safari does Actually Safari sometimes does and sometimes doesn't, in a gc-dependent way. It's quite lovely.
(In reply to comment #17) > > Is this part of DOM standard? > > It's being discussed. > > > and see neither Chrome and Safari does > > Actually Safari sometimes does and sometimes doesn't, in a gc-dependent way. > It's quite lovely. The discussion is here: http://lists.w3.org/Archives/Public/www-dom/2012OctDec/thread.html#msg143 and http://lists.w3.org/Archives/Public/www-dom/2013JanMar/thread.html#msg67
So it seems to me that the *most* sanity results from the strongest guarantee: ->Script should never have access to an un-upgraded custom element. Deviation from this invariant exposes a fracture in the mental model that page script may implement host (DOM) elements. This invariant is unachievable, as demonstrated in Morrita-san's original example. I.e. since registration can happen at any time, script will always have access to an un-upgraded element before it was registered. However, a slightly less strong guarantee *is* possible: ->Script should never have access to an un-upgraded custom element, once the identity of that element is known (i.e. it has been registered). In my mind, anything short of this is a serious flaw in the processing model of custom elements and falling short should have strong justification.
Also, WRT To <template> contents, the question arises: should template contents also be upgraded? Given that <template> is the primitive for expressing prototypes of DOM fragments -- and script is very likely to interact with those elements, the desirability of a strong guarantee about custom element upgrade necessarily extends to template contents. At worst, the upgrade algorithm (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-element-upgrade) to should upgrade all elements which are a host-including inclusive ancestor (http://dom.spec.whatwg.org/#concept-tree-host-including-inclusive-ancestor) of the document.
Rafael's argument is compelling to me, so I guess I would revise my answer to be A. > Dimitri was asked directly about 'sharing registries' and he said he thought > 'no'. I think for A to work, we have to have some sharing of registries.
And we are also prepared to accept the notion from my 'sidebar' above that custom elements will need to take care about what context they are in before taking action (specifically in _readyCallback_). I'm being vague because previously I used a bad example ('img'), but I think the bottom line is that a custom element would be advised to test 'ownerDocument.defaultView' in some cases.
Putting aside cross-document thing, I'm OK to take A. It might be surprising for developers to have such side effect to out-of-document elements, but I agree that it results better invariant as Raphael pointed. For cross document (custom) element adoption, we need to align HTML Imports definition where external custom elements and many <template>s are defined. And taking A, this can be discussed in perfectly orthogonal way. So should the summary of this bug be something like "Out-of-document elements should be upgraded"?
+1. I think it's far more surprising that out of document elements would not be upgraded.
Re-reading this, I am convinced that we should upgrade all elements whose ownerDocument is the document with which we register the new element.
https://dvcs.w3.org/hg/webcomponents/rev/9a2f50cedba0 https://dvcs.w3.org/hg/webcomponents/rev/4e93030dfed7 Now moar better. All elements are upgraded, whether in tree or not. Please look over the spec and let me know if I goofed up anything.