Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (104258 => 104259)
--- trunk/Source/WebCore/CMakeLists.txt 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/CMakeLists.txt 2012-01-06 01:58:34 UTC (rev 104259)
@@ -610,6 +610,7 @@
dom/TransformSourceLibxslt.cpp
dom/Traversal.cpp
dom/TreeScope.cpp
+ dom/TreeScopeAdopter.cpp
dom/TreeWalker.cpp
dom/UIEvent.cpp
dom/UIEventWithKeyState.cpp
Modified: trunk/Source/WebCore/ChangeLog (104258 => 104259)
--- trunk/Source/WebCore/ChangeLog 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/ChangeLog 2012-01-06 01:58:34 UTC (rev 104259)
@@ -1,3 +1,60 @@
+2012-01-04 Hajime Morrita <[email protected]>
+
+ [Refactoring] Moving between TreeScopes should be done by its own class.
+ https://bugs.webkit.org/show_bug.cgi?id=75290
+
+ Reviewed by Ryosuke Niwa.
+
+ This change extracted Node::setTreeScopeRecursively(),
+ setDocumentRecursively() and a part of setDocument() into a new
+ class called TreeScopeAdopter. By doing this, the idea of
+ moving a node from scope to scope, that was originally hidden
+ behind the forest of Node APIs, has become clearer.
+
+ Note that this change is a preparation for Bug 59816.
+
+ No new tests. No behavioral change.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/ContainerNode.cpp: Followed the renaming.
+ (WebCore::ContainerNode::takeAllChildrenFrom):
+ (WebCore::ContainerNode::insertBefore):
+ (WebCore::ContainerNode::replaceChild):
+ (WebCore::ContainerNode::removeBetween):
+ (WebCore::ContainerNode::removeChildren):
+ (WebCore::ContainerNode::appendChild):
+ (WebCore::ContainerNode::parserAddChild):
+ * dom/DOMAllInOne.cpp:
+ * dom/Document.cpp: Followed te renaming.
+ (WebCore::Document::setDocType):
+ (WebCore::Document::adoptNode):
+ * dom/Element.cpp: Followed te renaming.
+ (WebCore::Element::removeShadowRoot):
+ * dom/Node.cpp:
+ (WebCore::Node::setDocument):
+ (WebCore::Node::setTreeScope):
+ (WebCore::Node::didMoveToNewDocument):
+ * dom/Node.h:
+ * dom/TreeScope.h:
+ * dom/TreeScope.cpp:
+ (WebCore::TreeScope::adoptIfNeeded): moved from setTreeScopeRecursively()
+ * dom/TreeScopeAdopter.cpp: Added.
+ (WebCore::TreeScopeAdopter::TreeScopeAdopter):
+ (WebCore::TreeScopeAdopter::moveTreeToNewScope):
+ (WebCore::TreeScopeAdopter::moveTreeToNewDocument):
+ (WebCore::TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled):
+ (WebCore::TreeScopeAdopter::moveNodeToNewDocument):
+ * dom/TreeScopeAdopter.h: Added.
+ (WebCore::TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled):
+ (WebCore::TreeScopeAdopter::execute):
+ (WebCore::TreeScopeAdopter::needsScopeChange()):
+ (WebCore::TreeScopeAdopter::shadowRootFor):
+
2012-01-05 Jochen Eisinger <[email protected]>
Disallow access to DOM storage from detached frames.
Property changes on: trunk/Source/WebCore/ChangeLog
___________________________________________________________________
Deleted: svn:executable
Modified: trunk/Source/WebCore/GNUmakefile.list.am (104258 => 104259)
--- trunk/Source/WebCore/GNUmakefile.list.am 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2012-01-06 01:58:34 UTC (rev 104259)
@@ -1674,6 +1674,8 @@
Source/WebCore/dom/TreeDepthLimit.h \
Source/WebCore/dom/TreeScope.cpp \
Source/WebCore/dom/TreeScope.h \
+ Source/WebCore/dom/TreeScopeAdopter.cpp \
+ Source/WebCore/dom/TreeScopeAdopter.h \
Source/WebCore/dom/TreeWalker.cpp \
Source/WebCore/dom/TreeWalker.h \
Source/WebCore/dom/UIEvent.cpp \
Modified: trunk/Source/WebCore/Target.pri (104258 => 104259)
--- trunk/Source/WebCore/Target.pri 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/Target.pri 2012-01-06 01:58:34 UTC (rev 104259)
@@ -574,6 +574,7 @@
dom/TouchList.cpp \
dom/Traversal.cpp \
dom/TreeScope.cpp \
+ dom/TreeScopeAdopter.cpp \
dom/TreeWalker.cpp \
dom/UIEvent.cpp \
dom/UIEventWithKeyState.cpp \
@@ -1670,6 +1671,7 @@
dom/Traversal.h \
dom/TreeDepthLimit.h \
dom/TreeScope.h \
+ dom/TreeScopeAdopter.h \
dom/TreeWalker.h \
dom/UIEvent.h \
dom/UIEventWithKeyState.h \
Modified: trunk/Source/WebCore/WebCore.gypi (104258 => 104259)
--- trunk/Source/WebCore/WebCore.gypi 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/WebCore.gypi 2012-01-06 01:58:34 UTC (rev 104259)
@@ -5465,6 +5465,8 @@
'dom/TreeDepthLimit.h',
'dom/TreeScope.cpp',
'dom/TreeScope.h',
+ 'dom/TreeScopeAdopter.cpp',
+ 'dom/TreeScopeAdopter.h',
'dom/TreeWalker.cpp',
'dom/TreeWalker.h',
'dom/UIEvent.cpp',
Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (104258 => 104259)
--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-01-06 01:58:34 UTC (rev 104259)
@@ -51774,6 +51774,62 @@
>
</File>
<File
+ RelativePath="..\dom\TreeScopeAdopter.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo_CFLite|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo_CFLite|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Production|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\dom\TreeScopeAdopter.h"
+ >
+ </File>
+ <File
RelativePath="..\dom\TreeWalker.cpp"
>
<FileConfiguration
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (104258 => 104259)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-01-06 01:58:34 UTC (rev 104259)
@@ -3507,6 +3507,8 @@
A77979290D6B9E64003851B9 /* JSImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = A77979250D6B9E64003851B9 /* JSImageData.h */; };
A77B41A012E675A90054343D /* TextEventInputType.h in Headers */ = {isa = PBXBuildFile; fileRef = A77B419F12E675A90054343D /* TextEventInputType.h */; settings = {ATTRIBUTES = (Private, ); }; };
A77D0012133B0AEB00D6658C /* TextChecking.h in Headers */ = {isa = PBXBuildFile; fileRef = A77D0011133B0AEB00D6658C /* TextChecking.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A77E1FEF14AACB6E005B7CB6 /* TreeScopeAdopter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77E1FED14AACB6E005B7CB6 /* TreeScopeAdopter.cpp */; };
+ A77E1FF014AACB6E005B7CB6 /* TreeScopeAdopter.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E1FEE14AACB6E005B7CB6 /* TreeScopeAdopter.h */; };
A781C6A713828B5D0012A62A /* DocumentMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A781C6A613828B5D0012A62A /* DocumentMarker.cpp */; };
A784941B0B5FE507001E237A /* Clipboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A784941A0B5FE507001E237A /* Clipboard.cpp */; };
A78E526F1346BD1700AD9C31 /* MeterShadowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78E526D1346BD1700AD9C31 /* MeterShadowElement.cpp */; };
@@ -10776,6 +10778,8 @@
A77979250D6B9E64003851B9 /* JSImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSImageData.h; sourceTree = "<group>"; };
A77B419F12E675A90054343D /* TextEventInputType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextEventInputType.h; sourceTree = "<group>"; };
A77D0011133B0AEB00D6658C /* TextChecking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextChecking.h; sourceTree = "<group>"; };
+ A77E1FED14AACB6E005B7CB6 /* TreeScopeAdopter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TreeScopeAdopter.cpp; sourceTree = "<group>"; };
+ A77E1FEE14AACB6E005B7CB6 /* TreeScopeAdopter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeScopeAdopter.h; sourceTree = "<group>"; };
A781C6A613828B5D0012A62A /* DocumentMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarker.cpp; sourceTree = "<group>"; };
A784941A0B5FE507001E237A /* Clipboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Clipboard.cpp; sourceTree = "<group>"; };
A78E526D1346BD1700AD9C31 /* MeterShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MeterShadowElement.cpp; sourceTree = "<group>"; };
@@ -21444,6 +21448,8 @@
37FD4297118368460093C029 /* TreeDepthLimit.h */,
14D64B5A134A5B6B00E58FDA /* TreeScope.cpp */,
14D64B5B134A5B6B00E58FDA /* TreeScope.h */,
+ A77E1FED14AACB6E005B7CB6 /* TreeScopeAdopter.cpp */,
+ A77E1FEE14AACB6E005B7CB6 /* TreeScopeAdopter.h */,
854FE72E0A2297BE0058D7AD /* TreeWalker.cpp */,
854FE72F0A2297BE0058D7AD /* TreeWalker.h */,
1A750D3C0A90DE35000FF215 /* TreeWalker.idl */,
@@ -24695,6 +24701,7 @@
854FE7370A2297BE0058D7AD /* Traversal.h in Headers */,
37FD4298118368460093C029 /* TreeDepthLimit.h in Headers */,
14D64B5D134A5B6B00E58FDA /* TreeScope.h in Headers */,
+ A77E1FF014AACB6E005B7CB6 /* TreeScopeAdopter.h in Headers */,
1419D2C50CEA6F6100FF507A /* TreeShared.h in Headers */,
854FE7390A2297BE0058D7AD /* TreeWalker.h in Headers */,
37C28A6810F659CC008C7813 /* TypesettingFeatures.h in Headers */,
@@ -27626,6 +27633,7 @@
49E911D10EF86D47009D0CAF /* TranslateTransformOperation.cpp in Sources */,
854FE7360A2297BE0058D7AD /* Traversal.cpp in Sources */,
14D64B5C134A5B6B00E58FDA /* TreeScope.cpp in Sources */,
+ A77E1FEF14AACB6E005B7CB6 /* TreeScopeAdopter.cpp in Sources */,
854FE7380A2297BE0058D7AD /* TreeWalker.cpp in Sources */,
93309E19099E64920056E581 /* TypingCommand.cpp in Sources */,
85031B4D0A44EFC700F992E0 /* UIEvent.cpp in Sources */,
Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/ContainerNode.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -99,7 +99,7 @@
// FIXME: Together with adoptNode above, the tree scope might get updated recursively twice
// (if the document changed or oldParent was in a shadow tree, AND *this is in a shadow tree).
// Can we do better?
- child->setTreeScopeRecursively(treeScope());
+ treeScope()->adoptIfNeeded(child.get());
if (attached() && !child->attached())
child->attach();
}
@@ -175,7 +175,7 @@
InspectorInstrumentation::willInsertDOMNode(document(), child, this);
#endif
- child->setTreeScopeRecursively(treeScope());
+ treeScope()->adoptIfNeeded(child);
insertBeforeCommon(next.get(), child);
@@ -329,7 +329,7 @@
InspectorInstrumentation::willInsertDOMNode(document(), child.get(), this);
#endif
- child->setTreeScopeRecursively(treeScope());
+ treeScope()->adoptIfNeeded(child.get());
// Add child after "prev".
forbidEventDispatch();
@@ -509,7 +509,7 @@
oldChild->setNextSibling(0);
oldChild->setParent(0);
- oldChild->setTreeScopeRecursively(document());
+ document()->adoptIfNeeded(oldChild);
allowEventDispatch();
}
@@ -564,7 +564,7 @@
n->setPreviousSibling(0);
n->setNextSibling(0);
n->setParent(0);
- n->setTreeScopeRecursively(document());
+ document()->adoptIfNeeded(n.get());
m_firstChild = next;
if (n == m_lastChild)
@@ -649,7 +649,7 @@
InspectorInstrumentation::willInsertDOMNode(document(), child, this);
#endif
- child->setTreeScopeRecursively(treeScope());
+ treeScope()->adoptIfNeeded(child);
// Append child to the end of the list
forbidEventDispatch();
@@ -697,7 +697,7 @@
Node* last = m_lastChild;
// FIXME: This method should take a PassRefPtr.
appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
- newChild->setTreeScopeRecursively(treeScope());
+ treeScope()->adoptIfNeeded(newChild.get());
allowEventDispatch();
Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/DOMAllInOne.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/DOMAllInOne.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -129,6 +129,7 @@
#include "TransformSourceLibxslt.cpp"
#include "Traversal.cpp"
#include "TreeScope.cpp"
+#include "TreeScopeAdopter.cpp"
#include "TreeWalker.cpp"
#include "UIEvent.cpp"
#include "UIEventWithKeyState.cpp"
Modified: trunk/Source/WebCore/dom/Document.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/Document.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/Document.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -712,7 +712,7 @@
ASSERT(!m_docType || !docType);
m_docType = docType;
if (m_docType)
- m_docType->setTreeScopeRecursively(this);
+ this->adoptIfNeeded(m_docType.get());
}
DOMImplementation* Document::implementation()
@@ -942,7 +942,7 @@
source->parentNode()->removeChild(source.get(), ec);
}
- source->setTreeScopeRecursively(this);
+ this->adoptIfNeeded(source.get());
return source;
}
Modified: trunk/Source/WebCore/dom/Element.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/Element.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/Element.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -1221,7 +1221,7 @@
oldRoot->detach();
oldRoot->setShadowHost(0);
- oldRoot->setTreeScopeRecursively(document());
+ document()->adoptIfNeeded(oldRoot.get());
if (oldRoot->inDocument())
oldRoot->removedFromDocument();
else
Modified: trunk/Source/WebCore/dom/Node.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/Node.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/Node.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -90,6 +90,7 @@
#include "TagNodeList.h"
#include "Text.h"
#include "TextEvent.h"
+#include "TreeScopeAdopter.h"
#include "UIEvent.h"
#include "UIEventWithKeyState.h"
#include "WebKitAnimationEvent.h"
@@ -417,37 +418,30 @@
doc->guardDeref();
}
-#ifndef NDEBUG
-
-static bool didMoveToNewDocumentWasCalled;
-static Document* oldDocumentDidMoveToNewDocumentWasCalledWith;
-
-#endif
-
void Node::setDocument(Document* document)
{
ASSERT(!inDocument() || m_document == document);
if (inDocument() || m_document == document)
return;
- document->guardRef();
-
- if (m_document) {
- m_document->moveNodeIteratorsToNewDocument(this, document);
- m_document->guardDeref();
- }
-
- Document* oldDocument = m_document;
m_document = document;
+}
-#ifndef NDEBUG
- didMoveToNewDocumentWasCalled = false;
- oldDocumentDidMoveToNewDocumentWasCalledWith = oldDocument;
-#endif
+NodeRareData* Node::setTreeScope(TreeScope* scope)
+{
+ if (!scope) {
+ if (hasRareData()) {
+ NodeRareData* data = ""
+ data->setTreeScope(0);
+ return data;
+ }
- didMoveToNewDocument(oldDocument);
+ return 0;
+ }
- ASSERT(didMoveToNewDocumentWasCalled);
+ NodeRareData* data = ""
+ data->setTreeScope(scope);
+ return data;
}
TreeScope* Node::treeScope() const
@@ -459,54 +453,6 @@
return scope ? scope : m_document;
}
-void Node::setTreeScopeRecursively(TreeScope* newTreeScope)
-{
- ASSERT(this);
- ASSERT(!isDocumentNode());
- ASSERT(newTreeScope);
- ASSERT(!m_deletionHasBegun);
-
- TreeScope* currentTreeScope = treeScope();
- if (currentTreeScope == newTreeScope)
- return;
-
- Document* currentDocument = document();
- Document* newDocument = newTreeScope->document();
- // If an element is moved from a document and then eventually back again the collection cache for
- // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
- // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
- // we ensure that the collection cache will be invalidated as needed when the element is moved back.
- if (currentDocument && currentDocument != newDocument)
- currentDocument->incDOMTreeVersion();
-
- for (Node* node = this; node; node = node->traverseNextNode(this)) {
- if (newTreeScope == newDocument) {
- if (node->hasRareData())
- node->rareData()->setTreeScope(0);
- // Setting the new document tree scope will be handled implicitly
- // by setDocument() below.
- } else
- node->ensureRareData()->setTreeScope(newTreeScope);
-
- if (node->hasRareData() && node->rareData()->nodeLists()) {
- node->rareData()->nodeLists()->invalidateCaches();
- if (currentTreeScope)
- currentTreeScope->removeNodeListCache();
- newTreeScope->addNodeListCache();
- }
-
- node->setDocument(newDocument);
-
- if (!node->isElementNode())
- continue;
- if (ShadowRoot* shadowRoot = toElement(node)->shadowRoot()) {
- shadowRoot->setParentTreeScope(newTreeScope);
- if (currentDocument != newDocument)
- shadowRoot->setDocumentRecursively(newDocument);
- }
- }
-}
-
NodeRareData* Node::rareData() const
{
ASSERT(hasRareData());
@@ -852,19 +798,6 @@
return node->isElementNode() ? toElement(node)->shadowRoot() : 0;
}
-void Node::setDocumentRecursively(Document* newDocument)
-{
- ASSERT(document() != newDocument);
-
- for (Node* node = this; node; node = node->traverseNextNode(this)) {
- node->setDocument(newDocument);
- if (!node->isElementNode())
- continue;
- if (ShadowRoot* shadow = shadowRoot(node))
- shadow->setDocumentRecursively(newDocument);
- }
-}
-
inline void Node::setStyleChange(StyleChangeType changeType)
{
m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
@@ -2408,13 +2341,8 @@
void Node::didMoveToNewDocument(Document* oldDocument)
{
- ASSERT(!didMoveToNewDocumentWasCalled);
- ASSERT_UNUSED(oldDocument, oldDocument == oldDocumentDidMoveToNewDocumentWasCalledWith);
+ TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument);
-#ifndef NDEBUG
- didMoveToNewDocumentWasCalled = true;
-#endif
-
// FIXME: Event listener types for this node should be set on the new owner document here.
#if ENABLE(MUTATION_OBSERVERS)
Modified: trunk/Source/WebCore/dom/Node.h (104258 => 104259)
--- trunk/Source/WebCore/dom/Node.h 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/Node.h 2012-01-06 01:58:34 UTC (rev 104259)
@@ -104,6 +104,7 @@
class Node : public EventTarget, public ScriptWrappable, public TreeShared<ContainerNode> {
friend class Document;
friend class TreeScope;
+ friend class TreeScopeAdopter;
public:
enum NodeType {
@@ -383,9 +384,6 @@
TreeScope* treeScope() const;
- // Used by the basic DOM methods (e.g., appendChild()).
- void setTreeScopeRecursively(TreeScope*);
-
// Returns true if this node is associated with a document and is in its associated document's
// node tree, false otherwise.
bool inDocument() const
@@ -695,9 +693,9 @@
void clearHasCustomStyleForRenderer() { clearFlag(HasCustomStyleForRendererFlag); }
private:
- // Do not use this method to change the document of a node until after the node has been
- // removed from its previous document.
- void setDocumentRecursively(Document*);
+ // These API should be only used for a tree scope migration.
+ // setTreeScope() returns NodeRareData to save extra nodeRareData() invocations on the caller site.
+ NodeRareData* setTreeScope(TreeScope*);
void setDocument(Document*);
enum EditableLevel { Editable, RichlyEditable };
Modified: trunk/Source/WebCore/dom/TreeScope.cpp (104258 => 104259)
--- trunk/Source/WebCore/dom/TreeScope.cpp 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/TreeScope.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -31,6 +31,7 @@
#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "NodeRareData.h"
+#include "TreeScopeAdopter.h"
namespace WebCore {
@@ -137,5 +138,16 @@
return true;
}
+void TreeScope::adoptIfNeeded(Node* node)
+{
+ ASSERT(this);
+ ASSERT(node);
+ ASSERT(!node->isDocumentNode());
+ ASSERT(!node->m_deletionHasBegun);
+ TreeScopeAdopter adopter(node, this);
+ if (adopter.needsScopeChange())
+ adopter.execute();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/TreeScope.h (104258 => 104259)
--- trunk/Source/WebCore/dom/TreeScope.h 2012-01-06 01:37:39 UTC (rev 104258)
+++ trunk/Source/WebCore/dom/TreeScope.h 2012-01-06 01:58:34 UTC (rev 104259)
@@ -64,6 +64,9 @@
virtual bool applyAuthorSheets() const;
+ // Used by the basic DOM mutation methods (e.g., appendChild()).
+ void adoptIfNeeded(Node*);
+
protected:
TreeScope(Document*, ConstructionType = CreateContainer);
virtual ~TreeScope();
Added: trunk/Source/WebCore/dom/TreeScopeAdopter.cpp (0 => 104259)
--- trunk/Source/WebCore/dom/TreeScopeAdopter.cpp (rev 0)
+++ trunk/Source/WebCore/dom/TreeScopeAdopter.cpp 2012-01-06 01:58:34 UTC (rev 104259)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 1999 Lars Knoll ([email protected])
+ * (C) 1999 Antti Koivisto ([email protected])
+ * (C) 2001 Dirk Mueller ([email protected])
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "config.h"
+#include "TreeScopeAdopter.h"
+
+#include "Document.h"
+#include "NodeRareData.h"
+#include "ShadowRoot.h"
+
+namespace WebCore {
+
+static inline ShadowRoot* shadowRootFor(Node* node)
+{
+ return node->isElementNode() ? toElement(node)->shadowRoot() : 0;
+}
+
+void TreeScopeAdopter::moveTreeToNewScope(Node* root) const
+{
+ ASSERT(needsScopeChange());
+
+ // If an element is moved from a document and then eventually back again the collection cache for
+ // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
+ // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
+ // we ensure that the collection cache will be invalidated as needed when the element is moved back.
+ Document* oldDocument = m_oldScope->document();
+ Document* newDocument = m_newScope->document();
+ bool willMoveToNewDocument = oldDocument != newDocument;
+ if (oldDocument && willMoveToNewDocument)
+ oldDocument->incDOMTreeVersion();
+
+ for (Node* node = root; node; node = node->traverseNextNode(root)) {
+ NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope);
+ if (rareData && rareData->nodeLists()) {
+ if (m_oldScope)
+ m_oldScope->removeNodeListCache();
+ m_newScope->addNodeListCache();
+ }
+
+ if (willMoveToNewDocument)
+ moveNodeToNewDocument(node, oldDocument, newDocument);
+
+ if (ShadowRoot* shadow = shadowRootFor(node)) {
+ shadow->setParentTreeScope(m_newScope);
+ if (willMoveToNewDocument)
+ moveTreeToNewDocument(shadow, oldDocument, newDocument);
+ }
+ }
+}
+
+void TreeScopeAdopter::moveTreeToNewDocument(Node* root, Document* oldDocument, Document* newDocument) const
+{
+ for (Node* node = root; node; node = node->traverseNextNode(root)) {
+ moveNodeToNewDocument(node, oldDocument, newDocument);
+ if (ShadowRoot* shadow = shadowRootFor(node))
+ moveTreeToNewDocument(shadow, oldDocument, newDocument);
+ }
+}
+
+#ifndef NDEBUG
+static bool didMoveToNewDocumentWasCalled = false;
+static Document* oldDocumentDidMoveToNewDocumentWasCalledWith = NULL;
+
+void TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(Document* oldDocument)
+{
+ ASSERT(!didMoveToNewDocumentWasCalled);
+ ASSERT_UNUSED(oldDocument, oldDocument == oldDocumentDidMoveToNewDocumentWasCalledWith);
+ didMoveToNewDocumentWasCalled = true;
+}
+#endif
+
+void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const
+{
+ ASSERT(!node->inDocument() || oldDocument != newDocument);
+
+ newDocument->guardRef();
+ if (oldDocument) {
+ oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
+ oldDocument->guardDeref();
+ }
+
+ node->setDocument(newDocument);
+
+#ifndef NDEBUG
+ didMoveToNewDocumentWasCalled = false;
+ oldDocumentDidMoveToNewDocumentWasCalledWith = oldDocument;
+#endif
+
+ node->didMoveToNewDocument(oldDocument);
+ ASSERT(didMoveToNewDocumentWasCalled);
+}
+
+}
Added: trunk/Source/WebCore/dom/TreeScopeAdopter.h (0 => 104259)
--- trunk/Source/WebCore/dom/TreeScopeAdopter.h (rev 0)
+++ trunk/Source/WebCore/dom/TreeScopeAdopter.h 2012-01-06 01:58:34 UTC (rev 104259)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1999 Lars Knoll ([email protected])
+ * (C) 1999 Antti Koivisto ([email protected])
+ * (C) 2001 Dirk Mueller ([email protected])
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef TreeScopeAdopter_h
+#define TreeScopeAdopter_h
+
+#include "Element.h"
+
+namespace WebCore {
+
+class TreeScopeAdopter {
+public:
+ explicit TreeScopeAdopter(Node* toAdopt, TreeScope* newScope);
+
+ void execute() const { moveTreeToNewScope(m_toAdopt); }
+ bool needsScopeChange() const { return m_oldScope != m_newScope; }
+
+#ifdef NDEBUG
+ static void ensureDidMoveToNewDocumentWasCalled(Document*) { }
+#else
+ static void ensureDidMoveToNewDocumentWasCalled(Document*);
+#endif
+
+private:
+ void moveTreeToNewScope(Node*) const;
+ void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
+ void moveNodeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
+
+ Node* m_toAdopt;
+ TreeScope* m_newScope;
+ TreeScope* m_oldScope;
+};
+
+inline TreeScopeAdopter::TreeScopeAdopter(Node* toAdopt, TreeScope* newScope)
+ : m_toAdopt(toAdopt)
+ , m_newScope(newScope)
+ , m_oldScope(toAdopt->treeScope())
+{
+ ASSERT(newScope);
+}
+
+}
+
+#endif