Re: Mutation events replacement

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