mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
bug 61663 - repeat headers and footers on more than 2 pages. sr=attinasi, r=bernd.mielke@snafu.de.
This commit is contained in:
parent
754cff3879
commit
1642ac06f0
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user