Re: Mutation events replacement

On Thu, Jun 30, 2011 at 2:11 AM, Jonas Sicking <jonas@sicking.cc> wrote:

> 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.


Since the execution turn is a DOM/host concept, we can add something like an
event handler to the scope which fires before exit. Something like:

   window.addEventListener("turnEnd", ...);

Listeners could be handed the mutation lists as members of the event object
they're provided. I know Rafael has more concrete ideas here about the
queues to be produced/consumed, but generally speaking, having the ability
to continue to add turnEnd listeners while still in a turn gives you the
power to operate on consistent state without forcing the start/end pair or
specific exception handling logic. Think of it as a <script> element's
"finally" block.


> > 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 10:04:40 UTC