On 1/13/15 12:50 PM, Domenic Denicola wrote:
Agreed. That needs to be done with <img is="my-img">, IMO. (Assuming the
upgrading design doesn't get switched to DOM mutation, of course.)
Although! Briefly yesterday Arv mentioned that for Blink's DOM implementation there's no real
difference in "internal slots" between <img> and <span>: both just have a
single internal slot pointing to the C++ backing object.
Just a few notes:
1) This is not universal across implementations. For example, Gecko
will handle some property accesses by storing the values in additional
internal slots on IDL objects. We're not doing that on any elements
right now, but would likely start doing that for HTMLMediaElement's
TimeRanges attributes, for example, if those ever switch away from the
"return a new object on every get" behavior.
2) Updating the value in the internal slot means changing the C++
object identity, which means finding all the C++ places that have
pointers to it (like the DOM tree) and ... something. Not updating the
value in the internal slot means you now have an <img> pointing to the
wrong C++ class or something.
In any case, we seem agreed that for now this case needs to stick to the
is="" syntax.
The argument for different constructors is that: **assuming we want a design
such that parsing-then-upgrading an element is the same as calling its
constructor**, then we need the constructor to be split into two pieces:
allocation, which happens on parse and is not overridden by author-defined
subclasses, and initialization, which happens at upgrade time and is what
authors define.
Right, that makes sense.
However, when authors design constructors with `class C1 extends HTMLElement {
constructor(...) { ... } }`, their constructor will do both allocation and
initialization. We can't separately call the initialization part of it at
upgrade time without also allocating a new object.
Hmm.
So this is a situation where having the [[Call]] of the constructor do
something "magic" (like ignoring the super() call in the script) might
be nice, but I agree it would be really weird.
Thus, given a parse-then-upgrade scenario, we can essentially never call C1's
constructor.
Yes, agreed.
We *could* call some other method of C1 at upgrade time. Say, createdCallback.
Right.
We could even generate a constructor, call it C2, that does HTMLElement
allocation + calls createdCallback. That's what the current spec does.
OK. Or we could leave that up to the class implementor. That is, they
could do:
class C1 extends HTMLElement {
constructor(...args) { super(...args); this.createdCallback(); }
};
if they want a nontrivial createdCallback. It does mean more
boilerplate, though.
I guess that's basically Arv's proposal, yes?
I'm less worried about the extra leeway in this setup per se and more
worried about whether the extra leeway would be a footgun in practice...
Thank you for explaining; I see the issues more clearly now.
-Boris