Changeset 99338 in webkit
- Timestamp:
- Nov 4, 2011 5:44:46 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 14 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r99337 r99338 1 2011-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 1 77 2011-11-04 Raymond Toy <rtoy@google.com> 2 78 -
trunk/Source/WebCore/GNUmakefile.list.am
r99332 r99338 1270 1270 Source/WebCore/dom/MutationEvent.cpp \ 1271 1271 Source/WebCore/dom/MutationEvent.h \ 1272 Source/WebCore/dom/MutationObserverRegistration.cpp \ 1273 Source/WebCore/dom/MutationObserverRegistration.h \ 1272 1274 Source/WebCore/dom/MutationRecord.cpp \ 1273 1275 Source/WebCore/dom/MutationRecord.h \ -
trunk/Source/WebCore/Target.pri
r99332 r99338 534 534 dom/MouseRelatedEvent.cpp \ 535 535 dom/MutationEvent.cpp \ 536 dom/MutationObserverRegistration.cpp \ 536 537 dom/MutationRecord.cpp \ 537 538 dom/NamedNodeMap.cpp \ … … 1621 1622 dom/MutationCallback.h \ 1622 1623 dom/MutationEvent.h \ 1624 dom/MutationObserverRegistration.h \ 1623 1625 dom/MutationRecord.h \ 1624 1626 dom/NamedNodeMap.h \ -
trunk/Source/WebCore/WebCore.gypi
r99332 r99338 5267 5267 'dom/MutationEvent.cpp', 5268 5268 'dom/MutationEvent.h', 5269 'dom/MutationObserverRegistration.cpp', 5270 'dom/MutationObserverRegistration.h', 5269 5271 'dom/MutationRecord.cpp', 5270 5272 'dom/MutationRecord.h', -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r99332 r99338 46643 46643 </File> 46644 46644 <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 46645 46701 RelativePath="..\dom\MutationRecord.cpp" 46646 46702 > -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r99332 r99338 5782 5782 D619A307144E00BE004BC302 /* ChildListMutationScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D619A305144E00BE004BC302 /* ChildListMutationScope.cpp */; }; 5783 5783 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 */; }; 5784 5786 D70AD65713E1342B005B50B4 /* RenderRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D70AD65513E1342B005B50B4 /* RenderRegion.cpp */; }; 5785 5787 D70AD65813E1342B005B50B4 /* RenderRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = D70AD65613E1342B005B50B4 /* RenderRegion.h */; }; … … 13086 13088 D619A305144E00BE004BC302 /* ChildListMutationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChildListMutationScope.cpp; sourceTree = "<group>"; }; 13087 13089 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>"; }; 13088 13092 D70AD65513E1342B005B50B4 /* RenderRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderRegion.cpp; sourceTree = "<group>"; }; 13089 13093 D70AD65613E1342B005B50B4 /* RenderRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderRegion.h; sourceTree = "<group>"; }; … … 21108 21112 85031B340A44EFC700F992E0 /* MutationEvent.h */, 21109 21113 93EEC1F309C2877700C515D1 /* MutationEvent.idl */, 21114 D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */, 21115 D6E276AE14637455001D280A /* MutationObserverRegistration.h */, 21110 21116 C6F08FB91430FE8F00685849 /* MutationRecord.cpp */, 21111 21117 C6F08FBA1430FE8F00685849 /* MutationRecord.h */, … … 23586 23592 C6F0900A14327B6100685849 /* MutationCallback.h in Headers */, 23587 23593 85031B4A0A44EFC700F992E0 /* MutationEvent.h in Headers */, 23594 D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */, 23588 23595 C6F08FBD1430FE8F00685849 /* MutationRecord.h in Headers */, 23589 23596 A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */, … … 26641 26648 93309DFB099E64920056E581 /* MoveSelectionCommand.cpp in Sources */, 26642 26649 85031B490A44EFC700F992E0 /* MutationEvent.cpp in Sources */, 26650 D6E276AF14637455001D280A /* MutationObserverRegistration.cpp in Sources */, 26643 26651 C6F08FBC1430FE8F00685849 /* MutationRecord.cpp in Sources */, 26644 26652 BCF34A3711A231CD00C71804 /* NamedNodeMap.cpp in Sources */, -
trunk/Source/WebCore/dom/CharacterData.cpp
r99128 r99338 206 206 static void enqueueCharacterDataMutationRecord(Node* node, const String& oldData) 207 207 { 208 HashMap<WebKitMutationObserver*, Mutation ObserverOptions> observers;208 HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers; 209 209 node->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::CharacterData); 210 210 if (observers.isEmpty()) -
trunk/Source/WebCore/dom/ChildListMutationScope.cpp
r99305 r99338 245 245 } 246 246 247 HashMap<WebKitMutationObserver*, Mutation ObserverOptions> observers;247 HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers; 248 248 target->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::ChildList); 249 249 if (observers.isEmpty()) -
trunk/Source/WebCore/dom/Element.cpp
r98910 r99338 634 634 static void enqueueAttributesMutationRecord(Element* element, const QualifiedName& name, const AtomicString& oldValue) 635 635 { 636 HashMap<WebKitMutationObserver*, Mutation ObserverOptions> observers;636 HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers; 637 637 element->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::Attributes); 638 638 if (observers.isEmpty()) -
trunk/Source/WebCore/dom/MutationObserverRegistration.h
r99337 r99338 29 29 */ 30 30 31 #ifndef WebKitMutationObserver_h32 #define WebKitMutationObserver_h31 #ifndef MutationObserverRegistration_h 32 #define MutationObserverRegistration_h 33 33 34 34 #if ENABLE(MUTATION_OBSERVERS) 35 35 36 #include <wtf/HashMap.h>36 #include "WebKitMutationObserver.h" 37 37 #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> 42 40 43 41 namespace WebCore { 44 42 45 class MutationCallback; 46 class MutationRecord; 47 class Node; 43 class MutationObserverRegistration { 44 public: 48 45 49 typedef unsigned char MutationObserverOptions; 50 typedef HashSet<RefPtr<Node> > NodeHashSet; 46 static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<WebKitMutationObserver>, Node*); 51 47 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(); 59 49 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(); 66 54 67 static PassRefPtr<WebKitMutationObserver> create(PassRefPtr<MutationCallback>); 68 static void deliverAllMutations(); 55 bool shouldReceiveMutationFrom(Node*, WebKitMutationObserver::MutationType); 69 56 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); } 77 59 78 60 private: 79 WebKitMutationObserver(PassRefPtr<MutationCallback>);61 MutationObserverRegistration(PassRefPtr<WebKitMutationObserver>, Node*); 80 62 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; 83 68 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; 90 70 }; 91 71 92 } 72 } // namespace WebCore 93 73 94 74 #endif // ENABLE(MUTATION_OBSERVERS) 95 75 96 #endif // WebKitMutationObserver_h76 #endif // MutationObserverRegistration_h -
trunk/Source/WebCore/dom/Node.cpp
r98805 r99338 549 549 550 550 #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()); 555 552 #endif 556 553 … … 2697 2694 2698 2695 #if ENABLE(MUTATION_OBSERVERS) 2699 Vector< MutationObserverRegistration>* Node::mutationObserverRegistry()2696 Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry() 2700 2697 { 2701 2698 return hasRareData() ? rareData()->mutationObserverRegistry() : 0; 2702 2699 } 2703 2700 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(); 2701 HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry() 2702 { 2703 return hasRareData() ? rareData()->transientMutationObserverRegistry() : 0; 2704 } 2705 2706 void 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 2735 void 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 2741 MutationObserverRegistration* 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 2755 void Node::unregisterMutationObserver(MutationObserverRegistration* registration) 2756 { 2757 Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry(); 2747 2758 ASSERT(registry); 2748 2759 if (!registry) 2749 2760 return; 2750 2761 2751 MutationObserverRegistration registration(observer, 0, registrationNode);2752 2762 size_t index = registry->find(registration); 2753 2763 ASSERT(index != notFound); … … 2758 2768 } 2759 2769 2770 void Node::registerTransientMutationObserver(MutationObserverRegistration* registration) 2771 { 2772 ensureRareData()->ensureTransientMutationObserverRegistry()->add(registration); 2773 } 2774 2775 void 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 2760 2786 void Node::notifyMutationObserversNodeWillDetach() 2761 2787 { 2762 2788 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); 2777 2798 } 2778 2799 } -
trunk/Source/WebCore/dom/Node.h
r98659 r99338 35 35 #include <wtf/Forward.h> 36 36 #include <wtf/ListHashSet.h> 37 #include <wtf/text/AtomicString.h> 37 38 38 39 #if USE(JSC) … … 591 592 592 593 #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*); 603 599 void notifyMutationObserversNodeWillDetach(); 604 600 #endif // ENABLE(MUTATION_OBSERVERS) … … 728 724 729 725 #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); 731 729 #endif 732 730 -
trunk/Source/WebCore/dom/NodeRareData.h
r98659 r99338 30 30 #endif 31 31 32 #include "MutationObserverRegistration.h" 32 33 #include "NameNodeList.h" 33 34 #include "QualifiedName.h" … … 37 38 #include <wtf/OwnPtr.h> 38 39 #include <wtf/PassOwnPtr.h> 40 #include <wtf/text/AtomicString.h> 39 41 #include <wtf/text/StringHash.h> 40 42 … … 89 91 }; 90 92 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) const101 {102 return observer == other.observer && registrationNode == other.registrationNode;103 }104 105 bool hasAllOptions(MutationObserverOptions options) const106 {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 whose114 // 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 at116 // least for the lifetime of this Registration in its m_transientObservedNodes map.117 Node* registrationNode;118 };119 #endif // ENABLE(MUTATION_OBSERVERS)120 121 93 class NodeRareData { 122 94 WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED; … … 169 141 170 142 #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() 173 145 { 174 146 if (!m_mutationObserverRegistry) 175 m_mutationObserverRegistry = adoptPtr(new Vector< MutationObserverRegistration>);147 m_mutationObserverRegistry = adoptPtr(new Vector<OwnPtr<MutationObserverRegistration> >); 176 148 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(); 177 157 } 178 158 #endif … … 196 176 197 177 #if ENABLE(MUTATION_OBSERVERS) 198 OwnPtr<Vector<MutationObserverRegistration> > m_mutationObserverRegistry; 178 OwnPtr<Vector<OwnPtr<MutationObserverRegistration> > > m_mutationObserverRegistry; 179 OwnPtr<HashSet<MutationObserverRegistration*> > m_transientMutationObserverRegistry; 199 180 #endif 200 181 }; -
trunk/Source/WebCore/dom/WebKitMutationObserver.cpp
r98659 r99338 36 36 37 37 #include "MutationCallback.h" 38 #include "MutationObserverRegistration.h" 38 39 #include "MutationRecord.h" 39 40 #include "Node.h" … … 54 55 WebKitMutationObserver::~WebKitMutationObserver() 55 56 { 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()); 63 58 } 64 59 65 60 void WebKitMutationObserver::observe(Node* node, MutationObserverOptions options) 66 61 { 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); 80 64 } 81 65 82 66 void WebKitMutationObserver::disconnect() 83 67 { 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(); 89 71 } 90 72 91 void WebKitMutationObserver::observ edNodeDestructed(Node* node)73 void WebKitMutationObserver::observationStarted(MutationObserverRegistration* registration) 92 74 { 93 ASSERT(!m_transientObservedNodes.contains(node)); 75 ASSERT(!m_registrations.contains(registration)); 76 m_registrations.add(registration); 77 } 94 78 95 size_t index = m_observedNodes.find(node); 96 ASSERT(index != notFound); 97 if (index == notFound) 98 return; 99 100 m_observedNodes.remove(index); 79 void WebKitMutationObserver::observationEnded(MutationObserverRegistration* registration) 80 { 81 ASSERT(m_registrations.contains(registration)); 82 m_registrations.remove(registration); 101 83 } 102 84 … … 115 97 } 116 98 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 142 99 void WebKitMutationObserver::deliver() 143 100 { 144 101 MutationRecordArray records; 145 102 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 147 107 m_callback->handleEvent(&records, this); 148 108 } -
trunk/Source/WebCore/dom/WebKitMutationObserver.h
r98659 r99338 34 34 #if ENABLE(MUTATION_OBSERVERS) 35 35 36 #include <wtf/HashMap.h>37 36 #include <wtf/HashSet.h> 38 #include <wtf/Pass OwnPtr.h>37 #include <wtf/PassRefPtr.h> 39 38 #include <wtf/RefCounted.h> 40 39 #include <wtf/RefPtr.h> 41 #include <wtf/Vector.h> 40 #include <wtf/text/AtomicString.h> 41 #include <wtf/text/AtomicStringHash.h> 42 42 43 43 namespace WebCore { 44 44 45 45 class MutationCallback; 46 class MutationObserverRegistration; 46 47 class MutationRecord; 47 48 class Node; 48 49 49 50 typedef unsigned char MutationObserverOptions; 50 typedef HashSet<RefPtr<Node> > NodeHashSet;51 typedef unsigned char MutationRecordDeliveryOptions; 51 52 52 53 class WebKitMutationObserver : public RefCounted<WebKitMutationObserver> { … … 58 59 }; 59 60 60 enum O ptionFlags{61 enum ObservationFlags { 61 62 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, 65 69 }; 66 70 … … 72 76 void observe(Node*, MutationObserverOptions); 73 77 void disconnect(); 74 void willDetachNodeInObservedSubtree(PassRefPtr<Node> registrationNode, MutationObserverOptions, PassRefPtr<Node> detachingNode);75 void observ edNodeDestructed(Node*);78 void observationStarted(MutationObserverRegistration*); 79 void observationEnded(MutationObserverRegistration*); 76 80 void enqueueMutationRecord(PassRefPtr<MutationRecord>); 77 81 78 82 private: 79 83 WebKitMutationObserver(PassRefPtr<MutationCallback>); 80 81 void clearAllTransientObservations();82 84 void deliver(); 83 85 84 86 RefPtr<MutationCallback> m_callback; 85 87 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; 90 89 }; 91 90
Note: See TracChangeset
for help on using the changeset viewer.