Re: Mutation events replacement

On Wednesday, June 29, 2011, Aryeh Gregor <Simetrical+w3c@gmail.com> wrote:
> On Tue, Jun 28, 2011 at 5:24 PM, Jonas Sicking <jonas@sicking.cc> wrote:
>> This new proposal solves both these by making all the modifications
>> first, then firing all the events. Hence the implementation can
>> separate implementing the mutating function from the code that sends
>> out notifications.
>>
>> Conceptually, you simply queue all notifications in a queue as you're
>> making modifications to the DOM, then right before returning from the
>> function you insert a call like "flushAllPendingNotifications()". This
>> way you don't have to care at all about what happens when those
>> notifications fire.
>
> So when exactly are these notifications going to be fired?  In
> particular, I hope non-DOM Core specifications are going to have
> precise control over when they're fired.  For instance, execCommand()
> will ideally want to do all its mutations at once and only then fire
> the notifications (which I'm told is how WebKit currently works).  How
> will this work spec-wise?  Will we have hooks to say things like
> "remove a node but don't fire the notifications yet", and then have to
> add an extra line someplace saying to fire all the notifications?
> This could be awkward in some cases.  At least personally, I often say
> things like "call insertNode(foo) on the range" in the middle of a
> long algorithm, and I don't want magic happening at that point just
> because DOM Range fires notifications before returning from
> insertNode.

Heh. It's like spec people has to deal with the same complexities as
implementors has had for years. Revenge at last!!

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.

> Also, even if specs have precise control, I take it the idea is
> authors won't, right?  If a library wants to implement some fancy
> feature and be compatible with users of the library firing these
> notifications, they'd really want to be able to control when
> notifications are fired, just like specs want to.  In practice, the
> only reason this isn't an issue with DOM mutation events is because
> they can say "don't use them", and in fact people rarely do use them,
> but that doesn't seem ideal -- it's just saying library authors
> shouldn't bother to be robust.

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.

> 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?  If we're already delaying
> them such that there are no guarantees about what the DOM will look
> like by the time they fire, it seems like delaying them further
> shouldn't hurt the use-cases too much more.  And then we don't have to
> put further effort into saying exactly when they fire for each method.
>  But this is pretty obvious, so I assume there's some good reason not
> to do it.

To enable things like widget libraries which want to keep state
up-to-date with a DOM.

/ Jonas

Received on Thursday, 30 June 2011 01:12:55 UTC