Source/WebCore/ChangeLog

 12011-12-15 Rafael Weinstein <rafaelw@chromium.org>
 2
 3 [MutationObservers] Add a document-level flag that can trivially be checked to avoid doing unnessary work if mutation observers absent
 4 https://bugs.webkit.org/show_bug.cgi?id=74641
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This patch adds a byte of flags to Document, of which three bits are used to signal if any
 9 node owned by the document has a Mutation Observer of the given type. This is used to
 10 reduce the cost of discovering there are none to a single (inlined) method call and bit-check.
 11 Also, a similar byte of flags which was used to optimize a particular case when mutation observers
 12 are present has been removed, with the reasoning that we should first focus on minimizing impact on
 13 the null-case before optimizing particular in-use cases.
 14
 15 Also, MutationObserverInterestGroup is broken out into its own file (which probably should have happened
 16 earlier, but now avoids a circular header dependency).
 17
 18 No tests needed. This patch is just a refactor.
 19
 20 * CMakeLists.txt:
 21 * GNUmakefile.list.am:
 22 * Target.pri:
 23 * WebCore.gypi:
 24 * WebCore.vcproj/WebCore.vcproj:
 25 * WebCore.xcodeproj/project.pbxproj:
 26 * css/CSSMutableStyleDeclaration.cpp:
 27 * dom/CharacterData.cpp:
 28 * dom/ChildListMutationScope.cpp:
 29 * dom/Document.cpp:
 30 (WebCore::Document::Document):
 31 * dom/Document.h:
 32 (WebCore::Document::hasMutationObserversOfType):
 33 (WebCore::Document::hasMutationObservers):
 34 (WebCore::Document::addMutationObserverTypes):
 35 * dom/Element.cpp:
 36 * dom/MutationObserverInterestGroup.cpp: Added.
 37 (WebCore::MutationObserverInterestGroup::createIfNeeded):
 38 (WebCore::MutationObserverInterestGroup::MutationObserverInterestGroup):
 39 (WebCore::MutationObserverInterestGroup::isOldValueRequested):
 40 (WebCore::MutationObserverInterestGroup::enqueueMutationRecord):
 41 * dom/MutationObserverInterestGroup.h: Copied from Source/WebCore/dom/WebKitMutationObserver.h.
 42 (WebCore::MutationObserverInterestGroup::createForChildListMutation):
 43 (WebCore::MutationObserverInterestGroup::createForCharacterDataMutation):
 44 (WebCore::MutationObserverInterestGroup::createForAttributesMutation):
 45 (WebCore::MutationObserverInterestGroup::hasOldValue):
 46 * dom/Node.cpp:
 47 (WebCore::Node::didMoveToNewOwnerDocument):
 48 (WebCore::Node::getRegisteredMutationObserversOfType):
 49 (WebCore::Node::notifyMutationObserversNodeWillDetach):
 50 * dom/Node.h:
 51 * dom/WebKitMutationObserver.cpp:
 52 (WebCore::WebKitMutationObserver::observe):
 53 * dom/WebKitMutationObserver.h:
 54
1552011-12-14 Anders Carlsson <andersca@apple.com>
256
357 Add WTF::Function to wtf/Forward.h

Source/WebCore/CMakeLists.txt

@@SET(WebCore_SOURCES
561561 dom/MouseEvent.cpp
562562 dom/MouseRelatedEvent.cpp
563563 dom/MutationEvent.cpp
 564 dom/MutationObserverInterestGroup.cpp
 565 dom/MutationObserverRegistration.cpp
564566 dom/MutationRecord.cpp
565567 dom/NamedNodeMap.cpp
566568 dom/NameNodeList.cpp

Source/WebCore/GNUmakefile.list.am

@@webcore_sources += \
12811281 Source/WebCore/dom/MutationCallback.h \
12821282 Source/WebCore/dom/MutationEvent.cpp \
12831283 Source/WebCore/dom/MutationEvent.h \
 1284 Source/WebCore/dom/MutationObserverInterestGroup.cpp \
 1285 Source/WebCore/dom/MutationObserverInterestGroup.h \
12841286 Source/WebCore/dom/MutationObserverRegistration.cpp \
12851287 Source/WebCore/dom/MutationObserverRegistration.h \
12861288 Source/WebCore/dom/MutationRecord.cpp \

Source/WebCore/Target.pri

@@SOURCES += \
527527 dom/MouseEvent.cpp \
528528 dom/MouseRelatedEvent.cpp \
529529 dom/MutationEvent.cpp \
 530 dom/MutationObserverInterestGroup.cpp \
530531 dom/MutationObserverRegistration.cpp \
531532 dom/MutationRecord.cpp \
532533 dom/NamedNodeMap.cpp \

Source/WebCore/WebCore.gypi

53485348 'dom/MutationCallback.h',
53495349 'dom/MutationEvent.cpp',
53505350 'dom/MutationEvent.h',
 5351 'dom/MutationObserverInterestGroup.cpp',
 5352 'dom/MutationObserverInterestGroup.h',
53515353 'dom/MutationObserverRegistration.cpp',
53525354 'dom/MutationObserverRegistration.h',
53535355 'dom/MutationRecord.cpp',

Source/WebCore/WebCore.vcproj/WebCore.vcproj

4931749317 >
4931849318 </File>
4931949319 <File
49320  RelativePath="..\dom\MutationObserverRegistration.cpp"
 49320 RelativePath="..\dom\MutationObserverInterestGroup.cpp"
4932149321 >
4932249322 <FileConfiguration
4932349323 Name="Debug|Win32"

4936949369 </FileConfiguration>
4937049370 </File>
4937149371 <File
49372  RelativePath="..\dom\MutationObserverRegistration.h"
 49372 RelativePath="..\dom\MutationObserverInterestGroup.h"
4937349373 >
4937449374 </File>
 49375 <File
 49376 RelativePath="..\dom\MutationObserverRegistration.cpp"
 49377 >
 49378 <FileConfiguration
 49379 Name="Debug|Win32"
 49380 ExcludedFromBuild="true"
 49381 >
 49382 <Tool
 49383 Name="VCCLCompilerTool"
 49384 />
 49385 </FileConfiguration>
 49386 <FileConfiguration
 49387 Name="Release|Win32"
 49388 ExcludedFromBuild="true"
 49389 >
 49390 <Tool
 49391 Name="VCCLCompilerTool"
 49392 />
 49393 </FileConfiguration>
 49394 <FileConfiguration
 49395 Name="Debug_Cairo_CFLite|Win32"
 49396 ExcludedFromBuild="true"
 49397 >
 49398 <Tool
 49399 Name="VCCLCompilerTool"
 49400 />
 49401 </FileConfiguration>
 49402 <FileConfiguration
 49403 Name="Release_Cairo_CFLite|Win32"
 49404 ExcludedFromBuild="true"
 49405 >
 49406 <Tool
 49407 Name="VCCLCompilerTool"
 49408 />
 49409 </FileConfiguration>
 49410 <FileConfiguration
 49411 Name="Debug_All|Win32"
 49412 ExcludedFromBuild="true"
 49413 >
 49414 <Tool
 49415 Name="VCCLCompilerTool"
 49416 />
 49417 </FileConfiguration>
 49418 <FileConfiguration
 49419 Name="Production|Win32"
 49420 ExcludedFromBuild="true"
 49421 >
 49422 <Tool
 49423 Name="VCCLCompilerTool"
 49424 />
 49425 </FileConfiguration>
 49426 </File>
 49427 <File
 49428 RelativePath="..\dom\MutationObserverRegistration.h"
 49429 >
 49430 </File>
4937549431 <File
4937649432 RelativePath="..\dom\MutationRecord.cpp"
4937749433 >

Source/WebCore/WebCore.xcodeproj/project.pbxproj

58345834 D619A308144E00BE004BC302 /* ChildListMutationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D619A306144E00BE004BC302 /* ChildListMutationScope.h */; };
58355835 D6E276AF14637455001D280A /* MutationObserverRegistration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */; };
58365836 D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = D6E276AE14637455001D280A /* MutationObserverRegistration.h */; };
 5837 D6E528A3149A926D00EFE1F3 /* MutationObserverInterestGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6E528A1149A926D00EFE1F3 /* MutationObserverInterestGroup.cpp */; };
 5838 D6E528A4149A926D00EFE1F3 /* MutationObserverInterestGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = D6E528A2149A926D00EFE1F3 /* MutationObserverInterestGroup.h */; };
58375839 D70AD65713E1342B005B50B4 /* RenderRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D70AD65513E1342B005B50B4 /* RenderRegion.cpp */; };
58385840 D70AD65813E1342B005B50B4 /* RenderRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = D70AD65613E1342B005B50B4 /* RenderRegion.h */; };
58395841 D7613A501474F13F00DB8606 /* WebKitNamedFlow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D7613A4E1474F13F00DB8606 /* WebKitNamedFlow.cpp */; };

1321413216 D619A306144E00BE004BC302 /* ChildListMutationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChildListMutationScope.h; sourceTree = "<group>"; };
1321513217 D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutationObserverRegistration.cpp; sourceTree = "<group>"; };
1321613218 D6E276AE14637455001D280A /* MutationObserverRegistration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutationObserverRegistration.h; sourceTree = "<group>"; };
 13219 D6E528A1149A926D00EFE1F3 /* MutationObserverInterestGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutationObserverInterestGroup.cpp; sourceTree = "<group>"; };
 13220 D6E528A2149A926D00EFE1F3 /* MutationObserverInterestGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutationObserverInterestGroup.h; sourceTree = "<group>"; };
1321713221 D70AD65513E1342B005B50B4 /* RenderRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderRegion.cpp; sourceTree = "<group>"; };
1321813222 D70AD65613E1342B005B50B4 /* RenderRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderRegion.h; sourceTree = "<group>"; };
1321913223 D7613A4A1474EE9500DB8606 /* WebKitNamedFlow.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitNamedFlow.idl; sourceTree = "<group>"; };

2133021334 85031B330A44EFC700F992E0 /* MutationEvent.cpp */,
2133121335 85031B340A44EFC700F992E0 /* MutationEvent.h */,
2133221336 93EEC1F309C2877700C515D1 /* MutationEvent.idl */,
 21337 D6E528A1149A926D00EFE1F3 /* MutationObserverInterestGroup.cpp */,
 21338 D6E528A2149A926D00EFE1F3 /* MutationObserverInterestGroup.h */,
2133321339 D6E276AD14637455001D280A /* MutationObserverRegistration.cpp */,
2133421340 D6E276AE14637455001D280A /* MutationObserverRegistration.h */,
2133521341 C6F08FB91430FE8F00685849 /* MutationRecord.cpp */,

2380623812 93309DFC099E64920056E581 /* MoveSelectionCommand.h in Headers */,
2380723813 C6F0900A14327B6100685849 /* MutationCallback.h in Headers */,
2380823814 85031B4A0A44EFC700F992E0 /* MutationEvent.h in Headers */,
 23815 D6E528A4149A926D00EFE1F3 /* MutationObserverInterestGroup.h in Headers */,
2380923816 D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */,
2381023817 C6F08FBD1430FE8F00685849 /* MutationRecord.h in Headers */,
2381123818 A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */,

2689626903 85031B470A44EFC700F992E0 /* MouseRelatedEvent.cpp in Sources */,
2689726904 93309DFB099E64920056E581 /* MoveSelectionCommand.cpp in Sources */,
2689826905 85031B490A44EFC700F992E0 /* MutationEvent.cpp in Sources */,
 26906 D6E528A3149A926D00EFE1F3 /* MutationObserverInterestGroup.cpp in Sources */,
2689926907 D6E276AF14637455001D280A /* MutationObserverRegistration.cpp in Sources */,
2690026908 C6F08FBC1430FE8F00685849 /* MutationRecord.cpp in Sources */,
2690126909 BCF34A3711A231CD00C71804 /* NamedNodeMap.cpp in Sources */,

Source/WebCore/css/CSSMutableStyleDeclaration.cpp

3535#include "ExceptionCode.h"
3636#include "HTMLNames.h"
3737#include "InspectorInstrumentation.h"
 38#include "MutationObserverInterestGroup.h"
3839#include "MutationRecord.h"
3940#include "StyledElement.h"
4041#include "WebKitMutationObserver.h"

Source/WebCore/dom/CharacterData.cpp

2727#include "ExceptionCode.h"
2828#include "InspectorInstrumentation.h"
2929#include "MutationEvent.h"
 30#include "MutationObserverInterestGroup.h"
3031#include "MutationRecord.h"
3132#include "NodeRenderingContext.h"
3233#include "RenderText.h"

Source/WebCore/dom/ChildListMutationScope.cpp

3636
3737#include "DocumentFragment.h"
3838#include "Element.h"
 39#include "MutationObserverInterestGroup.h"
3940#include "MutationRecord.h"
4041#include "Node.h"
4142#include "StaticNodeList.h"

Source/WebCore/dom/Document.cpp

@@Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
382382 , m_compatibilityModeLocked(false)
383383 , m_domTreeVersion(++s_globalTreeVersion)
384384#if ENABLE(MUTATION_OBSERVERS)
385  , m_subtreeMutationObserverTypes(0)
 385 , m_mutationObserverTypes(0)
386386#endif
387387 , m_styleSheets(StyleSheetList::create(this))
388388 , m_readyState(Complete)

Source/WebCore/dom/Document.h

@@public:
787787 void addListenerTypeIfNeeded(const AtomicString& eventType);
788788
789789#if ENABLE(MUTATION_OBSERVERS)
790  bool hasSubtreeMutationObserverOfType(WebKitMutationObserver::MutationType type) const
 790 bool hasMutationObserversOfType(WebKitMutationObserver::MutationType type) const
791791 {
792  return m_subtreeMutationObserverTypes & type;
 792 return m_mutationObserverTypes & type;
793793 }
794  bool hasSubtreeMutationObserver() const { return m_subtreeMutationObserverTypes; }
795  void addSubtreeMutationObserverTypes(MutationObserverOptions types) { m_subtreeMutationObserverTypes |= types; }
 794 bool hasMutationObservers() const { return m_mutationObserverTypes; }
 795 void addMutationObserverTypes(MutationObserverOptions types) { m_mutationObserverTypes |= types; }
796796#endif
797797
798798 CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);

@@private:
12671267 unsigned short m_listenerTypes;
12681268
12691269#if ENABLE(MUTATION_OBSERVERS)
1270  MutationObserverOptions m_subtreeMutationObserverTypes;
 1270 MutationObserverOptions m_mutationObserverTypes;
12711271#endif
12721272
12731273 RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set.

Source/WebCore/dom/Element.cpp

4848#include "HTMLNames.h"
4949#include "HTMLParserIdioms.h"
5050#include "InspectorInstrumentation.h"
 51#include "MutationObserverInterestGroup.h"
5152#include "MutationRecord.h"
5253#include "NodeList.h"
5354#include "NodeRenderStyle.h"

Source/WebCore/dom/MutationObserverInterestGroup.cpp

 1/*
 2 * Copyright (C) 2011 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions are
 6 * met:
 7 *
 8 * * Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * * Redistributions in binary form must reproduce the above
 11 * copyright notice, this list of conditions and the following disclaimer
 12 * in the documentation and/or other materials provided with the
 13 * distribution.
 14 * * Neither the name of Google Inc. nor the names of its
 15 * contributors may be used to endorse or promote products derived from
 16 * this software without specific prior written permission.
 17 *
 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29 */
 30
 31#include "config.h"
 32
 33#if ENABLE(MUTATION_OBSERVERS)
 34
 35#include "MutationObserverInterestGroup.h"
 36
 37#include "MutationObserverRegistration.h"
 38#include "MutationRecord.h"
 39#include "Node.h"
 40#include "QualifiedName.h"
 41
 42namespace WebCore {
 43
 44PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag)
 45{
 46 HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
 47 target->getRegisteredMutationObserversOfType(observers, type, attributeName);
 48 if (observers.isEmpty())
 49 return nullptr;
 50
 51 return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
 52}
 53
 54MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
 55 : m_oldValueFlag(oldValueFlag)
 56{
 57 ASSERT(!observers.isEmpty());
 58 m_observers.swap(observers);
 59}
 60
 61bool MutationObserverInterestGroup::isOldValueRequested()
 62{
 63 for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
 64 if (hasOldValue(iter->second))
 65 return true;
 66 }
 67 return false;
 68}
 69
 70void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
 71{
 72 RefPtr<MutationRecord> mutation = prpMutation;
 73 RefPtr<MutationRecord> mutationWithNullOldValue;
 74 for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
 75 WebKitMutationObserver* observer = iter->first;
 76 if (hasOldValue(iter->second)) {
 77 observer->enqueueMutationRecord(mutation);
 78 continue;
 79 }
 80 if (!mutationWithNullOldValue) {
 81 if (mutation->oldValue().isNull())
 82 mutationWithNullOldValue = mutation;
 83 else
 84 mutationWithNullOldValue = MutationRecord::createWithNullOldValue(mutation).get();
 85 }
 86 observer->enqueueMutationRecord(mutationWithNullOldValue);
 87 }
 88}
 89
 90} // namespace WebCore
 91
 92#endif // ENABLE(MUTATION_OBSERVERS)

Source/WebCore/dom/MutationObserverInterestGroup.h

 1/*
 2 * Copyright (C) 2011 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions are
 6 * met:
 7 *
 8 * * Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * * Redistributions in binary form must reproduce the above
 11 * copyright notice, this list of conditions and the following disclaimer
 12 * in the documentation and/or other materials provided with the
 13 * distribution.
 14 * * Neither the name of Google Inc. nor the names of its
 15 * contributors may be used to endorse or promote products derived from
 16 * this software without specific prior written permission.
 17 *
 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29 */
 30
 31#ifndef MutationObserverInterestGroup_h
 32#define MutationObserverInterestGroup_h
 33
 34#if ENABLE(MUTATION_OBSERVERS)
 35
 36#include "Document.h"
 37#include "Node.h"
 38#include "QualifiedName.h"
 39#include "WebKitMutationObserver.h"
 40#include <wtf/HashMap.h>
 41#include <wtf/PassOwnPtr.h>
 42#include <wtf/text/AtomicString.h>
 43
 44namespace WebCore {
 45
 46class MutationObserverInterestGroup {
 47public:
 48 static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node* target)
 49 {
 50 if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::ChildList))
 51 return nullptr;
 52
 53 MutationRecordDeliveryOptions oldValueFlag = 0;
 54 return createIfNeeded(target, WebKitMutationObserver::ChildList, nullAtom, oldValueFlag);
 55 }
 56
 57 static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node* target)
 58 {
 59 if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::CharacterData))
 60 return nullptr;
 61
 62 return createIfNeeded(target, WebKitMutationObserver::CharacterData, nullAtom, WebKitMutationObserver::CharacterDataOldValue);
 63 }
 64
 65 static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node* target, const QualifiedName& attributeName)
 66 {
 67 if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::Attributes))
 68 return nullptr;
 69
 70 return createIfNeeded(target, WebKitMutationObserver::Attributes, attributeName.localName(), WebKitMutationObserver::AttributeOldValue);
 71 }
 72
 73 bool isOldValueRequested();
 74 void enqueueMutationRecord(PassRefPtr<MutationRecord>);
 75
 76private:
 77 static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag);
 78 MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
 79
 80 bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
 81
 82 HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> m_observers;
 83 MutationRecordDeliveryOptions m_oldValueFlag;
 84};
 85
 86}
 87
 88#endif // ENABLE(MUTATION_OBSERVERS)
 89
 90#endif // MutationObserverInterestGroup_h

Source/WebCore/dom/Node.cpp

@@void Node::didMoveToNewOwnerDocument()
25042504#if ENABLE(MUTATION_OBSERVERS)
25052505 if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
25062506 for (size_t i = 0; i < registry->size(); ++i) {
2507  if (registry->at(i)->isSubtree())
2508  document()->addSubtreeMutationObserverTypes(registry->at(i)->mutationTypes());
 2507 document()->addMutationObserverTypes(registry->at(i)->mutationTypes());
25092508 }
25102509 }
25112510
25122511 if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) {
25132512 for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
2514  if ((*iter)->isSubtree())
2515  document()->addSubtreeMutationObserverTypes((*iter)->mutationTypes());
 2513 document()->addMutationObserverTypes((*iter)->mutationTypes());
25162514 }
25172515 }
25182516#endif

@@void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*,
27042702 }
27052703}
27062704
2707 bool Node::mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType type)
2708 {
2709  return document()->hasSubtreeMutationObserverOfType(type) || (hasRareData() && (rareData()->mutationObserverRegistry() || rareData()->transientMutationObserverRegistry()));
2710 }
2711 
27122705void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type, const AtomicString& attributeName)
27132706{
27142707 collectMatchingObserversForMutation(observers, this, type, attributeName);
2715 
2716  if (!document()->hasSubtreeMutationObserverOfType(type))
2717  return;
2718 
27192708 for (Node* node = parentNode(); node; node = node->parentNode())
27202709 collectMatchingObserversForMutation(observers, node, type, attributeName);
27212710}

@@void Node::unregisterTransientMutationObserver(MutationObserverRegistration* reg
27672756
27682757void Node::notifyMutationObserversNodeWillDetach()
27692758{
2770  if (!document()->hasSubtreeMutationObserver())
 2759 if (!document()->hasMutationObservers())
27712760 return;
27722761
27732762 for (Node* node = parentNode(); node; node = node->parentNode()) {

Source/WebCore/dom/Node.h

@@public:
599599
600600#if ENABLE(MUTATION_OBSERVERS)
601601 void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom);
602  bool mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType);
603602 MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>);
604603 void unregisterMutationObserver(MutationObserverRegistration*);
605604 void registerTransientMutationObserver(MutationObserverRegistration*);

Source/WebCore/dom/WebKitMutationObserver.cpp

4040#include "MutationObserverRegistration.h"
4141#include "MutationRecord.h"
4242#include "Node.h"
43 #include "QualifiedName.h"
4443#include <wtf/ListHashSet.h>
4544
4645namespace WebCore {

@@void WebKitMutationObserver::observe(Node* node, MutationObserverOptions options
8483 MutationObserverRegistration* registration = node->registerMutationObserver(this);
8584 registration->resetObservation(options, attributeFilter);
8685
87  if (registration->isSubtree())
88  node->document()->addSubtreeMutationObserverTypes(registration->mutationTypes());
 86 node->document()->addMutationObserverTypes(registration->mutationTypes());
8987}
9088
9189void WebKitMutationObserver::disconnect()

@@void WebKitMutationObserver::deliverAllMutations()
149147 deliveryInProgress = false;
150148}
151149
152 PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag)
153 {
154  if (!target->mayHaveMutationObserversOfType(type))
155  return nullptr;
156 
157  HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
158  target->getRegisteredMutationObserversOfType(observers, type, attributeName);
159  if (observers.isEmpty())
160  return nullptr;
161 
162  return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
163 }
164 
165 MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
166  : m_oldValueFlag(oldValueFlag)
167 {
168  ASSERT(!observers.isEmpty());
169  m_observers.swap(observers);
170 }
171 
172 bool MutationObserverInterestGroup::isOldValueRequested()
173 {
174  for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
175  if (hasOldValue(iter->second))
176  return true;
177  }
178  return false;
179 }
180 
181 void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
182 {
183  RefPtr<MutationRecord> mutation = prpMutation;
184  RefPtr<MutationRecord> mutationWithNullOldValue;
185  for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
186  WebKitMutationObserver* observer = iter->first;
187  if (hasOldValue(iter->second)) {
188  observer->enqueueMutationRecord(mutation);
189  continue;
190  }
191  if (!mutationWithNullOldValue) {
192  if (mutation->oldValue().isNull())
193  mutationWithNullOldValue = mutation;
194  else
195  mutationWithNullOldValue = MutationRecord::createWithNullOldValue(mutation).get();
196  }
197  observer->enqueueMutationRecord(mutationWithNullOldValue);
198  }
199 }
200 
201150} // namespace WebCore
202151
203152#endif // ENABLE(MUTATION_OBSERVERS)

Source/WebCore/dom/WebKitMutationObserver.h

3333
3434#if ENABLE(MUTATION_OBSERVERS)
3535
36 #include "QualifiedName.h"
3736#include <wtf/HashMap.h>
3837#include <wtf/HashSet.h>
39 #include <wtf/PassOwnPtr.h>
4038#include <wtf/PassRefPtr.h>
4139#include <wtf/RefCounted.h>
4240#include <wtf/RefPtr.h>

@@class MutationCallback;
4947class MutationObserverRegistration;
5048class MutationRecord;
5149class Node;
52 class QualifiedName;
5350
5451typedef int ExceptionCode;
5552

@@private:
9895 HashSet<MutationObserverRegistration*> m_registrations;
9996};
10097
101 class MutationObserverInterestGroup {
102 public:
103  static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node* target)
104  {
105  MutationRecordDeliveryOptions oldValueFlag = 0;
106  return createIfNeeded(target, WebKitMutationObserver::ChildList, nullAtom, oldValueFlag);
107  }
108  static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node* target)
109  {
110  return createIfNeeded(target, WebKitMutationObserver::CharacterData, nullAtom, WebKitMutationObserver::CharacterDataOldValue);
111  }
112  static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node* target, const QualifiedName& attributeName)
113  {
114  return createIfNeeded(target, WebKitMutationObserver::Attributes, attributeName.localName(), WebKitMutationObserver::AttributeOldValue);
115  }
116 
117  bool isOldValueRequested();
118  void enqueueMutationRecord(PassRefPtr<MutationRecord>);
119 
120 private:
121  static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag);
122  MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
123 
124  bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
125 
126  HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> m_observers;
127  MutationRecordDeliveryOptions m_oldValueFlag;
128 };
129 
13098}
13199
132100#endif // ENABLE(MUTATION_OBSERVERS)