bug 61663 - repeat headers and footers on more than 2 pages. sr=attinasi, r=bernd.mielke@snafu.de.

This commit is contained in:
karnaze%netscape.com 2001-04-09 14:21:24 +00:00
parent 754cff3879
commit 1642ac06f0
8 changed files with 128 additions and 60 deletions

View File

@ -10541,6 +10541,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
NS_ASSERTION(!state.mFloatedItems.childList, "unexpected floated element");
NS_RELEASE(headerFooter);
headerFooterFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
((nsTableRowGroupFrame*)headerFooterFrame)->SetRepeatable(PR_TRUE);
// Table specific initialization
((nsTableRowGroupFrame*)headerFooterFrame)->InitRepeatedFrame
@ -10553,13 +10554,6 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
NS_RELEASE(rowGroupStyle);
// Header and footer must be first, and then the body row groups.
// So if we found a body row group, then stop looking for header and
// footer elements
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay) {
break;
}
// Get the next row group frame
rowGroupFrame->GetNextSibling(&rowGroupFrame);
}

View File

@ -10541,6 +10541,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
NS_ASSERTION(!state.mFloatedItems.childList, "unexpected floated element");
NS_RELEASE(headerFooter);
headerFooterFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
((nsTableRowGroupFrame*)headerFooterFrame)->SetRepeatable(PR_TRUE);
// Table specific initialization
((nsTableRowGroupFrame*)headerFooterFrame)->InitRepeatedFrame
@ -10553,13 +10554,6 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
NS_RELEASE(rowGroupStyle);
// Header and footer must be first, and then the body row groups.
// So if we found a body row group, then stop looking for header and
// footer elements
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay) {
break;
}
// Get the next row group frame
rowGroupFrame->GetNextSibling(&rowGroupFrame);
}

View File

@ -2002,7 +2002,7 @@ nsTableFrame::MoveOverflowToChildList(nsIPresContext* aPresContext)
for (nsIFrame* f = prevOverflowFrames; f; f->GetNextSibling(&f)) {
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevInFlow, this);
}
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
mFrames.AppendFrames(this, prevOverflowFrames);
result = PR_TRUE;
}
}
@ -2744,16 +2744,20 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
void
nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody)
nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody,
nsTableRowGroupFrame** aHead,
nsTableRowGroupFrame** aFoot)
{
aChildren.Clear();
nsIFrame* head = nsnull;
nsIFrame* foot = nsnull;
if (aFirstBody) {
*aFirstBody = nsnull;
}
// initialize out parameters, if present
if (aFirstBody) *aFirstBody = nsnull;
if (aHead) *aHead = nsnull;
if (aFoot) *aFoot = nsnull;
nsIFrame* kidFrame = mFrames.FirstChild();
nsVoidArray nonRowGroups;
// put the tbodies first, and the non row groups last
@ -2768,6 +2772,9 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
else {
head = kidFrame;
if (aHead) {
*aHead = (nsTableRowGroupFrame*)head;
}
}
break;
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
@ -2776,6 +2783,9 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
else {
foot = kidFrame;
if (aFoot) {
*aFoot = (nsTableRowGroupFrame*)foot;
}
}
break;
default:
@ -2809,6 +2819,16 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
}
static PRBool
IsRepeatable(nsTableRowGroupFrame& aHeaderOrFooter,
nscoord aPageHeight)
{
nsRect rect;
aHeaderOrFooter.GetRect(rect);
return (rect.height < (aPageHeight / 4));
}
// Reflow the children based on the avail size and reason in aReflowState
// update aReflowMetrics a aStatus
NS_METHOD
@ -2830,7 +2850,8 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
nsVoidArray rowGroups;
PRUint32 numRowGroups;
OrderRowGroups(rowGroups, numRowGroups, &aReflowState.firstBodySection);
nsTableRowGroupFrame *thead, *tfoot;
OrderRowGroups(rowGroups, numRowGroups, &aReflowState.firstBodySection, &thead, &tfoot);
PRBool haveReflowedRowGroup = PR_FALSE;
for (PRUint32 childX = 0; ((PRInt32)childX) < rowGroups.Count(); childX++) {
@ -2847,7 +2868,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
if (doReflowChild) {
nsSize kidAvailSize(aReflowState.availSize);
// if this is a tbody in paginated mode reduce the height by a repeated footer
// if the child is a tbody in paginated mode reduce the height by a repeated footer
nsIFrame* repeatedFooter = nsnull;
nscoord repeatedFooterHeight = 0;
if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.height)) {
@ -2985,6 +3006,20 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
SetHaveReflowedColGroups(PR_TRUE);
}
// set the repeatablility of headers and footers in the original table during its first reflow
// the repeatability of header and footers on continued tables is handled when they are created
if (isPaginated && !mPrevInFlow && (NS_UNCONSTRAINEDSIZE == aReflowState.availSize.height)) {
nscoord pageHeight;
aPresContext->GetPageHeight(&pageHeight);
// don't repeat the thead or tfoot unless it is < 25% of the page height
if (thead) {
thead->SetRepeatable(IsRepeatable(*thead, pageHeight));
}
if (tfoot) {
tfoot->SetRepeatable(IsRepeatable(*tfoot, pageHeight));
}
}
if (aReflowedAtLeastOne) {
*aReflowedAtLeastOne = haveReflowedRowGroup;
}
@ -4406,7 +4441,17 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame,
printf("r=%d a=%s,%s ", aState.reason, width, height);
PrettyUC(aState.mComputedWidth, width);
PrettyUC(aState.mComputedHeight, height);
printf("c=%s,%s cnt=%d \n", width, height, gRflCount);
printf("c=%s,%s ", width, height);
nsIFrame* inFlow;
aFrame->GetPrevInFlow(&inFlow);
if (inFlow) {
printf("pif=%p ", inFlow);
}
aFrame->GetNextInFlow(&inFlow);
if (inFlow) {
printf("nif=%p ", inFlow);
}
printf("cnt=%d \n", gRflCount);
gRflCount++;
//if (32 == gRflCount) {
// NS_ASSERTION(PR_FALSE, "stop");

View File

@ -666,9 +666,11 @@ protected:
public:
// put the children frames in the display order (e.g. thead before tbody before tfoot)
// and put the non row group frames at the end. Also return the number of row group frames.
void OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody = nsnull);
void OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody = nsnull,
nsTableRowGroupFrame** aHead = nsnull,
nsTableRowGroupFrame** aFoot = nsnull);
// Returns PR_TRUE if there are any cells above the row at
// aRowIndex and spanning into the row at aRowIndex

View File

@ -44,6 +44,7 @@
nsTableRowGroupFrame::nsTableRowGroupFrame()
{
SetRepeatable(PR_FALSE);
#ifdef DEBUG_TABLE_REFLOW_TIMING
mTimer = new nsReflowTimer(this);
#endif
@ -1013,20 +1014,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.width = aReflowState.availableWidth;
aDesiredSize.height = state.y;
// determine if the row group is repeatable in paginated mode
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
nscoord pageHeight;
aPresContext->GetPageHeight(&pageHeight);
// don't repeat the thead or tfoot unless it is < 25% of the page height
PRBool repeatable = (aDesiredSize.height < (pageHeight / 4));
SetRepeatable(repeatable);
}
// shrink wrap rows to height of tallest cell in that row
PRBool isTableUnconstrainedReflow =
(NS_UNCONSTRAINEDSIZE == aReflowState.parentReflowState->availableWidth);
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
// Avoid calling CalculateRowHeights. We can avoid it if the table is going to be
// doing a pass 2 reflow. In the case where the table is getting an unconstrained
// reflow, then we need to do this because the table will skip the pass 2 reflow,

View File

@ -2002,7 +2002,7 @@ nsTableFrame::MoveOverflowToChildList(nsIPresContext* aPresContext)
for (nsIFrame* f = prevOverflowFrames; f; f->GetNextSibling(&f)) {
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevInFlow, this);
}
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
mFrames.AppendFrames(this, prevOverflowFrames);
result = PR_TRUE;
}
}
@ -2744,16 +2744,20 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
void
nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody)
nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody,
nsTableRowGroupFrame** aHead,
nsTableRowGroupFrame** aFoot)
{
aChildren.Clear();
nsIFrame* head = nsnull;
nsIFrame* foot = nsnull;
if (aFirstBody) {
*aFirstBody = nsnull;
}
// initialize out parameters, if present
if (aFirstBody) *aFirstBody = nsnull;
if (aHead) *aHead = nsnull;
if (aFoot) *aFoot = nsnull;
nsIFrame* kidFrame = mFrames.FirstChild();
nsVoidArray nonRowGroups;
// put the tbodies first, and the non row groups last
@ -2768,6 +2772,9 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
else {
head = kidFrame;
if (aHead) {
*aHead = (nsTableRowGroupFrame*)head;
}
}
break;
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
@ -2776,6 +2783,9 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
else {
foot = kidFrame;
if (aFoot) {
*aFoot = (nsTableRowGroupFrame*)foot;
}
}
break;
default:
@ -2809,6 +2819,16 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
}
}
static PRBool
IsRepeatable(nsTableRowGroupFrame& aHeaderOrFooter,
nscoord aPageHeight)
{
nsRect rect;
aHeaderOrFooter.GetRect(rect);
return (rect.height < (aPageHeight / 4));
}
// Reflow the children based on the avail size and reason in aReflowState
// update aReflowMetrics a aStatus
NS_METHOD
@ -2830,7 +2850,8 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
nsVoidArray rowGroups;
PRUint32 numRowGroups;
OrderRowGroups(rowGroups, numRowGroups, &aReflowState.firstBodySection);
nsTableRowGroupFrame *thead, *tfoot;
OrderRowGroups(rowGroups, numRowGroups, &aReflowState.firstBodySection, &thead, &tfoot);
PRBool haveReflowedRowGroup = PR_FALSE;
for (PRUint32 childX = 0; ((PRInt32)childX) < rowGroups.Count(); childX++) {
@ -2847,7 +2868,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
if (doReflowChild) {
nsSize kidAvailSize(aReflowState.availSize);
// if this is a tbody in paginated mode reduce the height by a repeated footer
// if the child is a tbody in paginated mode reduce the height by a repeated footer
nsIFrame* repeatedFooter = nsnull;
nscoord repeatedFooterHeight = 0;
if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.height)) {
@ -2985,6 +3006,20 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext,
SetHaveReflowedColGroups(PR_TRUE);
}
// set the repeatablility of headers and footers in the original table during its first reflow
// the repeatability of header and footers on continued tables is handled when they are created
if (isPaginated && !mPrevInFlow && (NS_UNCONSTRAINEDSIZE == aReflowState.availSize.height)) {
nscoord pageHeight;
aPresContext->GetPageHeight(&pageHeight);
// don't repeat the thead or tfoot unless it is < 25% of the page height
if (thead) {
thead->SetRepeatable(IsRepeatable(*thead, pageHeight));
}
if (tfoot) {
tfoot->SetRepeatable(IsRepeatable(*tfoot, pageHeight));
}
}
if (aReflowedAtLeastOne) {
*aReflowedAtLeastOne = haveReflowedRowGroup;
}
@ -4406,7 +4441,17 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame,
printf("r=%d a=%s,%s ", aState.reason, width, height);
PrettyUC(aState.mComputedWidth, width);
PrettyUC(aState.mComputedHeight, height);
printf("c=%s,%s cnt=%d \n", width, height, gRflCount);
printf("c=%s,%s ", width, height);
nsIFrame* inFlow;
aFrame->GetPrevInFlow(&inFlow);
if (inFlow) {
printf("pif=%p ", inFlow);
}
aFrame->GetNextInFlow(&inFlow);
if (inFlow) {
printf("nif=%p ", inFlow);
}
printf("cnt=%d \n", gRflCount);
gRflCount++;
//if (32 == gRflCount) {
// NS_ASSERTION(PR_FALSE, "stop");

View File

@ -666,9 +666,11 @@ protected:
public:
// put the children frames in the display order (e.g. thead before tbody before tfoot)
// and put the non row group frames at the end. Also return the number of row group frames.
void OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody = nsnull);
void OrderRowGroups(nsVoidArray& aChildren,
PRUint32& aNumRowGroups,
nsIFrame** aFirstBody = nsnull,
nsTableRowGroupFrame** aHead = nsnull,
nsTableRowGroupFrame** aFoot = nsnull);
// Returns PR_TRUE if there are any cells above the row at
// aRowIndex and spanning into the row at aRowIndex

View File

@ -44,6 +44,7 @@
nsTableRowGroupFrame::nsTableRowGroupFrame()
{
SetRepeatable(PR_FALSE);
#ifdef DEBUG_TABLE_REFLOW_TIMING
mTimer = new nsReflowTimer(this);
#endif
@ -1013,20 +1014,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.width = aReflowState.availableWidth;
aDesiredSize.height = state.y;
// determine if the row group is repeatable in paginated mode
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
nscoord pageHeight;
aPresContext->GetPageHeight(&pageHeight);
// don't repeat the thead or tfoot unless it is < 25% of the page height
PRBool repeatable = (aDesiredSize.height < (pageHeight / 4));
SetRepeatable(repeatable);
}
// shrink wrap rows to height of tallest cell in that row
PRBool isTableUnconstrainedReflow =
(NS_UNCONSTRAINEDSIZE == aReflowState.parentReflowState->availableWidth);
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
// Avoid calling CalculateRowHeights. We can avoid it if the table is going to be
// doing a pass 2 reflow. In the case where the table is getting an unconstrained
// reflow, then we need to do this because the table will skip the pass 2 reflow,