Tables now clear the isTopOfPage when appropriate

This commit is contained in:
troy%netscape.com 1998-12-14 01:24:11 +00:00
parent 5658a6f312
commit 09777c2885
6 changed files with 260 additions and 36 deletions

View File

@ -1703,6 +1703,9 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
nsSize maxKidElementSize(0,0);
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState,
availSize, aReason);
// Note: we don't bother checking here for whether we should clear the
// isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue...
PRInt32 yCoord = y;
if (NS_UNCONSTRAINEDSIZE!=yCoord)
yCoord+= topInset;
@ -2440,7 +2443,8 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
reason = eReflowReason_Resize;
// this never passes reflows down to colgroups
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
nsIFrame* firstRowGroupFrame = nsnull;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
{
nsSize kidAvailSize(aReflowState.availSize);
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
@ -2449,7 +2453,15 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ // for all colgroups and rowgroups...
{
// Keep track of the first row group frame: we need this to correctly clear
// the isTopOfPage flag and when pushing frames
if (nsnull == firstRowGroupFrame) {
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
firstRowGroupFrame = kidFrame;
}
}
const nsStyleSpacing* kidSpacing;
kidFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)kidSpacing));
nsMargin kidMargin;
@ -2472,20 +2484,25 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
aReflowState.reflowState, kidAvailSize,
reason);
if ((nsnull != firstRowGroupFrame) && (kidFrame != firstRowGroupFrame)) {
// If this isn't the first row group frame or the header or footer, then
// we can't be at the top of the page anymore...
kidReflowState.isTopOfPage = PR_FALSE;
}
nscoord x = aReflowState.leftInset + kidMargin.left;
nscoord y = aReflowState.topInset + aReflowState.y + topMargin;
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p with reason=%d\n", kidFrame, reason);
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
// Did the child fit?
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
{
// The child is too tall to fit in the available space, and it's
// not our first child
// XXX TROY: checking mFirstChild here is probably wrong. Should check to see if its the first row group?
PushChildren(kidFrame, prevKidFrame);
//XXX TROY: set aStatus?
break;
if (desiredSize.height > kidAvailSize.height) {
if ((nsnull != firstRowGroupFrame) && (kidFrame != firstRowGroupFrame)) {
// The child is too tall to fit in the available space, and it's
// not our first row grpup frame
PushChildren(kidFrame, prevKidFrame);
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
}
// Place the child after taking into account it's margin

View File

@ -356,8 +356,19 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
}
// Reflow the child into the available space
#if 1
// XXX Give it as much room as it wants. We'll deal with splitting later
// after we've computed the row heights taking into account cells with
// row spans...
kidAvailSize.height = NS_UNCONSTRAINEDSIZE;
#endif
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState.reflowState,
kidAvailSize, aReason);
if (kidFrame != mFirstChild) {
// If this isn't the first row frame, then we can't be at the top of
// the page anymore...
kidReflowState.isTopOfPage = PR_FALSE;
}
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
@ -366,6 +377,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
this, kidFrame, desiredSize.width);
#if 0
// Did the child fit?
if ((kidFrame != mFirstChild) &&
((kidAvailSize.height <= 0) ||
@ -380,6 +392,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
#endif
// Place the child after taking into account its margin
nsRect kidRect (kidMargin.left, aReflowState.y, desiredSize.width, desiredSize.height);
@ -394,6 +407,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
// Remember where we just were in case we end up pushing children
prevKidFrame = kidFrame;
#if 0
/* Row groups should not create continuing frames for rows
* unless they absolutely have to!
* check to see if this is absolutely necessary (with new params from troy)
@ -433,6 +447,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
}
break;
}
#endif
// Add back in the left and right margins, because one row does not
// impact another row's width
@ -828,6 +843,74 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aP
return NS_OK;
}
nsresult
nsTableRowGroupFrame::SplitRowGroup(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsIFrame* prevKidFrame = nsnull;
// Walk each of the row frames looking for the first row frame that
// doesn't fit in the available space
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
nsRect bounds;
kidFrame->GetRect(bounds);
if (bounds.YMost() > aReflowState.maxSize.height) {
// If this is the first row frame then we need to split it
if (nsnull == prevKidFrame) {
// Reflow the row in the available space and have it split
// XXX Account for horizontal margins...
#if 0
nsSize kidAvailSize(aReflowState.maxSize.width,
aReflowState.maxSize.height - bounds.y);
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState,
kidAvailSize, eReflowReason_Resize);
nsReflowMetrics desiredSize;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
kidFrame->SizeTo(desiredSize.width, desiredSize.height);
NS_ASSERTION(NS_FRAME_IS_NOT_COMPLETE(aStatus), "unexpected status");
// Create a continuing frame, add it to the child list, and then push it
// and the frames that follow
// XXX Check whether it already has a next-in-flow
nsIFrame* continuingFrame;
nsIStyleContext* kidSC;
kidFrame->GetStyleContext(kidSC);
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC, continuingFrame);
NS_RELEASE(kidSC);
// Add it to the child list
nsIFrame* nextSibling;
kidFrame->GetNextSibling(nextSibling);
continuingFrame->SetNextSibling(nextSibling);
kidFrame->SetNextSibling(continuingFrame);
// Push it and the frames that follow
PushChildren(continuingFrame, kidFrame);
aDesiredSize.height = bounds.y;
#endif
} else {
// See whether the row frame has cells that span into it or across it
PushChildren(kidFrame, prevKidFrame);
aDesiredSize.height = bounds.y;
}
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
prevKidFrame = kidFrame;
}
return NS_OK;
}
/** Layout the entire row group.
* This method stacks rows vertically according to HTML 4.0 rules.
* Rows are responsible for layout of their children.
@ -874,11 +957,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
nsnull, aReflowState.reason, PR_TRUE);
}
// XXX We need to figure out what to do about this...
#if 0
// Did we successfully reflow our mapped children?
if (NS_FRAME_COMPLETE==aStatus) {
// Try and pull-up some children from a next-in-flow
rv = PullUpChildren(aPresContext, aDesiredSize, state, aStatus);
}
#endif
if (NS_FRAME_IS_COMPLETE(aStatus)) {
// Don't forget to add in the bottom margin from our last child.
@ -898,6 +984,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
if (eReflowReason_Initial != aReflowState.reason) {
CalculateRowHeights(aPresContext, aDesiredSize, aReflowState);
}
// See if all the frames fit
if (aDesiredSize.height > aReflowState.maxSize.height) {
// Nope, find a place to split the row group
SplitRowGroup(aPresContext, aDesiredSize, aReflowState, aStatus);
}
}
if (gsDebug==PR_TRUE)

View File

@ -33,8 +33,6 @@ struct RowGroupReflowState;
*
* @see nsTableFrame
* @see nsTableRowFrame
*
* @author sclark
*/
class nsTableRowGroupFrame : public nsHTMLContainerFrame
{
@ -109,12 +107,12 @@ protected:
RowGroupReflowState& aReflowState,
const nsMargin& aKidMargin);
void PlaceChild( nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
void PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
void CalculateRowHeights(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -212,6 +210,11 @@ protected:
RowGroupReflowState& aReflowState,
nsReflowStatus& aStatus);
nsresult SplitRowGroup(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
private:
nsIAtom *mType;

View File

@ -1703,6 +1703,9 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
nsSize maxKidElementSize(0,0);
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState,
availSize, aReason);
// Note: we don't bother checking here for whether we should clear the
// isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue...
PRInt32 yCoord = y;
if (NS_UNCONSTRAINEDSIZE!=yCoord)
yCoord+= topInset;
@ -2440,7 +2443,8 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
reason = eReflowReason_Resize;
// this never passes reflows down to colgroups
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
nsIFrame* firstRowGroupFrame = nsnull;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
{
nsSize kidAvailSize(aReflowState.availSize);
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
@ -2449,7 +2453,15 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ // for all colgroups and rowgroups...
{
// Keep track of the first row group frame: we need this to correctly clear
// the isTopOfPage flag and when pushing frames
if (nsnull == firstRowGroupFrame) {
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
firstRowGroupFrame = kidFrame;
}
}
const nsStyleSpacing* kidSpacing;
kidFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)kidSpacing));
nsMargin kidMargin;
@ -2472,20 +2484,25 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
aReflowState.reflowState, kidAvailSize,
reason);
if ((nsnull != firstRowGroupFrame) && (kidFrame != firstRowGroupFrame)) {
// If this isn't the first row group frame or the header or footer, then
// we can't be at the top of the page anymore...
kidReflowState.isTopOfPage = PR_FALSE;
}
nscoord x = aReflowState.leftInset + kidMargin.left;
nscoord y = aReflowState.topInset + aReflowState.y + topMargin;
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p with reason=%d\n", kidFrame, reason);
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
// Did the child fit?
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
{
// The child is too tall to fit in the available space, and it's
// not our first child
// XXX TROY: checking mFirstChild here is probably wrong. Should check to see if its the first row group?
PushChildren(kidFrame, prevKidFrame);
//XXX TROY: set aStatus?
break;
if (desiredSize.height > kidAvailSize.height) {
if ((nsnull != firstRowGroupFrame) && (kidFrame != firstRowGroupFrame)) {
// The child is too tall to fit in the available space, and it's
// not our first row grpup frame
PushChildren(kidFrame, prevKidFrame);
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
}
// Place the child after taking into account it's margin

View File

@ -356,8 +356,19 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
}
// Reflow the child into the available space
#if 1
// XXX Give it as much room as it wants. We'll deal with splitting later
// after we've computed the row heights taking into account cells with
// row spans...
kidAvailSize.height = NS_UNCONSTRAINEDSIZE;
#endif
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState.reflowState,
kidAvailSize, aReason);
if (kidFrame != mFirstChild) {
// If this isn't the first row frame, then we can't be at the top of
// the page anymore...
kidReflowState.isTopOfPage = PR_FALSE;
}
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
@ -366,6 +377,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
this, kidFrame, desiredSize.width);
#if 0
// Did the child fit?
if ((kidFrame != mFirstChild) &&
((kidAvailSize.height <= 0) ||
@ -380,6 +392,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
#endif
// Place the child after taking into account its margin
nsRect kidRect (kidMargin.left, aReflowState.y, desiredSize.width, desiredSize.height);
@ -394,6 +407,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
// Remember where we just were in case we end up pushing children
prevKidFrame = kidFrame;
#if 0
/* Row groups should not create continuing frames for rows
* unless they absolutely have to!
* check to see if this is absolutely necessary (with new params from troy)
@ -433,6 +447,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
}
break;
}
#endif
// Add back in the left and right margins, because one row does not
// impact another row's width
@ -828,6 +843,74 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aP
return NS_OK;
}
nsresult
nsTableRowGroupFrame::SplitRowGroup(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsIFrame* prevKidFrame = nsnull;
// Walk each of the row frames looking for the first row frame that
// doesn't fit in the available space
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
nsRect bounds;
kidFrame->GetRect(bounds);
if (bounds.YMost() > aReflowState.maxSize.height) {
// If this is the first row frame then we need to split it
if (nsnull == prevKidFrame) {
// Reflow the row in the available space and have it split
// XXX Account for horizontal margins...
#if 0
nsSize kidAvailSize(aReflowState.maxSize.width,
aReflowState.maxSize.height - bounds.y);
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState,
kidAvailSize, eReflowReason_Resize);
nsReflowMetrics desiredSize;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
kidFrame->SizeTo(desiredSize.width, desiredSize.height);
NS_ASSERTION(NS_FRAME_IS_NOT_COMPLETE(aStatus), "unexpected status");
// Create a continuing frame, add it to the child list, and then push it
// and the frames that follow
// XXX Check whether it already has a next-in-flow
nsIFrame* continuingFrame;
nsIStyleContext* kidSC;
kidFrame->GetStyleContext(kidSC);
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC, continuingFrame);
NS_RELEASE(kidSC);
// Add it to the child list
nsIFrame* nextSibling;
kidFrame->GetNextSibling(nextSibling);
continuingFrame->SetNextSibling(nextSibling);
kidFrame->SetNextSibling(continuingFrame);
// Push it and the frames that follow
PushChildren(continuingFrame, kidFrame);
aDesiredSize.height = bounds.y;
#endif
} else {
// See whether the row frame has cells that span into it or across it
PushChildren(kidFrame, prevKidFrame);
aDesiredSize.height = bounds.y;
}
aStatus = NS_FRAME_NOT_COMPLETE;
break;
}
prevKidFrame = kidFrame;
}
return NS_OK;
}
/** Layout the entire row group.
* This method stacks rows vertically according to HTML 4.0 rules.
* Rows are responsible for layout of their children.
@ -874,11 +957,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
nsnull, aReflowState.reason, PR_TRUE);
}
// XXX We need to figure out what to do about this...
#if 0
// Did we successfully reflow our mapped children?
if (NS_FRAME_COMPLETE==aStatus) {
// Try and pull-up some children from a next-in-flow
rv = PullUpChildren(aPresContext, aDesiredSize, state, aStatus);
}
#endif
if (NS_FRAME_IS_COMPLETE(aStatus)) {
// Don't forget to add in the bottom margin from our last child.
@ -898,6 +984,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
if (eReflowReason_Initial != aReflowState.reason) {
CalculateRowHeights(aPresContext, aDesiredSize, aReflowState);
}
// See if all the frames fit
if (aDesiredSize.height > aReflowState.maxSize.height) {
// Nope, find a place to split the row group
SplitRowGroup(aPresContext, aDesiredSize, aReflowState, aStatus);
}
}
if (gsDebug==PR_TRUE)

View File

@ -33,8 +33,6 @@ struct RowGroupReflowState;
*
* @see nsTableFrame
* @see nsTableRowFrame
*
* @author sclark
*/
class nsTableRowGroupFrame : public nsHTMLContainerFrame
{
@ -109,12 +107,12 @@ protected:
RowGroupReflowState& aReflowState,
const nsMargin& aKidMargin);
void PlaceChild( nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
void PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
void CalculateRowHeights(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -212,6 +210,11 @@ protected:
RowGroupReflowState& aReflowState,
nsReflowStatus& aStatus);
nsresult SplitRowGroup(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
private:
nsIAtom *mType;