Index: third_party/WebKit/Source/core/dom/ContainerNode.cpp |
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
index 207659d70f65cfdf3da66036ac30f8ba15cce0d2..a0e874a314b9761c50faf43deb44540d829dc37a 100644 |
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
@@ -266,8 +266,6 @@ class ContainerNode::AdoptAndAppendChild { |
Node* ContainerNode::insertBefore(Node* newChild, |
Node* refChild, |
ExceptionState& exceptionState) { |
- // https://dom.spec.whatwg.org/#concept-node-pre-insert |
- |
// insertBefore(node, 0) is equivalent to appendChild(node) |
if (!refChild) |
return appendChild(newChild, exceptionState); |
@@ -286,12 +284,9 @@ Node* ContainerNode::insertBefore(Node* newChild, |
return nullptr; |
} |
- // 3. If reference child is node, set it to node’s next sibling. |
- if (refChild == newChild) { |
- refChild = newChild->nextSibling(); |
- if (!refChild) |
- return appendChild(newChild, exceptionState); |
- } |
+ // Nothing to do. |
+ if (refChild->previousSibling() == newChild || refChild == newChild) |
+ return newChild; |
NodeVector targets; |
if (!collectChildrenAndRemoveFromOldParentWithCheck( |
@@ -396,7 +391,8 @@ void ContainerNode::parserInsertBefore(Node* newChild, Node& nextChild) { |
Node* ContainerNode::replaceChild(Node* newChild, |
Node* oldChild, |
ExceptionState& exceptionState) { |
- // https://dom.spec.whatwg.org/#concept-node-replace |
+ if (oldChild == newChild) // Nothing to do. |
+ return oldChild; |
if (!oldChild) { |
exceptionState.throwDOMException(NotFoundError, |
@@ -416,23 +412,17 @@ Node* ContainerNode::replaceChild(Node* newChild, |
} |
ChildListMutationScope mutation(*this); |
- // 7. Let reference child be child’s next sibling. |
Node* next = oldChild->nextSibling(); |
- // 8. If reference child is node, set it to node’s next sibling. |
- if (next == newChild) |
- next = newChild->nextSibling(); |
- |
- // TODO(tkent): According to the specification, we should remove |newChild| |
- // from its parent here, and create a separated mutation record for it. |
- // Refer to imported/wpt/dom/nodes/MutationObserver-childList.html. |
- // 12. If child’s parent is not null, run these substeps: |
- // 1. Set removedNodes to a list solely containing child. |
- // 2. Remove child from its parent with the suppress observers flag set. |
+ // Remove the node we're replacing. |
removeChild(oldChild, exceptionState); |
if (exceptionState.hadException()) |
return nullptr; |
+ if (next && (next->previousSibling() == newChild || |
+ next == newChild)) // nothing to do |
+ return oldChild; |
+ |
// Does this one more time because removeChild() fires a MutationEvent. |
if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
return oldChild; |
@@ -659,6 +649,9 @@ Node* ContainerNode::appendChild(Node* newChild, |
return newChild; |
DCHECK(newChild); |
+ if (newChild == m_lastChild) // nothing to do |
+ return newChild; |
+ |
NodeVector targets; |
if (!collectChildrenAndRemoveFromOldParentWithCheck( |
nullptr, nullptr, *newChild, targets, exceptionState)) |
@@ -766,10 +759,6 @@ void ContainerNode::attachLayoutTree(const AttachContext& context) { |
childrenContext.resolvedStyle = nullptr; |
for (Node* child = firstChild(); child; child = child->nextSibling()) { |
-#if DCHECK_IS_ON() |
- DCHECK(child->needsAttach() || |
- childAttachedAllowedWhenAttachingChildren(this)); |
esprehn
2017/02/13 22:19:41
Lets add this back?
nainar
2017/02/14 03:42:08
Done.
|
-#endif |
if (child->needsAttach()) |
child->attachLayoutTree(childrenContext); |
} |
@@ -1280,7 +1269,6 @@ void ContainerNode::setRestyleFlag(DynamicRestyleFlags mask) { |
void ContainerNode::recalcDescendantStyles(StyleRecalcChange change) { |
DCHECK(document().inStyleRecalc()); |
DCHECK(change >= UpdatePseudoElements || childNeedsStyleRecalc()); |
- DCHECK(!needsStyleRecalc()); |
esprehn
2017/02/13 22:19:41
ditto
nainar
2017/02/14 03:42:08
This information isn't true anymore. We are retain
|
// This loop is deliberately backwards because we use insertBefore in the |
// layout tree, and want to avoid a potentially n^2 loop to find the insertion |
@@ -1305,6 +1293,25 @@ void ContainerNode::recalcDescendantStyles(StyleRecalcChange change) { |
} |
} |
+void ContainerNode::rebuildChildrenLayoutTrees() { |
+ DCHECK(!needsReattachLayoutTree()); |
+ |
+ for (Node* child = lastChild(); child; child = child->previousSibling()) { |
+ if (child->needsReattachLayoutTree() || |
+ child->childNeedsReattachLayoutTree()) { |
+ if (child->isTextNode()) |
+ toText(child)->rebuildTextLayoutTree(); |
+ else if (child->isElementNode()) |
+ toElement(child)->rebuildLayoutTree(); |
+ } |
+ } |
+ clearNeedsStyleRecalc(); |
+ // This is done in ContainerNode::attachLayoutTree but will never be cleared |
+ // if we don't enter ContainerNode::attachLayoutTree so we do it here. |
+ clearChildNeedsStyleRecalc(); |
+ clearChildNeedsReattachLayoutTree(); |
+} |
+ |
void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, |
Element* changedElement, |
Node* nodeBeforeChange, |