Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Unified Diff: Source/core/dom/ContainerNode.cpp

Issue 305603003: Merge ChildNodeInsertionNotifier and ChildNodeRemovalNotifier into ContainerNode (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Don't mess with RefPtr protects yet Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/dom/ContainerNode.h ('k') | Source/core/dom/ContainerNodeAlgorithms.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/ContainerNode.cpp
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 427e089656ad09e4104b4bd8a2f08822764e1101..366598a9ce6a8220762d91d88a5d7cfb667cfcad 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -36,11 +36,15 @@
#include "core/dom/NodeRareData.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
+#include "core/dom/ScriptForbiddenScope.h"
#include "core/dom/SelectorQuery.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/MutationEvent.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/RadioNodeList.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTheme.h"
@@ -289,7 +293,7 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil
childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ notifyNodeInserted(*newChild);
}
void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
@@ -466,7 +470,7 @@ void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
Node* next = child->nextSibling();
removeBetween(prev, next, *child);
childrenChanged(false, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(*child);
+ notifyNodeRemoved(*child);
}
dispatchSubtreeModifiedEvent();
}
@@ -512,7 +516,7 @@ void ContainerNode::parserRemoveChild(Node& oldChild)
removeBetween(prev, next, oldChild);
childrenChanged(true, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(oldChild);
+ notifyNodeRemoved(oldChild);
}
// this differs from other remove functions because it forcibly removes all the children,
@@ -563,7 +567,7 @@ void ContainerNode::removeChildren()
childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
for (size_t i = 0; i < removedChildren.size(); ++i)
- ChildNodeRemovalNotifier(*this).notify(*removedChildren[i]);
+ notifyNodeRemoved(*removedChildren[i]);
}
dispatchSubtreeModifiedEvent();
@@ -650,7 +654,65 @@ void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
ChildListMutationScope(*this).childAdded(*newChild);
childrenChanged(true, last, 0, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ notifyNodeInserted(*newChild);
+}
+
+void ContainerNode::notifyNodeInserted(Node& root)
+{
+ ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
+
+ InspectorInstrumentation::didInsertDOMNode(&root);
+
+ RefPtr<Node> protectDocument(root.document());
+ RefPtr<Node> protectNode(root);
+
+ NodeVector postInsertionNotificationTargets;
+
+ {
+ NoEventDispatchAssertion assertNoEventDispatch;
+ ScriptForbiddenScope forbidScript;
+ notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
+ }
+
+ for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) {
+ Node* targetNode = postInsertionNotificationTargets[i].get();
+ if (targetNode->inDocument())
+ targetNode->didNotifySubtreeInsertionsToDocument();
+ }
+}
+
+void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInsertionNotificationTargets)
+{
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we don't notify leaf nodes when when inserting
+ // into detached subtrees.
+ if (!inDocument() && !node->isContainerNode())
+ continue;
+ if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node->insertedInto(this))
+ postInsertionNotificationTargets.append(node);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeInsertedInternal(*shadowRoot, postInsertionNotificationTargets);
+ }
+}
+
+void ContainerNode::notifyNodeRemoved(Node& root)
+{
+ ScriptForbiddenScope forbidScript;
+ NoEventDispatchAssertion assertNoEventDispatch;
+
+ Document& document = root.document();
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we skip notifying Text nodes and other leaf nodes
+ // of removal when they're not in the Document tree since the virtual
+ // call to removedFrom is not needed.
+ if (!node->inDocument() && !node->isContainerNode())
+ continue;
+ if (document.cssTarget() == node)
+ document.setCSSTarget(0);
+ node->removedFrom(this);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeRemoved(*shadowRoot);
+ }
}
void ContainerNode::attach(const AttachContext& context)
@@ -1021,7 +1083,7 @@ void ContainerNode::updateTreeAfterInsertion(Node& child)
childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
- ChildNodeInsertionNotifier(*this).notify(child);
+ notifyNodeInserted(child);
dispatchChildInsertionEvents(child);
}
« no previous file with comments | « Source/core/dom/ContainerNode.h ('k') | Source/core/dom/ContainerNodeAlgorithms.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698