Bug 1041512 - Mark intrinsic widths dirty on a style change even if the frame hasn't had its first reflow yet. r=dbaron
This commit is contained in:
@@ -501,11 +501,6 @@ RestyleManager::RecomputePosition(nsIFrame* aFrame)
|
|||||||
void
|
void
|
||||||
RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
|
RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
|
||||||
{
|
{
|
||||||
// If the frame hasn't even received an initial reflow, then don't
|
|
||||||
// send it a style-change reflow!
|
|
||||||
if (aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsIPresShell::IntrinsicDirty dirtyType;
|
nsIPresShell::IntrinsicDirty dirtyType;
|
||||||
if (aHint & nsChangeHint_ClearDescendantIntrinsics) {
|
if (aHint & nsChangeHint_ClearDescendantIntrinsics) {
|
||||||
NS_ASSERTION(aHint & nsChangeHint_ClearAncestorIntrinsics,
|
NS_ASSERTION(aHint & nsChangeHint_ClearAncestorIntrinsics,
|
||||||
@@ -518,18 +513,23 @@ RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsFrameState dirtyBits;
|
nsFrameState dirtyBits;
|
||||||
if (aHint & nsChangeHint_NeedDirtyReflow) {
|
if (aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||||
|
dirtyBits = nsFrameState(0);
|
||||||
|
} else if (aHint & nsChangeHint_NeedDirtyReflow) {
|
||||||
dirtyBits = NS_FRAME_IS_DIRTY;
|
dirtyBits = NS_FRAME_IS_DIRTY;
|
||||||
} else {
|
} else {
|
||||||
dirtyBits = NS_FRAME_HAS_DIRTY_CHILDREN;
|
dirtyBits = NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're not going to clear any intrinsic sizes on the frames, and
|
||||||
|
// there are no dirty bits to set, then there's nothing to do.
|
||||||
|
if (dirtyType == nsIPresShell::eResize && !dirtyBits)
|
||||||
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
mPresContext->PresShell()->FrameNeedsReflow(aFrame, dirtyType, dirtyBits);
|
mPresContext->PresShell()->FrameNeedsReflow(aFrame, dirtyType, dirtyBits);
|
||||||
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
|
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
|
||||||
} while (aFrame);
|
} while (aFrame);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -495,9 +495,13 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Tell the pres shell that a frame needs to be marked dirty and needs
|
* Tell the pres shell that a frame needs to be marked dirty and needs
|
||||||
* Reflow. It's OK if this is an ancestor of the frame needing reflow as
|
* Reflow. It's OK if this is an ancestor of the frame needing reflow as
|
||||||
* long as the ancestor chain between them doesn't cross a reflow root. The
|
* long as the ancestor chain between them doesn't cross a reflow root.
|
||||||
* bit to add should be either NS_FRAME_IS_DIRTY or
|
*
|
||||||
* NS_FRAME_HAS_DIRTY_CHILDREN (but not both!).
|
* The bit to add should be NS_FRAME_IS_DIRTY, NS_FRAME_HAS_DIRTY_CHILDREN
|
||||||
|
* or nsFrameState(0); passing 0 means that dirty bits won't be set on the
|
||||||
|
* frame or its ancestors/descendants, but that intrinsic widths will still
|
||||||
|
* be marked dirty. Passing aIntrinsicDirty = eResize and aBitToAdd = 0
|
||||||
|
* would result in no work being done, so don't do that.
|
||||||
*/
|
*/
|
||||||
enum IntrinsicDirty {
|
enum IntrinsicDirty {
|
||||||
// XXXldb eResize should be renamed
|
// XXXldb eResize should be renamed
|
||||||
@@ -506,8 +510,8 @@ public:
|
|||||||
eStyleChange // Do eTreeChange, plus all of aFrame's descendants
|
eStyleChange // Do eTreeChange, plus all of aFrame's descendants
|
||||||
};
|
};
|
||||||
virtual void FrameNeedsReflow(nsIFrame *aFrame,
|
virtual void FrameNeedsReflow(nsIFrame *aFrame,
|
||||||
IntrinsicDirty aIntrinsicDirty,
|
IntrinsicDirty aIntrinsicDirty,
|
||||||
nsFrameState aBitToAdd) = 0;
|
nsFrameState aBitToAdd) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls FrameNeedsReflow on all fixed position children of the root frame.
|
* Calls FrameNeedsReflow on all fixed position children of the root frame.
|
||||||
|
|||||||
@@ -2775,10 +2775,11 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
|
|||||||
nsFrameState aBitToAdd)
|
nsFrameState aBitToAdd)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aBitToAdd == NS_FRAME_IS_DIRTY ||
|
NS_PRECONDITION(aBitToAdd == NS_FRAME_IS_DIRTY ||
|
||||||
aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN,
|
aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN ||
|
||||||
|
!aBitToAdd,
|
||||||
"Unexpected bits being added");
|
"Unexpected bits being added");
|
||||||
NS_PRECONDITION(aIntrinsicDirty != eStyleChange ||
|
NS_PRECONDITION(!(aIntrinsicDirty == eStyleChange &&
|
||||||
aBitToAdd == NS_FRAME_IS_DIRTY,
|
aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN),
|
||||||
"bits don't correspond to style change reason");
|
"bits don't correspond to style change reason");
|
||||||
|
|
||||||
NS_ASSERTION(!mIsReflowing, "can't mark frame dirty during reflow");
|
NS_ASSERTION(!mIsReflowing, "can't mark frame dirty during reflow");
|
||||||
@@ -2876,6 +2877,11 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
|
|||||||
} while (stack.Length() != 0);
|
} while (stack.Length() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip setting dirty bits up the tree if we weren't given a bit to add.
|
||||||
|
if (!aBitToAdd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Set NS_FRAME_HAS_DIRTY_CHILDREN bits (via nsIFrame::ChildIsDirty)
|
// Set NS_FRAME_HAS_DIRTY_CHILDREN bits (via nsIFrame::ChildIsDirty)
|
||||||
// up the tree until we reach either a frame that's already dirty or
|
// up the tree until we reach either a frame that's already dirty or
|
||||||
// a reflow root.
|
// a reflow root.
|
||||||
|
|||||||
Reference in New Issue
Block a user