Index: third_party/WebKit/Source/core/dom/Element.cpp |
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp |
index 7a6688b1a524f0d35371390cd52e2ea488d15955..4ccf579e028cb164d8c6d02b63b7a1736dfc647d 100644 |
--- a/third_party/WebKit/Source/core/dom/Element.cpp |
+++ b/third_party/WebKit/Source/core/dom/Element.cpp |
@@ -1835,7 +1835,7 @@ PassRefPtr<ComputedStyle> Element::originalStyleForLayoutObject() { |
return document().ensureStyleResolver().styleForElement(this); |
} |
-void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling) { |
+void Element::recalcStyle(StyleRecalcChange change) { |
DCHECK(document().inStyleRecalc()); |
DCHECK(!document().lifecycle().inDetach()); |
DCHECK(!parentOrShadowHostNode()->needsStyleRecalc()); |
@@ -1858,6 +1858,7 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling) { |
if (parentComputedStyle()) |
change = recalcOwnStyle(change); |
clearNeedsStyleRecalc(); |
+ clearNeedsReattachLayoutTree(); |
} |
// If we reattached we don't need to recalc the style of our descendants |
@@ -1889,13 +1890,11 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling) { |
childNeedsStyleRecalc() ? Force : change); |
clearChildNeedsStyleRecalc(); |
+ clearChildNeedsReattachLayoutTree(); |
} |
if (hasCustomStyleCallbacks()) |
didRecalcStyle(change); |
- |
- if (change == Reattach) |
- reattachWhitespaceSiblingsIfNeeded(nextTextSibling); |
} |
PassRefPtr<ComputedStyle> Element::propagateInheritedProperties( |
@@ -1944,6 +1943,7 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change) { |
if (localChange == Reattach) { |
document().addNonAttachedStyle(*this, std::move(newStyle)); |
+ setNeedsReattachLayoutTree(); |
return rebuildLayoutTree(); |
} |
@@ -1987,12 +1987,31 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change) { |
} |
StyleRecalcChange Element::rebuildLayoutTree() { |
+ DCHECK(inActiveDocument()); |
AttachContext reattachContext; |
reattachContext.resolvedStyle = document().getNonAttachedStyle(*this); |
bool layoutObjectWillChange = needsAttach() || layoutObject(); |
+ |
+ // We are calling Element::rebuildLayoutTree() from inside |
+ // Element::recalcOwnStyle where we set the NeedsReattachLayoutTree |
+ // flag - so needsReattachLayoutTree() should always be true. |
+ DCHECK(parentNode()); |
+ DCHECK(parentNode()->childNeedsReattachLayoutTree()); |
+ DCHECK(needsReattachLayoutTree()); |
reattachLayoutTree(reattachContext); |
- if (layoutObjectWillChange || layoutObject()) |
+ // Since needsReattachLayoutTree() is always true we go into |
+ // reattachLayoutTree() which reattaches all the descendant |
+ // sub-trees. At this point no child should need reattaching. |
+ DCHECK(!childNeedsReattachLayoutTree()); |
+ |
+ if (layoutObjectWillChange || layoutObject()) { |
+ // nextTextSibling is passed on to recalcStyle from recalcDescendantStyles |
+ // we can either traverse the current subtree from this node onwards |
+ // or store it. |
+ // The choice is between increased time and increased memory complexity. |
+ reattachWhitespaceSiblingsIfNeeded(nextTextSibling()); |
return Reattach; |
+ } |
return ReattachNoLayoutObject; |
} |