RE: Custom elements Constructor-Dmitry baseline proposal

2015-08-21 Thread Domenic Denicola
From: Maciej Stachowiak [mailto:m...@apple.com]


 On Aug 17, 2015, at 3:19 PM, Domenic Denicola d...@domenic.me wrote:

  - Parser-created custom elements and upgraded custom elements will
 have their constructor and attributeChange callbacks called at a time when all
 their children and attributes are already present, but
 
 Did you change that relative to the spec? Previously, parser-created custom
 elements would have their constructor called at a time when an
 unpredictable number of their children were present.

You're right that I didn't get this quite spelled out. Fortunately, given your 
below suggestion, I would have had to rewrite it anyway :).

  - Elements created via new XCustomElement() or
 document.createElement(x-custom-element) will have their constructor
 run at a time when no children or attributes are present.
 
 If you really got it down to two states, I like reducing the number of word
 states, but I would prefer to put parser-created custom elements in this
 second bucket. They should have their constructor called while they have no
 children and attributes, instead of when they have all of them.

This seems reasonable and doable. Here's my try at making it work:

- Diff from previous revision: 
https://github.com/w3c/webcomponents/pull/297/files?short_path=876522d#diff-876522df93719f9da9871064880af5d2
- All together: 
https://github.com/domenic/webcomponents/blob/constructor-dmitry-revisions/proposals/Constructor-Dmitry.md

 If any of this happens, an upgradeable element will be stuck in the pre-
 upgrade state for a possibly unboundedly long amount of time.

This seems totally fine to me though. You're basically saying that you don't 
upgrade elements that are left often. Not a big deal. You have to actually have 
a full `x-custom-foo.../x-custom-foo` before you get a proper custom 
element. Just `x-custom-foo...` alone does not cut it.

 Against this, we have the proposal to forcibly put elements in a naked state
 before calling the constructor for upgrade, then restore them. That has the
 known bad property of forcing iframe children to reload. I owe the group
 thoughts on whether we can avoid that problem.

 ...

 I will read the document more closely soon, to see if it seems like a
 reasonable baseline. I agree it would be fine to start with something good
 that uses the constructor and has two possible stats for constructor
 invocation, then see if we can get it down to one.

Awesome! And yeah, the intent of this was exactly to provide such a baseline, 
and see if we could come up with a good solution for reducing the two states 
down to one using trickery such as that you mention. As a summary, after the 
above changes we have these two states:

- Upgraded custom elements, or elements created via other algorithms that are 
constructing a larger tree (such as cloneNode), will have their constructor and 
attributeChange callbacks called at a time when all their children and 
attributes are already present.
- Elements created via new XCustomElement() or 
document.createElement(x-custom-element) or via the parser will have their 
constructor run at a time when no children or attributes are present.

Note that we could move elements created via other algorithms that are 
constructing a larger tree into the latter bucket too, at the cost of 
synchronous script execution during all such algorithms. But the UA appetite 
for that was... mixed, and I don't think we should do so. It seems fine to 
leave their fate the same as upgrades, whichever way it shakes out.


Re: Custom elements Constructor-Dmitry baseline proposal

2015-08-21 Thread Maciej Stachowiak

 On Aug 17, 2015, at 3:19 PM, Domenic Denicola d...@domenic.me wrote:
 
 In 
 https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_w3c_webcomponents_blob_gh-2Dpages_proposals_Constructor-2DDmitry.mdd=BQIGaQc=eEvniauFctOgLOKGJOplqwr=Cq0heWYmrUNShLjLIzuzGQm=U2qIHSkYawudMNTponjVOJxTr1-blzlm_skvYTCFFrks=Fqq6RL3oe2zmH8pGykh6XfqVC6LYMZILABlqZPRGG74e=
   I’ve written up in some detail what I consider to be the current 
 state-of-the-art in custom elements proposals. That is, if we take the 
 current spec, and modify it in ways that everyone agrees are good ideas, we 
 end up with the Constructor-Dmitry proposal.
 
 The changes, in descending order of importance, are:
 
 - Don't generate new classes as return values from registerElement, i.e. 
 don't treat the second argument as a dumb { prototype } property bag. (This 
 is the original Dmitry proposal.)
 - Allow the use of ES2015 constructors directly, instead of createdCallback. 
 (This uses the constructor-call trick we discovered at the F2F.)
 - Use symbols instead of strings for custom element callbacks.
 - Fire attributeChanged and attached callbacks during parsing/upgrading
 
 Those of you at the F2F may remember me saying something like If only we 
 knew about the constructor call trick before this meeting, I think we would 
 have had consensus! This document outlines what I think the consensus would 
 have looked like, perhaps modulo some quibbling about replacing or 
 supplementing attached/detached with different callbacks.
 
 So my main intent in writing this up is to provide a starting point that we 
 can all use, to talk about potential modifications. In particular, at the F2F 
 there was a lot of contention over the consistent world view issue, which 
 is still present in the proposal:
 
 - Parser-created custom elements and upgraded custom elements will have their 
 constructor and attributeChange callbacks called at a time when all their 
 children and attributes are already present, but

Did you change that relative to the spec? Previously, parser-created custom 
elements would have their constructor called at a time when an unpredictable 
number of their children were present. 

 - Elements created via new XCustomElement() or 
 document.createElement(x-custom-element) will have their constructor run at 
 a time when no children or attributes are present.

If you really got it down to two states, I like reducing the number of word 
states, but I would prefer to put parser-created custom elements in this second 
bucket. They should have their constructor called while they have no children 
and attributes, instead of when they have all of them.

My reasons for this:

(1) This is more likely to lead to correctly coding your custom elements to 
rely on change notifications exclusively, rather than on what is present at 
parse time.
(2) Framework developers find it a footgun and an inconvenience for 
parser-created elements to have their constructor called with children present.
(3) It is possible for a parser-created element to render before all of its 
children are present. It's also possible for it to never reach the state where 
it is known all of its children [that will be created by the parser] are 
present. I can give examples if you like. Based on this, I think it's better 
to upgrade them as early as possible.

For these two reasons (#1 and #2 were mentioned in the f2f, #3 is something I 
thought of later), I think parser-created elements should have their 
constructor called early instead of late.

However, if we care about these edge cases, note that #3 *also* applies to 
upgrade. If we want to do upgrade late, and it's on a parser-created element, 
it may be the case that the element has already rendered when the info needed 
to upgrade it comes in, but it may be an unboundedly long time until all its 
children come in.

I guess I should give examples, so cases where this can happen:

(A) Load of the main document stalls partway through the element's children, 
before a close tag has been seen. But the upgrade script comes in via script 
async even during the stall.
(B) The document keeps loading forever by design. Admittedly this is unlikely 
for modern web design.
(C) The document is created with document.open()/document.write(), the element 
in question never has a close tag written, and no one ever calls 
document.close(). People actually still do this sometimes to populate opened 
windows or the like.

If any of this happens, an upgradeable element will be stuck in the pre-upgrade 
state for a possibly unboundedly long amount of time.

This seems like a bad property. 

Against this, we have the proposal to forcibly put elements in a naked state 
before calling the constructor for upgrade, then restore them. That has the 
known bad property of forcing iframe children to reload. I owe the group 
thoughts on whether we can avoid that problem.

 
 If we still think that this is a showstopper to consensus (do we!?) then I 
 

Re: Custom elements Constructor-Dmitry baseline proposal

2015-08-18 Thread Anne van Kesteren
Thank you for writing this up. Would be interesting to hear what
Maciej and Ryosuke think.

On Tue, Aug 18, 2015 at 12:19 AM, Domenic Denicola d...@domenic.me wrote:
 - Use symbols instead of strings for custom element callbacks.

So the way this is done is that they are publicly available on the
prototype. Does that mean behavior can change during the lifetime?
What does that mean for builtin elements that do not have these
callbacks on their prototype?

Also, we probably need to rename registerElement() due to the
different semantics.

Also, you want to sort the attributes in some way before calling
attributeChanged from upgrades, or we must finally agree on that
attributes are sorted in some deterministic way:

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

I also thought the idea was to pass attached/detached their changed
ancestor and perhaps rename them inserted/removed (and no longer scope
them to document change).


-- 
https://annevankesteren.nl/



Custom elements Constructor-Dmitry baseline proposal

2015-08-17 Thread Domenic Denicola
In 
https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Constructor-Dmitry.md
 I’ve written up in some detail what I consider to be the current 
state-of-the-art in custom elements proposals. That is, if we take the current 
spec, and modify it in ways that everyone agrees are good ideas, we end up with 
the Constructor-Dmitry proposal.

The changes, in descending order of importance, are:

- Don't generate new classes as return values from registerElement, i.e. don't 
treat the second argument as a dumb { prototype } property bag. (This is the 
original Dmitry proposal.)
- Allow the use of ES2015 constructors directly, instead of createdCallback. 
(This uses the constructor-call trick we discovered at the F2F.)
- Use symbols instead of strings for custom element callbacks.
- Fire attributeChanged and attached callbacks during parsing/upgrading

Those of you at the F2F may remember me saying something like If only we knew 
about the constructor call trick before this meeting, I think we would have had 
consensus! This document outlines what I think the consensus would have looked 
like, perhaps modulo some quibbling about replacing or supplementing 
attached/detached with different callbacks.

So my main intent in writing this up is to provide a starting point that we can 
all use, to talk about potential modifications. In particular, at the F2F there 
was a lot of contention over the consistent world view issue, which is still 
present in the proposal:

- Parser-created custom elements and upgraded custom elements will have their 
constructor and attributeChange callbacks called at a time when all their 
children and attributes are already present, but
- Elements created via new XCustomElement() or 
document.createElement(x-custom-element) will have their constructor run at a 
time when no children or attributes are present.

If we still think that this is a showstopper to consensus (do we!?) then I hope 
we can use this proposal as a baseline from which to derive additive solutions. 
Alternately, maybe you all will read this proposal and be amazed at how great 
it is already, and agree we can move on, leaving the consistent world view 
issue aside as an edge-case that shouldn't prevent cross-browser consensus on 
custom elements :)