Web components f2f, July 2015

21 Jul 2015

See also: IRC log


Annevk, DomC, Chaals, Léonie, AliceB, AlexR, Hayato, DomD, MarkG, WChen, Samw, othermaci-J, TOC, ScottM, Sorvall, AKlein, Dglazkov, BinHu, Travis, Arron, Ryosuke


-> https://www.w3.org/wiki/Webapps/WebComponentsJuly2015Meeting agenda

<scribe> scribe: chaals

DD: We have the contentious bits wiki and position papers. Think we should start with the key question - do we run author code during {*}

… Google says no, this is mutation events without eough value to do.

… want to call the hook you provide, instead of vice versa.

AvK: Question - has Apple figured out processing model for cloning?

… think the parsing I can see, but cloning not so much.

MJS: Tricky thing is the stuff that invoke cloning. 3 technically interesting things that might invoke a constructor: parsing, cloning, directly creating by name.

… not sure if createElement gets invoked, so may not be such an issue but it wasn't mentioned and seems distinct.

… tricky Q: what might do cloning in middle of a complex operation and need to be done defensively. Seems like editing code is likely to be trickiest. Ryosuke pointed out that for technical correctness editing has to be prepared for event to be dispatched synchronously in the middle of somewhere.

… edge cases but hard to track. E.g. using delete on a focused thing you might have to synchronously dispatch blur, so you need to be prepared anyway. Which makes this a difference of degree not kind.

Travis: Mutation events are necessary for advanced editors, even though we don't like them.

mjs: Not like mutation events will go tomorrow, but in webkit we defer them to the end of the editing operation for enhanced not-quite-so-crazy

… wouldn't work here.

… Do have Jonas' almost-synchronous proposal, might be a variant of that. But where you're creating new elements, coding defensively is probably feasible and less than mutations.

DomD: The world *should* be nice...
... Other interesting case is where there sin't afailure mode - in the document, what do we do?

mjs: When constructor throws? Throwing isn't useful we need *A* behaviour for that but doesn't need to be pretty, pick whatever is easy to implement.

<Varunkumar> not available on Webex today?

AvK: No guarantee the constructor constructs an element anyway.

[apparently no webex]

[5: Webex request denied]

AK: 2 things - being defensive and the need to specify what happens, and editing right now isn't specified.

<Varunkumar> any other options for us folks from India to connect to?

mjs: Think the likely common case for reasonable elements is they don't do crazy things in construction. So for normal interop, don't know if it will be common to edit things with custom elements in the middle. A custom element that mutates random other things is crazy, so it is important not to crash, but it's an edge case.

AK: Want to specify this beyond "don't crash".

AvK: In DOM need to define what happens for ranges. could be rethrow.

TL: Could define mutation events in there for me

AvK: Considered it, but people still want to remove them.

TL: Can mjs talk about insert/remove?

DomD: The other part is that this makes algorithms obervable.

… that nails down semantics not currently required.

MJS: Mutation events create some of this, because you need to get the things in the same order. Don't think the phenomenon is new...

DomD: Yes, it is a question of degree.

… you wouldn't have complete freedom.

SamW: That's what happens when you expose lower level.

TL: ECMAScript proxy opened up this issue. ggood or bad?

AK: Been problematic, opened up interop issues.

MJS: If you go into DOM operations, there aren't interesting degrees of implementation freedom that synchronous constructors would rule out.

… reomve/insert that don't create elements…

AvK: There might be cases with ranges where you have to throw earlier or later, but minor details.

DomD: images getting laoded and cached before throwing.

AvK: User agents can optimise those things. All of network is a bit racy.

DomD: exaplins what happens with img loading.

… document.write is fun.

AvK: Evil. same as using it to write a script element.

… HTML parser needs checks. We know when we hit the end of a script, but not for a new-tag, when it is safe to synchronise.

DomD: So, Yes we run author code. Yes, but later, when speced. What do we do in themeantime?

… like we did with imperative distribution API. We need someone to go spec it.

MJS: We're thinking of replacement not necessarily addition. Having constructor and creative callback at the same time will be confusing. Don't think we want two warts here.

DomD: Default calls element.created. If you override it, then it doesn't get called.

MJS: That's different ...

DD, AR: Not really.

MJS: Gets called at a different time

DD: Yes, synch constructor comes at a different time.

MJS: Created callaback can be implemented on top of synchronous constructors. maybe we're done.

DD: when that is specced...

AvK: Does anyone have time to figure out the processing model and write patches for the spec?

MJS: If we got around to implementing and it hadn't been specced, we would try to do that. Don't have someone available off-hand to get it perfect now, but could get a first draft. Step 0 is figure out what results in element creation ...

AvK: The things you said. Parser, doc.createEl, cloning.

MJS: But the next level up - wat calls those. Those are where you need defensiveness.

… so where we need to spec. Does anyone have data on what things invoke those operations?

DC: In blinnk we have audio metadata that does that…

MJS: Is that enforced, or an annotation?

DC: Annotation that makes teh system drain the callback queue.

… could be enforced but isn't. Not useful to find all things that can do this because we have bugs where we should have applied it but didn't. E.g. named attribute getter on el.style

… we could get these things.

[explore - doesn't create elements]

DC: We could find this out.

AvK: I feel like it isn't a long list. createElem, innerHTML, rangeAPI, fragments, and editing is built on top to use those. Don't think there are more things for cloning.

DC: My experience is there is always one more, but falls in those - normally in editing.

TL: If you can hadnle range, you can handle all the cases...

MJS: Editing is more complex than ranges because it mixes them up, so need to be super-paranoid.

AvK: Range can do that already.

MJS: What if we say custom element constructors are not allowed to change DOM except their own shadow - if they do, the operation that invoked it completely throws.

TL: They will cloneNode the template.

DC: Nice idea, finding the boundary is tricky. Ther limit says there are no modifications, ...

DG: sounds like we talk about a lot of cost to spec this - what is the benefit of it. Compare to other proposals and weight costs/benefits.

MJS: Could list up pros/cons on the whiteboard.

<annevk> pros and cons of proposals

[discussions of what people like as structures… being noted into the etherPad]

[There is a microtask checkpoint before entering a script element]

MJS: If you have multiple callacks, they can look at each other and see things in a half-constructed state.

… if you are being initialised, your peers might not be completed.

TL: There is a way around the observability. If you go to grab unupgraded element you preempt.

MJS: That cycles…
... We tried that idea, but no.

SM: polymer has learned we have to be defensive, this might happen.

MJS: So things are created from outside in. You know your parents
... So the state of the DOM is unpredictable.

SO: Not sure why that is more objectionable than what we were talking about earlier, where there are things you shouldn't do with constructor. Seems like either way there are DOM manipulations that don't make sense.

MJS: Different kind of problem…

… there we have deterministic behaviour, here we may be dependent on network behaviour providing non-determinism.

DomD: Hol the presses on network behaviour, thought we eliminated that with the HTML parser.

MJS: Boundaries between data chunks to parse then return to the loop cannot be set, because you don't know what you are getting next.

DD: So if we allow throwing depending on the timing we lose "parser will end up producing the same DOM"

AvK: There are random things you could do still.

SO: so non-deterministic state is observable in callback

… potentially, restrictions around it could be specced to fix this.

MJS: Not sure that is possible

SM: Is it clear that the domain of problems are different?

MJS: Don't see how to make created callback work and rule out non-determinism introduced by network variation.

SM: We disallow looking at children - we want an explicit platform signal.

DD: What if we take cycle detection, but instead of upgrading if you inspect it, we sust throw.

SM: We live in the world mjs describes. But don't think we cannot live there.

SW: Our constructors do litt.e Nothing, or set up shadow roots. Don't load...

<scribe> … New image calls a constructor, then sets a src. Can happen in sequence...

… you can do setAttribute in the constructor, but we don't in our native implementation.

DG: Would say that in guidance too

MJS: Elements setting attributes is an anti-pattern…

… parameters can be handled outsied the construction.

SM: Is there another lifecycle, like childrenComplete, where we can get deterministic behaviour?

MJS: Only when you are created and nothing has been inserted yet.

… after setting parser-created attributes we have something, and when a child is inserted.

… or when you are inserted/removed from a doc / DOM subtree.

SM: We need that too.

… you can lazily construct as you add things

AvK: HTML requires callbacks for endtag in some cases.

SW: Constructor sets state that is needed.

MJS: input without a type attrivbute set has to have something, but when it gets a type it varies wildly.

SM: Polymer iterates over attributes

DC: Maybe that is wrong...

MJS You could try to return to event loop when creating the element, but can't go there in the middle of an operation.

DG: So cons on both cases - constructor is complex to spec, createdCallback is that network non-determinism is going to create exciting times.

… does not match ES6 a concern?

AvK: TC39 might want to use constructors.

DD: Not so sure taht is a worry.

MJS: When prototype swizzling happens, something complex goes on if you only get the propotypes later. Some think that is a feature, others a bug.

TOC: worth pointing out that the costs are paid differently - network determinism is paid by authors, complexity of spec is paid by browser developers and specheads (who deserve all the pain they get)

SM: So we *can't get anything deterministic based on callback?

DC: Can be done…

… complexity is when we are running authordefined script.

MJS: You could get down to "if done by parser we drop down to event loop, but if you're in middle of a DOM operation you don't get callback until it's all done"

DD: That removes the network non-determinism

AK: Won't be trivial to add the restrictions

MJS: If you clone subtree with custom element in it you're into a hairy spot of when to do that. And template element encourages doing that.

DG: View upgrades and constructors as sort of the same problem - because in callback world the solution is the same.

… so weighing of the balance applies in the upgrade world.

… sunch constructors means authors need to be sure their definition is loaded before the parser runs.

[possible compromise is to support both appraoches.]

SO: We're looking at either an authoring anti-pattern or a performance anti-pattern …

[discussion of what DomD proposed and what it means - is it bimodal?]]

<annevk> We're discussing https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Parser-Created-Constructors.md

DC: find and replace things is tricky - you can't always find them.

MJS: So to support upgrade, you might not be able to find everything to upgrade.

… maybe you could make it an explicit behaviour when you register an element.

… to keep a reference to it.

… this could be non-deterministically bad.

DC/TL: proxies is worse than proto-swizzling for JS engine, for speed.

[Do we know about author experience of proxies? Probably not really]

DG: Protoswizzling is actually very common in developer-land

SM: We get lots of problems with non-determinism, have zero bug reports from protoswizzling

DG: This is how people to custom-elements-lite today.

SO: WOuld want to consider less-good upgrades before just dumping them.

MJS: What if it were replacement model, and you need to reget a new wrapper?

AR: we tried this with becomes. Footguns were pretty bad.

… eg in loading process you enhance your document, and then later they get replaced. Surprisingly.

MJS: libraries were fine with protoswizzling?

AR: Largely because they add event handlers

DG: leads to spamming of mutation observers

AR: Problem in the wild.

<alex> hello

MJS: Can we have a model that allows upgrade, isn't non-deterministic, and doesn't suck?

… (topic for after lunch)


<smaug> based on the notes, looks like no new magical great solutions for the issue.

<smaug> yet

<alex> Quick question, I have been on the webex for about an hour now to join the meeting today but the line was silent the entire time

<alex> was that by design?

<alex> are you proactively blocking folks from attending remotely?

<alex> no biggie if so, just don't want to hang on the line any longer if that is the case

<alex> /me waves hello

-> https://docs.google.com/document/d/1KSwKrTU2d0uJCf55tV-jur_0sYxCNMuM7Dl3vqb0bu4/edit?usp=sharing continuation of the minutes, being taken by Domenic Cooney

[begin of google doc copy]

Etherpad from morning session

(dglazkov reconvenes)

Maciej: lunch ideas; I thought about the list of pros and cons and wrote this list of desirable properties (in etherpad). One thing is determinism. We haven’ thought about this to now; this is a problem with createdCallback because network randomness can affect when this runs

domenic: There’s network non-determinism which exists for all implementations; then there are implementation differences.

Maciej: a speced you don’t know (state) when your createdCallback runs--none, some, all children--because of network or implementation differences or whatever. There are use cases when upgrade is reasonable although some of my Apple colleagues have doubts about these. Constructors don’t give you tools to do upgrade because of shadow dom, etc. Upgrade by replacement broke legacy code per Alex Russel because attached event listeners would be broken by being stuck on the old element. Preserving identity is good. Not spamming mutation observers is good. Performance (fast) is good. P2 requirements, good but maybe nonessential: Being able to literally use ES6 constructor syntax, this may be more important if TC39 ties more requirements to the constructors. Second, upgrade being fully automatic, things happen ‘magically’ without you doing something special. P3, running user code at weird times is bad. Content authors have to deal with the P1-2 issues; P3 issue is one for spec authors and implementers who would need to deal with the complexity. Does everyone agree to this list?

Travis: is this strictly in order within the bucket?

Maciej: no, just in buckets.

slightlyoff: I do agree with the P1 list.

dglazkov: Do we want to do anything about extensible web and constraints about Custom Elements and HTML?

domenic: HTML just doesn’t have to make a lot of these decisions.

slightlyoff: but in future you could imagine engines loading rare elements on the fly so even though engines don’t have some issues today they may in the future.

domenic: are there things we can punt and some things we need in V1?

maciej: first can we think if we can hit a lot of the desirable properties and then look at consequences of that. THe toughest problem is the combination of determinism, supporting upgrade and wrapper identity. I think it’s not impossible but you have to do some weird things. If your upgrade can happen whenever script runs it hints at the dilemma because your upgrade can happen at any time; ideas welcome; I’ll try to put things in columns.

con’t if we set aside constructor syntax can we get determinism and upgrade without game breaking flaws. In the no upgrade case when you have a definition at parser or creation time, call createdCallback immediately before setting attributes or properties. A callback for now.

Then in the upgrade scenario, when a definition comes in later, silence Mutation Observers temporarily; remove from parent; remove attributes; remove children; run the created callback; reset the attributes; insert into parent; and add children. This is a wacky set of steps but what it guarantees from the created callback point of view is that upgrade looks the same as being parsed. The order of these operations matches the order the parser does things. I guess there’s a swizzle the prototype step here before the created callback.

This is deterministic, preserves identity, does not spam mutation observers… performance is a question. I guess at the end there is un-mute Mutation Observers.

Anne: what if an iframe blows up its world?

AdamK: You have to destroy the frame when you remove an iframe (talking about if the child being removed and reinserted when the child is an iframe) … You’ve made the local state about the element reasonable but what about the state of the world?

Maciej: Having a consistent world state isn’t compatible with upgrade, but it does hit most of the key properties. This is like domenic’s proposals but this, despite the wackiness, gives you many of the properties at once.

cont’d what if you wanted to support constructor syntax? At the no-upgrade case just call the constructor at the obvious time. For upgrade, if you see a hyphen element and don’t have a definition, create a proxy. Then at upgrade time you swap what the proxy is backed by. This does not need to be a fully general ES6 proxy, you just need to be able to forward everything.

slightlyoff: you need to be sure you never leak that object

domenic: you don’t need to do “all those steps over there” you just need to …

maciej: (talking about copying from a proxy to a new object, event listeners and expandos.) I know general proxies are hard to make fast, but what about a proxy that just forwards to one of two objects. ES engine authors, how hard is this? The window object can do magic like this? It was a yearlong parade of security holes…

adamk: it’s still not interoperable…

anne: if you have proxies you don’t need to do this remove and insert trick

maciej: that’s interesting, you can do the pointer swap at the end. At this case you not only need to propagate event listeners but shadow DOM

domenic: and the child list…

adamk: and you need to find any references to that thing in JavaScript

maciej: the child and attribute lists would need to be merged … if we accept other weird cases this shows we can get a lot of what we want

adamk: need to see more of the version on the right, there’s devils in those details

domenic: when you said things about iframes, I got scared -- really like the P1 P2 P3 (brings up the Parser Created Constructors). If the parser’s seen your el, you just modify the prototype that’s already there

travil: this is like upgrade?

domenic: achieves similar results, but doesn’t actually change prototypes.

travil: do you need to track all instances?

adamk: two types of prototype changing -- 1) swizzling and 2) mutating the prototype object.

domenic: explains “set”: if we set a name that already appears in the doc, we throw, or we could say that the ones were created before, we can...

maciej: does createdCallback exist in this model?

domenic: I added lifecycle hooks.(explains https://github.com/domenic/webcomponents/blob/parser-created-constructors/proposals/Parser-Created-Constructors.md)

domenic: You can use the constructor syntax, and you can have a fully automatic upgrade. The determinism is still there. So.. maybe that’s what this comes down to. If we need an upgrade of any sort, we need something like what Maciej outlined.

anne: so all three proposals have synchronous constructors, so that seems like something we would need to figure out. P3 is never achieved.

maciej: it would be possible in my proposal to never do that, or if you’re doing a set of compound steps you do the upgrade steps at the end. In the second one you could do the same trick to avoid having to run code during editing code. For a parser-created element or simple cases like cloneNode of a leaf node you could run the constructor; for complex cases create the proxy and do the upgrade dance at the end.

domenic: we could go all the way and do one extreme version: we always do upgrade

maciej: (discusses proposals), they show that this is a tractable problem.

sorvel: a potential to do something less strong than removing the children? Element can’t see any children?

maciej: tricky, and weird. probably not a good idea.

domenic: introduce a new concept called “hidden”, something we can skip.

maciej: removal is one thing, but you also want to adds things with callback, lots of tricky things.

anne: removing the style element with affect rendering

maciej: does the order of insertion for style matter? travis, anne -- yes

dglazkov: what about the finished parsing children?

anne: dialog and fullscreen are also affected, you would exit fullscreen on an upgrade

maciej: you would end up with children of custom elements being upgraded first

dominicc: I thought polymer like that?

scott: we have landed in a place where we can’t rely on anything

maciej: that gets you down to two states; createElement is like being parsed with no children. If you deep clone an element with children, you wouldn’t call finishedParsingChildren is weird.

dglazkov: we have the hook finishedParsingChildren, we can call the callback anything.

anne: removing and reinserting seems infeasible because of iframe style dialog … everything that has hooks for inserting and removing from the document

rniwa: we could add handwaving to those elements’ algorithms

domenic: what was the goal?

maciej: so the sequence of steps is always be the same. still need individual callbacks.

domenic: the reason we’re hiding this is to get you to consistent state. We’re doing this to make you not see the state that’s changed between when element instantiated and callback is called.

maciej: what we want to have happen is that the custom element code cannot observe whether it is in the document or not; have children or not; etc. and what we don’t want to have happen is the destructive effects of removal. “Hidden” is a red herring. So strawman, what if you removed them and just didn’t call the internal hooks? Ideally you should be able to move things in the DOM without crazy destructive side effects.

anne: not feasible, you can have a reference to the iframe and start acting on it and it’s simultaneously in and not in the document and things will break. Proxy with pointer swap seems feasible but people had non specific concerns.

maciej: we need to flesh these out. Maybe we don’t care about iframes with Custom Elements.

anne: and fullscreen? and dialog? Removing a fullscreen element pops you out of fullscreen?

(kidding around about this being a corner case)

maciej: Maybe we just define these corner cases even if it’s not pretty “fix it like you’d fix a dog” killing and resetting iframes might be less bad than forcing authors to deal with parser non-determinism forever.

slightlyoff: you could only see the iframe internals if it’s the same origin

dominicc: I guess you could postMessage

travis: would like to pursue dglazkov’s idea on finishParsingChildren. it seems to solve non-determinism.

maciej, scott: you can never assume your children are all there

travis: I’m talking about the initial state; you still have to react to changes.

scott: it’s too easy to write somethngi that depends on exactly what’s available when it is created

maciej: it’s better to always create elements in a blank state and force them to handle callbacks for changes so they also have to handle the dynamic states

rniwa: (example of the problem)

dglazkov: there are two different things, anticipating dynamic changes to the element, which I agree with. And the other thing is running when you’re in some random state because the parser finished a packet.

maciej: if you’ve coded to handle dynamic updates you don’t want to write things twice so your createdCallback will just want to call your update handlers with the initial state. It’s a TRAP!

sorvell: so (someone) said we should consider these separately

maciej: there’s a tricky aspect where if you have an async script element and it has the definition where the open tag of the element has been parsed but not the closed element; you have to have a queue for the not-yet-safe-to-upgrade elements and do them later. My favourite solution is the proxy solution but in needs more details fleshed out. It gives you (enumerates benefits.)

domenic: I agree; this lengthens the path to getting this speced and implemented so much. We already have to work out when to do things synchronously, but also..

anne: but you could always do upgrade

maciej: because the upgrade case is “tabula rasa” you could treat calling it synchronously as an optimization, (example of parser already being able to call script)

domenic: so we need to be able to have proxies and copy over the internal state that isn’t handled by the backing object

anne: if you have a proxy class, it could handle the event listeners

domenic: proxies are only for custom state

maciej: you could require that getters or setters on the proxy … (something)

anne: are proxies visible to script? What is proxy instance.prototype?

domenic: we have a bad record with this historically. Prototype is just a property you can point to anything.

adamk: the constructor can’t fake the “this”, it won’t match the proxy

(crosstalk about proxies, it’s all very very very deep)

(Talk about having only one proxy and having super return the same object.)

dominicc proposes an idea of using no proxies (swizzling -- dominic, fill it in here :)

maciej: the tradeoff is, do you want to do this whacky upgrade dance with removing children, or do you want to use a proxy.

dglazkov: that’s why you should use finished children hook instead!

adamk: this still doesn’t make anne happy, but this indicates ES6 from behaving naughtily and returning an existing object.

anne wants explanation

maciej: this is a way to have constructors and consistency…

anne: we were also talking about returning the proxy instance from super, but that would also have children

rniwa: I think maciej was saying we would (comment about the ordering of operations) so this doesn’t work with iframes

maciej: I think we need bake time for these proposals to figure out if any of these are feasible

domenic: well, we’re here…

maciej: are there any other open issues?

dominicc: ”is”

rniwa: when the upgrade happens

maciej: I think this settles that

anne: any shadow DOM topics so we can ship that

charles, mark, etc. : ”is”

domenic, scott the set of custom element callbacks

charles: I suggest we take a break before we dive into these


domenic: evolution I have. Consistent state. What if we call constructor, but at the created callback time. We have a consistent state, even if this is the void state.

maciej: when would there be no void state? Parser void state is when you don’t have any children, siblings, or parent.

domenic: kind of okay to have a parent?

maciej: still get an inconsistency when created by the parser vs. not by the parser.

domenic: still pretty reasonable.

maciej: Polymer folks said it was a problem

domenic: we could reinforce by always calling callbacks.

maciej: you could just write it wrong by not listening to callback at all

sorvel: want to accommodate the most the person who’s typing HTML. The person who’s writing components is the one who should take the responsibility

maciej: let’s come up with a proposal that tries to address both

domenic: ok, let’s start with attributes!

annevk,maciej point out the problem with global attributes -- focus/style/etc.

maciej tries to enumerate consistent state (aria, iframes, object, etc.) -- elements with destructive side effects.

dominicc: two cases: destructive side effects, we could delay them until it goes back in. What about the weird state when the user code is reaching out and touching it and it’s in the weird state.

maciej: question? how common is it to have an iframe as a descendant of a custom element? if it’s not a lot, maybe it’s okay to do something sucky.

adamk, domenic give examples (layout custom elements with ads or “like” widgets)

annevk: choose between determinism and upgrades

weinig: what do peeps typically do in custom element created callbacks?

sjmiles, sorvell typically peeps write code that does not anticipate having different states. Polymer usually attaches shadow DOM and then queues up attribute callbacks.

maciej: you are effectively faking tabula rasa

sjmiles: yes

weinig: is there a way to avoid createdCallback or constructor at all?

sjmiles: we considered just removing it

weinig: maybe a PImpl pattern

sjmiles: reluctant to say that nobody needs it, but maybe

maciej: I guess it’s like Proxy

domenic: people want getters/methods -- and you can’t do that. I guess no constructor with data pimpl, something we could do.

sjmiles: call createShadowRoot?

adamk: what are we trying to do? a) Prevent doing stuff in constructor or b) limit visible local state inside of a constructor

rniwa: headless shadow root, that you can create and pass, and it could be attached later

annevk: state object, it has shadow root, and it gets copied over.

maciej: what if you want to have a light-dom custom element. want to create light dom in the constructor.

weinig: why?

rniwa: also could do this when inserted.

sjmiles: want to be lazy

adamk: what’s the right time to start work? inserted may be called when you already have children, and that could lead to inconsistent state.

rniwa: distinction is expectation. Construction state is initial slate.

domenic: maybe there should be two callbacks? created callback and constructor. “Created” generally called when you have children/attributes. Created insight about timing for the developer.

annevk: what’s the problem with the state object? Why is it disliked?

maciej: assumptions: createdCallback does not actually get the element, only as subset of some properties. There is some way for you to create/access an interior state object. How do you pass the methods/properties to your element?

sjmiles: set the property, and copy properties and ignore it.

maciej: copying properties seems like a weird way of doing this?

maciej, sjmiles are discussing a state object vs. upgrade dance solution.

slightlyoff: what is the specific bad behavior with iframe

annevk: hard side effects of when an element is removed from the document

maciej: seems like layout manager is a bad candidate for upgrade.

sjmiles: roughly true, but doesn’t matter. People do it all the time.

(discussion about FOUC and footguns)

maciej: state object moves us farther away from having constructors

travil: compatible with a world with isolated custom elements

domenic: oooooh

annevk: state object solves one problem with initialization, but still does not solve problems with callbacks

sjmiles: we had to really embrace the dynamicism of things coming in.

maciej: what if the means of exposing custom methods were different from custom element instantiation?

domenic: looks a lot like PCC, except the method does not have access to custom element itself.

rniwa: how do you create instance variables?

adamk: initalizers in the future, but right now you use constructors. greatly debated, but ways out?

rniwa: what if we got rid of created/constructor completely. When initializers arrive, you no longer has to have an extra check for initialization.

DG: People get bitten because they assume a state that isn’t reliable, because callbacks are queued

Maciej: Are they microtasks?

DG: No, a queue.

[cross discussion :(]

DG: inconsistent state isn’t just a problem of initialization. You could have callbacks in a queue because you’re doing appendChild so you cannot rely on the state. it is a cultural shift in how to build things. Inconsistent state will be constant part of the landscape

Scott: Yes. Making that less bad is a good idea, but shouldn’t die if we can’t do that

Maciej: if we bite the bullet on constructors in random code, @@@

rniwa: We already have to do this. Same with beforeunload on iframe. There are a bunch of others. Don’t think we can delay stuff to be safer - we can’t get rid of what we have now.

AvK: These affect range ops. Spec doesn’t deal with these, does it?

MJS: Prolly not.

AvK: There are removing steps but range operations can do nasty things

MJS: Even appendChild might have to happen with things going on between the steps. The algorithm has to deal with that

AvK: So we have to support mutation events in the DOM

RN: Yes. We already have to do that though.

AvK: We need to spec these pieces.

RN: list of events: blur, focus/in/out, beforeunload on iframe’s document or the element itself.

Discussion about the value of synchronous callbacks, and whether they offer value vs. cost. There are already many cases where we (browsers) fire synchronous events, and the browsers are hardened to handle these cases. Why offer asynchronous (scoped) callbacks when we could get the actual synchronous callbacks?

anne: The nanotask thing is only really different from the synchronous case when you have compound operations as far as I can tell, like innerHTML or a range clone or delete. If we already need to run synchronous code where you do the blur.

sam: Can you get into the case where an element and its attribute callbacks are out of sync?

dominicc: I’ve seen editing do it.

maciej: multiple in/out of document can make you out of sync by using appendchild

anne: we have a primitive operation for inserting a documentfragment



maciej: when you get a removed callback ideally you wouldn’t have a parent and after inserted you would, so with an appendChild remove you should not have the old parent or the new parent at that point

annevk: the problem is that the DOM spec does not spec append/remove correctly.

adamk: what about editing? Don’t we already delay something?

maciej: went with the assumption that it was helped, but it was incorrectly naive.

adamk: conclusion that it doesn’t matter if we add more attack vectors.

maciej: if you’re trying to add memory corruption, doesn’t matter if it’s weird or super-weird.

(therapy session about mutation events and editing)

maciej: need to have an agenda for the rest of the meeting

[End of google docs copy]

[Ryosuke joins, Alex is out]

[Alex has not been taken out, because he is back]

<smaug> oh, etherpad

<slightlyoff> rumors of my death (etc. etc.)

Etherpad copy

Shared Doc for afternoon notes: https://docs.google.com/document/d/1KSwKrTU2d0uJCf55tV-jur_0sYxCNMuM7Dl3vqb0bu4/edit?usp=sharing

Custom constructors



createdCallback of some sort (i.e. running author code right before returning to script)



Desirable Properties




Maciej's thoughts on how to get as many of these as possible (copied from whiteboard):

1. An approach to meeting the key P1 goals

In the No-Upgrade scenario (coming from the definition parser or at creation time), call the created callback immediately.

In upgrade scenario:

2. If you wanted to use ES6 constructor syntax

In No-Upgrade case, call the constructor

In the upgrade case:

Create a proxy.

and then ummm… all the steps above?

3. Domenic's proposal

Parser-created constructors

elementsRegistry.set("x-foo", class C extends HTMLElement{}).setLifecycle(
          { created(…) {} } )

Another proposal from Domenic/Dominic:

let returnMe;

class HTMLElement {
    constructor() {
        if (returnMe) {
            return returnMe;

        // ...

        return allocateFromUACode();

class XFoo extends HTMLElement {
    constructor() {
        super(); // effectively does this = returnMe

function upgradeEl(el) {
    returnMe = el;
    new XFoo();

Summary of Action Items

[End of minutes]

Minutes formatted by David Booth's scribe.perl version 1.140 (CVS log)
$Date: 2015/07/22 14:04:15 $

Scribe.perl diagnostic output

[Delete this section before finalizing the minutes.]
This is scribe.perl Revision: 1.140  of Date: 2014-11-06 18:16:30
Check for newer version at http://dev.w3.org/cvsweb/~checkout~/2002/scribe/

Guessing input format: RRSAgent_Text_Format (score 1.00)

Succeeded: s/delelte/delete on a focused thing/
Succeeded: s/rage/range/
Succeeded: s|https://etherpad.mozilla.org/customelements|-> https://etherpad.mozilla.org/customelements pros and cons of proposals|
Succeeded: s/goes on/goes on if you only get the propotypes later/
Succeeded: s/means/means - is it bimodal?]/
Found Scribe: chaals
Inferring ScribeNick: chaals

WARNING: No "Topic:" lines found.

Present: Annevk DomC Chaals Léonie AliceB AlexR Hayato DomD MarkG WChen Samw othermaci-J TOC ScottM Sorvall AKlein Dglazkov BinHu Travis Arron Ryosuke

WARNING: No meeting chair found!
You should specify the meeting chair like this:
<dbooth> Chair: dbooth

Got date from IRC log name: 21 Jul 2015
Guessing minutes URL: http://www.w3.org/2015/07/21-webapps-minutes.html
People with action items:

WARNING: Input appears to use implicit continuation lines.
You may need the "-implicitContinuations" option.

WARNING: No "Topic: ..." lines found!
Resulting HTML may have an empty (invalid) <ol>...</ol>.

Explanation: "Topic: ..." lines are used to indicate the start of
new discussion topics or agenda items, such as:
<dbooth> Topic: Review of Amy's report

[End of scribe.perl diagnostic output]