Index: Source/core/dom/ContainerNodeAlgorithms.h |
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h |
index fbac15b690b481353814c5e386c50c2310d81fd0..da2c4fabf5d262566d61899d4bb0c59ac773613b 100644 |
--- a/Source/core/dom/ContainerNodeAlgorithms.h |
+++ b/Source/core/dom/ContainerNodeAlgorithms.h |
@@ -71,60 +71,7 @@ namespace Private { |
template<class GenericNode, class GenericNodeContainer> |
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&); |
-} |
- |
-// Helper functions for TreeShared-derived classes, which have a 'Node' style interface |
-// This applies to 'ContainerNode' and 'SVGElementInstance' |
-template<class GenericNode, class GenericNodeContainer> |
-inline void removeDetachedChildrenInContainer(GenericNodeContainer& container) |
-{ |
- // List of nodes to be deleted. |
- GenericNode* head = 0; |
- GenericNode* tail = 0; |
- |
- Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, container); |
- |
- GenericNode* n; |
- GenericNode* next; |
- while ((n = head) != 0) { |
-#if !ENABLE(OILPAN) |
- ASSERT_WITH_SECURITY_IMPLICATION(n->m_deletionHasBegun); |
-#endif |
- |
- next = n->nextSibling(); |
- n->setNextSibling(0); |
- |
- head = next; |
- if (next == 0) |
- tail = 0; |
- |
- if (n->hasChildren()) |
- Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n)); |
- |
-#if !ENABLE(OILPAN) |
- delete n; |
-#endif |
- } |
-} |
- |
-template<class GenericNode, class GenericNodeContainer> |
-inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& container) |
-{ |
- child.setParentOrShadowHostNode(&container); |
- |
- GenericNode* lastChild = container.lastChild(); |
- if (lastChild) { |
- child.setPreviousSibling(lastChild); |
- lastChild->setNextSibling(&child); |
- } else { |
- container.setFirstChild(&child); |
- } |
- |
- container.setLastChild(&child); |
-} |
- |
-// Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace |
-namespace Private { |
+ // Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace |
template<class GenericNode, class GenericNodeContainer, bool dispatchRemovalNotification> |
struct NodeRemovalDispatcher { |
@@ -171,28 +118,6 @@ namespace Private { |
if (next) |
next->setPreviousSibling(0); |
-#if ENABLE(OILPAN) |
- { |
- // Always notify nodes of removal from the document even if they |
- // are going to die. Nodes do not immediately die when their |
- // refcounts reach zero with Oilpan. They die at the next garbage |
- // collection. The notifications when removed from document |
- // allows us to perform cleanup on the nodes when they are removed |
- // instead of when their destructors are called. |
- RefPtr<GenericNode> protect(n); // removedFromDocument may remove all references to this node. |
- NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container); |
- } |
- if (!n->refCount()) { |
- // Add the node to the list of nodes to be deleted. |
- // Reuse the nextSibling pointer for this purpose. |
- if (tail) |
- tail->setNextSibling(n); |
- else |
- head = n; |
- |
- tail = n; |
- } |
-#else |
if (!n->refCount()) { |
#if SECURITY_ASSERT_ENABLED |
n->m_deletionHasBegun = true; |
@@ -209,7 +134,6 @@ namespace Private { |
RefPtr<GenericNode> protect(n); // removedFromDocument may remove all references to this node. |
NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container); |
} |
-#endif // ENABLE(OILPAN) |
} |
container.setLastChild(0); |
@@ -217,6 +141,70 @@ namespace Private { |
} // namespace Private |
+// Helper functions for TreeShared-derived classes, which have a 'Node' style interface |
+// This applies to 'ContainerNode' and 'SVGElementInstance' |
haraken
2014/05/06 04:20:16
FYI, SVGElementInstance is going to be removed soo
Mads Ager (chromium)
2014/05/06 08:26:00
That is great! Right now this code is only used fo
|
+template<class GenericNode, class GenericNodeContainer> |
+inline void removeDetachedChildrenInContainer(GenericNodeContainer& container) |
haraken
2014/05/06 04:20:16
Just help me understand (very fundamental question
Mads Ager (chromium)
2014/05/06 08:26:00
Yes, it is very confusing. This is still called by
|
+{ |
+#if ENABLE(OILPAN) |
+ // Always dispatch node removal notifications when nodes are |
+ // removed. This maintains the invariant that either nodes have |
+ // been removed from their container and their removedFrom method has |
+ // been called, or the nodes die with the their container. |
haraken
2014/05/06 04:20:16
the their container => their container
Just to co
Mads Ager (chromium)
2014/05/06 08:26:00
That is correct. This is only called from SVGEleme
|
+ GenericNode* next = 0; |
+ for (GenericNode* n = container.firstChild(); n; n = next) { |
+ next = n->nextSibling(); |
+ n->setNextSibling(0); |
+ n->setParentOrShadowHostNode(0); |
+ if (next) |
+ next->setPreviousSibling(0); |
+ Private::NodeRemovalDispatcher<GenericNode, GenericNodeContainer, Private::ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container); |
+ } |
+ container.setFirstChild(0); |
+ container.setLastChild(0); |
+#else |
+ // List of nodes to be deleted. |
+ GenericNode* head = 0; |
+ GenericNode* tail = 0; |
+ |
+ Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, container); |
+ |
+ GenericNode* n; |
+ GenericNode* next; |
+ while ((n = head) != 0) { |
+ ASSERT_WITH_SECURITY_IMPLICATION(n->m_deletionHasBegun); |
+ |
+ next = n->nextSibling(); |
+ n->setNextSibling(0); |
+ |
+ head = next; |
+ if (next == 0) |
+ tail = 0; |
+ |
+ if (n->hasChildren()) |
+ Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n)); |
+ |
+ delete n; |
+ } |
+#endif |
+} |
+ |
+template<class GenericNode, class GenericNodeContainer> |
+inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& container) |
+{ |
+ child.setParentOrShadowHostNode(&container); |
+ |
+ GenericNode* lastChild = container.lastChild(); |
+ if (lastChild) { |
+ child.setPreviousSibling(lastChild); |
+ lastChild->setNextSibling(&child); |
+ } else { |
+ container.setFirstChild(&child); |
+ } |
+ |
+ container.setLastChild(&child); |
+} |
+ |
inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& node) |
{ |
ASSERT(m_insertionPoint.inDocument()); |