Bug 70436

Summary: [MutationObservers] Implement basic subtree observation
Product: WebKit Reporter: Adam Klein <adamk>
Component: New BugsAssignee: Adam Klein <adamk>
Status: RESOLVED FIXED    
Severity: Normal CC: darin, ojan, rafaelw, rniwa, sam, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 68729    
Attachments:
Description Flags
Patch
none
Extracted helper function
none
Merged to r98133
none
Patch for landing none

Description Adam Klein 2011-10-19 13:38:07 PDT
[MutationObservers] Implement basic subtree observation
Comment 1 Adam Klein 2011-10-19 13:45:55 PDT
Created attachment 111668 [details]
Patch
Comment 2 Rafael Weinstein 2011-10-20 14:19:52 PDT
Comment on attachment 111668 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111668&action=review

> Source/WebCore/dom/Node.cpp:2695
> +        const size_t size = observerEntries->size();

maybe extract a static utility function here?
Comment 3 Adam Klein 2011-10-20 14:33:18 PDT
Comment on attachment 111668 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111668&action=review

>> Source/WebCore/dom/Node.cpp:2695
>> +        const size_t size = observerEntries->size();
> 
> maybe extract a static utility function here?

That's how I started, but it the inner if-statement differs depending on whether we're looking at the node itself or one of its ancestors.  This means that either we do extra checking inside the loop (bad for performance), or we extract the test out into a functor (bad for readability, imho).  That's why I ended up "unrolling" the code manually.  Let me know if you'd prefer the functor approach (I really don't want to do any more work in the inner loop than I have to).
Comment 4 Ryosuke Niwa 2011-10-20 15:18:37 PDT
Comment on attachment 111668 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111668&action=review

>>> Source/WebCore/dom/Node.cpp:2695

>> 
>> maybe extract a static utility function here?
> 
> That's how I started, but it the inner if-statement differs depending on whether we're looking at the node itself or one of its ancestors.  This means that either we do extra checking inside the loop (bad for performance), or we extract the test out into a functor (bad for readability, imho).  That's why I ended up "unrolling" the code manually.  Let me know if you'd prefer the functor approach (I really don't want to do any more work in the inner loop than I have to).

I think we should keep matches to take MutationObserverOptions and do:
if (Vector<MutationObserverEntry>* observerEntries = mutationObserverEntries())
    addMatchedObserverEntriesToSet(observerSet, *observerEntries, type);
for (Node* node = parentNode(); node; node = node->parentNode()) {
    if (Vector<MutationObserverEntry>* observerEntries = node->mutationObserverEntries())
        addMatchedObserverEntriesToSet(observerSet, *observerEntries, type | WebKitMutationObserver::Subtree);
}
Comment 5 Adam Klein 2011-10-20 15:32:42 PDT
Created attachment 111856 [details]
Extracted helper function
Comment 6 Adam Klein 2011-10-20 15:33:23 PDT
Comment on attachment 111668 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=111668&action=review

>>>> Source/WebCore/dom/Node.cpp:2695
>>>> +        const size_t size = observerEntries->size();
>>> 
>>> maybe extract a static utility function here?
>> 
>> That's how I started, but it the inner if-statement differs depending on whether we're looking at the node itself or one of its ancestors.  This means that either we do extra checking inside the loop (bad for performance), or we extract the test out into a functor (bad for readability, imho).  That's why I ended up "unrolling" the code manually.  Let me know if you'd prefer the functor approach (I really don't want to do any more work in the inner loop than I have to).
> 
> 

After talking to Rafael offline, came up with a fix (just make matches() stricter).  I've now extracted the loop into its own function.
Comment 7 Adam Klein 2011-10-21 13:24:37 PDT
Created attachment 112009 [details]
Merged to r98133
Comment 8 Ryosuke Niwa 2011-10-21 15:22:34 PDT
Comment on attachment 112009 [details]
Merged to r98133

View in context: https://bugs.webkit.org/attachment.cgi?id=112009&action=review

r=me provided problems listed below are all addressed.

> Source/WebCore/ChangeLog:9
> +        Note that this patch only implements "basic" subtree
> +        semantics, not the fully robust semantics described in

Nit: semantics should probably on the previous line to avoid awkward line break.

> Source/WebCore/ChangeLog:22
> +        (WebCore::addMatchingObservers): Static helper method for the below.

I'm not sure what you're referring to by "the below". Could you spell out the function name here?

> Source/WebCore/dom/Node.cpp:2703
> +    if (observerEntries) {

We prefer early exiting over nesting ifs especially when the if statement appears at the beginning of a function and the normal flow is to do whatever inside the if.

> LayoutTests/fast/mutation/observe-subtree.html:32
> +        observer = new WebKitMutationObserver(function(m) {
> +            mutations = m;

Nit: please avoid using one-letter variable.

> LayoutTests/fast/mutation/observe-subtree.html:75
> +        observer = new WebKitMutationObserver(function(m) {
> +            mutations = m;
> +        });
> +        observer2 = new WebKitMutationObserver(function(m) {
> +            mutations2 = m;
> +        });

Ditto about one-letter variables.

> LayoutTests/fast/mutation/observe-subtree.html:116
> +        observer = new WebKitMutationObserver(function(m) {
> +            mutations = m;
> +            ++calls;
> +        });

Ditto.
Comment 9 Adam Klein 2011-10-21 15:36:15 PDT
Comment on attachment 112009 [details]
Merged to r98133

View in context: https://bugs.webkit.org/attachment.cgi?id=112009&action=review

>> Source/WebCore/ChangeLog:9
>> +        semantics, not the fully robust semantics described in
> 
> Nit: semantics should probably on the previous line to avoid awkward line break.

Done.

>> Source/WebCore/ChangeLog:22
>> +        (WebCore::addMatchingObservers): Static helper method for the below.
> 
> I'm not sure what you're referring to by "the below". Could you spell out the function name here?

Done.

>> Source/WebCore/dom/Node.cpp:2703
>> +    if (observerEntries) {
> 
> We prefer early exiting over nesting ifs especially when the if statement appears at the beginning of a function and the normal flow is to do whatever inside the if.

Done.

>> LayoutTests/fast/mutation/observe-subtree.html:32
>> +            mutations = m;
> 
> Nit: please avoid using one-letter variable.

Done.

>> LayoutTests/fast/mutation/observe-subtree.html:75
>> +        });
> 
> Ditto about one-letter variables.

Done.

>> LayoutTests/fast/mutation/observe-subtree.html:116
>> +        });
> 
> Ditto.

Done.
Comment 10 Adam Klein 2011-10-21 15:36:47 PDT
Created attachment 112033 [details]
Patch for landing
Comment 11 WebKit Review Bot 2011-10-21 15:51:39 PDT
Comment on attachment 112033 [details]
Patch for landing

Clearing flags on attachment: 112033

Committed r98163: <http://trac.webkit.org/changeset/98163>
Comment 12 WebKit Review Bot 2011-10-21 15:51:44 PDT
All reviewed patches have been landed.  Closing bug.