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 fd79b779eabf4799b7ba977e3148225b61db4544..5d45afb6bb9798e2f65262e2827a7b477448bb8f 100644 |
--- a/third_party/WebKit/Source/core/dom/Element.cpp |
+++ b/third_party/WebKit/Source/core/dom/Element.cpp |
@@ -183,7 +183,6 @@ Element::Element(const QualifiedName& tagName, |
: ContainerNode(document, type), m_tagName(tagName) {} |
Element::~Element() { |
- DCHECK(needsAttach()); |
nainar
2016/11/29 06:13:39
See comment in ContainerNode destructor.
|
} |
inline ElementRareData* Element::elementRareData() const { |
@@ -1662,7 +1661,7 @@ void Element::attachLayoutTree(const AttachContext& context) { |
// We've already been through detach when doing an attach, but we might |
// need to clear any state that's been added since then. |
- if (hasRareData() && getStyleChangeType() == NeedsReattachStyleChange) { |
nainar
2016/11/29 06:13:39
We are setting the corresponging NeedsReattachLayo
|
+ if (hasRareData() && needsReattachLayoutTree()) { |
ElementRareData* data = elementRareData(); |
data->clearComputedStyle(); |
} |
@@ -1750,7 +1749,7 @@ void Element::detachLayoutTree(const AttachContext& context) { |
setNeedsResizeObserverUpdate(); |
- DCHECK(needsAttach()); |
+ DCHECK(needsReattachLayoutTree()); |
} |
bool Element::pseudoStyleCacheIsInvalid(const ComputedStyle* currentStyle, |
@@ -1856,7 +1855,6 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling) { |
if (parentComputedStyle()) |
change = recalcOwnStyle(change, nextTextSibling); |
clearNeedsStyleRecalc(); |
- clearNeedsReattachLayoutTree(); |
} |
// If we reattached we don't need to recalc the style of our descendants |
@@ -1886,9 +1884,6 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling) { |
// non-floating we have to take it into account for the first letter. |
updatePseudoElement(PseudoIdFirstLetter, |
childNeedsStyleRecalc() ? Force : change); |
- |
- clearChildNeedsStyleRecalc(); |
- clearChildNeedsReattachLayoutTree(); |
} |
if (hasCustomStyleCallbacks()) |
@@ -1948,7 +1943,7 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change, |
styleReattachData.nextTextSibling = nextTextSibling; |
document().addStyleReattachData(*this, styleReattachData); |
setNeedsReattachLayoutTree(); |
- return rebuildLayoutTree(); |
+ return Reattach; |
} |
DCHECK(oldStyle); |
@@ -1989,23 +1984,31 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change, |
return localChange; |
} |
-StyleRecalcChange Element::rebuildLayoutTree() { |
+void Element::rebuildLayoutTree() { |
DCHECK(inActiveDocument()); |
+ DCHECK(!needsStyleRecalc()); |
+ DCHECK(!childNeedsStyleRecalc()); |
+ DCHECK(parentNode()); |
+ DCHECK(parentNode()->childNeedsReattachLayoutTree()); |
+ |
StyleReattachData styleReattachData = document().getStyleReattachData(*this); |
AttachContext reattachContext; |
reattachContext.resolvedStyle = styleReattachData.computedStyle.get(); |
- bool layoutObjectWillChange = needsAttach() || layoutObject(); |
+ bool layoutObjectWillChange = needsReattachLayoutTree() || 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); |
- // Since needsReattachLayoutTree() is always true we go into |
- // reattachLayoutTree() which reattaches all the descendant |
- // sub-trees. At this point no child should need reattaching. |
+ if (needsReattachLayoutTree()) { |
+ reattachLayoutTree(reattachContext); |
+ } else if (childNeedsReattachLayoutTree()) { |
+ SelectorFilterParentScope filterScope(*this); |
+ StyleSharingDepthScope sharingScope(*this); |
+ reattachPseudoElementLayoutTree(PseudoIdBefore); |
+ rebuildShadowRootLayoutTree(); |
+ rebuildDescendantLayoutTree(); |
+ reattachPseudoElementLayoutTree(PseudoIdAfter); |
+ reattachPseudoElementLayoutTree(PseudoIdBackdrop); |
+ reattachPseudoElementLayoutTree(PseudoIdFirstLetter); |
+ } |
+ DCHECK(!needsReattachLayoutTree()); |
DCHECK(!childNeedsReattachLayoutTree()); |
if (layoutObjectWillChange || layoutObject()) { |
@@ -2014,9 +2017,29 @@ StyleRecalcChange Element::rebuildLayoutTree() { |
// or store it. |
// The choice is between increased time and increased memory complexity. |
reattachWhitespaceSiblingsIfNeeded(styleReattachData.nextTextSibling); |
- return Reattach; |
} |
- return ReattachNoLayoutObject; |
+} |
+ |
+void Element::rebuildShadowRootLayoutTree() { |
+ DCHECK(!needsStyleRecalc()); |
+ DCHECK(!childNeedsStyleRecalc()); |
+ DCHECK(!needsReattachLayoutTree()); |
+ for (ShadowRoot* root = youngestShadowRoot(); root; |
+ root = root->olderShadowRoot()) { |
+ if (root->needsReattachLayoutTree() || root->childNeedsReattachLayoutTree()) |
+ root->rebuildLayoutTree(); |
+ } |
+} |
+ |
+void Element::reattachPseudoElementLayoutTree(PseudoId pseudoId) { |
+ DCHECK(!needsStyleRecalc()); |
+ DCHECK(!childNeedsStyleRecalc()); |
+ DCHECK(!needsReattachLayoutTree()); |
+ if (PseudoElement* element = pseudoElement(pseudoId)) { |
+ if (element->needsReattachLayoutTree() || |
+ element->childNeedsReattachLayoutTree()) |
+ element->rebuildLayoutTree(); |
+ } |
} |
void Element::updateCallbackSelectors(const ComputedStyle* oldStyle, |
@@ -3243,8 +3266,9 @@ void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { |
if (pseudoId == PseudoIdBackdrop) |
document().addToTopLayer(element, this); |
element->insertedInto(this); |
+ element->setLocalNeedsReattachLayoutTree(); |
nainar
2016/11/29 06:13:39
Only the Pseudo Element needs to be reattached.
|
element->attachLayoutTree(); |
- |
+ DCHECK(!element->needsReattachLayoutTree()); |
InspectorInstrumentation::pseudoElementCreated(element); |
ensureElementRareData().setPseudoElement(pseudoId, element); |