Changeset 99338 in webkit


Ignore:
Timestamp:
Nov 4, 2011 5:44:46 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[MutationObservers] Refactor MutationObserverRegistration into its own class that is
referenced by registration points

https://bugs.webkit.org/show_bug.cgi?id=71577

Patch by Rafael Weinstein <rafaelw@chromium.org> on 2011-11-04
Reviewed by Ojan Vafai.

MutationObserverRegistration is now owned by the node which is observed. If transient
registrations are created, they hold a reference to this object.

The ownership relationship between Node, MutationObserverRegistration &
WebKitMutationObserver now goes like this: WebKitMutationObserver is RefCounted -
and only script and MutationObserverRegistration take references to it. Exactly
one MutationObserverRegistration can exist for any given tuple of
<Node, WebKitMutationObserver>. This represents an observer observing at a given
Node. Further observation by the same observer has the effect of *resetting*
the existing observation. The Node owns the MutationObserverRegistration.
Transient registrations are only pointers to the registration. The registration
keeps a RefPtr to its registration node and all of its transient registration nodes
as long as *any* transient registrations exist. This ensures the registration
and all registration nodes stay alive at least until the end of the microtask.

No tests required - refactor only.

  • GNUmakefile.list.am:
  • WebCore.gypi:
  • WebCore.pro:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/CharacterData.cpp:

(WebCore::enqueueCharacterDataMutationRecord):

  • dom/ChildListMutationScope.cpp:

(WebCore::MutationAccumulationRouter::MutationAccumulationRouter::incrementScopingLevel):

  • dom/Element.cpp:

(WebCore::enqueueAttributesMutationRecord):

  • dom/MutationObserverRegistration.cpp: Added.

(WebCore::MutationObserverRegistration::create):
(WebCore::MutationObserverRegistration::MutationObserverRegistration):
(WebCore::MutationObserverRegistration::~MutationObserverRegistration):
(WebCore::MutationObserverRegistration::resetObservation):
(WebCore::MutationObserverRegistration::observedSubtreeNodeWillDetach):
(WebCore::MutationObserverRegistration::clearTransientRegistrations):
(WebCore::MutationObserverRegistration::unregister):
(WebCore::MutationObserverRegistration::shouldReceiveMutationFrom):

  • dom/MutationObserverRegistration.h: Copied from Source/WebCore/dom/WebKitMutationObserver.h.

(WebCore::MutationObserverRegistration::observer):
(WebCore::MutationObserverRegistration::deliveryOptions):

  • dom/Node.cpp:

(WebCore::Node::clearRareData):
(WebCore::Node::mutationObserverRegistry):
(WebCore::Node::transientMutationObserverRegistry):
(WebCore::addObserverToDeliverySet):
(WebCore::Node::collectMatchingObserversForMutation):
(WebCore::Node::getRegisteredMutationObserversOfType):
(WebCore::Node::registerMutationObserver):
(WebCore::Node::unregisterMutationObserver):
(WebCore::Node::registerTransientMutationObserver):
(WebCore::Node::unregisterTransientMutationObserver):
(WebCore::Node::notifyMutationObserversNodeWillDetach):

  • dom/Node.h:
  • dom/NodeRareData.h:

(WebCore::NodeRareData::mutationObserverRegistry):
(WebCore::NodeRareData::ensureMutationObserverRegistry):
(WebCore::NodeRareData::transientMutationObserverRegistry):
(WebCore::NodeRareData::ensureTransientMutationObserverRegistry):

  • dom/WebKitMutationObserver.cpp:

(WebCore::WebKitMutationObserver::~WebKitMutationObserver):
(WebCore::WebKitMutationObserver::observe):
(WebCore::WebKitMutationObserver::disconnect):
(WebCore::WebKitMutationObserver::observationStarted):
(WebCore::WebKitMutationObserver::observationEnded):
(WebCore::WebKitMutationObserver::deliver):

  • dom/WebKitMutationObserver.h:
Location:
trunk/Source/WebCore
Files:
1 added
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r99337 r99338  
     12011-11-04  Rafael Weinstein  <rafaelw@chromium.org>
     2
     3        [MutationObservers] Refactor MutationObserverRegistration into its own class that is
     4        referenced by registration points
     5
     6        https://bugs.webkit.org/show_bug.cgi?id=71577
     7
     8        Reviewed by Ojan Vafai.
     9
     10        MutationObserverRegistration is now owned by the node which is observed. If transient
     11        registrations are created, they hold a reference to this object.
     12
     13        The ownership relationship between Node, MutationObserverRegistration &
     14        WebKitMutationObserver now goes like this: WebKitMutationObserver is RefCounted -
     15        and only script and MutationObserverRegistration take references to it. Exactly
     16        one MutationObserverRegistration can exist for any given tuple of
     17        <Node, WebKitMutationObserver>. This represents an observer observing at a given
     18        Node. Further observation by the same observer has the effect of *resetting*
     19        the existing observation. The Node owns the MutationObserverRegistration.
     20        Transient registrations are only pointers to the registration. The registration
     21        keeps a RefPtr to its registration node and all of its transient registration nodes
     22        as long as *any* transient registrations exist. This ensures the registration
     23        and all registration nodes stay alive at least until the end of the microtask.
     24
     25        No tests required - refactor only.
     26
     27        * GNUmakefile.list.am:
     28        * WebCore.gypi:
     29        * WebCore.pro:
     30        * WebCore.vcproj/WebCore.vcproj:
     31        * WebCore.xcodeproj/project.pbxproj:
     32        * dom/CharacterData.cpp:
     33        (WebCore::enqueueCharacterDataMutationRecord):
     34        * dom/ChildListMutationScope.cpp:
     35        (WebCore::MutationAccumulationRouter::MutationAccumulationRouter::incrementScopingLevel):
     36        * dom/Element.cpp:
     37        (WebCore::enqueueAttributesMutationRecord):
     38        * dom/MutationObserverRegistration.cpp: Added.
     39        (WebCore::MutationObserverRegistration::create):
     40        (WebCore::MutationObserverRegistration::MutationObserverRegistration):
     41        (WebCore::MutationObserverRegistration::~MutationObserverRegistration):
     42        (WebCore::MutationObserverRegistration::resetObservation):
     43        (WebCore::MutationObserverRegistration::observedSubtreeNodeWillDetach):
     44        (WebCore::MutationObserverRegistration::clearTransientRegistrations):
     45        (WebCore::MutationObserverRegistration::unregister):
     46        (WebCore::MutationObserverRegistration::shouldReceiveMutationFrom):
     47        * dom/MutationObserverRegistration.h: Copied from Source/WebCore/dom/WebKitMutationObserver.h.
     48        (WebCore::MutationObserverRegistration::observer):
     49        (WebCore::MutationObserverRegistration::deliveryOptions):
     50        * dom/Node.cpp:
     51        (WebCore::Node::clearRareData):
     52        (WebCore::Node::mutationObserverRegistry):
     53        (WebCore::Node::transientMutationObserverRegistry):
     54        (WebCore::addObserverToDeliverySet):
     55        (WebCore::Node::collectMatchingObserversForMutation):
     56        (WebCore::Node::getRegisteredMutationObserversOfType):
     57        (WebCore::Node::registerMutationObserver):
     58        (WebCore::Node::unregisterMutationObserver):
     59        (WebCore::Node::registerTransientMutationObserver):
     60        (WebCore::Node::unregisterTransientMutationObserver):
     61        (WebCore::Node::notifyMutationObserversNodeWillDetach):
     62        * dom/Node.h:
     63        * dom/NodeRareData.h:
     64        (WebCore::NodeRareData::mutationObserverRegistry):
     65        (WebCore::NodeRareData::ensureMutationObserverRegistry):
     66        (WebCore::NodeRareData::transientMutationObserverRegistry):
     67        (WebCore::NodeRareData::ensureTransientMutationObserverRegistry):
     68        * dom/WebKitMutationObserver.cpp:
     69        (WebCore::WebKitMutationObserver::~WebKitMutationObserver):
     70        (WebCore::WebKitMutationObserver::observe):
     71        (WebCore::WebKitMutationObserver::disconnect):
     72        (WebCore::WebKitMutationObserver::observationStarted):
     73        (WebCore::WebKitMutationObserver::observationEnded):
     74        (WebCore::WebKitMutationObserver::deliver):
     75        * dom/WebKitMutationObserver.h:
     76
    1772011-11-04  Raymond Toy  <rtoy@google.com>
    278
  • trunk/Source/WebCore/GNUmakefile.list.am

    r99332 r99338  
    12701270        Source/WebCore/dom/MutationEvent.cpp \
    12711271        Source/WebCore/dom/MutationEvent.h \
     1272        Source/WebCore/dom/MutationObserverRegistration.cpp \
     1273        Source/WebCore/dom/MutationObserverRegistration.h \
    12721274        Source/WebCore/dom/MutationRecord.cpp \
    12731275        Source/WebCore/dom/MutationRecord.h \
  • trunk/Source/WebCore/Target.pri

    r99332 r99338  
    534534    dom/MouseRelatedEvent.cpp \
    535535    dom/MutationEvent.cpp \
     536    dom/MutationObserverRegistration.cpp \
    536537    dom/MutationRecord.cpp \
    537538    dom/NamedNodeMap.cpp \
     
    16211622    dom/MutationCallback.h \
    16221623    dom/MutationEvent.h \
     1624    dom/MutationObserverRegistration.h \
    16231625    dom/MutationRecord.h \
    16241626    dom/NamedNodeMap.h \
  • trunk/Source/WebCore/WebCore.gypi

    r99332 r99338  
    52675267            'dom/MutationEvent.cpp',
    52685268            'dom/MutationEvent.h',
     5269            'dom/MutationObserverRegistration.cpp',
     5270            'dom/MutationObserverRegistration.h',
    52695271            'dom/MutationRecord.cpp',
    52705272            'dom/MutationRecord.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r99332 r99338  
    4664346643                        </File>
    4664446644                        <File
     46645                                RelativePath="..\dom\MutationObserverRegistration.cpp"
     46646                                >
     46647                                <FileConfiguration
     46648                                        Name="Debug|Win32"
     46649                                        ExcludedFromBuild="true"
     46650                                        >
     46651                                        <Tool
     46652                                                Name="VCCLCompilerTool"
     46653                                        />
     46654                                </FileConfiguration>
     46655                                <FileConfiguration
     46656                                        Name="Release|Win32"
     46657                                        ExcludedFromBuild="true"
     46658                                        >
     46659                                        <Tool
     46660                                                Name="VCCLCompilerTool"
     46661                                        />
     46662                                </FileConfiguration>
     46663                                <FileConfiguration
     46664                                        Name="Debug_Cairo_CFLite|Win32"
     46665                                        ExcludedFromBuild="true"
     46666                                        >
     46667                                        <Tool
     46668                                                Name="VCCLCompilerTool"
     46669                                        />
     46670                                </FileConfiguration>
     46671                                <FileConfiguration
     46672                                        Name="Release_Cairo_CFLite|Win32"
     46673                                        ExcludedFromBuild="true"
     46674                                        >
     46675                                        <Tool
     46676                                                Name="VCCLCompilerTool"
     46677                                        />
     46678                                </FileConfiguration>
     46679                                <FileConfiguration
     46680                                        Name="Debug_All|Win32"
     46681                                        ExcludedFromBuild="true"
     46682                                        >
     46683                                        <Tool
     46684                                                Name="VCCLCompilerTool"
     46685                                        />
     46686                                </FileConfiguration>
     46687                                <FileConfiguration
     46688                                        Name="Production|Win32"
     46689                                        ExcludedFromBuild="true"
     46690                                        >
     46691                                        <Tool
     46692                                                Name="VCCLCompilerTool"
     46693                                        />
     46694                                </FileConfiguration>
     46695                        </File>
     46696                        <File
     46697                                RelativePath="..\dom\MutationObserverRegistration.h"
     46698                                >
     46699                        </File>
     46700                        <File
    4664546701                                RelativePath="..\dom\MutationRecord.cpp"
    4664646702                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r99332 r99338  
    57825782                D619A307144E00BE004BC302 /* ChildListMutationScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D619A305144E00BE004BC302 /* ChildListMutationScope.cpp */; };
    57835783                D619A308144E00BE004BC302 /* ChildListMutationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D619A306144E00BE004BC302 /* ChildListMutationScope.h */; };
     5784                D6E276AF14637455001D280A /* MutationObserverRegistration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */; };
     5785                D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = D6E276AE14637455001D280A /* MutationObserverRegistration.h */; };
    57845786                D70AD65713E1342B005B50B4 /* RenderRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D70AD65513E1342B005B50B4 /* RenderRegion.cpp */; };
    57855787                D70AD65813E1342B005B50B4 /* RenderRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = D70AD65613E1342B005B50B4 /* RenderRegion.h */; };
     
    1308613088                D619A305144E00BE004BC302 /* ChildListMutationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChildListMutationScope.cpp; sourceTree = "<group>"; };
    1308713089                D619A306144E00BE004BC302 /* ChildListMutationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChildListMutationScope.h; sourceTree = "<group>"; };
     13090                D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutationObserverRegistration.cpp; sourceTree = "<group>"; };
     13091                D6E276AE14637455001D280A /* MutationObserverRegistration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutationObserverRegistration.h; sourceTree = "<group>"; };
    1308813092                D70AD65513E1342B005B50B4 /* RenderRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderRegion.cpp; sourceTree = "<group>"; };
    1308913093                D70AD65613E1342B005B50B4 /* RenderRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderRegion.h; sourceTree = "<group>"; };
     
    2110821112                                85031B340A44EFC700F992E0 /* MutationEvent.h */,
    2110921113                                93EEC1F309C2877700C515D1 /* MutationEvent.idl */,
     21114                                D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */,
     21115                                D6E276AE14637455001D280A /* MutationObserverRegistration.h */,
    2111021116                                C6F08FB91430FE8F00685849 /* MutationRecord.cpp */,
    2111121117                                C6F08FBA1430FE8F00685849 /* MutationRecord.h */,
     
    2358623592                                C6F0900A14327B6100685849 /* MutationCallback.h in Headers */,
    2358723593                                85031B4A0A44EFC700F992E0 /* MutationEvent.h in Headers */,
     23594                                D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */,
    2358823595                                C6F08FBD1430FE8F00685849 /* MutationRecord.h in Headers */,
    2358923596                                A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */,
     
    2664126648                                93309DFB099E64920056E581 /* MoveSelectionCommand.cpp in Sources */,
    2664226649                                85031B490A44EFC700F992E0 /* MutationEvent.cpp in Sources */,
     26650                                D6E276AF14637455001D280A /* MutationObserverRegistration.cpp in Sources */,
    2664326651                                C6F08FBC1430FE8F00685849 /* MutationRecord.cpp in Sources */,
    2664426652                                BCF34A3711A231CD00C71804 /* NamedNodeMap.cpp in Sources */,
  • trunk/Source/WebCore/dom/CharacterData.cpp

    r99128 r99338  
    206206static void enqueueCharacterDataMutationRecord(Node* node, const String& oldData)
    207207{
    208     HashMap<WebKitMutationObserver*, MutationObserverOptions> observers;
     208    HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
    209209    node->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::CharacterData);
    210210    if (observers.isEmpty())
  • trunk/Source/WebCore/dom/ChildListMutationScope.cpp

    r99305 r99338  
    245245    }
    246246
    247     HashMap<WebKitMutationObserver*, MutationObserverOptions> observers;
     247    HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
    248248    target->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::ChildList);
    249249    if (observers.isEmpty())
  • trunk/Source/WebCore/dom/Element.cpp

    r98910 r99338  
    634634static void enqueueAttributesMutationRecord(Element* element, const QualifiedName& name, const AtomicString& oldValue)
    635635{
    636     HashMap<WebKitMutationObserver*, MutationObserverOptions> observers;
     636    HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
    637637    element->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::Attributes);
    638638    if (observers.isEmpty())
  • trunk/Source/WebCore/dom/MutationObserverRegistration.h

    r99337 r99338  
    2929 */
    3030
    31 #ifndef WebKitMutationObserver_h
    32 #define WebKitMutationObserver_h
     31#ifndef MutationObserverRegistration_h
     32#define MutationObserverRegistration_h
    3333
    3434#if ENABLE(MUTATION_OBSERVERS)
    3535
    36 #include <wtf/HashMap.h>
     36#include "WebKitMutationObserver.h"
    3737#include <wtf/HashSet.h>
    38 #include <wtf/PassOwnPtr.h>
    39 #include <wtf/RefCounted.h>
    40 #include <wtf/RefPtr.h>
    41 #include <wtf/Vector.h>
     38#include <wtf/text/AtomicString.h>
     39#include <wtf/text/AtomicStringHash.h>
    4240
    4341namespace WebCore {
    4442
    45 class MutationCallback;
    46 class MutationRecord;
    47 class Node;
     43class MutationObserverRegistration {
     44public:
    4845
    49 typedef unsigned char MutationObserverOptions;
    50 typedef HashSet<RefPtr<Node> > NodeHashSet;
     46    static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<WebKitMutationObserver>, Node*);
    5147
    52 class WebKitMutationObserver : public RefCounted<WebKitMutationObserver> {
    53 public:
    54     enum MutationType {
    55         ChildList = 1 << 0,
    56         Attributes = 1 << 1,
    57         CharacterData = 1 << 2
    58     };
     48    ~MutationObserverRegistration();
    5949
    60     enum OptionFlags {
    61         Subtree = 1 << 3,
    62         AttributeOldValue = 1 << 4,
    63         CharacterDataOldValue = 1 << 5,
    64         AttributeFilter = 1 << 6
    65     };
     50    void resetObservation(MutationObserverOptions);
     51    void observedSubtreeNodeWillDetach(PassRefPtr<Node>);
     52    void clearTransientRegistrations();
     53    void unregister();
    6654
    67     static PassRefPtr<WebKitMutationObserver> create(PassRefPtr<MutationCallback>);
    68     static void deliverAllMutations();
     55    bool shouldReceiveMutationFrom(Node*, WebKitMutationObserver::MutationType);
    6956
    70     ~WebKitMutationObserver();
    71 
    72     void observe(Node*, MutationObserverOptions);
    73     void disconnect();
    74     void willDetachNodeInObservedSubtree(PassRefPtr<Node> registrationNode, MutationObserverOptions, PassRefPtr<Node> detachingNode);
    75     void observedNodeDestructed(Node*);
    76     void enqueueMutationRecord(PassRefPtr<MutationRecord>);
     57    WebKitMutationObserver* observer() { return m_observer.get(); }
     58    MutationRecordDeliveryOptions deliveryOptions() { return m_options & (WebKitMutationObserver::AttributeOldValue | WebKitMutationObserver::CharacterDataOldValue); }
    7759
    7860private:
    79     WebKitMutationObserver(PassRefPtr<MutationCallback>);
     61    MutationObserverRegistration(PassRefPtr<WebKitMutationObserver>, Node*);
    8062
    81     void clearAllTransientObservations();
    82     void deliver();
     63    RefPtr<WebKitMutationObserver> m_observer;
     64    Node* m_registrationNode;
     65    RefPtr<Node> m_registrationNodeKeepAlive;
     66    typedef HashSet<RefPtr<Node> > NodeHashSet;
     67    OwnPtr<NodeHashSet> m_transientRegistrationNodes;
    8368
    84     RefPtr<MutationCallback> m_callback;
    85     Vector<RefPtr<MutationRecord> > m_records;
    86     Vector<Node*> m_observedNodes; // NodeRareData has a RefPtr to this, so use a weak pointer to avoid a cycle.
    87 
    88     // FIXME: Change this to be OwnPtr<NodeHashSet> when OwnPtr supports being contained as map values.
    89     HashMap<RefPtr<Node>, NodeHashSet*> m_transientObservedNodes;
     69    MutationObserverOptions m_options;
    9070};
    9171
    92 }
     72} // namespace WebCore
    9373
    9474#endif // ENABLE(MUTATION_OBSERVERS)
    9575
    96 #endif // WebKitMutationObserver_h
     76#endif // MutationObserverRegistration_h
  • trunk/Source/WebCore/dom/Node.cpp

    r98805 r99338  
    549549
    550550#if ENABLE(MUTATION_OBSERVERS)
    551     if (Vector<MutationObserverRegistration>* registry = mutationObserverRegistry()) {
    552         for (size_t i = 0; i < registry->size(); ++i)
    553             registry->at(i).observer->observedNodeDestructed(this);
    554     }
     551    ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
    555552#endif
    556553
     
    26972694
    26982695#if ENABLE(MUTATION_OBSERVERS)
    2699 Vector<MutationObserverRegistration>* Node::mutationObserverRegistry()
     2696Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
    27002697{
    27012698    return hasRareData() ? rareData()->mutationObserverRegistry() : 0;
    27022699}
    27032700
    2704 static void addMatchingObservers(HashMap<WebKitMutationObserver*, MutationObserverOptions>& observers, Vector<MutationObserverRegistration>* registry, MutationObserverOptions options)
    2705 {
    2706     if (!registry)
    2707         return;
    2708 
    2709     const size_t size = registry->size();
    2710     for (size_t i = 0; i < size; ++i) {
    2711         MutationObserverRegistration& entry = registry->at(i);
    2712 
    2713         if (!entry.hasAllOptions(options))
    2714             continue;
    2715 
    2716         pair<HashMap<WebKitMutationObserver*, MutationObserverOptions>::iterator, bool> result = observers.add(entry.observer.get(), entry.options);
    2717         if (!result.second)
    2718             result.first->second |= entry.options;
    2719     }
    2720 }
    2721 
    2722 void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationObserverOptions>& observers, WebKitMutationObserver::MutationType type)
    2723 {
    2724     addMatchingObservers(observers, mutationObserverRegistry(), type);
    2725     for (Node* node = parentNode(); node; node = node->parentNode())
    2726         addMatchingObservers(observers, node->mutationObserverRegistry(), type | WebKitMutationObserver::Subtree);
    2727 }
    2728 
    2729 Node::MutationRegistrationResult Node::registerMutationObserver(PassRefPtr<WebKitMutationObserver> observer, MutationObserverOptions options, Node* registrationNode)
    2730 {
    2731     Vector<MutationObserverRegistration>* registry = ensureRareData()->ensureMutationObserverRegistry();
    2732     MutationObserverRegistration registration(observer, options, registrationNode);
    2733 
    2734     size_t index = registry->find(registration);
    2735     if (index == notFound) {
    2736         registry->append(registration);
    2737         return MutationObserverRegistered;
    2738     }
    2739 
    2740     registry->at(index).options = registration.options;
    2741     return MutationRegistrationOptionsReset;
    2742 }
    2743 
    2744 void Node::unregisterMutationObserver(PassRefPtr<WebKitMutationObserver> observer, Node* registrationNode)
    2745 {
    2746     Vector<MutationObserverRegistration>* registry = mutationObserverRegistry();
     2701HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
     2702{
     2703    return hasRareData() ? rareData()->transientMutationObserverRegistry() : 0;
     2704}
     2705
     2706void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, Node* fromNode, WebKitMutationObserver::MutationType type)
     2707{
     2708    if (Vector<OwnPtr<MutationObserverRegistration> >* registry = fromNode->mutationObserverRegistry()) {
     2709        const size_t size = registry->size();
     2710        for (size_t i = 0; i < size; ++i) {
     2711            MutationObserverRegistration* registration = registry->at(i).get();
     2712            if (registration->shouldReceiveMutationFrom(this, type)) {
     2713                MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions();
     2714                pair<HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator, bool> result = observers.add(registration->observer(), deliveryOptions);
     2715                if (!result.second)
     2716                    result.first->second |= deliveryOptions;
     2717
     2718            }
     2719        }
     2720    }
     2721
     2722    if (HashSet<MutationObserverRegistration*>* transientRegistry = fromNode->transientMutationObserverRegistry()) {
     2723        for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
     2724            MutationObserverRegistration* registration = *iter;
     2725            if (registration->shouldReceiveMutationFrom(this, type)) {
     2726                MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions();
     2727                pair<HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator, bool> result = observers.add(registration->observer(), deliveryOptions);
     2728                if (!result.second)
     2729                    result.first->second |= deliveryOptions;
     2730            }
     2731        }
     2732    }
     2733}
     2734
     2735void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type)
     2736{
     2737    for (Node* node = this; node; node = node->parentNode())
     2738        collectMatchingObserversForMutation(observers, node, type);
     2739}
     2740
     2741MutationObserverRegistration* Node::registerMutationObserver(PassRefPtr<WebKitMutationObserver> observer)
     2742{
     2743    Vector<OwnPtr<MutationObserverRegistration> >* registry = ensureRareData()->ensureMutationObserverRegistry();
     2744    for (size_t i = 0; i < registry->size(); ++i) {
     2745        if (registry->at(i)->observer() == observer)
     2746            return registry->at(i).get();
     2747    }
     2748
     2749    OwnPtr<MutationObserverRegistration> registration = MutationObserverRegistration::create(observer, this);
     2750    MutationObserverRegistration* registrationPtr = registration.get();
     2751    registry->append(registration.release());
     2752    return registrationPtr;
     2753}
     2754
     2755void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
     2756{
     2757    Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry();
    27472758    ASSERT(registry);
    27482759    if (!registry)
    27492760        return;
    27502761
    2751     MutationObserverRegistration registration(observer, 0, registrationNode);
    27522762    size_t index = registry->find(registration);
    27532763    ASSERT(index != notFound);
     
    27582768}
    27592769
     2770void Node::registerTransientMutationObserver(MutationObserverRegistration* registration)
     2771{
     2772    ensureRareData()->ensureTransientMutationObserverRegistry()->add(registration);
     2773}
     2774
     2775void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
     2776{
     2777    HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry();
     2778    ASSERT(transientRegistry);
     2779    if (!transientRegistry)
     2780        return;
     2781
     2782    ASSERT(transientRegistry->contains(registration));
     2783    transientRegistry->remove(registration);
     2784}
     2785
    27602786void Node::notifyMutationObserversNodeWillDetach()
    27612787{
    27622788    for (Node* node = parentNode(); node; node = node->parentNode()) {
    2763         Vector<MutationObserverRegistration>* registry = node->mutationObserverRegistry();
    2764         if (!registry)
    2765             continue;
    2766 
    2767         const size_t size = registry->size();
    2768         for (size_t i = 0; i < size; ++i) {
    2769             MutationObserverRegistration& registration = registry->at(i);
    2770             if (!registration.hasAllOptions(WebKitMutationObserver::Subtree))
    2771                 continue;
    2772 
    2773             Node* registrationNode = registration.registrationNode;
    2774             if (!registrationNode)
    2775                 registrationNode = node;
    2776             registration.observer->willDetachNodeInObservedSubtree(registrationNode, registration.options, this);
     2789        if (Vector<OwnPtr<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
     2790            const size_t size = registry->size();
     2791            for (size_t i = 0; i < size; ++i)
     2792                registry->at(i)->observedSubtreeNodeWillDetach(this);
     2793        }
     2794
     2795        if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) {
     2796            for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
     2797                (*iter)->observedSubtreeNodeWillDetach(this);
    27772798        }
    27782799    }
  • trunk/Source/WebCore/dom/Node.h

    r98659 r99338  
    3535#include <wtf/Forward.h>
    3636#include <wtf/ListHashSet.h>
     37#include <wtf/text/AtomicString.h>
    3738
    3839#if USE(JSC)
     
    591592
    592593#if ENABLE(MUTATION_OBSERVERS)
    593     void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationObserverOptions>&, WebKitMutationObserver::MutationType);
    594 
    595     enum MutationRegistrationResult {
    596         MutationObserverRegistered,
    597         MutationRegistrationOptionsReset
    598     };
    599     MutationRegistrationResult registerMutationObserver(PassRefPtr<WebKitMutationObserver>, MutationObserverOptions, Node* registrationNode = 0);
    600 
    601     void unregisterMutationObserver(PassRefPtr<WebKitMutationObserver>, Node* registrationNode = 0);
    602 
     594    void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType);
     595    MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>);
     596    void unregisterMutationObserver(MutationObserverRegistration*);
     597    void registerTransientMutationObserver(MutationObserverRegistration*);
     598    void unregisterTransientMutationObserver(MutationObserverRegistration*);
    603599    void notifyMutationObserversNodeWillDetach();
    604600#endif // ENABLE(MUTATION_OBSERVERS)
     
    728724
    729725#if ENABLE(MUTATION_OBSERVERS)
    730     Vector<MutationObserverRegistration>* mutationObserverRegistry();
     726    Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
     727    HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
     728    void collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, Node* fromNode, WebKitMutationObserver::MutationType);
    731729#endif
    732730
  • trunk/Source/WebCore/dom/NodeRareData.h

    r98659 r99338  
    3030#endif
    3131
     32#include "MutationObserverRegistration.h"
    3233#include "NameNodeList.h"
    3334#include "QualifiedName.h"
     
    3738#include <wtf/OwnPtr.h>
    3839#include <wtf/PassOwnPtr.h>
     40#include <wtf/text/AtomicString.h>
    3941#include <wtf/text/StringHash.h>
    4042
     
    8991};
    9092
    91 #if ENABLE(MUTATION_OBSERVERS)
    92 struct MutationObserverRegistration {
    93     MutationObserverRegistration(PassRefPtr<WebKitMutationObserver> observer, MutationObserverOptions options, Node* node)
    94         : observer(observer)
    95         , options(options)
    96         , registrationNode(node)
    97     {
    98     }
    99 
    100     bool operator==(const MutationObserverRegistration& other) const
    101     {
    102         return observer == other.observer && registrationNode == other.registrationNode;
    103     }
    104 
    105     bool hasAllOptions(MutationObserverOptions options) const
    106     {
    107         return (this->options & options) == options;
    108     }
    109 
    110     RefPtr<WebKitMutationObserver> observer;
    111     MutationObserverOptions options;
    112 
    113     // registrationNode will be 0 if the registration is non-transient. I.e. The registrationNode is the Node in whose
    114     // registry it exists.
    115     // Note that this doesn't need to be a RefPtr because the observer will be holding a RefPtr to the same node at
    116     // least for the lifetime of this Registration in its m_transientObservedNodes map.
    117     Node* registrationNode;
    118 };
    119 #endif // ENABLE(MUTATION_OBSERVERS)
    120 
    12193class NodeRareData {
    12294    WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
     
    169141
    170142#if ENABLE(MUTATION_OBSERVERS)
    171     Vector<MutationObserverRegistration>* mutationObserverRegistry() { return m_mutationObserverRegistry.get(); }
    172     Vector<MutationObserverRegistration>* ensureMutationObserverRegistry()
     143    Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry() { return m_mutationObserverRegistry.get(); }
     144    Vector<OwnPtr<MutationObserverRegistration> >* ensureMutationObserverRegistry()
    173145    {
    174146        if (!m_mutationObserverRegistry)
    175             m_mutationObserverRegistry = adoptPtr(new Vector<MutationObserverRegistration>);
     147            m_mutationObserverRegistry = adoptPtr(new Vector<OwnPtr<MutationObserverRegistration> >);
    176148        return m_mutationObserverRegistry.get();
     149    }
     150
     151    HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry() { return m_transientMutationObserverRegistry.get(); }
     152    HashSet<MutationObserverRegistration*>* ensureTransientMutationObserverRegistry()
     153    {
     154        if (!m_transientMutationObserverRegistry)
     155            m_transientMutationObserverRegistry = adoptPtr(new HashSet<MutationObserverRegistration*>);
     156        return m_transientMutationObserverRegistry.get();
    177157    }
    178158#endif
     
    196176
    197177#if ENABLE(MUTATION_OBSERVERS)
    198     OwnPtr<Vector<MutationObserverRegistration> > m_mutationObserverRegistry;
     178    OwnPtr<Vector<OwnPtr<MutationObserverRegistration> > > m_mutationObserverRegistry;
     179    OwnPtr<HashSet<MutationObserverRegistration*> > m_transientMutationObserverRegistry;
    199180#endif
    200181};
  • trunk/Source/WebCore/dom/WebKitMutationObserver.cpp

    r98659 r99338  
    3636
    3737#include "MutationCallback.h"
     38#include "MutationObserverRegistration.h"
    3839#include "MutationRecord.h"
    3940#include "Node.h"
     
    5455WebKitMutationObserver::~WebKitMutationObserver()
    5556{
    56     clearAllTransientObservations();
    57 }
    58 
    59 static inline void clearTransientObservationsForRegistration(WebKitMutationObserver* observer, Node* registrationNode, PassOwnPtr<NodeHashSet> transientNodes)
    60 {
    61     for (NodeHashSet::iterator iter = transientNodes->begin(); iter != transientNodes->end(); ++iter)
    62         (*iter)->unregisterMutationObserver(observer, registrationNode);
     57    ASSERT(m_registrations.isEmpty());
    6358}
    6459
    6560void WebKitMutationObserver::observe(Node* node, MutationObserverOptions options)
    6661{
    67     // FIXME: More options composition work needs to be done here, e.g., validation.
    68 
    69     if (node->registerMutationObserver(this, options) == Node::MutationObserverRegistered) {
    70         m_observedNodes.append(node);
    71         return;
    72     }
    73 
    74     HashMap<RefPtr<Node>, NodeHashSet*>::iterator iter = m_transientObservedNodes.find(node);
    75     if (iter == m_transientObservedNodes.end())
    76         return;
    77 
    78     clearTransientObservationsForRegistration(this, node, adoptPtr(iter->second));
    79     m_transientObservedNodes.remove(iter);
     62    MutationObserverRegistration* registration = node->registerMutationObserver(this);
     63    registration->resetObservation(options);
    8064}
    8165
    8266void WebKitMutationObserver::disconnect()
    8367{
    84     for (size_t i = 0; i < m_observedNodes.size(); ++i)
    85         m_observedNodes[i]->unregisterMutationObserver(this);
    86 
    87     m_observedNodes.clear();
    88     clearAllTransientObservations();
     68    HashSet<MutationObserverRegistration*> registrations(m_registrations);
     69    for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
     70        (*iter)->unregister();
    8971}
    9072
    91 void WebKitMutationObserver::observedNodeDestructed(Node* node)
     73void WebKitMutationObserver::observationStarted(MutationObserverRegistration* registration)
    9274{
    93     ASSERT(!m_transientObservedNodes.contains(node));
     75    ASSERT(!m_registrations.contains(registration));
     76    m_registrations.add(registration);
     77}
    9478
    95     size_t index = m_observedNodes.find(node);
    96     ASSERT(index != notFound);
    97     if (index == notFound)
    98         return;
    99 
    100     m_observedNodes.remove(index);
     79void WebKitMutationObserver::observationEnded(MutationObserverRegistration* registration)
     80{
     81    ASSERT(m_registrations.contains(registration));
     82    m_registrations.remove(registration);
    10183}
    10284
     
    11597}
    11698
    117 void WebKitMutationObserver::willDetachNodeInObservedSubtree(PassRefPtr<Node> prpRegistrationNode, MutationObserverOptions options, PassRefPtr<Node> prpDetachingNode)
    118 {
    119     RefPtr<Node> registrationNode = prpRegistrationNode;
    120     RefPtr<Node> detachingNode = prpDetachingNode;
    121 
    122     detachingNode->registerMutationObserver(this, options, registrationNode.get());
    123     HashMap<RefPtr<Node>, NodeHashSet*>::iterator iter = m_transientObservedNodes.find(registrationNode);
    124     if (iter != m_transientObservedNodes.end()) {
    125         iter->second->add(detachingNode);
    126         return;
    127     }
    128 
    129     OwnPtr<NodeHashSet> set = adoptPtr(new NodeHashSet());
    130     set->add(detachingNode);
    131     m_transientObservedNodes.set(registrationNode, set.leakPtr());
    132 }
    133 
    134 void WebKitMutationObserver::clearAllTransientObservations()
    135 {
    136     for (HashMap<RefPtr<Node>, NodeHashSet*>::iterator iter = m_transientObservedNodes.begin(); iter != m_transientObservedNodes.end(); ++iter)
    137         clearTransientObservationsForRegistration(this, iter->first.get(), adoptPtr(iter->second));
    138 
    139     m_transientObservedNodes.clear();
    140 }
    141 
    14299void WebKitMutationObserver::deliver()
    143100{
    144101    MutationRecordArray records;
    145102    records.swap(m_records);
    146     clearAllTransientObservations();
     103
     104    for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
     105        (*iter)->clearTransientRegistrations();
     106
    147107    m_callback->handleEvent(&records, this);
    148108}
  • trunk/Source/WebCore/dom/WebKitMutationObserver.h

    r98659 r99338  
    3434#if ENABLE(MUTATION_OBSERVERS)
    3535
    36 #include <wtf/HashMap.h>
    3736#include <wtf/HashSet.h>
    38 #include <wtf/PassOwnPtr.h>
     37#include <wtf/PassRefPtr.h>
    3938#include <wtf/RefCounted.h>
    4039#include <wtf/RefPtr.h>
    41 #include <wtf/Vector.h>
     40#include <wtf/text/AtomicString.h>
     41#include <wtf/text/AtomicStringHash.h>
    4242
    4343namespace WebCore {
    4444
    4545class MutationCallback;
     46class MutationObserverRegistration;
    4647class MutationRecord;
    4748class Node;
    4849
    4950typedef unsigned char MutationObserverOptions;
    50 typedef HashSet<RefPtr<Node> > NodeHashSet;
     51typedef unsigned char MutationRecordDeliveryOptions;
    5152
    5253class WebKitMutationObserver : public RefCounted<WebKitMutationObserver> {
     
    5859    };
    5960
    60     enum OptionFlags {
     61    enum ObservationFlags {
    6162        Subtree = 1 << 3,
    62         AttributeOldValue = 1 << 4,
    63         CharacterDataOldValue = 1 << 5,
    64         AttributeFilter = 1 << 6
     63        AttributeFilter = 1 << 4
     64    };
     65
     66    enum DeliveryFlags {
     67        AttributeOldValue = 1 << 5,
     68        CharacterDataOldValue = 1 << 6,
    6569    };
    6670
     
    7276    void observe(Node*, MutationObserverOptions);
    7377    void disconnect();
    74     void willDetachNodeInObservedSubtree(PassRefPtr<Node> registrationNode, MutationObserverOptions, PassRefPtr<Node> detachingNode);
    75     void observedNodeDestructed(Node*);
     78    void observationStarted(MutationObserverRegistration*);
     79    void observationEnded(MutationObserverRegistration*);
    7680    void enqueueMutationRecord(PassRefPtr<MutationRecord>);
    7781
    7882private:
    7983    WebKitMutationObserver(PassRefPtr<MutationCallback>);
    80 
    81     void clearAllTransientObservations();
    8284    void deliver();
    8385
    8486    RefPtr<MutationCallback> m_callback;
    8587    Vector<RefPtr<MutationRecord> > m_records;
    86     Vector<Node*> m_observedNodes; // NodeRareData has a RefPtr to this, so use a weak pointer to avoid a cycle.
    87 
    88     // FIXME: Change this to be OwnPtr<NodeHashSet> when OwnPtr supports being contained as map values.
    89     HashMap<RefPtr<Node>, NodeHashSet*> m_transientObservedNodes;
     88    HashSet<MutationObserverRegistration*> m_registrations;
    9089};
    9190
Note: See TracChangeset for help on using the changeset viewer.