W3C home > Mailing lists > Public > www-dom@w3.org > January to March 2012

Re: [dom] mutation observer follow up

From: Adam Klein <adamk@chromium.org>
Date: Fri, 17 Feb 2012 11:13:28 -0800
Message-ID: <CAEvLGcJwxrm-wMWF6NhhiUeTFD6aOP-BcxaxTooJSfL3wSG5EQ@mail.gmail.com>
To: olli@pettay.fi
Cc: Anne van Kesteren <annevk@opera.com>, "www-dom@w3.org" <www-dom@w3.org>
On Fri, Feb 17, 2012 at 10:51 AM, Olli Pettay <Olli.Pettay@helsinki.fi> wrote:
> On 02/17/2012 08:41 PM, Adam Klein wrote:
>> On Fri, Feb 17, 2012 at 5:55 AM, Anne van Kesteren<annevk@opera.com>
>>  wrote:
>>> Is there any particular reason why the "registered observer" definition
>>> is
>>> sometimes referred to as "registration" and sometimes as "registered
>>> observer"?
>> Only that I first thought that "registration" might suffice as an
>> explanation but switched to the clearer (but more verbose) "registered
>> observer" later (the class in WebKit is called
>> MutationObserverRegistration). Using one name everywhere seems fine;
>> if you have any ideas on a better (possibly one-word) name, I'd be
>> happy for suggestions.
>>> What is "transient" for?
>> It's needed to make sure observers can hear about things that happen
>> in a newly-disconnected tree. Imagine I want to hear when any<a>  tags
>> leave the document, and consider the dom tree:
>> <div>
>>   <span>
>>     <a></a>
>>   </span>
>> </div>
>> where there's a subtree observer at<div>.  Now I do:
>> span.remove()
>> a.remove()
>> If we didn't have transient observers, the observer would only see one
>> record, notifying it that span was removed. But by that time,<a>
>> would no longer be a child of<span>, so the<a>  tag would have been
>> removed "in secret".  That's why we need to add transient observers
>> every time we disconnect some node where a subtree observer exists
>> (note that it's required also for, e.g., attribute mutations: what if
>> <a>'s href attr changed while it was disconnected?).
>> I'll explain below how transient observers are different from normal
>> registered observers.
>>> We need to add some kind of flag to "insert"/"remove" so that "replace
>>> all"
>>> can have a special MutationRecord object for textContent and innerHTML
>>> and
>>> such (and that then "insert"/"remove" not generate additional
>>> MutationRecord
>>> objects).
>> Yes, that's a major thing that's missing. In discussion with Rafael,
>> we've been thinking about trying to simplify the way textContent and
>> innerHTML records work such that the removals and insertions would be
>> in different records (in WebKit, at least, this would simplify
>> implementation). The basic idea would be that "remove all children"
>> would trigger one record, and then inserting the children would
>> trigger a second.  I'm interested if Olli has any input on this from
>> an implementation perspective in Firefox.
> That feels a bit strange. Either we collect the changes to one
> record (both removals and insertions) or we create separate
> record for all the changes (one record for each node removal etc.)
> The latter would be easier for implementation, but would lead to
> tons of records.
> So, at least atm I'd prefer having just one record for textContent/innerHTML
> -like mutations

The nice thing about doing two records (one with all the removals, one
with all the additions) instead of one is that this requirement of
"collection" would be gone. Instead, the "remove all" step would just
snap up the whole removed child list, and the "insert a
documentfragment" would take care of the rest (this is the
implementation simplification I referred to). Right now, we use an
RAII object to collect mutations, but in the common case we only
"collect" one thing (for appendChild, insertBefore, removeChild).

>From the point of view of an observer, there's no difference between
getting two records and getting one record.  And memory-usage wise,
there's barely a difference (it's just a few pointers).

- Adam
Received on Friday, 17 February 2012 19:13:59 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 20 October 2015 10:46:18 UTC