- From: Aryeh Gregor <Simetrical+w3c@gmail.com>
- Date: Tue, 5 Jul 2011 12:30:52 -0400
- To: Jonas Sicking <jonas@sicking.cc>
- Cc: "Olli@pettay.fi" <Olli@pettay.fi>, Anne van Kesteren <annevk@opera.com>, Webapps WG <public-webapps@w3.org>
On Wed, Jun 29, 2011 at 9:11 PM, Jonas Sicking <jonas@sicking.cc> wrote: > Heh. It's like spec people has to deal with the same complexities as > implementors has had for years. Revenge at last!! :) Yeah, as specs get more detailed, writing them is kind of like writing a mini-implementation. Except spec authors get to use pseudocode that skips over inconvenient details if they don't seem important, and we don't have to care as much about performance. Actually, the way I'm writing specs right now maps almost line-to-line to a JS implementation I write in parallel. > Jokes aside. I think the way to do this is that the spec should > introduce the concept of a "compound mutating function". Functions > like insertBefore, removeChild and the innerHTML setter should claim > to be such functions. Any other function can also be defined to be > such a function, such as your execCommand function. > > Whenever a mutation happens, the notifications for it is put on a > list. Once the outermost compound mutation function exits, all > notifications are fired. That makes sense. It will look close to sync in some cases, but there will be lots of common things that make it look closer to async (parser insertions, innerHTML, etc.), so hopefully it won't be too confusing for authors. > The problem is that there is no good way to do this. The only API that > we could expose to JS is something like a beginBatch/endBatch pair of > functions. But what do we do if the author never calls endBatch? > > This is made especially bad by the fact that JavaScript uses > exceptions which makes it very easy to miss calling endBatch if an > exception is thrown unless the developer uses "finally", which most > don't. Why not have a function like suspendMutationEvents() that just makes the current JavaScript function a compound mutating function? That is, when you call that function, all mutation events are suspended until the function exits. I don't know if it would be useful enough to be worth creating, but it should work fine in principle, right? >> Maybe this is a stupid question, since I'm not familiar at all with >> the use-cases involved, but why can't we delay firing the >> notifications until the event loop spins? . . . > > To enable things like widget libraries which want to keep state > up-to-date with a DOM. I'm inferring from other posts in the thread that this is specifically because they want to be able to respond to mutations before the document is repainted or becomes responsive to user interaction. Is this right, or are there other reasons it can't be fully async? Specifically, could we make a new "pre-event loop" that runs right before the regular event loop, therefore before the page responds to user input but after the currently running script has completed? Or would this be a problem because the page might be repainted before the event loop spins, and we don't want the intermediate DOM to be user-visible? Are there other concerns? If it turns out one of the constraints here is that we want mutation events to finish before the page is repainted, we should explicitly specify that UAs must not update the display of the page due to DOM mutations between the time when a compound mutating function starts running and when all corresponding mutation handlers have run, or something like that. That makes sense: we don't want the page to be repainted halfway through an execCommand() execution anyway, for instance.
Received on Tuesday, 5 July 2011 16:31:39 UTC