Handle the vertical resizing in the first pass reflow correctly when we've previously done a special height reflow. b=381507 r=dholbert sr=roc

This commit is contained in:
dbaron%dbaron.org 2007-06-18 23:19:39 +00:00
Родитель 4f77038521
Коммит 2bb707fe73
4 изменённых файлов: 44 добавлений и 11 удалений

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsLineBox.h"
#include "nsImageFrame.h"
#include "nsTableFrame.h"
#include "nsTableCellFrame.h"
#include "nsIServiceManager.h"
#include "nsIPercentHeightObserver.h"
#include "nsContentUtils.h"
@ -364,8 +365,14 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
// XXX Should we really need to null check mCBReflowState? (We do for
// at least nsBoxFrame).
if (mFlags.mSpecialHeightReflow && IS_TABLE_CELL(frame->GetType()) &&
if (IS_TABLE_CELL(frame->GetType()) &&
(mFlags.mSpecialHeightReflow ||
(frame->GetFirstInFlow()->GetStateBits() &
NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) &&
(frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
// Need to set the bit on the cell so that
// mCBReflowState->mFlags.mVResize is set correctly below when
// reflowing descendant.
mFlags.mVResize = PR_TRUE;
} else if (mCBReflowState && !frame->IsContainingBlock()) {
// XXX Is this problematic for relatively positioned inlines acting
@ -374,7 +381,6 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
} else if (mComputedHeight == NS_AUTOHEIGHT) {
if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
mCBReflowState) {
// XXX This condition doesn't quite match CalcQuirkContainingBlockHeight.
mFlags.mVResize = mCBReflowState->mFlags.mVResize;
} else {
mFlags.mVResize = mFlags.mHResize || NS_SUBTREE_DIRTY(frame);
@ -385,6 +391,25 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
mComputedHeight + mComputedBorderPadding.TopBottom();
}
const PRBool dependsOnCBHeight =
mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mMaxHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetBottomUnit() == eStyleUnit_Percent ||
frame->IsBoxFrame();
// If we're the child of a table cell that performs special height
// reflows and we could be the child that requires them, always set
// the vertical resize in case this is the first pass before the
// special height reflow.
if (!mFlags.mVResize && mCBReflowState &&
IS_TABLE_CELL(mCBReflowState->frame->GetType()) &&
dependsOnCBHeight)
mFlags.mVResize = PR_TRUE;
// Set NS_FRAME_CONTAINS_RELATIVE_HEIGHT if it's needed.
// It would be nice to check that |mComputedHeight != NS_AUTOHEIGHT|
// &&ed with the percentage height check. However, this doesn't get
// along with table special height reflows, since a special height
@ -392,13 +417,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
// of table cells) can cause not just a single percentage height to
// become fixed, but an entire descendant chain of percentage heights
// to become fixed.
if ((mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mMaxHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetBottomUnit() == eStyleUnit_Percent ||
frame->IsBoxFrame()) &&
mCBReflowState) {
if (dependsOnCBHeight && mCBReflowState) {
const nsHTMLReflowState *rs = this;
PRBool hitCBReflowState = PR_FALSE;
do {

Просмотреть файл

@ -755,6 +755,10 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
if (aReflowState.mFlags.mSpecialHeightReflow) {
GetFirstInFlow()->AddStateBits(NS_TABLE_CELL_HAD_SPECIAL_REFLOW);
}
// work around pixel rounding errors, round down to ensure we don't exceed the avail height in
nscoord availHeight = aReflowState.availableHeight;
@ -818,7 +822,11 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
// but only those than are tables in standards mode. NeedsToObserve
// will determine how far this is propagated to descendants.
kidReflowState.mPercentHeightObserver = this;
if (aReflowState.mFlags.mSpecialHeightReflow) {
if (aReflowState.mFlags.mSpecialHeightReflow ||
(GetFirstInFlow()->GetStateBits() & NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) {
// We need to force the kid to have mVResize set if we've had a
// special reflow in the past, since the non-special reflow needs to
// resize back to what it was without the special height reflow.
kidReflowState.mFlags.mVResize = PR_TRUE;
}

Просмотреть файл

@ -52,6 +52,7 @@ class nsTableFrame;
* Additional frame-state bits
*/
#define NS_TABLE_CELL_CONTENT_EMPTY 0x80000000
#define NS_TABLE_CELL_HAD_SPECIAL_REFLOW 0x20000000
#define NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT 0x10000000
/**

Просмотреть файл

@ -1864,7 +1864,12 @@ NS_METHOD nsTableFrame::Reflow(nsPresContext* aPresContext,
PRBool haveDesiredHeight = PR_FALSE;
PRBool reflowedChildren = PR_FALSE;
if (aReflowState.mComputedHeight != NS_UNCONSTRAINEDSIZE) {
if (aReflowState.mComputedHeight != NS_UNCONSTRAINEDSIZE ||
// Also check mVResize, to handle the first Reflow preceding a
// special height Reflow, when we've already had a special height
// Reflow (where mComputedHeight would not be
// NS_UNCONSTRAINEDSIZE, but without a style change in between).
aReflowState.mFlags.mVResize) {
// XXX Eventually, we should modify DistributeHeightToRows to use
// nsTableRowFrame::GetHeight instead of nsIFrame::GetSize().height.
// That way, it will make its calculations based on internal table