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

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

Issue 2473743003: Call Element::rebuildLayoutTree from Document::updateStyle directly (Closed)
Patch Set: Fix failures due to information not being retained correctly for detachLayoutTree() in Text::reatta… Created 3 years, 10 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
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,

Powered by Google App Engine
This is Rietveld 408576698