Abstract nsChangeHint_NonInherited_Hints into a function so that it accurately reports the reflow cases to all callers. (Bug 779968, patch 4) r=bzbarsky

This is in preparation for adding an additional caller.

nsChangeHint_NonInherited_Hints will be reintroduced in patch 6, but as
the maximum set of such hints rather than the minimal set, and with the
less confusing name nsChangeHint_Hints_NotHandledForDescendants.
This commit is contained in:
L. David Baron 2012-09-07 10:13:36 -07:00
parent c596be2ae1
commit 5b62990545
3 changed files with 39 additions and 39 deletions

View File

@ -107,25 +107,10 @@ enum nsChangeHint {
* has changed whether the frame is a container for fixed-pos or abs-pos
* elements, but reframing is otherwise not needed.
*/
nsChangeHint_AddOrRemoveTransform = 0x4000,
nsChangeHint_AddOrRemoveTransform = 0x4000
/**
* We have an optimization when processing change hints which prevents
* us from visiting the descendants of a node when a hint on that node
* is being processed. This optimization does not apply in some of the
* cases where applying a hint to an element does not necessarily result
* in the same hint being handled on the descendants.
*
* If you're adding such a hint, you should add your hint to this list.
*/
nsChangeHint_NonInherited_Hints =
nsChangeHint_UpdateTransformLayer |
nsChangeHint_UpdateEffects |
nsChangeHint_UpdateOpacityLayer |
nsChangeHint_UpdateOverflow |
nsChangeHint_ChildrenOnlyTransform |
nsChangeHint_RecomputePosition |
nsChangeHint_AddOrRemoveTransform
// IMPORTANT NOTE: When adding new hints, consider whether you need to
// add them to NS_HintsNotHandledForDescendantsIn() below.
};
// Redefine these operators to return nothing. This will catch any use
@ -164,6 +149,40 @@ inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) {
return (aSubset & aSuperSet) == aSubset;
}
/**
* We have an optimization when processing change hints which prevents
* us from visiting the descendants of a node when a hint on that node
* is being processed. This optimization does not apply in some of the
* cases where applying a hint to an element does not necessarily result
* in the same hint being handled on the descendants.
*/
inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
nsChangeHint result = nsChangeHint(aChangeHint & (
nsChangeHint_UpdateTransformLayer |
nsChangeHint_UpdateEffects |
nsChangeHint_UpdateOpacityLayer |
nsChangeHint_UpdateOverflow |
nsChangeHint_ChildrenOnlyTransform |
nsChangeHint_RecomputePosition |
nsChangeHint_AddOrRemoveTransform));
if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint) &&
NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) {
// If NeedDirtyReflow is *not* set, then NeedReflow is a
// non-inherited hint.
NS_UpdateHint(result, nsChangeHint_NeedReflow);
}
if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics, aChangeHint) &&
NS_IsHintSubset(nsChangeHint_ClearAncestorIntrinsics, aChangeHint)) {
// If ClearDescendantIntrinsics is *not* set, then
// ClearAncestorIntrinsics is a non-inherited hint.
NS_UpdateHint(result, nsChangeHint_ClearAncestorIntrinsics);
}
return result;
}
// Redefine the old NS_STYLE_HINT constants in terms of the new hint structure
#define NS_STYLE_HINT_NONE \
nsChangeHint(0)

View File

@ -1011,28 +1011,10 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
nsTArray<nsIContent*>& aVisibleKidsOfHiddenElement,
TreeMatchContext &aTreeMatchContext)
{
if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aMinChange)) {
// If aMinChange doesn't include nsChangeHint_NeedDirtyReflow, clear out
// all the reflow change bits from it, so that we'll make sure to append a
// change to the list for ourselves if we need a reflow. We need this
// because the parent may or may not actually end up reflowing us
// otherwise.
aMinChange = NS_SubtractHint(aMinChange, nsChangeHint_ReflowFrame);
} else if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics,
aMinChange)) {
// If aMinChange doesn't include nsChangeHint_ClearDescendantIntrinsics,
// clear out the nsChangeHint_ClearAncestorIntrinsics flag, since it's
// possible that we had some random ancestor that cleared ancestor
// intrinsic widths, but we still need to clear intrinsic widths on frames
// that are our ancestors but its descendants.
aMinChange =
NS_SubtractHint(aMinChange, nsChangeHint_ClearAncestorIntrinsics);
}
// We need to generate a new change list entry for every frame whose style
// comparision returns one of these hints. These hints don't automatically
// update all their descendant frames.
aMinChange = NS_SubtractHint(aMinChange, nsChangeHint_NonInherited_Hints);
aMinChange = NS_SubtractHint(aMinChange, NS_HintsNotHandledForDescendantsIn(aMinChange));
// It would be nice if we could make stronger assertions here; they
// would let us simplify the ?: expressions below setting |content|

View File

@ -399,8 +399,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
nsStyle##struct_::MaxDifference()), \
"CalcDifference() returned bigger hint than MaxDifference()"); \
NS_ASSERTION(nsStyle##struct_::ForceCompare() || \
NS_IsHintSubset(nsStyle##struct_::MaxDifference(), \
nsChangeHint(~nsChangeHint_NonInherited_Hints)), \
NS_HintsNotHandledForDescendantsIn(nsStyle##struct_::MaxDifference()) == 0, \
"Structs that can return non-inherited hints must return true " \
"from ForceCompare"); \
NS_UpdateHint(hint, this##struct_->CalcDifference(*other##struct_)); \