bug 125543 - Prevent row groups from splitting in the reflow preceeding a special height reflow. Cells are only notified that they should observe a percent height element if the element is inside the table's cell. Percent height elements inside the body will have a height based on the page height when printing. sr=kin, r=alexsavulov.

This commit is contained in:
karnaze@netscape.com
2002-04-10 21:32:41 +00:00
parent 6b41e30fe0
commit 335ac62023
18 changed files with 250 additions and 120 deletions

View File

@@ -48,14 +48,18 @@ class nsIPresContext;
/** /**
* This interface is supported by frames that need to provide computed height * This interface is supported by frames that need to provide computed height
* values to children during reflow which would otherwise not happen. Currently only * values to children during reflow which would otherwise not happen. Currently only
* tables support this. * table cells support this.
*/ */
class nsIPercentHeightObserver : public nsISupports class nsIPercentHeightObserver : public nsISupports
{ {
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPERCENTHEIGHTOBSERVER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPERCENTHEIGHTOBSERVER_IID)
NS_IMETHOD NotifyPercentHeight(const nsHTMLReflowState& aReflowState) = 0; // Notify the observer that aReflowState has no computed height, but it has a percent height
virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) = 0;
// Ask the observer if it should observe aReflowState.frame
virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState) = 0;
}; };
#endif // nsIPercentHeightObserver_h___ #endif // nsIPercentHeightObserver_h___

View File

@@ -48,14 +48,18 @@ class nsIPresContext;
/** /**
* This interface is supported by frames that need to provide computed height * This interface is supported by frames that need to provide computed height
* values to children during reflow which would otherwise not happen. Currently only * values to children during reflow which would otherwise not happen. Currently only
* tables support this. * table cells support this.
*/ */
class nsIPercentHeightObserver : public nsISupports class nsIPercentHeightObserver : public nsISupports
{ {
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPERCENTHEIGHTOBSERVER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPERCENTHEIGHTOBSERVER_IID)
NS_IMETHOD NotifyPercentHeight(const nsHTMLReflowState& aReflowState) = 0; // Notify the observer that aReflowState has no computed height, but it has a percent height
virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) = 0;
// Ask the observer if it should observe aReflowState.frame
virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState) = 0;
}; };
#endif // nsIPercentHeightObserver_h___ #endif // nsIPercentHeightObserver_h___

View File

@@ -1828,21 +1828,25 @@ nsFrame::DidReflow(nsIPresContext* aPresContext,
NS_FRAME_HAS_DIRTY_CHILDREN); NS_FRAME_HAS_DIRTY_CHILDREN);
} }
// Notify the percent height observer if this is an initial or resize constrained reflow // Notify the percent height observer if this is an initial or resize reflow (XXX
// it should probably be any type of reflow, but this would need further testing)
// and there is a percent height but no computed height. The observer may be able to // and there is a percent height but no computed height. The observer may be able to
// initiate another reflow with a computed height. This happens in the case where a table // initiate another reflow with a computed height. This happens in the case where a table
// cell has no computed height but can fabricate one when the cell height is known. // cell has no computed height but can fabricate one when the cell height is known.
if (aReflowState && (aReflowState->mPercentHeightObserver) && // an observer if (aReflowState && (aReflowState->mPercentHeightObserver) && // an observer
((eReflowReason_Initial == aReflowState->reason) || // initial or resize reflow ((eReflowReason_Initial == aReflowState->reason) || // initial or resize reflow
(eReflowReason_Resize == aReflowState->reason)) && (eReflowReason_Resize == aReflowState->reason)) &&
(NS_UNCONSTRAINEDSIZE != aReflowState->availableWidth) && // constrained width reflow
((NS_UNCONSTRAINEDSIZE == aReflowState->mComputedHeight) || // no computed height ((NS_UNCONSTRAINEDSIZE == aReflowState->mComputedHeight) || // no computed height
(0 == aReflowState->mComputedHeight)) && (0 == aReflowState->mComputedHeight)) &&
aReflowState->mStylePosition && // percent height aReflowState->mStylePosition && // percent height
(eStyleUnit_Percent == aReflowState->mStylePosition->mHeight.GetUnit())) { (eStyleUnit_Percent == aReflowState->mStylePosition->mHeight.GetUnit())) {
nsIFrame* prevInFlow;
GetPrevInFlow(&prevInFlow);
if (!prevInFlow) { // 1st in flow
aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState); aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState);
} }
}
return NS_OK; return NS_OK;
} }

View File

@@ -50,6 +50,7 @@
#include "nsImageFrame.h" #include "nsImageFrame.h"
#include "nsIPref.h" #include "nsIPref.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIPercentHeightObserver.h"
#define IS_TABLE_CELL(frameType)\ #define IS_TABLE_CELL(frameType)\
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType)) ((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
@@ -163,7 +164,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
if (aInit) { if (aInit) {
@@ -195,7 +198,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
Init(aPresContext); Init(aPresContext);
@@ -226,7 +231,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight); Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
@@ -1367,7 +1374,7 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState,
nscoord result = 0; nscoord result = 0;
const nsHTMLReflowState* rs = &aReflowState; const nsHTMLReflowState* rs = &aReflowState;
for (; rs; rs = (nsHTMLReflowState *)(rs->parentReflowState)) { for (; rs && rs->frame; rs = (nsHTMLReflowState *)(rs->parentReflowState)) {
nsCOMPtr<nsIAtom> frameType; nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType)); rs->frame->GetFrameType(getter_AddRefs(frameType));
// if the ancestor is auto height then skip it and continue up if it // if the ancestor is auto height then skip it and continue up if it
@@ -1405,18 +1412,28 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState,
rs = scrollState; rs = scrollState;
} }
} }
else if (nsLayoutAtoms::pageContentFrame == frameType.get()) {
nsIFrame* prevInFlow;
rs->frame->GetPrevInFlow(&prevInFlow);
// only use the page content frame for a height basis if it is the first in flow
if (prevInFlow)
break;
}
else { else {
break; break;
} }
// if the ancestor has a computed height, it is the percent base // if the ancestor is the page content frame then the percent base is
result = rs->mComputedHeight; // the avail height, otherwise it is the computed height
result = (nsLayoutAtoms::pageContentFrame == frameType.get())
? rs->availableHeight : rs->mComputedHeight;
// if unconstrained - don't sutract borders - would result in huge height // if unconstrained - don't sutract borders - would result in huge height
if (NS_AUTOHEIGHT == result) return result; if (NS_AUTOHEIGHT == result) return result;
// if we got to the canvas frame, then subtract out // if we got to the canvas or page content frame, then subtract out
// margin/border/padding for the BODY and HTML elements // margin/border/padding for the BODY and HTML elements
if (nsLayoutAtoms::canvasFrame == frameType.get()) { if ((nsLayoutAtoms::canvasFrame == frameType.get()) ||
(nsLayoutAtoms::pageContentFrame == frameType.get())) {
result -= GetVerticalMarginBorderPadding(firstBlockRS); result -= GetVerticalMarginBorderPadding(firstBlockRS);
result -= GetVerticalMarginBorderPadding(firstAreaRS); result -= GetVerticalMarginBorderPadding(firstAreaRS);

View File

@@ -1828,21 +1828,25 @@ nsFrame::DidReflow(nsIPresContext* aPresContext,
NS_FRAME_HAS_DIRTY_CHILDREN); NS_FRAME_HAS_DIRTY_CHILDREN);
} }
// Notify the percent height observer if this is an initial or resize constrained reflow // Notify the percent height observer if this is an initial or resize reflow (XXX
// it should probably be any type of reflow, but this would need further testing)
// and there is a percent height but no computed height. The observer may be able to // and there is a percent height but no computed height. The observer may be able to
// initiate another reflow with a computed height. This happens in the case where a table // initiate another reflow with a computed height. This happens in the case where a table
// cell has no computed height but can fabricate one when the cell height is known. // cell has no computed height but can fabricate one when the cell height is known.
if (aReflowState && (aReflowState->mPercentHeightObserver) && // an observer if (aReflowState && (aReflowState->mPercentHeightObserver) && // an observer
((eReflowReason_Initial == aReflowState->reason) || // initial or resize reflow ((eReflowReason_Initial == aReflowState->reason) || // initial or resize reflow
(eReflowReason_Resize == aReflowState->reason)) && (eReflowReason_Resize == aReflowState->reason)) &&
(NS_UNCONSTRAINEDSIZE != aReflowState->availableWidth) && // constrained width reflow
((NS_UNCONSTRAINEDSIZE == aReflowState->mComputedHeight) || // no computed height ((NS_UNCONSTRAINEDSIZE == aReflowState->mComputedHeight) || // no computed height
(0 == aReflowState->mComputedHeight)) && (0 == aReflowState->mComputedHeight)) &&
aReflowState->mStylePosition && // percent height aReflowState->mStylePosition && // percent height
(eStyleUnit_Percent == aReflowState->mStylePosition->mHeight.GetUnit())) { (eStyleUnit_Percent == aReflowState->mStylePosition->mHeight.GetUnit())) {
nsIFrame* prevInFlow;
GetPrevInFlow(&prevInFlow);
if (!prevInFlow) { // 1st in flow
aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState); aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState);
} }
}
return NS_OK; return NS_OK;
} }

View File

@@ -50,6 +50,7 @@
#include "nsImageFrame.h" #include "nsImageFrame.h"
#include "nsIPref.h" #include "nsIPref.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIPercentHeightObserver.h"
#define IS_TABLE_CELL(frameType)\ #define IS_TABLE_CELL(frameType)\
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType)) ((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
@@ -163,7 +164,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
if (aInit) { if (aInit) {
@@ -195,7 +198,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
Init(aPresContext); Init(aPresContext);
@@ -226,7 +231,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
mSpaceManager = aParentReflowState.mSpaceManager; mSpaceManager = aParentReflowState.mSpaceManager;
mLineLayout = aParentReflowState.mLineLayout; mLineLayout = aParentReflowState.mLineLayout;
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage; mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver; mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nsnull;
mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator; mPercentHeightReflowInitiator = aParentReflowState.mPercentHeightReflowInitiator;
Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight); Init(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
@@ -1367,7 +1374,7 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState,
nscoord result = 0; nscoord result = 0;
const nsHTMLReflowState* rs = &aReflowState; const nsHTMLReflowState* rs = &aReflowState;
for (; rs; rs = (nsHTMLReflowState *)(rs->parentReflowState)) { for (; rs && rs->frame; rs = (nsHTMLReflowState *)(rs->parentReflowState)) {
nsCOMPtr<nsIAtom> frameType; nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType)); rs->frame->GetFrameType(getter_AddRefs(frameType));
// if the ancestor is auto height then skip it and continue up if it // if the ancestor is auto height then skip it and continue up if it
@@ -1405,18 +1412,28 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState,
rs = scrollState; rs = scrollState;
} }
} }
else if (nsLayoutAtoms::pageContentFrame == frameType.get()) {
nsIFrame* prevInFlow;
rs->frame->GetPrevInFlow(&prevInFlow);
// only use the page content frame for a height basis if it is the first in flow
if (prevInFlow)
break;
}
else { else {
break; break;
} }
// if the ancestor has a computed height, it is the percent base // if the ancestor is the page content frame then the percent base is
result = rs->mComputedHeight; // the avail height, otherwise it is the computed height
result = (nsLayoutAtoms::pageContentFrame == frameType.get())
? rs->availableHeight : rs->mComputedHeight;
// if unconstrained - don't sutract borders - would result in huge height // if unconstrained - don't sutract borders - would result in huge height
if (NS_AUTOHEIGHT == result) return result; if (NS_AUTOHEIGHT == result) return result;
// if we got to the canvas frame, then subtract out // if we got to the canvas or page content frame, then subtract out
// margin/border/padding for the BODY and HTML elements // margin/border/padding for the BODY and HTML elements
if (nsLayoutAtoms::canvasFrame == frameType.get()) { if ((nsLayoutAtoms::canvasFrame == frameType.get()) ||
(nsLayoutAtoms::pageContentFrame == frameType.get())) {
result -= GetVerticalMarginBorderPadding(firstBlockRS); result -= GetVerticalMarginBorderPadding(firstBlockRS);
result -= GetVerticalMarginBorderPadding(firstAreaRS); result -= GetVerticalMarginBorderPadding(firstAreaRS);

View File

@@ -156,7 +156,7 @@ NoComputedHeightBetween(const nsHTMLReflowState& aReflowState,
// nsIPercentHeightObserver methods // nsIPercentHeightObserver methods
nsresult void
nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState) nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
{ {
if (!NeedSpecialReflow()) { if (!NeedSpecialReflow()) {
@@ -166,17 +166,36 @@ nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
// initiating frame and the cell. // initiating frame and the cell.
for (const nsHTMLReflowState* rs = aReflowState.parentReflowState; rs; rs = rs->parentReflowState) { for (const nsHTMLReflowState* rs = aReflowState.parentReflowState; rs; rs = rs->parentReflowState) {
if ((NS_UNCONSTRAINEDSIZE != rs->mComputedHeight) && (0 != rs->mComputedHeight)) { if ((NS_UNCONSTRAINEDSIZE != rs->mComputedHeight) && (0 != rs->mComputedHeight)) {
return NS_OK; return;
} }
// stop when we reach the cell frame // stop when we reach the cell frame
if (rs->frame == this) { if (rs->frame == this) {
nsTableFrame::RequestSpecialHeightReflow(*rs); nsTableFrame::RequestSpecialHeightReflow(*rs);
return NS_OK; return;
} }
} }
NS_ASSERTION(PR_FALSE, "program error in NotifyPercentHeight"); NS_ASSERTION(PR_FALSE, "program error in NotifyPercentHeight");
} }
return NS_OK; }
// The cell needs to observe its block and things inside its block but nothing below that
PRBool
nsTableCellFrame::NeedsToObserve(const nsHTMLReflowState& aReflowState)
{
PRBool result = PR_FALSE;
const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) { // cell observes the parent
result = PR_TRUE;
parentRS = parentRS->parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) { // cell observers the grand parent
parentRS = parentRS->parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) {
// cell observes the great grand parent, so we have gone too deep
result = PR_FALSE;
}
}
}
return result;
} }
nsresult nsresult
@@ -798,6 +817,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
// see if a special height reflow needs to occur due to having a pct height // see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
// this should probably be cached somewhere // this should probably be cached somewhere
@@ -883,8 +903,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nscoord computedPaginatedHeight = 0; nscoord computedPaginatedHeight = 0;
if (aReflowState.mFlags.mSpecialHeightReflow || if (aReflowState.mFlags.mSpecialHeightReflow ||
(HadSpecialReflow() && ((eReflowReason_Incremental == aReflowState.reason) || (HadSpecialReflow() && (eReflowReason_Incremental == aReflowState.reason))) {
(eReflowReason_Resize == aReflowState.reason)))) {
((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset; ((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset;
DISPLAY_REFLOW_CHANGE(); DISPLAY_REFLOW_CHANGE();
} }

View File

@@ -116,7 +116,9 @@ public:
nsIAtom* aListName, nsIAtom* aListName,
nsIFrame* aOldFrame); nsIFrame* aOldFrame);
NS_IMETHOD NotifyPercentHeight(const nsHTMLReflowState& aReflowState); virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState);
virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState);
void InitCellFrame(PRInt32 aColIndex); void InitCellFrame(PRInt32 aColIndex);

View File

@@ -1898,8 +1898,7 @@ nsTableFrame::CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowSt
nsIFrame* prevInFlow; nsIFrame* prevInFlow;
aReflowState.frame->GetPrevInFlow(&prevInFlow); aReflowState.frame->GetPrevInFlow(&prevInFlow);
if ((NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth) && // not first pass reflow if (!prevInFlow && // 1st in flow && // 1st in flow
!prevInFlow && // 1st in flow && // 1st in flow
((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) || // no computed height ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) || // no computed height
(0 == aReflowState.mComputedHeight)) && (0 == aReflowState.mComputedHeight)) &&
::IsPctStyleHeight(aReflowState.mStylePosition)) { // pct height ::IsPctStyleHeight(aReflowState.mStylePosition)) { // pct height
@@ -2056,6 +2055,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
} }
nsresult rv = NS_OK; nsresult rv = NS_OK;
// see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
// see if collapsing borders need to be calculated // see if collapsing borders need to be calculated
if (!mPrevInFlow && IsBorderCollapse() && NeedToCalcBCBorders()) { if (!mPrevInFlow && IsBorderCollapse() && NeedToCalcBCBorders()) {
GET_TWIPS_TO_PIXELS(aPresContext, p2t); GET_TWIPS_TO_PIXELS(aPresContext, p2t);
@@ -2132,35 +2135,33 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
// and other reflows which require either a strategy init or balance. This isn't done // and other reflows which require either a strategy init or balance. This isn't done
// during an unconstrained reflow because another reflow will be processed later. // during an unconstrained reflow because another reflow will be processed later.
if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) { if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
if (!mPrevInFlow) {
// see if an extra reflow will be necessary when the table is nested, there is a pct height,
// no computed height, but a height on the containing table
if ( ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) ||
(0 == aReflowState.mComputedHeight)) &&
IsPctHeight(mStyleContext)) {
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
}
// see if an extra reflow will be necessary in pagination mode when there is a specified table height // see if an extra reflow will be necessary in pagination mode when there is a specified table height
else if (isPaginated && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight)) { if (isPaginated && !mPrevInFlow && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight)) {
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState); nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((tableSpecifiedHeight > 0) && if ((tableSpecifiedHeight > 0) &&
(tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) { (tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
SetNeedToInitiateSpecialReflow(PR_TRUE); SetNeedToInitiateSpecialReflow(PR_TRUE);
} }
} }
} nsIFrame* lastChildReflowed = nsnull;
// if we need to reflow the table an extra time, then don't constrain the height of the previous reflow PRBool willInitiateSpecialReflow =
nscoord availHeight = !aReflowState.mFlags.mSpecialHeightReflow && ((NeedToInitiateSpecialReflow() || InitiatedSpecialReflow()) &&
(NeedSpecialReflow() | NeedToInitiateSpecialReflow()) (aReflowState.mFlags.mSpecialHeightReflow || !NeedSpecialReflow()));
// do the pass 2 reflow unless this is a special height reflow and we will be
// initiating a special height reflow
if (!(aReflowState.mFlags.mSpecialHeightReflow && willInitiateSpecialReflow)) {
// if we need to initiate a special height reflow, then don't constrain the
// height of the reflow before that
nscoord availHeight = (willInitiateSpecialReflow)
? NS_UNCONSTRAINEDSIZE : aReflowState.availableHeight; ? NS_UNCONSTRAINEDSIZE : aReflowState.availableHeight;
nsIFrame* lastChildReflowed;
ReflowTable(aPresContext, aDesiredSize, aReflowState, availHeight, nextReason, ReflowTable(aPresContext, aDesiredSize, aReflowState, availHeight, nextReason,
lastChildReflowed, doCollapse, balanced, aStatus); lastChildReflowed, doCollapse, balanced, aStatus);
}
if (NeedToInitiateSpecialReflow() && if (willInitiateSpecialReflow && NS_FRAME_IS_COMPLETE(aStatus)) {
(aReflowState.mFlags.mSpecialHeightReflow || !NeedSpecialReflow())) { // distribute extra vertical space to rows
aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState); // distributes extra vertical space to rows aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState);
((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = PR_TRUE; ((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = PR_TRUE;
// save the previous special height reflow initiator, install us as the new one // save the previous special height reflow initiator, install us as the new one
nsIFrame* specialReflowInitiator = aReflowState.mPercentHeightReflowInitiator; nsIFrame* specialReflowInitiator = aReflowState.mPercentHeightReflowInitiator;
@@ -2171,6 +2172,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
nextReason, lastChildReflowed, doCollapse, balanced, aStatus); nextReason, lastChildReflowed, doCollapse, balanced, aStatus);
// restore the previous special height reflow initiator // restore the previous special height reflow initiator
((nsHTMLReflowState&)aReflowState).mPercentHeightReflowInitiator = specialReflowInitiator; ((nsHTMLReflowState&)aReflowState).mPercentHeightReflowInitiator = specialReflowInitiator;
// XXX We should call SetInitiatedSpecialReflow(PR_FALSE) at some point, but it is difficult to tell when
SetInitiatedSpecialReflow(PR_TRUE);
if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
// if there is an incomplete child, then set the desired height to include it but not the next one // if there is an incomplete child, then set the desired height to include it but not the next one

View File

@@ -554,9 +554,13 @@ public:
PRBool NeedSpecialReflow() const; PRBool NeedSpecialReflow() const;
void SetNeedSpecialReflow(PRBool aValue); void SetNeedSpecialReflow(PRBool aValue);
PRBool NeedToInitiateSpecialReflow() const; PRBool NeedToInitiateSpecialReflow() const;
void SetNeedToInitiateSpecialReflow(PRBool aValue); void SetNeedToInitiateSpecialReflow(PRBool aValue);
PRBool InitiatedSpecialReflow() const;
void SetInitiatedSpecialReflow(PRBool aValue);
protected: protected:
/** protected constructor. /** protected constructor.
@@ -955,8 +959,9 @@ protected:
unsigned mRowInserted:1; unsigned mRowInserted:1;
unsigned mNeedSpecialReflow:1; unsigned mNeedSpecialReflow:1;
unsigned mNeedToInitiateSpecialReflow:1; unsigned mNeedToInitiateSpecialReflow:1;
unsigned mInitiatedSpecialReflow:1;
unsigned mNeedToCalcBCBorders:1; unsigned mNeedToCalcBCBorders:1;
unsigned : 18; // unused unsigned : 17; // unused
} mBits; } mBits;
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
@@ -1079,6 +1084,17 @@ inline void nsTableFrame::SetNeedToInitiateSpecialReflow(PRBool aValue)
{ {
mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue; mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue;
} }
inline PRBool nsTableFrame::InitiatedSpecialReflow() const
{
return (PRBool)mBits.mInitiatedSpecialReflow;
}
inline void nsTableFrame::SetInitiatedSpecialReflow(PRBool aValue)
{
mBits.mInitiatedSpecialReflow = (unsigned)aValue;
}
inline PRBool nsTableFrame::IsRowInserted() const inline PRBool nsTableFrame::IsRowInserted() const
{ {
return (PRBool)mBits.mRowInserted; return (PRBool)mBits.mRowInserted;

View File

@@ -997,8 +997,9 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
(eReflowReason_StyleChange == aReflowState.reason) || (eReflowReason_StyleChange == aReflowState.reason) ||
isPaginated || isPaginated ||
(aReflowState.mFlags.mSpecialHeightReflow && cellFrame->NeedSpecialReflow()) || (aReflowState.mFlags.mSpecialHeightReflow && cellFrame->NeedSpecialReflow()) ||
(!aReflowState.mFlags.mSpecialHeightReflow && cellFrame->HadSpecialReflow()) ||
HasPctHeight() || HasPctHeight() ||
notifyStyleChange ){ notifyStyleChange) {
// Reflow the cell to fit the available width, height // Reflow the cell to fit the available width, height
nsSize kidAvailSize(availColWidth, aReflowState.availableHeight); nsSize kidAvailSize(availColWidth, aReflowState.availableHeight);
nsReflowReason reason = eReflowReason_Resize; nsReflowReason reason = eReflowReason_Resize;
@@ -1443,6 +1444,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
if (!tableFrame) return NS_ERROR_NULL_POINTER; if (!tableFrame) return NS_ERROR_NULL_POINTER;
// see if a special height reflow needs to occur due to having a pct height // see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
switch (aReflowState.reason) { switch (aReflowState.reason) {

View File

@@ -1186,16 +1186,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
PRBool isPaginated; PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated); aPresContext->IsPaginated(&isPaginated);
// If this is a special height reflow, set our desired size to what is was previously and return
// if we will be getting another special height reflow. In paginated mode, SetNeedSpecialReflow(PR_TRUE)
// may not have been called if reflow was a result of having a height on the containing table
if (nsTableFrame::IsPrematureSpecialHeightReflow(aReflowState, mRect, NeedSpecialReflow() || isPaginated, aDesiredSize))
return NS_OK;
nsTableFrame* tableFrame = nsnull; nsTableFrame* tableFrame = nsnull;
rv = nsTableFrame::GetTableFrame(this, tableFrame); rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (!aPresContext || !tableFrame) return NS_ERROR_NULL_POINTER; if (!aPresContext || !tableFrame) return NS_ERROR_NULL_POINTER;
// see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
nsRowGroupReflowState state(aReflowState, tableFrame); nsRowGroupReflowState state(aReflowState, tableFrame);
PRBool haveDesiredHeight = PR_FALSE; PRBool haveDesiredHeight = PR_FALSE;

View File

@@ -156,7 +156,7 @@ NoComputedHeightBetween(const nsHTMLReflowState& aReflowState,
// nsIPercentHeightObserver methods // nsIPercentHeightObserver methods
nsresult void
nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState) nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
{ {
if (!NeedSpecialReflow()) { if (!NeedSpecialReflow()) {
@@ -166,17 +166,36 @@ nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
// initiating frame and the cell. // initiating frame and the cell.
for (const nsHTMLReflowState* rs = aReflowState.parentReflowState; rs; rs = rs->parentReflowState) { for (const nsHTMLReflowState* rs = aReflowState.parentReflowState; rs; rs = rs->parentReflowState) {
if ((NS_UNCONSTRAINEDSIZE != rs->mComputedHeight) && (0 != rs->mComputedHeight)) { if ((NS_UNCONSTRAINEDSIZE != rs->mComputedHeight) && (0 != rs->mComputedHeight)) {
return NS_OK; return;
} }
// stop when we reach the cell frame // stop when we reach the cell frame
if (rs->frame == this) { if (rs->frame == this) {
nsTableFrame::RequestSpecialHeightReflow(*rs); nsTableFrame::RequestSpecialHeightReflow(*rs);
return NS_OK; return;
} }
} }
NS_ASSERTION(PR_FALSE, "program error in NotifyPercentHeight"); NS_ASSERTION(PR_FALSE, "program error in NotifyPercentHeight");
} }
return NS_OK; }
// The cell needs to observe its block and things inside its block but nothing below that
PRBool
nsTableCellFrame::NeedsToObserve(const nsHTMLReflowState& aReflowState)
{
PRBool result = PR_FALSE;
const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) { // cell observes the parent
result = PR_TRUE;
parentRS = parentRS->parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) { // cell observers the grand parent
parentRS = parentRS->parentReflowState;
if (parentRS && (parentRS->mPercentHeightObserver == this)) {
// cell observes the great grand parent, so we have gone too deep
result = PR_FALSE;
}
}
}
return result;
} }
nsresult nsresult
@@ -798,6 +817,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
// see if a special height reflow needs to occur due to having a pct height // see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
// this should probably be cached somewhere // this should probably be cached somewhere
@@ -883,8 +903,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nscoord computedPaginatedHeight = 0; nscoord computedPaginatedHeight = 0;
if (aReflowState.mFlags.mSpecialHeightReflow || if (aReflowState.mFlags.mSpecialHeightReflow ||
(HadSpecialReflow() && ((eReflowReason_Incremental == aReflowState.reason) || (HadSpecialReflow() && (eReflowReason_Incremental == aReflowState.reason))) {
(eReflowReason_Resize == aReflowState.reason)))) {
((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset; ((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset;
DISPLAY_REFLOW_CHANGE(); DISPLAY_REFLOW_CHANGE();
} }

View File

@@ -116,7 +116,9 @@ public:
nsIAtom* aListName, nsIAtom* aListName,
nsIFrame* aOldFrame); nsIFrame* aOldFrame);
NS_IMETHOD NotifyPercentHeight(const nsHTMLReflowState& aReflowState); virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState);
virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState);
void InitCellFrame(PRInt32 aColIndex); void InitCellFrame(PRInt32 aColIndex);

View File

@@ -1898,8 +1898,7 @@ nsTableFrame::CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowSt
nsIFrame* prevInFlow; nsIFrame* prevInFlow;
aReflowState.frame->GetPrevInFlow(&prevInFlow); aReflowState.frame->GetPrevInFlow(&prevInFlow);
if ((NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth) && // not first pass reflow if (!prevInFlow && // 1st in flow && // 1st in flow
!prevInFlow && // 1st in flow && // 1st in flow
((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) || // no computed height ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) || // no computed height
(0 == aReflowState.mComputedHeight)) && (0 == aReflowState.mComputedHeight)) &&
::IsPctStyleHeight(aReflowState.mStylePosition)) { // pct height ::IsPctStyleHeight(aReflowState.mStylePosition)) { // pct height
@@ -2056,6 +2055,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
} }
nsresult rv = NS_OK; nsresult rv = NS_OK;
// see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
// see if collapsing borders need to be calculated // see if collapsing borders need to be calculated
if (!mPrevInFlow && IsBorderCollapse() && NeedToCalcBCBorders()) { if (!mPrevInFlow && IsBorderCollapse() && NeedToCalcBCBorders()) {
GET_TWIPS_TO_PIXELS(aPresContext, p2t); GET_TWIPS_TO_PIXELS(aPresContext, p2t);
@@ -2132,35 +2135,33 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
// and other reflows which require either a strategy init or balance. This isn't done // and other reflows which require either a strategy init or balance. This isn't done
// during an unconstrained reflow because another reflow will be processed later. // during an unconstrained reflow because another reflow will be processed later.
if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) { if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
if (!mPrevInFlow) {
// see if an extra reflow will be necessary when the table is nested, there is a pct height,
// no computed height, but a height on the containing table
if ( ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) ||
(0 == aReflowState.mComputedHeight)) &&
IsPctHeight(mStyleContext)) {
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
}
// see if an extra reflow will be necessary in pagination mode when there is a specified table height // see if an extra reflow will be necessary in pagination mode when there is a specified table height
else if (isPaginated && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight)) { if (isPaginated && !mPrevInFlow && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight)) {
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState); nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((tableSpecifiedHeight > 0) && if ((tableSpecifiedHeight > 0) &&
(tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) { (tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
SetNeedToInitiateSpecialReflow(PR_TRUE); SetNeedToInitiateSpecialReflow(PR_TRUE);
} }
} }
} nsIFrame* lastChildReflowed = nsnull;
// if we need to reflow the table an extra time, then don't constrain the height of the previous reflow PRBool willInitiateSpecialReflow =
nscoord availHeight = !aReflowState.mFlags.mSpecialHeightReflow && ((NeedToInitiateSpecialReflow() || InitiatedSpecialReflow()) &&
(NeedSpecialReflow() | NeedToInitiateSpecialReflow()) (aReflowState.mFlags.mSpecialHeightReflow || !NeedSpecialReflow()));
// do the pass 2 reflow unless this is a special height reflow and we will be
// initiating a special height reflow
if (!(aReflowState.mFlags.mSpecialHeightReflow && willInitiateSpecialReflow)) {
// if we need to initiate a special height reflow, then don't constrain the
// height of the reflow before that
nscoord availHeight = (willInitiateSpecialReflow)
? NS_UNCONSTRAINEDSIZE : aReflowState.availableHeight; ? NS_UNCONSTRAINEDSIZE : aReflowState.availableHeight;
nsIFrame* lastChildReflowed;
ReflowTable(aPresContext, aDesiredSize, aReflowState, availHeight, nextReason, ReflowTable(aPresContext, aDesiredSize, aReflowState, availHeight, nextReason,
lastChildReflowed, doCollapse, balanced, aStatus); lastChildReflowed, doCollapse, balanced, aStatus);
}
if (NeedToInitiateSpecialReflow() && if (willInitiateSpecialReflow && NS_FRAME_IS_COMPLETE(aStatus)) {
(aReflowState.mFlags.mSpecialHeightReflow || !NeedSpecialReflow())) { // distribute extra vertical space to rows
aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState); // distributes extra vertical space to rows aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState);
((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = PR_TRUE; ((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = PR_TRUE;
// save the previous special height reflow initiator, install us as the new one // save the previous special height reflow initiator, install us as the new one
nsIFrame* specialReflowInitiator = aReflowState.mPercentHeightReflowInitiator; nsIFrame* specialReflowInitiator = aReflowState.mPercentHeightReflowInitiator;
@@ -2171,6 +2172,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
nextReason, lastChildReflowed, doCollapse, balanced, aStatus); nextReason, lastChildReflowed, doCollapse, balanced, aStatus);
// restore the previous special height reflow initiator // restore the previous special height reflow initiator
((nsHTMLReflowState&)aReflowState).mPercentHeightReflowInitiator = specialReflowInitiator; ((nsHTMLReflowState&)aReflowState).mPercentHeightReflowInitiator = specialReflowInitiator;
// XXX We should call SetInitiatedSpecialReflow(PR_FALSE) at some point, but it is difficult to tell when
SetInitiatedSpecialReflow(PR_TRUE);
if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
// if there is an incomplete child, then set the desired height to include it but not the next one // if there is an incomplete child, then set the desired height to include it but not the next one

View File

@@ -554,9 +554,13 @@ public:
PRBool NeedSpecialReflow() const; PRBool NeedSpecialReflow() const;
void SetNeedSpecialReflow(PRBool aValue); void SetNeedSpecialReflow(PRBool aValue);
PRBool NeedToInitiateSpecialReflow() const; PRBool NeedToInitiateSpecialReflow() const;
void SetNeedToInitiateSpecialReflow(PRBool aValue); void SetNeedToInitiateSpecialReflow(PRBool aValue);
PRBool InitiatedSpecialReflow() const;
void SetInitiatedSpecialReflow(PRBool aValue);
protected: protected:
/** protected constructor. /** protected constructor.
@@ -955,8 +959,9 @@ protected:
unsigned mRowInserted:1; unsigned mRowInserted:1;
unsigned mNeedSpecialReflow:1; unsigned mNeedSpecialReflow:1;
unsigned mNeedToInitiateSpecialReflow:1; unsigned mNeedToInitiateSpecialReflow:1;
unsigned mInitiatedSpecialReflow:1;
unsigned mNeedToCalcBCBorders:1; unsigned mNeedToCalcBCBorders:1;
unsigned : 18; // unused unsigned : 17; // unused
} mBits; } mBits;
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
@@ -1079,6 +1084,17 @@ inline void nsTableFrame::SetNeedToInitiateSpecialReflow(PRBool aValue)
{ {
mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue; mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue;
} }
inline PRBool nsTableFrame::InitiatedSpecialReflow() const
{
return (PRBool)mBits.mInitiatedSpecialReflow;
}
inline void nsTableFrame::SetInitiatedSpecialReflow(PRBool aValue)
{
mBits.mInitiatedSpecialReflow = (unsigned)aValue;
}
inline PRBool nsTableFrame::IsRowInserted() const inline PRBool nsTableFrame::IsRowInserted() const
{ {
return (PRBool)mBits.mRowInserted; return (PRBool)mBits.mRowInserted;

View File

@@ -997,8 +997,9 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
(eReflowReason_StyleChange == aReflowState.reason) || (eReflowReason_StyleChange == aReflowState.reason) ||
isPaginated || isPaginated ||
(aReflowState.mFlags.mSpecialHeightReflow && cellFrame->NeedSpecialReflow()) || (aReflowState.mFlags.mSpecialHeightReflow && cellFrame->NeedSpecialReflow()) ||
(!aReflowState.mFlags.mSpecialHeightReflow && cellFrame->HadSpecialReflow()) ||
HasPctHeight() || HasPctHeight() ||
notifyStyleChange ){ notifyStyleChange) {
// Reflow the cell to fit the available width, height // Reflow the cell to fit the available width, height
nsSize kidAvailSize(availColWidth, aReflowState.availableHeight); nsSize kidAvailSize(availColWidth, aReflowState.availableHeight);
nsReflowReason reason = eReflowReason_Resize; nsReflowReason reason = eReflowReason_Resize;
@@ -1443,6 +1444,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
if (!tableFrame) return NS_ERROR_NULL_POINTER; if (!tableFrame) return NS_ERROR_NULL_POINTER;
// see if a special height reflow needs to occur due to having a pct height // see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
switch (aReflowState.reason) { switch (aReflowState.reason) {

View File

@@ -1186,16 +1186,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
PRBool isPaginated; PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated); aPresContext->IsPaginated(&isPaginated);
// If this is a special height reflow, set our desired size to what is was previously and return
// if we will be getting another special height reflow. In paginated mode, SetNeedSpecialReflow(PR_TRUE)
// may not have been called if reflow was a result of having a height on the containing table
if (nsTableFrame::IsPrematureSpecialHeightReflow(aReflowState, mRect, NeedSpecialReflow() || isPaginated, aDesiredSize))
return NS_OK;
nsTableFrame* tableFrame = nsnull; nsTableFrame* tableFrame = nsnull;
rv = nsTableFrame::GetTableFrame(this, tableFrame); rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (!aPresContext || !tableFrame) return NS_ERROR_NULL_POINTER; if (!aPresContext || !tableFrame) return NS_ERROR_NULL_POINTER;
// see if a special height reflow needs to occur due to having a pct height
if (!NeedSpecialReflow())
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
nsRowGroupReflowState state(aReflowState, tableFrame); nsRowGroupReflowState state(aReflowState, tableFrame);
PRBool haveDesiredHeight = PR_FALSE; PRBool haveDesiredHeight = PR_FALSE;