mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
bug 558574 - fix issues with table footer placement and missed page breaks inside of row groups r=roc
This commit is contained in:
parent
5abba25dc5
commit
5b3485bfc6
@ -286,20 +286,25 @@ IsRepeatedFrame(nsIFrame* kidFrame)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTableFrame::PageBreakAfter(nsIFrame& aSourceFrame,
|
||||
nsTableFrame::PageBreakAfter(nsIFrame* aSourceFrame,
|
||||
nsIFrame* aNextFrame)
|
||||
{
|
||||
const nsStyleDisplay* display = aSourceFrame.GetStyleDisplay();
|
||||
const nsStyleDisplay* display = aSourceFrame->GetStyleDisplay();
|
||||
nsTableRowGroupFrame* prevRg = do_QueryFrame(aSourceFrame);
|
||||
// don't allow a page break after a repeated element ...
|
||||
if (display->mBreakAfter && !IsRepeatedFrame(&aSourceFrame)) {
|
||||
if (display->mBreakAfter || (prevRg && prevRg->HasInternalBreakAfter()) &&
|
||||
!IsRepeatedFrame(aSourceFrame)) {
|
||||
return !(aNextFrame && IsRepeatedFrame(aNextFrame)); // or before
|
||||
}
|
||||
|
||||
if (aNextFrame) {
|
||||
display = aNextFrame->GetStyleDisplay();
|
||||
// don't allow a page break before a repeated element ...
|
||||
if (display->mBreakBefore && !IsRepeatedFrame(aNextFrame)) {
|
||||
return !IsRepeatedFrame(&aSourceFrame); // or after
|
||||
nsTableRowGroupFrame* nextRg = do_QueryFrame(aNextFrame);
|
||||
if (display->mBreakBefore ||
|
||||
(nextRg && nextRg->HasInternalBreakBefore()) &&
|
||||
!IsRepeatedFrame(aNextFrame)) {
|
||||
return !IsRepeatedFrame(aSourceFrame); // or after
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
@ -2613,6 +2618,34 @@ nsTableFrame::SetupHeaderFooterChild(const nsTableReflowState& aReflowState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState,
|
||||
nsTableRowGroupFrame *aTfoot,
|
||||
nscoord aFooterHeight)
|
||||
{
|
||||
nsPresContext* presContext = PresContext();
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
kidAvailSize.height = aFooterHeight;
|
||||
nsHTMLReflowState footerReflowState(presContext,
|
||||
aReflowState.reflowState,
|
||||
aTfoot, kidAvailSize,
|
||||
-1, -1, PR_FALSE);
|
||||
InitChildReflowState(footerReflowState);
|
||||
aReflowState.y += GetCellSpacingY();
|
||||
|
||||
nsRect origTfootRect = aTfoot->GetRect();
|
||||
nsRect origTfootOverflowRect = aTfoot->GetOverflowRect();
|
||||
|
||||
nsReflowStatus footerStatus;
|
||||
nsHTMLReflowMetrics desiredSize;
|
||||
desiredSize.width = desiredSize.height = 0;
|
||||
ReflowChild(aTfoot, presContext, desiredSize, footerReflowState,
|
||||
aReflowState.x, aReflowState.y,
|
||||
NS_FRAME_INVALIDATE_ON_MOVE, footerStatus);
|
||||
PlaceChild(aReflowState, aTfoot, desiredSize, origTfootRect,
|
||||
origTfootOverflowRect);
|
||||
}
|
||||
|
||||
// Reflow the children based on the avail size and reason in aReflowState
|
||||
// update aReflowMetrics a aStatus
|
||||
NS_METHOD
|
||||
@ -2630,7 +2663,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
// XXXldb Should we be checking constrained height instead?
|
||||
PRBool isPaginated = presContext->IsPaginated();
|
||||
PRBool isPaginated = presContext->IsPaginated() &&
|
||||
NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height;
|
||||
|
||||
aOverflowArea = nsRect (0, 0, 0, 0);
|
||||
|
||||
@ -2665,7 +2699,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// if the child is a tbody in paginated mode reduce the height by a repeated footer
|
||||
PRBool allowRepeatedFooter = PR_FALSE;
|
||||
for (PRUint32 childX = 0; childX < rowGroups.Length(); childX++) {
|
||||
nsIFrame* kidFrame = rowGroups[childX];
|
||||
// Get the frame state bits
|
||||
@ -2677,13 +2712,15 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
NS_FRAME_CONTAINS_RELATIVE_HEIGHT)))) {
|
||||
if (pageBreak) {
|
||||
PushChildren(rowGroups, childX);
|
||||
if (allowRepeatedFooter) {
|
||||
PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
|
||||
}
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
break;
|
||||
}
|
||||
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
// if the child is a tbody in paginated mode reduce the height by a repeated footer
|
||||
PRBool allowRepeatedFooter = PR_FALSE;
|
||||
allowRepeatedFooter = PR_FALSE;
|
||||
if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.height)) {
|
||||
nsTableRowGroupFrame* kidRG =
|
||||
static_cast<nsTableRowGroupFrame*>(kidFrame);
|
||||
@ -2754,6 +2791,9 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
if (nextRowGroupFrame) {
|
||||
PlaceChild(aReflowState, kidFrame, desiredSize, oldKidRect,
|
||||
oldKidOverflowRect);
|
||||
if (allowRepeatedFooter) {
|
||||
PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
|
||||
}
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
PushChildren(rowGroups, childX + 1);
|
||||
aLastChildReflowed = kidFrame;
|
||||
@ -2763,7 +2803,9 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
}
|
||||
else { // we are not on top, push this rowgroup onto the next page
|
||||
if (prevKidFrame) { // we had a rowgroup before so push this
|
||||
// XXXroc shouldn't we add a repeated footer here?
|
||||
if (allowRepeatedFooter) {
|
||||
PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
|
||||
}
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
PushChildren(rowGroups, childX);
|
||||
aLastChildReflowed = prevKidFrame;
|
||||
@ -2780,7 +2822,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
(NS_UNCONSTRAINEDSIZE != kidReflowState.availableHeight)) {
|
||||
nsIFrame* nextKid =
|
||||
(childX + 1 < rowGroups.Length()) ? rowGroups[childX + 1] : nsnull;
|
||||
pageBreak = PageBreakAfter(*kidFrame, nextKid);
|
||||
pageBreak = PageBreakAfter(kidFrame, nextKid);
|
||||
}
|
||||
|
||||
// Place the child
|
||||
@ -2823,23 +2865,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
PushChildren(rowGroups, childX + 1);
|
||||
}
|
||||
if (allowRepeatedFooter) {
|
||||
kidAvailSize.height = footerHeight;
|
||||
nsHTMLReflowState footerReflowState(presContext,
|
||||
aReflowState.reflowState,
|
||||
tfoot, kidAvailSize,
|
||||
-1, -1, PR_FALSE);
|
||||
InitChildReflowState(footerReflowState);
|
||||
aReflowState.y += cellSpacingY;
|
||||
|
||||
nsRect origTfootRect = tfoot->GetRect();
|
||||
nsRect origTfootOverflowRect = tfoot->GetOverflowRect();
|
||||
|
||||
nsReflowStatus footerStatus;
|
||||
rv = ReflowChild(tfoot, presContext, desiredSize, footerReflowState,
|
||||
aReflowState.x, aReflowState.y,
|
||||
NS_FRAME_INVALIDATE_ON_MOVE, footerStatus);
|
||||
PlaceChild(aReflowState, tfoot, desiredSize, origTfootRect,
|
||||
origTfootOverflowRect);
|
||||
PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ public:
|
||||
|
||||
static void RePositionViews(nsIFrame* aFrame);
|
||||
|
||||
static PRBool PageBreakAfter(nsIFrame& aSourceFrame,
|
||||
static PRBool PageBreakAfter(nsIFrame* aSourceFrame,
|
||||
nsIFrame* aNextFrame);
|
||||
|
||||
nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
|
||||
@ -607,6 +607,9 @@ protected:
|
||||
nsHTMLReflowMetrics& aKidDesiredSize,
|
||||
const nsRect& aOriginalKidRect,
|
||||
const nsRect& aOriginalKidOverflowRect);
|
||||
void PlaceRepeatedFooter(nsTableReflowState& aReflowState,
|
||||
nsTableRowGroupFrame *aTfoot,
|
||||
nscoord aFooterHeight);
|
||||
|
||||
nsIFrame* GetFirstBodyRowGroupFrame();
|
||||
public:
|
||||
|
@ -363,7 +363,8 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||
|
||||
// XXXldb Should we really be checking this rather than available height?
|
||||
// (Think about multi-column layout!)
|
||||
PRBool isPaginated = aPresContext->IsPaginated();
|
||||
PRBool isPaginated = aPresContext->IsPaginated() &&
|
||||
NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height;
|
||||
|
||||
PRBool haveRow = PR_FALSE;
|
||||
PRBool reflowAllKids = aReflowState.reflowState.ShouldReflowAllKids() ||
|
||||
@ -459,7 +460,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||
if (isPaginated && aPageBreakBeforeEnd && !*aPageBreakBeforeEnd) {
|
||||
nsTableRowFrame* nextRow = rowFrame->GetNextRow();
|
||||
if (nextRow) {
|
||||
*aPageBreakBeforeEnd = nsTableFrame::PageBreakAfter(*kidFrame, nextRow);
|
||||
*aPageBreakBeforeEnd = nsTableFrame::PageBreakAfter(kidFrame, nextRow);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1268,7 +1269,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
|
||||
prevRowFrame = rowFrame;
|
||||
// see if there is a page break after the row
|
||||
nsTableRowFrame* nextRow = rowFrame->GetNextRow();
|
||||
if (nextRow && nsTableFrame::PageBreakAfter(*rowFrame, nextRow)) {
|
||||
if (nextRow && nsTableFrame::PageBreakAfter(rowFrame, nextRow)) {
|
||||
PushChildren(aPresContext, nextRow, rowFrame);
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
break;
|
||||
@ -1569,7 +1570,25 @@ nsTableRowGroupFrame::GetType() const
|
||||
return nsGkAtoms::tableRowGroupFrame;
|
||||
}
|
||||
|
||||
/** find page break before the first row **/
|
||||
PRBool
|
||||
nsTableRowGroupFrame::HasInternalBreakBefore() const
|
||||
{
|
||||
nsIFrame* firstChild = mFrames.FirstChild();
|
||||
if (!firstChild)
|
||||
return PR_FALSE;
|
||||
return firstChild->GetStyleDisplay()->mBreakBefore;
|
||||
}
|
||||
|
||||
/** find page break after the last row **/
|
||||
PRBool
|
||||
nsTableRowGroupFrame::HasInternalBreakAfter() const
|
||||
{
|
||||
nsIFrame* lastChild = mFrames.LastChild();
|
||||
if (!lastChild)
|
||||
return PR_FALSE;
|
||||
return lastChild->GetStyleDisplay()->mBreakAfter;
|
||||
}
|
||||
/* ----- global methods ----- */
|
||||
|
||||
nsIFrame*
|
||||
|
@ -436,6 +436,8 @@ public:
|
||||
void SetRepeatable(PRBool aRepeatable);
|
||||
PRBool HasStyleHeight() const;
|
||||
void SetHasStyleHeight(PRBool aValue);
|
||||
PRBool HasInternalBreakBefore() const;
|
||||
PRBool HasInternalBreakAfter() const;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user