Bug 1363805 - Part 2: Add a flag to note that a child has LaterSiblings hint. r?heycam
This flag is only used by nsComputedDOMStyle.
MozReview-Commit-ID: 2EzIYXCt5Rj
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -134,33 +134,36 @@ enum {
// is, has an animation-only style change pending _and_ that style
// change will attempt to restyle descendants).
ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT = ELEMENT_SHARED_RESTYLE_BIT_4,
// Set if this element has a pending restyle with an eRestyle_SomeDescendants
// restyle hint.
ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR = ELEMENT_FLAG_BIT(4),
+ // Set if a child element has later-sibling restyle hint. This is needed for
+ // nsComputedDOMStyle to decide when should we need to flush style (only used
+ // in Gecko).
+ ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT = ELEMENT_FLAG_BIT(5),
+
// Just the HAS_PENDING bits, for convenience
ELEMENT_PENDING_RESTYLE_FLAGS =
ELEMENT_HAS_PENDING_RESTYLE |
ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE,
// Just the IS_POTENTIAL bits, for convenience
ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS =
ELEMENT_IS_POTENTIAL_RESTYLE_ROOT |
ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT,
// All of the restyle bits together, for convenience.
ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_PENDING_RESTYLE_FLAGS |
ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS |
ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR,
- // ELEMENT_FLAG_BIT(5) is currently unused
-
// Remaining bits are for subclasses
ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 6
};
#undef ELEMENT_FLAG_BIT
// Make sure we have space for our bits
ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
@@ -1810,17 +1813,18 @@ inline const mozilla::dom::Element* nsIN
{
MOZ_ASSERT(IsElement());
return static_cast<const mozilla::dom::Element*>(this);
}
inline void nsINode::UnsetRestyleFlagsIfGecko()
{
if (IsElement() && !AsElement()->IsStyledByServo()) {
- UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
+ UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS |
+ ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
}
}
/**
* Macros to implement Clone(). _elementName is the class for which to implement
* Clone.
*/
#define NS_IMPL_ELEMENT_CLONE(_elementName) \
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -202,16 +202,20 @@ RestyleTracker::DoProcessRestyles()
RestyleData* data;
#ifdef DEBUG
bool found =
#endif
mPendingRestyles.Get(element, &data);
NS_ASSERTION(found, "Where did our entry go?");
data->mRestyleHint =
nsRestyleHint(data->mRestyleHint & ~eRestyle_LaterSiblings);
+
+ if (Element* parent = element->GetFlattenedTreeParentElement()) {
+ parent->UnsetFlags(ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
+ }
}
LOG_RESTYLE("%d pending restyles after expanding out "
"eRestyle_LaterSiblings", mPendingRestyles.Count());
mHaveLaterSiblingRestyles = false;
}
--- a/layout/base/RestyleTracker.h
+++ b/layout/base/RestyleTracker.h
@@ -351,16 +351,25 @@ RestyleTracker::AddPendingRestyle(Elemen
// PostRecreateFramesFor, so we need to track it here.
MOZ_ASSERT(curData, "expected to find a RestyleData for cur");
if (curData) {
curData->mDescendants.AppendElement(aElement);
}
}
}
+ // If we need to restyle later siblings, we will need a flag on parent to note
+ // that some children need restyle for nsComputedDOMStyle.
+ if (aRestyleHint & eRestyle_LaterSiblings) {
+ nsIContent* parent = aElement->GetFlattenedTreeParent();
+ if (parent && parent->IsElement()) {
+ parent->SetFlags(ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
+ }
+ }
+
mHaveLaterSiblingRestyles =
mHaveLaterSiblingRestyles || (aRestyleHint & eRestyle_LaterSiblings) != 0;
return hadRestyleLaterSiblings;
}
} // namespace mozilla
#endif /* mozilla_RestyleTracker_h */