[Bug 20488] [Custom]: Need to define what happens when nodes are adopted into or out of documents that have custom element definitions

https://www.w3.org/Bugs/Public/show_bug.cgi?id=20488

--- Comment #7 from Dominic Cooney <dominicc@chromium.org> ---
I have been looking at this recently. Noting that what happens to an element's
prototype when it moves between contexts isn't well defined, I think there are
a  choices here:


Planet 1

Similar to having an owner document, a custom element has an "owner
registration context." When it moves to a new registration context, it is
un-upgraded. Then it lives an independent new life; it might be upgraded in the
new context if there's a matching definition for it there.

Implied weirdness #1: When an element moves to the new context, it is still the
same object. So all of the per-instance expandos and whatnot are still there.
Maybe this problem is ameliorated by using ES6 symbols to record per-instance
custom element state.

Implied weirdness #2: Consider this case:

docB.body.appendChild(docA.body.firstChild)

where docA and docB are associated with different registration contexts, and
the each registration context has a matching definition for the element (call
them type A and type B).

The order of callbacks should be:

1: type A's leftDocumentCallback
2: type B's createdCallback
3: type B's enteredDocumentCallback

The weird thing is that when delivering callback 1, the element is *in* docB.
So you can't rely on an element's owner document's associated registration
context being the operative registration context when running a callback. I
tried implementing this in Blink and it is implementable but requires jumping
through hoops.

Implied weirdness #3: Changing the definition implies changing the element's
[[Prototype]]. But whenever you do that, it is going to be weird. If you do it
when it moves to the new document, then callback #1 (above) is going to be
dealing with an element that has the "wrong" prototype. If you do it before #2,
then there's a point in time when the element is in the new context with a
prototype from a different context.


Planet 2

When a custom element is upgraded, that definition is associated with it for
life. If it moves to a new context, it keeps the old definition. This is nice
because:

- A given element has a stable API. It is elaborated from the base type (eg
HTMLButtonElement) to the custom element when the element is upgraded, but it
never regresses backwards or changes.

- There's less magic involved. This is similar to what an author would get if
they passed a JavaScript object from one place to another.

- All of the per-instance state of the object--expandos, etc.--continue to make
sense because the definition did not change.

Implied weirdness #1: innerHTML no longer reliably round-trips things, because
an element may have picked up a definition in a different context. As it is
serialized and reparsed, the new element sloughs off that definition and picks
up whatever is in the new context.

Implied weirdness #2: An element is running around with lots of pointers to
state in a separate context via the prototype and callback closures around the
associated definition. This is no less weird than the author doing this in
JavaScript, I suppose.


The question is--which planet is OUR planet? We just need to find the Statue of
Liberty. I think she is on Planet 2.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Friday, 19 July 2013 02:03:10 UTC