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

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

Issue 306233005: Call insertedInto or removedFrom before childrenChanged (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Pass right flags, don't notify on ShadowRoot 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') | no next file » | 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 116d4763b1d45869f3c32854046cf486c73ebbad..a7d245ac234d45795d5052214f5e02bef8bcfb44 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -278,6 +278,8 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil
ASSERT(!newChild->isDocumentFragment());
ASSERT(!isHTMLTemplateElement(this));
+ RefPtr<Node> protect(this);
+
if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
return;
@@ -290,9 +292,7 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil
ChildListMutationScope(*this).childAdded(*newChild);
- childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
-
- notifyNodeInserted(*newChild);
+ notifyNodeInserted(*newChild, true);
}
void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
@@ -468,8 +468,8 @@ void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
Node* prev = child->previousSibling();
Node* next = child->nextSibling();
removeBetween(prev, next, *child);
- childrenChanged(false, prev, next, -1);
notifyNodeRemoved(*child);
+ childrenChanged(false, prev, next, -1);
}
dispatchSubtreeModifiedEvent();
}
@@ -504,6 +504,10 @@ void ContainerNode::parserRemoveChild(Node& oldChild)
ASSERT(oldChild.parentNode() == this);
ASSERT(!oldChild.isDocumentFragment());
+ ScriptForbiddenScope forbidScript;
+
+ RefPtr<Node> protect(this);
ojan 2014/06/04 00:38:46 Don't need this if script can't execute.
+
Node* prev = oldChild.previousSibling();
Node* next = oldChild.nextSibling();
@@ -513,9 +517,8 @@ void ContainerNode::parserRemoveChild(Node& oldChild)
oldChild.notifyMutationObserversNodeWillDetach();
removeBetween(prev, next, oldChild);
-
- childrenChanged(true, prev, next, -1);
notifyNodeRemoved(oldChild);
+ childrenChanged(true, prev, next, -1);
}
// this differs from other remove functions because it forcibly removes all the children,
@@ -550,23 +553,25 @@ void ContainerNode::removeChildren()
document().nodeChildrenWillBeRemoved(*this);
}
-
- NodeVector removedChildren;
{
HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
- {
+ ScriptForbiddenScope forbidScript;
+
+ // FIXME: We can't have a top level NoEventDispatchAssertion since
+ // SVGElement::invalidateInstances() is called inside ::childrenChanged
+ // and will stamp out new <use> shadow trees which mutates the DOM and
+ // hits the event dispatching assert in ::notifyNodeInserted. We should
+ // figure out how to make ths work async.
+
+ int childCount = 0;
+ while (RefPtr<Node> child = m_firstChild) {
NoEventDispatchAssertion assertNoEventDispatch;
- removedChildren.reserveInitialCapacity(countChildren());
- while (m_firstChild) {
- removedChildren.append(m_firstChild);
- removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
- }
+ ++childCount;
+ removeBetween(0, child->nextSibling(), *child);
+ notifyNodeRemoved(*child);
}
- childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
-
- for (size_t i = 0; i < removedChildren.size(); ++i)
- notifyNodeRemoved(*removedChildren[i]);
+ childrenChanged(false, 0, 0, -childCount);
}
dispatchSubtreeModifiedEvent();
@@ -637,11 +642,11 @@ void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
ASSERT(!newChild->isDocumentFragment());
ASSERT(!isHTMLTemplateElement(this));
+ RefPtr<Node> protect(this);
+
if (document() != newChild->document())
document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
- Node* last = m_lastChild;
-
{
NoEventDispatchAssertion assertNoEventDispatch;
ScriptForbiddenScope forbidScript;
@@ -653,22 +658,26 @@ void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
ChildListMutationScope(*this).childAdded(*newChild);
}
- childrenChanged(true, last, 0, 1);
- notifyNodeInserted(*newChild);
+ notifyNodeInserted(*newChild, true);
ojan 2014/06/04 00:38:46 Bool arguments!!
}
-void ContainerNode::notifyNodeInserted(Node& root)
+void ContainerNode::notifyNodeInserted(Node& root, bool createdByParser)
{
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
InspectorInstrumentation::didInsertDOMNode(&root);
RefPtr<Node> protect(this);
- RefPtr<Node> protectNode(root);
+ RefPtr<Node> protectRoot(root);
NodeVector postInsertionNotificationTargets;
notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
+ // ShadowRoots are not real children, we don't need to tell host that it's
+ // children changed when one is added.
+ if (!root.isShadowRoot())
ojan 2014/06/04 00:38:46 As per discussion in person, this is a little goof
+ childrenChanged(createdByParser, root.previousSibling(), root.nextSibling(), 1);
+
for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) {
Node* targetNode = postInsertionNotificationTargets[i].get();
if (targetNode->inDocument())
@@ -1079,8 +1088,6 @@ void ContainerNode::updateTreeAfterInsertion(Node& child)
ChildListMutationScope(*this).childAdded(child);
- childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
-
notifyNodeInserted(child);
dispatchChildInsertionEvents(child);
« no previous file with comments | « Source/core/dom/ContainerNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698