From 49e0a9f4cbd8d5e8a60bc6e7e9859280b179e618 Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Tue, 28 May 2002 22:50:43 +0000 Subject: [PATCH] bug 145305 - split floaters during printing. sr=attinasi, r=alexsavulov. git-svn-id: svn://10.0.0.236/trunk@122236 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsCSSFrameConstructor.cpp | 47 ++- mozilla/layout/base/public/nsIFrame.h | 13 + .../layout/forms/nsComboboxControlFrame.cpp | 2 + mozilla/layout/forms/nsFieldSetFrame.cpp | 1 + mozilla/layout/forms/nsFileControlFrame.cpp | 1 + mozilla/layout/forms/nsFormControlFrame.cpp | 1 + .../layout/forms/nsGfxButtonControlFrame.cpp | 1 + .../forms/nsGfxCheckboxControlFrame.cpp | 1 + .../layout/forms/nsGfxRadioControlFrame.cpp | 1 + .../layout/forms/nsHTMLButtonControlFrame.cpp | 1 + mozilla/layout/forms/nsIsIndexFrame.cpp | 7 +- mozilla/layout/forms/nsListControlFrame.cpp | 1 + mozilla/layout/generic/nsBRFrame.cpp | 2 + mozilla/layout/generic/nsBlockFrame.cpp | 275 ++++++++++++++---- mozilla/layout/generic/nsBlockFrame.h | 28 +- .../layout/generic/nsBlockReflowContext.cpp | 5 +- mozilla/layout/generic/nsBlockReflowState.cpp | 56 +++- mozilla/layout/generic/nsBlockReflowState.h | 19 +- mozilla/layout/generic/nsBulletFrame.cpp | 1 + mozilla/layout/generic/nsFirstLetterFrame.cpp | 1 + mozilla/layout/generic/nsFrame.cpp | 3 +- mozilla/layout/generic/nsFrameFrame.cpp | 1 + mozilla/layout/generic/nsFrameSetFrame.cpp | 2 + mozilla/layout/generic/nsGfxScrollFrame.cpp | 1 + .../layout/generic/nsHTMLContainerFrame.cpp | 6 +- mozilla/layout/generic/nsHTMLContainerFrame.h | 10 +- mozilla/layout/generic/nsHTMLFrame.cpp | 1 + mozilla/layout/generic/nsIFrame.h | 13 + mozilla/layout/generic/nsImageFrame.cpp | 1 + mozilla/layout/generic/nsInlineFrame.cpp | 5 +- mozilla/layout/generic/nsLeafFrame.cpp | 1 + mozilla/layout/generic/nsLineLayout.cpp | 10 +- mozilla/layout/generic/nsLineLayout.h | 8 +- mozilla/layout/generic/nsObjectFrame.cpp | 1 + mozilla/layout/generic/nsPageContentFrame.cpp | 1 + mozilla/layout/generic/nsPageFrame.cpp | 1 + mozilla/layout/generic/nsPlaceholderFrame.cpp | 1 + mozilla/layout/generic/nsPlaceholderFrame.h | 4 +- .../layout/generic/nsSimplePageSequence.cpp | 1 + mozilla/layout/generic/nsSpacerFrame.cpp | 1 + mozilla/layout/generic/nsTextFrame.cpp | 3 +- mozilla/layout/generic/nsViewportFrame.cpp | 1 + mozilla/layout/html/base/src/nsBRFrame.cpp | 2 + mozilla/layout/html/base/src/nsBlockFrame.cpp | 275 ++++++++++++++---- mozilla/layout/html/base/src/nsBlockFrame.h | 28 +- .../html/base/src/nsBlockReflowContext.cpp | 5 +- .../html/base/src/nsBlockReflowState.cpp | 56 +++- .../layout/html/base/src/nsBlockReflowState.h | 19 +- .../layout/html/base/src/nsBulletFrame.cpp | 1 + .../html/base/src/nsFirstLetterFrame.cpp | 1 + mozilla/layout/html/base/src/nsFrame.cpp | 3 +- .../layout/html/base/src/nsGfxScrollFrame.cpp | 1 + mozilla/layout/html/base/src/nsHRFrame.cpp | 1 + .../html/base/src/nsHTMLContainerFrame.cpp | 6 +- .../html/base/src/nsHTMLContainerFrame.h | 10 +- mozilla/layout/html/base/src/nsHTMLFrame.cpp | 1 + mozilla/layout/html/base/src/nsImageFrame.cpp | 1 + .../layout/html/base/src/nsInlineFrame.cpp | 5 +- mozilla/layout/html/base/src/nsLeafFrame.cpp | 1 + mozilla/layout/html/base/src/nsLineLayout.cpp | 10 +- mozilla/layout/html/base/src/nsLineLayout.h | 8 +- .../layout/html/base/src/nsObjectFrame.cpp | 1 + .../html/base/src/nsPageContentFrame.cpp | 1 + mozilla/layout/html/base/src/nsPageFrame.cpp | 1 + .../html/base/src/nsPlaceholderFrame.cpp | 1 + .../layout/html/base/src/nsPlaceholderFrame.h | 4 +- .../layout/html/base/src/nsScrollFrame.cpp | 1 + .../html/base/src/nsSimplePageSequence.cpp | 1 + .../layout/html/base/src/nsSpacerFrame.cpp | 1 + mozilla/layout/html/base/src/nsTextFrame.cpp | 3 +- .../layout/html/base/src/nsViewportFrame.cpp | 1 + mozilla/layout/html/document/src/html.css | 9 - .../layout/html/document/src/nsFrameFrame.cpp | 1 + .../html/document/src/nsFrameSetFrame.cpp | 2 + .../html/forms/src/nsComboboxControlFrame.cpp | 2 + .../layout/html/forms/src/nsFieldSetFrame.cpp | 1 + .../html/forms/src/nsFileControlFrame.cpp | 1 + .../html/forms/src/nsFormControlFrame.cpp | 1 + .../forms/src/nsGfxButtonControlFrame.cpp | 1 + .../forms/src/nsGfxCheckboxControlFrame.cpp | 1 + .../html/forms/src/nsGfxRadioControlFrame.cpp | 1 + .../html/forms/src/nsGfxTextControlFrame2.cpp | 1 + .../forms/src/nsHTMLButtonControlFrame.cpp | 1 + .../layout/html/forms/src/nsIsIndexFrame.cpp | 7 +- .../html/forms/src/nsListControlFrame.cpp | 1 + .../html/style/src/nsCSSFrameConstructor.cpp | 47 ++- .../html/table/src/nsTableCellFrame.cpp | 1 + .../layout/html/table/src/nsTableColFrame.cpp | 1 + .../html/table/src/nsTableColGroupFrame.cpp | 1 + .../layout/html/table/src/nsTableFrame.cpp | 5 +- .../html/table/src/nsTableOuterFrame.cpp | 1 + .../layout/html/table/src/nsTableRowFrame.cpp | 1 + .../html/table/src/nsTableRowGroupFrame.cpp | 1 + .../base/src/nsMathMLContainerFrame.cpp | 2 + .../base/src/nsMathMLForeignFrameWrapper.cpp | 1 + .../mathml/base/src/nsMathMLmactionFrame.cpp | 1 + .../mathml/base/src/nsMathMLmfencedFrame.cpp | 1 + .../mathml/base/src/nsMathMLmpaddedFrame.cpp | 1 + .../mathml/base/src/nsMathMLmrootFrame.cpp | 1 + .../mathml/base/src/nsMathMLmspaceFrame.cpp | 1 + .../mathml/base/src/nsMathMLmsqrtFrame.cpp | 1 + .../mathml/base/src/nsMathMLmtableFrame.cpp | 1 + mozilla/layout/style/html.css | 9 - .../svg/base/src/nsSVGOuterSVGFrame.cpp | 1 + mozilla/layout/tables/nsTableCellFrame.cpp | 1 + mozilla/layout/tables/nsTableColFrame.cpp | 1 + .../layout/tables/nsTableColGroupFrame.cpp | 1 + mozilla/layout/tables/nsTableFrame.cpp | 5 +- mozilla/layout/tables/nsTableOuterFrame.cpp | 1 + mozilla/layout/tables/nsTableRowFrame.cpp | 1 + .../layout/tables/nsTableRowGroupFrame.cpp | 1 + mozilla/layout/xul/base/src/nsBoxFrame.cpp | 9 +- .../xul/base/src/nsBoxToBlockAdaptor.cpp | 13 +- .../layout/xul/base/src/nsRootBoxFrame.cpp | 6 +- 114 files changed, 867 insertions(+), 269 deletions(-) diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index cbef1342416..84c1ba6c0e8 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -2726,7 +2726,7 @@ nsCSSFrameConstructor::ConstructTableRowFrame(nsIPresShell* aPresShel return rv; } - + nsresult nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell, nsIPresContext* aPresContext, @@ -3941,6 +3941,10 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, // The placeholder frame has a pointer back to the out-of-flow frame placeholderFrame->SetOutOfFlowFrame(aFrame); + nsFrameState frameState; + aFrame->GetFrameState(&frameState); + aFrame->SetFrameState(frameState | NS_FRAME_OUT_OF_FLOW); + // Add mapping from absolutely positioned frame to its placeholder frame aFrameManager->RegisterPlaceholderFrame(placeholderFrame); @@ -11560,22 +11564,22 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell, } NS_IMETHODIMP -nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, +nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, nsIPresContext* aPresContext, nsIFrame* aFrame, nsIFrame* aParentFrame, nsIFrame** aContinuingFrame) { - nsIAtom* frameType; - nsIContent* content; - nsIStyleContext* styleContext; - nsIFrame* newFrame = nsnull; - nsresult rv; + nsCOMPtr frameType; + nsCOMPtr content; + nsCOMPtr styleContext; + nsIFrame* newFrame = nsnull; + nsresult rv; // Use the frame type to determine what type of frame to create - aFrame->GetFrameType(&frameType); - aFrame->GetContent(&content); - aFrame->GetStyleContext(&styleContext); + aFrame->GetFrameType(getter_AddRefs(frameType)); + aFrame->GetContent(getter_AddRefs(content)); + aFrame->GetStyleContext(getter_AddRefs(styleContext)); if (nsLayoutAtoms::textFrame == frameType) { rv = NS_NewContinuingTextFrame(aPresShell, &newFrame); @@ -11727,16 +11731,29 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, if (NS_SUCCEEDED(rv)) { newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame); } - + } else if (nsLayoutAtoms::placeholderFrame == frameType) { + // create a continuing out of flow frame + nsIFrame* oofFrame = ((nsPlaceholderFrame*)aFrame)->GetOutOfFlowFrame(); + nsIFrame* oofContFrame; + CreateContinuingFrame(aPresShell, aPresContext, oofFrame, aParentFrame, &oofContFrame); + if (!oofContFrame) + return NS_ERROR_NULL_POINTER; + // create a continuing placeholder frame + nsCOMPtr frameManager; + aPresShell->GetFrameManager(getter_AddRefs(frameManager)); + NS_ASSERTION(frameManager, "no frame manager"); + CreatePlaceholderFrameFor(aPresShell, aPresContext, frameManager, content, + oofContFrame, styleContext, aParentFrame, &newFrame); + if (!newFrame) + return NS_ERROR_NULL_POINTER; + newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame); } else { NS_ASSERTION(PR_FALSE, "unexpected frame type"); rv = NS_ERROR_UNEXPECTED; } - *aContinuingFrame = newFrame; - NS_RELEASE(styleContext); - NS_IF_RELEASE(content); - NS_IF_RELEASE(frameType); + *aContinuingFrame = newFrame; + return rv; } diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index 5033239b969..210261fbbe6 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -347,6 +347,19 @@ typedef PRUint32 nsReflowStatus; ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \ NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE)) +// The frame (not counting a continuation) did not fit in the available height and +// wasn't at the top of a page. If it was at the top of a page, then it is not +// possible to reflow it again with more height, so we don't set it in that case. +#define NS_FRAME_TRUNCATED 0x0010 +#define NS_FRAME_IS_TRUNCATED(status) \ + (0 != ((status) & NS_FRAME_TRUNCATED)) +#define NS_FRAME_SET_TRUNCATION(status, aReflowState, aMetrics) \ + if (!aReflowState.mFlags.mIsTopOfPage && \ + aReflowState.availableHeight < aMetrics.height) \ + status |= NS_FRAME_TRUNCATED; \ + else \ + status &= ~NS_FRAME_TRUNCATED; + //---------------------------------------------------------------------- /** diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index 5172ee73766..daf7c31f544 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -1738,6 +1738,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mOverflowArea.y = 0; aDesiredSize.mOverflowArea.width = aDesiredSize.width; aDesiredSize.mOverflowArea.height = aDesiredSize.height; + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/forms/nsFieldSetFrame.cpp b/mozilla/layout/forms/nsFieldSetFrame.cpp index 8f1762723b7..cee73219e7d 100644 --- a/mozilla/layout/forms/nsFieldSetFrame.cpp +++ b/mozilla/layout/forms/nsFieldSetFrame.cpp @@ -597,6 +597,7 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext, printf(" and preferred size = %d\n", aDesiredSize.mMaximumWidth); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 6abf831c1e9..fe55e7987d6 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -428,6 +428,7 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index f24c84bc704..7303b3cbedb 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -567,6 +567,7 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp index 561200a046b..7ad9224a4d9 100644 --- a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp @@ -613,6 +613,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = aDesiredSize.height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp index 86a36c4a4ba..89dcf110a43 100644 --- a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -287,6 +287,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13) + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } #endif diff --git a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp index 89f0ae2c598..ab541bb0515 100644 --- a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp @@ -270,6 +270,7 @@ nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxRadioControlFrame", 12, 11) + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } #endif diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp index fc92bf64212..de537912a6e 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp @@ -686,6 +686,7 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/forms/nsIsIndexFrame.cpp b/mozilla/layout/forms/nsIsIndexFrame.cpp index dfd1539f272..a193371a7ce 100644 --- a/mozilla/layout/forms/nsIsIndexFrame.cpp +++ b/mozilla/layout/forms/nsIsIndexFrame.cpp @@ -327,9 +327,9 @@ nsIsIndexFrame::ScrollIntoView(nsIPresContext* aPresContext) NS_IMETHODIMP nsIsIndexFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { DO_GLOBAL_REFLOW_COUNT("nsIsIndexFrame", aReflowState.reason); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); @@ -337,6 +337,7 @@ NS_IMETHODIMP nsIsIndexFrame::Reflow(nsIPresContext* aPresContext, // The Areaframe takes care of all our reflow // (except for when style is used to change its size?) nsresult rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index e3e8d182c12..910a18069de 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -1316,6 +1316,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE"); NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE"); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsBRFrame.cpp b/mozilla/layout/generic/nsBRFrame.cpp index 57d2de128ec..0c0cfeec3ac 100644 --- a/mozilla/layout/generic/nsBRFrame.cpp +++ b/mozilla/layout/generic/nsBRFrame.cpp @@ -209,6 +209,8 @@ BRFrame::Reflow(nsIPresContext* aPresContext, else { aStatus = NS_FRAME_COMPLETE; } + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 983fcd50827..fe6b288bce8 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -947,6 +947,32 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, if (NS_FAILED(rv)) return rv; aStatus = state.mReflowStatus; + + // If there are incomplete floaters then they will go in the 1st line of the overflow lines. + if (state.mOverflowFloaters.NotEmpty()) { + aStatus = NS_FRAME_NOT_COMPLETE; + nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE); + if (overflowLines) { + // put the floaters at the beginning of the line + line_iterator firstLine = overflowLines->begin(); + nsIFrame* firstFrame = firstLine->mFirstChild; + firstLine->mFirstChild = state.mOverflowFloaters.FirstChild(); + PRInt32 numOverflowFloaters = state.mOverflowFloaters.GetLength(); + state.mOverflowFloaters.LastChild()->SetNextSibling(firstFrame); + firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowFloaters); + } + else { + // there aren't any overflow lines, so create a line, put the floaters in it, and then push. + nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(), + state.mOverflowFloaters.GetLength(), PR_FALSE); + if (!newLine) + return NS_ERROR_OUT_OF_MEMORY; + mLines.push_back(newLine); + nsLineList::iterator nextToLastLine = ----end_lines(); + PushLines(state, nextToLastLine); + } + } + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) { aStatus = NS_FRAME_COMPLETE; @@ -1080,6 +1106,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, } #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } @@ -3228,13 +3255,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // the available space. if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { PRBool madeContinuation; - rv = CreateContinuationFor(aState, aLine, frame, madeContinuation); - if (NS_FAILED(rv)) { + rv = CreateContinuationFor(aState, nsnull, frame, madeContinuation); + if (NS_FAILED(rv)) return rv; - } - // Push continuation to a new line, but only if we actually - // made one. + // Push continuation to a new line, but only if we actually made one. if (madeContinuation) { frame->GetNextSibling(&frame); nsLineBox* line = aState.NewLineBox(frame, 1, PR_TRUE); @@ -3242,11 +3267,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return NS_ERROR_OUT_OF_MEMORY; } mLines.after_insert(aLine, line); - - // Do not count the continuation child on the line it used - // to be on - aLine->SetChildCount(aLine->GetChildCount() - 1); - } + } // Advance to next line since some of the block fit. That way // only the following lines will be pushed. @@ -3378,9 +3399,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return rv; } -#define LINE_REFLOW_OK 0 -#define LINE_REFLOW_STOP 1 -#define LINE_REFLOW_REDO 2 +#define LINE_REFLOW_OK 0 +#define LINE_REFLOW_STOP 1 +#define LINE_REFLOW_REDO 2 +// a frame was complete, but truncated and not at the top of a page +#define LINE_REFLOW_TRUNCATED 3 nsresult nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, @@ -3469,6 +3492,38 @@ nsBlockFrame::DoReflowInlineFramesAuto(nsBlockReflowState& aState, return rv; } +// If at least one floater on the line was complete, not at the top of page, but was +// truncated, then restore the overflow floaters to what they were before and push the line. +// The floaters that will be removed from the list aren't yet known by the block's next in flow. +void +nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState, + line_iterator aLine, + nsIFrame* aLastPlaceholder, + PRBool& aKeepReflowGoing) +{ + nsIFrame* undoPlaceholder = nsnull; + if (aLastPlaceholder) { + aLastPlaceholder->GetNextSibling(&undoPlaceholder); + aLastPlaceholder->SetNextSibling(nsnull); + } + else { + undoPlaceholder = aState.mOverflowFloaters.FirstChild(); + aState.mOverflowFloaters.SetFrames(nsnull); + } + // remove the next in flows of the placeholders that need to be removed + for (nsIFrame* placeholder = undoPlaceholder; placeholder; ) { + nsSplittableFrame::RemoveFromFlow(placeholder); + nsIFrame* savePlaceholder = placeholder; + placeholder->GetNextSibling(&placeholder); + savePlaceholder->Destroy(aState.mPresContext); + } + line_iterator prevLine = aLine; + --prevLine; + PushLines(aState, prevLine); + aKeepReflowGoing = PR_FALSE; + aState.mReflowStatus = NS_FRAME_NOT_COMPLETE; +} + nsresult nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, nsLineLayout& aLineLayout, @@ -3529,6 +3584,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, aLineLayout.SetFirstLetterStyleOK(PR_TRUE); } + // keep track of the last overflow floater in case we need to undo and push the line + nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild(); + // Reflow the frames that are already on the line first nsresult rv = NS_OK; PRUint8 lineReflowStatus = LINE_REFLOW_OK; @@ -3557,6 +3615,11 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, aState.FreeLineBox(toremove); } --aLine; + + if (LINE_REFLOW_TRUNCATED == lineReflowStatus) { + // Push the line with the truncated floater + PushTruncatedPlaceholderLine(aState, aLine, lastPlaceholder, *aKeepReflowGoing); + } break; } frame->GetNextSibling(&frame); @@ -3608,7 +3671,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, // push the line and return now instead of later on after we are // past the floater. } - else { + else if (LINE_REFLOW_TRUNCATED != lineReflowStatus) { // If we are propagating out a break-before status then there is // no point in placing the line. if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) { @@ -3745,9 +3808,8 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // frame may already have a continuation. PRBool madeContinuation; rv = CreateContinuationFor(aState, aLine, aFrame, madeContinuation); - if (NS_FAILED(rv)) { + if (NS_FAILED(rv)) return rv; - } // Remember that the line has wrapped aLine->SetLineWrapped(PR_TRUE); } @@ -3773,23 +3835,26 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, else if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Frame is not-complete, no special breaking status + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. PRBool madeContinuation; - rv = CreateContinuationFor(aState, aLine, aFrame, madeContinuation); - if (NS_FAILED(rv)) { + rv = (nsLayoutAtoms::placeholderFrame == frameType) + ? SplitPlaceholder(aState, *aFrame) + : CreateContinuationFor(aState, aLine, aFrame, madeContinuation); + if (NS_FAILED(rv)) return rv; - } // Remember that the line has wrapped aLine->SetLineWrapped(PR_TRUE); - // If we are reflowing the first letter frame then don't split the - // line and don't stop the line reflow... - PRBool splitLine = !reflowingFirstLetter; + // If we are reflowing the first letter frame or a placeholder then + // don't split the line and don't stop the line reflow... + PRBool splitLine = !reflowingFirstLetter && + (nsLayoutAtoms::placeholderFrame != frameType); if (reflowingFirstLetter) { - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); if ((nsLayoutAtoms::inlineFrame == frameType.get()) || (nsLayoutAtoms::lineFrame == frameType.get())) { splitLine = PR_TRUE; @@ -3813,20 +3878,28 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } } } + else if (NS_FRAME_IS_TRUNCATED(frameReflowStatus)) { + // if the frame is a placeholder and was complete but truncated (and not at the top + // of page), the entire line will be pushed to give it another chance to not truncate. + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::placeholderFrame == frameType) { + *aLineReflowStatus = LINE_REFLOW_TRUNCATED; + } + } return NS_OK; } /** - * Create a continuation, if necessary, for aFrame. Place it on the - * same line that aFrame is on. Set aMadeNewFrame to PR_TRUE if a - * new frame is created. + * Create a continuation, if necessary, for aFrame. Place it in aLine + * if aLine is not null. Set aMadeNewFrame to PR_TRUE if a new frame is created. */ nsresult nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, - nsLineBox* aLine, - nsIFrame* aFrame, - PRBool& aMadeNewFrame) + nsLineBox* aLine, + nsIFrame* aFrame, + PRBool& aMadeNewFrame) { aMadeNewFrame = PR_FALSE; nsresult rv; @@ -3837,7 +3910,9 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, } if (nsnull != nextInFlow) { aMadeNewFrame = PR_TRUE; - aLine->SetChildCount(aLine->GetChildCount() + 1); + if (aLine) { + aLine->SetChildCount(aLine->GetChildCount() + 1); + } } #ifdef DEBUG VerifyLines(PR_FALSE); @@ -3845,6 +3920,25 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, return rv; } +nsresult +nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder) +{ + nsIFrame* nextInFlow; + nsresult rv = CreateNextInFlow(aState.mPresContext, this, &aPlaceholder, nextInFlow); + if (NS_FAILED(rv)) + return rv; + // put the sibling list back to what it was before the continuation was created + nsIFrame *contFrame, *next; + aPlaceholder.GetNextSibling(&contFrame); + contFrame->GetNextSibling(&next); + aPlaceholder.SetNextSibling(next); + contFrame->SetNextSibling(nsnull); + // add the placehoder to the overflow floaters + aState.mOverflowFloaters.AppendFrames(this, contFrame); + return NS_OK; +} + nsresult nsBlockFrame::SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, @@ -4164,10 +4258,19 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, // Any below current line floaters to place? if (aState.mBelowCurrentLineFloaters.NotEmpty()) { + // keep track of the last overflow floater in case we need to undo and push the line + nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild(); // Reflow the below-current-line floaters, then add them to the - // lines floater list. - aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters); - aLine->AppendFloaters(aState.mBelowCurrentLineFloaters); + // lines floater list if there aren't any truncated floaters. + if (aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters)) { + aLine->AppendFloaters(aState.mBelowCurrentLineFloaters); + } + else { + // At least one floater is truncated, so fix up any placeholders that got split and + // push the line. XXX It may be better to put the floater on the next line, but this + // is not common enough to justify the complexity. + PushTruncatedPlaceholderLine(aState, aLine, lastPlaceholder, *aKeepReflowGoing); + } } // When a line has floaters, factor them into the combined-area @@ -4825,10 +4928,56 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +void +nsBlockFrame::DoRemoveOutOfFlowFrame(nsIPresContext* aPresContext, + nsIFrame* aFrame) +{ + // First remove aFrame's next in flow + nsIFrame* nextInFlow; + aFrame->GetNextInFlow(&nextInFlow); + if (nextInFlow) { + nsBlockFrame::DoRemoveOutOfFlowFrame(aPresContext, nextInFlow); + } + // Now remove aFrame + const nsStyleDisplay* display = nsnull; + aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); + NS_ASSERTION(display, "program error"); + nsIFrame* parent; + aFrame->GetParent(&parent); +#ifdef DEBUG + NS_ASSERTION(parent, "program error"); + nsCOMPtr parentType; + parent->GetFrameType(getter_AddRefs(parentType)); + NS_ASSERTION((nsLayoutAtoms::blockFrame == parentType) || + (nsLayoutAtoms::areaFrame == parentType), "program error"); +#endif + nsBlockFrame* block = (nsBlockFrame*)parent; + // Remove aFrame from the appropriate list. + if (display->IsAbsolutelyPositioned()) { + nsCOMPtr presShell; + aPresContext->GetShell(getter_AddRefs(presShell)); + block->mAbsoluteContainer.RemoveFrame(block, aPresContext, *presShell, + nsLayoutAtoms::absoluteList, aFrame); + } + else { + block->mFloaters.RemoveFrame(aFrame); + } + // Destroy aFrame + nsSplittableFrame::RemoveFromFlow(aFrame); + aFrame->Destroy(aPresContext); +} + nsresult nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext, nsIFrame* aDeletedFrame) { + nsFrameState state; + aDeletedFrame->GetFrameState(&state); + if (state & NS_FRAME_OUT_OF_FLOW) { + DoRemoveOutOfFlowFrame(aPresContext, aDeletedFrame); + return NS_OK; + } + nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); @@ -5001,9 +5150,14 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext, void nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aChild) + nsIFrame* aChild) { - NS_PRECONDITION(IsChild(aPresContext, aChild), "bad geometric parent"); +#ifdef DEBUG + nsFrameState childState; + aChild->GetFrameState(&childState); + NS_PRECONDITION((childState & NS_FRAME_OUT_OF_FLOW) || IsChild(aPresContext, aChild), + "bad geometric parent"); +#endif nsIFrame* nextInFlow; aChild->GetNextInFlow(&nextInFlow); NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow"); @@ -5030,12 +5184,23 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsresult nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsRect& aCombinedRectResult, - nsMargin& aMarginResult, - nsMargin& aComputedOffsetsResult) + nsRect& aCombinedRectResult, + nsMargin& aMarginResult, + nsMargin& aComputedOffsetsResult, + nsReflowStatus& aReflowStatus) { + // Delete the placeholder's next in flows, if any + nsIFrame* nextInFlow; + aPlaceholder->GetNextInFlow(&nextInFlow); + if (nextInFlow) { + nsHTMLContainerFrame* parent; + aPlaceholder->GetParent((nsIFrame**)&parent); + NS_ASSERTION(parent, "no parent"); + parent->DeleteChildsNextInFlow(aState.mPresContext, aPlaceholder); + } // Reflow the floater. nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame(); + aReflowStatus = NS_FRAME_COMPLETE; #ifdef NOISY_FLOATER printf("Reflow Floater %p in parent %p, availSpace(%d,%d,%d,%d)\n", @@ -5048,19 +5213,29 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Compute the available width. By default, assume the width of the // containing block. nscoord availWidth; - if(aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)){ + if (aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)) { availWidth = NS_UNCONSTRAINEDSIZE; - }else{ + } + else { const nsStyleDisplay* floaterDisplay; floater->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)floaterDisplay); nsCompatibility mode; aState.mPresContext->GetCompatibilityMode(&mode); - if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || - eCompatibility_NavQuirks != mode ) { + nsIFrame* prevInFlow; + floater->GetPrevInFlow(&prevInFlow); + // if the floater is continued, constrain its width to the prev-in-flow's width + if (prevInFlow) { + nsRect rect; + prevInFlow->GetRect(rect); + availWidth = rect.width; + } + else if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { availWidth = aState.mContentArea.width; - }else{ + } + else { // give tables only the available space // if they can shrink we may not be constrained to place // them in the next line @@ -5076,6 +5251,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, availWidth -= availWidth % twp; } } + nscoord availHeight = (NS_UNCONSTRAINEDSIZE == aState.mAvailSpaceRect.height) + ? NS_UNCONSTRAINEDSIZE + : PR_MAX(0, aState.mContentArea.height - aState.mY); // If the floater's width is automatic, we can't let the floater's // width shrink below its maxElementSize. @@ -5091,7 +5269,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsRect availSpace(aState.BorderPadding().left, aState.BorderPadding().top, - availWidth, NS_UNCONSTRAINEDSIZE); + availWidth, availHeight); // Setup a block reflow state to reflow the floater. nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState, @@ -5101,11 +5279,10 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Reflow the floater PRBool isAdjacentWithTop = aState.IsAdjacentWithTop(); - nsReflowStatus frameReflowStatus; nsCollapsingMargin margin; nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, margin, isAdjacentWithTop, - aComputedOffsetsResult, frameReflowStatus); + aComputedOffsetsResult, aReflowStatus); if (NS_SUCCEEDED(rv) && isAutoWidth) { nscoord maxElementWidth = brc.GetMaxElementSize().width; if (maxElementWidth > availSpace.width) { @@ -5116,7 +5293,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsCollapsingMargin marginMES; rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, marginMES, isAdjacentWithTop, - aComputedOffsetsResult, frameReflowStatus); + aComputedOffsetsResult, aReflowStatus); } } @@ -5950,7 +6127,7 @@ nsBlockFrame::IsChild(nsIPresContext* aPresContext, nsIFrame* aFrame) return PR_TRUE; } nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE); - if (InLineList(*overflowLines, aFrame) && InSiblingList(*overflowLines, aFrame)) { + if (overflowLines && InLineList(*overflowLines, aFrame) && InSiblingList(*overflowLines, aFrame)) { return PR_TRUE; } return PR_FALSE; diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index 68daff1f07c..411d5e0397e 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -270,6 +270,9 @@ protected: nsresult DoRemoveFrame(nsIPresContext* aPresContext, nsIFrame* aDeletedFrame); + // Remove a floater, abs, rel positioned frame from the appropriate block's list + static void DoRemoveOutOfFlowFrame(nsIPresContext* aPresContext, + nsIFrame* aFrame); /** set up the conditions necessary for an initial reflow */ nsresult PrepareInitialReflow(nsBlockReflowState& aState); @@ -403,17 +406,30 @@ protected: nsresult ReflowFloater(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsRect& aCombinedRectResult, - nsMargin& aMarginResult, - nsMargin& aComputedOffsetsResult); + nsRect& aCombinedRectResult, + nsMargin& aMarginResult, + nsMargin& aComputedOffsetsResult, + nsReflowStatus& aReflowStatus); //---------------------------------------- // Methods for pushing/pulling lines/frames virtual nsresult CreateContinuationFor(nsBlockReflowState& aState, - nsLineBox* aLine, - nsIFrame* aFrame, - PRBool& aMadeNewFrame); + nsLineBox* aLine, + nsIFrame* aFrame, + PRBool& aMadeNewFrame); + + // Push aLine which contains a positioned element that was truncated. Clean up any + // placeholders on the same line that were continued. Set aKeepReflowGoing to false. + void PushTruncatedPlaceholderLine(nsBlockReflowState& aState, + line_iterator aLine, + nsIFrame* aLastPlaceholder, + PRBool& aKeepReflowGoing); + + // Create a contination for aPlaceholder and its out of flow frame and + // add it to the list of overflow floaters + nsresult SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder); nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, diff --git a/mozilla/layout/generic/nsBlockReflowContext.cpp b/mozilla/layout/generic/nsBlockReflowContext.cpp index 661bd1ea693..ffa0fcf55c9 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.cpp +++ b/mozilla/layout/generic/nsBlockReflowContext.cpp @@ -641,11 +641,12 @@ nsBlockReflowContext::DoReflowBlock(nsHTMLReflowState &aReflowState, aFrame->SetFrameState(state & ~NS_FRAME_FIRST_REFLOW); } - if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { + if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus) || + (state | NS_FRAME_OUT_OF_FLOW)) { // If frame is complete and has a next-in-flow, we need to delete // them now. Do not do this when a break-before is signaled because // the frame is going to get reflowed again (and may end up wanting - // a next-in-flow where it ends up). + // a next-in-flow where it ends up), unless it is an out of flow frame. if (NS_FRAME_IS_COMPLETE(aFrameReflowStatus)) { nsIFrame* kidNextInFlow; aFrame->GetNextInFlow(&kidNextInFlow); diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 96d06adb5c9..7a86e2d8a7a 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -123,6 +123,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState, } } mHaveRightFloaters = PR_FALSE; + mOverflowFloaters.SetFrames(nsnull); // Compute content area height. Unlike the width, if we have a // specified style height we ignore it since extra content is @@ -618,8 +619,9 @@ nsBlockReflowState::IsImpactedByFloater() const void -nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, - nsPlaceholderFrame* aPlaceholder) +nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, + nsPlaceholderFrame* aPlaceholder, + nsReflowStatus& aReflowStatus) { // Set the geometric parent of the floater nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame(); @@ -627,7 +629,7 @@ nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, // Then add the floater to the current line and place it when // appropriate - AddFloater(aLineLayout, aPlaceholder, PR_TRUE); + AddFloater(aLineLayout, aPlaceholder, PR_TRUE, aReflowStatus); } // This is called by the line layout's AddFloater method when a @@ -641,12 +643,14 @@ nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, // float as well unless it won't fit next to what we already have. // But nobody else implements it that way... void -nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, +nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, nsPlaceholderFrame* aPlaceholder, - PRBool aInitialReflow) + PRBool aInitialReflow, + nsReflowStatus& aReflowStatus) { NS_PRECONDITION(mBlock->end_lines() != mCurrentLine, "null ptr"); + aReflowStatus = NS_FRAME_COMPLETE; // Allocate a nsFloaterCache for the floater nsFloaterCache* fc = mFloaterCacheFreeList.Alloc(); fc->mPlaceholder = aPlaceholder; @@ -671,7 +675,7 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // And then place it PRBool isLeftFloater; - FlowAndPlaceFloater(fc, &isLeftFloater); + FlowAndPlaceFloater(fc, &isLeftFloater, aReflowStatus); // Pass on updated available space to the current inline reflow engine GetAvailableSpace(); @@ -825,8 +829,10 @@ nsBlockReflowState::CanPlaceFloater(const nsRect& aFloaterRect, void nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, - PRBool* aIsLeftFloater) + PRBool* aIsLeftFloater, + nsReflowStatus& aReflowStatus) { + aReflowStatus = NS_FRAME_COMPLETE; // Save away the Y coordinate before placing the floater. We will // restore mY at the end after placing the floater. This is // necessary because any adjustments to mY during the floater @@ -867,7 +873,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, // Reflow the floater mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, - aFloaterCache->mMargins, aFloaterCache->mOffsets); + aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus); // Get the floaters bounding box and margin information floater->GetRect(region); @@ -951,7 +957,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, GetAvailableSpace(); // reflow the floater again now since we have more space mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, - aFloaterCache->mMargins, aFloaterCache->mOffsets); + aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus); // Get the floaters bounding box and margin information floater->GetRect(region); // Adjust the floater size by its margin. That's the area that will @@ -973,14 +979,23 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, } else { isLeftFloater = PR_FALSE; - if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) - if(!keepFloaterOnSameLine) { + if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) { + nsIFrame* prevInFlow; + floater->GetPrevInFlow(&prevInFlow); + if (prevInFlow) { + nsRect rect; + prevInFlow->GetRect(rect); + region.x = rect.x; + } + else if (!keepFloaterOnSameLine) { region.x = mAvailSpaceRect.XMost() - region.width; - } else { + } + else { // this is the IE quirk (see few lines above) // the table is keept in the same line: don't let it overlap the previous floater region.x = mAvailSpaceRect.x; } + } else { okToAddRectRegion = PR_FALSE; region.x = mAvailSpaceRect.x; @@ -1102,7 +1117,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, /** * Place below-current-line floaters. */ -void +PRBool nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList) { nsFloaterCache* fc = aList.Head(); @@ -1119,10 +1134,23 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList) // Place the floater PRBool isLeftFloater; - FlowAndPlaceFloater(fc, &isLeftFloater); + nsReflowStatus reflowStatus; + FlowAndPlaceFloater(fc, &isLeftFloater, reflowStatus); + + if (NS_FRAME_IS_TRUNCATED(reflowStatus)) { + // return before processing all of the floaters, since the line will be pushed. + return PR_FALSE; + } + else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) { + // Create a continuation for the incomplete floater and its placeholder. + nsresult rv = mBlock->SplitPlaceholder(*this, *fc->mPlaceholder); + if (NS_FAILED(rv)) + return PR_FALSE; + } } fc = fc->Next(); } + return PR_TRUE; } void diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index caf95518cf4..c82f058c2e5 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -43,6 +43,7 @@ #include "nsBlockBandData.h" #include "nsLineBox.h" +#include "nsFrameList.h" class nsBlockFrame; @@ -67,19 +68,22 @@ public: void GetAvailableSpace(nscoord aY); - void InitFloater(nsLineLayout& aLineLayout, - nsPlaceholderFrame* aPlaceholderFrame); + void InitFloater(nsLineLayout& aLineLayout, + nsPlaceholderFrame* aPlaceholderFrame, + nsReflowStatus& aReflowStatus); - void AddFloater(nsLineLayout& aLineLayout, + void AddFloater(nsLineLayout& aLineLayout, nsPlaceholderFrame* aPlaceholderFrame, - PRBool aInitialReflow); + PRBool aInitialReflow, + nsReflowStatus& aReflowStatus); PRBool CanPlaceFloater(const nsRect& aFloaterRect, PRUint8 aFloats); void FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, - PRBool* aIsLeftFloater); + PRBool* aIsLeftFloater, + nsReflowStatus& aReflowStatus); - void PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters); + PRBool PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters); void ClearFloaters(nscoord aY, PRUint8 aBreakType); @@ -195,6 +199,9 @@ public: nsFloaterCacheFreeList mFloaterCacheFreeList; + // next-in-flows of incomplete floaters which get put into overflow lines + nsFrameList mOverflowFloaters; + // Previous child. This is used when pulling up a frame to update // the sibling list. nsIFrame* mPrevChild; diff --git a/mozilla/layout/generic/nsBulletFrame.cpp b/mozilla/layout/generic/nsBulletFrame.cpp index cc1b98a53be..018effd4f32 100644 --- a/mozilla/layout/generic/nsBulletFrame.cpp +++ b/mozilla/layout/generic/nsBulletFrame.cpp @@ -1501,6 +1501,7 @@ nsBulletFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->height = aMetrics.height; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsFirstLetterFrame.cpp b/mozilla/layout/generic/nsFirstLetterFrame.cpp index b7dea53b466..bc72bcc3e93 100644 --- a/mozilla/layout/generic/nsFirstLetterFrame.cpp +++ b/mozilla/layout/generic/nsFirstLetterFrame.cpp @@ -302,6 +302,7 @@ nsFirstLetterFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aReflowStatus, aReflowState, aMetrics); return rv; } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index c5f86f9dfaa..d519cf5fa43 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -1900,6 +1900,7 @@ nsFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = 0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } @@ -5098,7 +5099,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext, DR_state.PrettyUC(aMetrics.mMaximumWidth, width); printf("m=%s ", width); } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { printf("status=%d", aStatus); } printf("\n"); diff --git a/mozilla/layout/generic/nsFrameFrame.cpp b/mozilla/layout/generic/nsFrameFrame.cpp index 7714a736760..d7294b5fa55 100644 --- a/mozilla/layout/generic/nsFrameFrame.cpp +++ b/mozilla/layout/generic/nsFrameFrame.cpp @@ -571,6 +571,7 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext, ("exit nsHTMLFrameOuterFrame::Reflow: size=%d,%d status=%x", aDesiredSize.width, aDesiredSize.height, aStatus)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsFrameSetFrame.cpp b/mozilla/layout/generic/nsFrameSetFrame.cpp index 04f88aa38ae..d91a256e473 100644 --- a/mozilla/layout/generic/nsFrameSetFrame.cpp +++ b/mozilla/layout/generic/nsFrameSetFrame.cpp @@ -1400,6 +1400,8 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; mDrag.UnSet(); + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index 11810b3dad6..1b1bbf9073c 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -792,6 +792,7 @@ nsGfxScrollFrame::Reflow(nsIPresContext* aPresContext, mInner->mMaxElementSize.height = size->height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.cpp b/mozilla/layout/generic/nsHTMLContainerFrame.cpp index a8d9274a16b..5674a0ab0df 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/generic/nsHTMLContainerFrame.cpp @@ -142,9 +142,9 @@ nsHTMLContainerFrame::Paint(nsIPresContext* aPresContext, */ nsresult nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aOuterFrame, - nsIFrame* aFrame, - nsIFrame*& aNextInFlowResult) + nsIFrame* aOuterFrame, + nsIFrame* aFrame, + nsIFrame*& aNextInFlowResult) { aNextInFlowResult = nsnull; diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.h b/mozilla/layout/generic/nsHTMLContainerFrame.h index 277a27a6cc8..13b4e9d110d 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.h +++ b/mozilla/layout/generic/nsHTMLContainerFrame.h @@ -73,12 +73,14 @@ public: * already has a next-in-flow then this method does * nothing. Otherwise, a new continuation frame is created and * linked into the flow. In addition, the new frame becomes the - * next-sibling of aFrame. + * next-sibling of aFrame. If aPlaceholderResult is not null and + * aFrame is a float or positioned, then *aPlaceholderResult holds + * a placeholder. */ static nsresult CreateNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aOuterFrame, - nsIFrame* aFrame, - nsIFrame*& aNextInFlowResult); + nsIFrame* aOuterFrame, + nsIFrame* aFrame, + nsIFrame*& aNextInFlowResult); /** * Helper method to wrap views around frames. Used by containers diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp index b66181a93ad..87538fcc00d 100644 --- a/mozilla/layout/generic/nsHTMLFrame.cpp +++ b/mozilla/layout/generic/nsHTMLFrame.cpp @@ -620,6 +620,7 @@ CanvasFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index 5033239b969..210261fbbe6 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -347,6 +347,19 @@ typedef PRUint32 nsReflowStatus; ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \ NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE)) +// The frame (not counting a continuation) did not fit in the available height and +// wasn't at the top of a page. If it was at the top of a page, then it is not +// possible to reflow it again with more height, so we don't set it in that case. +#define NS_FRAME_TRUNCATED 0x0010 +#define NS_FRAME_IS_TRUNCATED(status) \ + (0 != ((status) & NS_FRAME_TRUNCATED)) +#define NS_FRAME_SET_TRUNCATION(status, aReflowState, aMetrics) \ + if (!aReflowState.mFlags.mIsTopOfPage && \ + aReflowState.availableHeight < aMetrics.height) \ + status |= NS_FRAME_TRUNCATED; \ + else \ + status &= ~NS_FRAME_TRUNCATED; + //---------------------------------------------------------------------- /** diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index 4b99c0858ca..4a5c6a4b90c 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -986,6 +986,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsImageFrame::Reflow: size=%d,%d", aMetrics.width, aMetrics.height)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index c4b5fffca99..ea49a4fdab9 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -433,6 +433,7 @@ nsInlineFrame::Reflow(nsIPresContext* aPresContext, // Note: the line layout code will properly compute our // NS_FRAME_OUTSIDE_CHILDREN state for us. + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } @@ -522,7 +523,7 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext, done = PR_TRUE; break; } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (!reflowingFirstLetter || NS_INLINE_IS_BREAK(aStatus)) { done = PR_TRUE; break; @@ -552,7 +553,7 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext, done = PR_TRUE; break; } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (!reflowingFirstLetter || NS_INLINE_IS_BREAK(aStatus)) { done = PR_TRUE; break; diff --git a/mozilla/layout/generic/nsLeafFrame.cpp b/mozilla/layout/generic/nsLeafFrame.cpp index 649736224a8..636bf4cc979 100644 --- a/mozilla/layout/generic/nsLeafFrame.cpp +++ b/mozilla/layout/generic/nsLeafFrame.cpp @@ -115,6 +115,7 @@ nsLeafFrame::Reflow(nsIPresContext* aPresContext, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsLeafFrame::Reflow: size=%d,%d", aMetrics.width, aMetrics.height)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index d1e0165d63b..ffc3675ba54 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -1097,6 +1097,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, } #endif // IBMBIDI + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + rv = aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus); if (NS_FAILED(rv)) { NS_WARNING( "Reflow of frame failed in nsLineLayout" ); @@ -1109,9 +1112,6 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, } #endif // IBMBIDI - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); - // SEC: added this next block for bug 45152 // text frames don't know how to invalidate themselves on initial reflow. Do it for them here. // This only shows up in textareas, so do a quick check to see if we're inside one @@ -1168,10 +1168,10 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, outOfFlowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); if (!display->IsAbsolutelyPositioned()) { if (eReflowReason_Incremental == reason) { - InitFloater((nsPlaceholderFrame*)aFrame); + InitFloater((nsPlaceholderFrame*)aFrame, aReflowStatus); } else { - AddFloater((nsPlaceholderFrame*)aFrame); + AddFloater((nsPlaceholderFrame*)aFrame, aReflowStatus); } nsIAtom* oofft; outOfFlowFrame->GetFrameType(&oofft); diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index 62ebcefa0b9..24d0c624807 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -226,12 +226,12 @@ public: //---------------------------------------- // Inform the line-layout about the presence of a floating frame // XXX get rid of this: use get-frame-type? - void InitFloater(nsPlaceholderFrame* aFrame) { - mBlockRS->InitFloater(*this, aFrame); + void InitFloater(nsPlaceholderFrame* aFrame, nsReflowStatus& aReflowStatus) { + mBlockRS->InitFloater(*this, aFrame, aReflowStatus); } - void AddFloater(nsPlaceholderFrame* aFrame) { - mBlockRS->AddFloater(*this, aFrame, PR_FALSE); + void AddFloater(nsPlaceholderFrame* aFrame, nsReflowStatus& aReflowStatus) { + mBlockRS->AddFloater(*this, aFrame, PR_FALSE, aReflowStatus); } //---------------------------------------- diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index 1ccba8cf844..fe7e35f29e2 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -1142,6 +1142,7 @@ nsObjectFrame::Reflow(nsIPresContext* aPresContext, } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } diff --git a/mozilla/layout/generic/nsPageContentFrame.cpp b/mozilla/layout/generic/nsPageContentFrame.cpp index 63befac9f39..bc99a3b6084 100644 --- a/mozilla/layout/generic/nsPageContentFrame.cpp +++ b/mozilla/layout/generic/nsPageContentFrame.cpp @@ -127,6 +127,7 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index fda9e0267b4..e8d77983f53 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -268,6 +268,7 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, PRINT_DEBUG_MSG2("PageFrame::Reflow %p ", this); PRINT_DEBUG_MSG3("[%d,%d]\n", aReflowState.availableWidth, aReflowState.availableHeight); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsPlaceholderFrame.cpp b/mozilla/layout/generic/nsPlaceholderFrame.cpp index 12c7f5658fc..7f8d18d9c6f 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.cpp +++ b/mozilla/layout/generic/nsPlaceholderFrame.cpp @@ -75,6 +75,7 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsPlaceholderFrame.h b/mozilla/layout/generic/nsPlaceholderFrame.h index 57099b6e8fc..37ef364163b 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.h +++ b/mozilla/layout/generic/nsPlaceholderFrame.h @@ -37,7 +37,7 @@ #ifndef nsPlaceholderFrame_h___ #define nsPlaceholderFrame_h___ -#include "nsFrame.h" +#include "nsSplittableFrame.h" nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstancePtrResult); @@ -45,7 +45,7 @@ nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstanceP * Implementation of a frame that's used as a placeholder for a frame that * has been moved out of the flow */ -class nsPlaceholderFrame : public nsFrame { +class nsPlaceholderFrame : public nsSplittableFrame { public: /** * Create a new placeholder frame diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index d56c7c7bc2a..44194a0f634 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -551,6 +551,7 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/generic/nsSpacerFrame.cpp b/mozilla/layout/generic/nsSpacerFrame.cpp index 473f90b19fc..f6e3380e7d0 100644 --- a/mozilla/layout/generic/nsSpacerFrame.cpp +++ b/mozilla/layout/generic/nsSpacerFrame.cpp @@ -166,6 +166,7 @@ SpacerFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->height = aMetrics.height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 81ae5fc6a38..4e8c28b7ec3 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -5412,7 +5412,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext, // - we fit in the available space. We may be complete, but if we // return a larger desired width than is available we may get pushed // and our frame width won't get set - if ((NS_FRAME_COMPLETE == aStatus) && (aMetrics.width <= maxWidth)) { + if (NS_FRAME_IS_COMPLETE(aStatus) && (aMetrics.width <= maxWidth)) { mState |= TEXT_OPTIMIZE_RESIZE; mRect.width = aMetrics.width; } @@ -5450,6 +5450,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext, aMetrics.width, aMetrics.height, aMetrics.ascent, aMetrics.descent, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/generic/nsViewportFrame.cpp b/mozilla/layout/generic/nsViewportFrame.cpp index db706b84291..4b52a821c92 100644 --- a/mozilla/layout/generic/nsViewportFrame.cpp +++ b/mozilla/layout/generic/nsViewportFrame.cpp @@ -618,6 +618,7 @@ ViewportFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsBRFrame.cpp b/mozilla/layout/html/base/src/nsBRFrame.cpp index 57d2de128ec..0c0cfeec3ac 100644 --- a/mozilla/layout/html/base/src/nsBRFrame.cpp +++ b/mozilla/layout/html/base/src/nsBRFrame.cpp @@ -209,6 +209,8 @@ BRFrame::Reflow(nsIPresContext* aPresContext, else { aStatus = NS_FRAME_COMPLETE; } + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 983fcd50827..fe6b288bce8 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -947,6 +947,32 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, if (NS_FAILED(rv)) return rv; aStatus = state.mReflowStatus; + + // If there are incomplete floaters then they will go in the 1st line of the overflow lines. + if (state.mOverflowFloaters.NotEmpty()) { + aStatus = NS_FRAME_NOT_COMPLETE; + nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE); + if (overflowLines) { + // put the floaters at the beginning of the line + line_iterator firstLine = overflowLines->begin(); + nsIFrame* firstFrame = firstLine->mFirstChild; + firstLine->mFirstChild = state.mOverflowFloaters.FirstChild(); + PRInt32 numOverflowFloaters = state.mOverflowFloaters.GetLength(); + state.mOverflowFloaters.LastChild()->SetNextSibling(firstFrame); + firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowFloaters); + } + else { + // there aren't any overflow lines, so create a line, put the floaters in it, and then push. + nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(), + state.mOverflowFloaters.GetLength(), PR_FALSE); + if (!newLine) + return NS_ERROR_OUT_OF_MEMORY; + mLines.push_back(newLine); + nsLineList::iterator nextToLastLine = ----end_lines(); + PushLines(state, nextToLastLine); + } + } + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) { aStatus = NS_FRAME_COMPLETE; @@ -1080,6 +1106,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, } #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } @@ -3228,13 +3255,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // the available space. if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { PRBool madeContinuation; - rv = CreateContinuationFor(aState, aLine, frame, madeContinuation); - if (NS_FAILED(rv)) { + rv = CreateContinuationFor(aState, nsnull, frame, madeContinuation); + if (NS_FAILED(rv)) return rv; - } - // Push continuation to a new line, but only if we actually - // made one. + // Push continuation to a new line, but only if we actually made one. if (madeContinuation) { frame->GetNextSibling(&frame); nsLineBox* line = aState.NewLineBox(frame, 1, PR_TRUE); @@ -3242,11 +3267,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return NS_ERROR_OUT_OF_MEMORY; } mLines.after_insert(aLine, line); - - // Do not count the continuation child on the line it used - // to be on - aLine->SetChildCount(aLine->GetChildCount() - 1); - } + } // Advance to next line since some of the block fit. That way // only the following lines will be pushed. @@ -3378,9 +3399,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return rv; } -#define LINE_REFLOW_OK 0 -#define LINE_REFLOW_STOP 1 -#define LINE_REFLOW_REDO 2 +#define LINE_REFLOW_OK 0 +#define LINE_REFLOW_STOP 1 +#define LINE_REFLOW_REDO 2 +// a frame was complete, but truncated and not at the top of a page +#define LINE_REFLOW_TRUNCATED 3 nsresult nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, @@ -3469,6 +3492,38 @@ nsBlockFrame::DoReflowInlineFramesAuto(nsBlockReflowState& aState, return rv; } +// If at least one floater on the line was complete, not at the top of page, but was +// truncated, then restore the overflow floaters to what they were before and push the line. +// The floaters that will be removed from the list aren't yet known by the block's next in flow. +void +nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState, + line_iterator aLine, + nsIFrame* aLastPlaceholder, + PRBool& aKeepReflowGoing) +{ + nsIFrame* undoPlaceholder = nsnull; + if (aLastPlaceholder) { + aLastPlaceholder->GetNextSibling(&undoPlaceholder); + aLastPlaceholder->SetNextSibling(nsnull); + } + else { + undoPlaceholder = aState.mOverflowFloaters.FirstChild(); + aState.mOverflowFloaters.SetFrames(nsnull); + } + // remove the next in flows of the placeholders that need to be removed + for (nsIFrame* placeholder = undoPlaceholder; placeholder; ) { + nsSplittableFrame::RemoveFromFlow(placeholder); + nsIFrame* savePlaceholder = placeholder; + placeholder->GetNextSibling(&placeholder); + savePlaceholder->Destroy(aState.mPresContext); + } + line_iterator prevLine = aLine; + --prevLine; + PushLines(aState, prevLine); + aKeepReflowGoing = PR_FALSE; + aState.mReflowStatus = NS_FRAME_NOT_COMPLETE; +} + nsresult nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, nsLineLayout& aLineLayout, @@ -3529,6 +3584,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, aLineLayout.SetFirstLetterStyleOK(PR_TRUE); } + // keep track of the last overflow floater in case we need to undo and push the line + nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild(); + // Reflow the frames that are already on the line first nsresult rv = NS_OK; PRUint8 lineReflowStatus = LINE_REFLOW_OK; @@ -3557,6 +3615,11 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, aState.FreeLineBox(toremove); } --aLine; + + if (LINE_REFLOW_TRUNCATED == lineReflowStatus) { + // Push the line with the truncated floater + PushTruncatedPlaceholderLine(aState, aLine, lastPlaceholder, *aKeepReflowGoing); + } break; } frame->GetNextSibling(&frame); @@ -3608,7 +3671,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, // push the line and return now instead of later on after we are // past the floater. } - else { + else if (LINE_REFLOW_TRUNCATED != lineReflowStatus) { // If we are propagating out a break-before status then there is // no point in placing the line. if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) { @@ -3745,9 +3808,8 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // frame may already have a continuation. PRBool madeContinuation; rv = CreateContinuationFor(aState, aLine, aFrame, madeContinuation); - if (NS_FAILED(rv)) { + if (NS_FAILED(rv)) return rv; - } // Remember that the line has wrapped aLine->SetLineWrapped(PR_TRUE); } @@ -3773,23 +3835,26 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, else if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Frame is not-complete, no special breaking status + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. PRBool madeContinuation; - rv = CreateContinuationFor(aState, aLine, aFrame, madeContinuation); - if (NS_FAILED(rv)) { + rv = (nsLayoutAtoms::placeholderFrame == frameType) + ? SplitPlaceholder(aState, *aFrame) + : CreateContinuationFor(aState, aLine, aFrame, madeContinuation); + if (NS_FAILED(rv)) return rv; - } // Remember that the line has wrapped aLine->SetLineWrapped(PR_TRUE); - // If we are reflowing the first letter frame then don't split the - // line and don't stop the line reflow... - PRBool splitLine = !reflowingFirstLetter; + // If we are reflowing the first letter frame or a placeholder then + // don't split the line and don't stop the line reflow... + PRBool splitLine = !reflowingFirstLetter && + (nsLayoutAtoms::placeholderFrame != frameType); if (reflowingFirstLetter) { - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); if ((nsLayoutAtoms::inlineFrame == frameType.get()) || (nsLayoutAtoms::lineFrame == frameType.get())) { splitLine = PR_TRUE; @@ -3813,20 +3878,28 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } } } + else if (NS_FRAME_IS_TRUNCATED(frameReflowStatus)) { + // if the frame is a placeholder and was complete but truncated (and not at the top + // of page), the entire line will be pushed to give it another chance to not truncate. + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::placeholderFrame == frameType) { + *aLineReflowStatus = LINE_REFLOW_TRUNCATED; + } + } return NS_OK; } /** - * Create a continuation, if necessary, for aFrame. Place it on the - * same line that aFrame is on. Set aMadeNewFrame to PR_TRUE if a - * new frame is created. + * Create a continuation, if necessary, for aFrame. Place it in aLine + * if aLine is not null. Set aMadeNewFrame to PR_TRUE if a new frame is created. */ nsresult nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, - nsLineBox* aLine, - nsIFrame* aFrame, - PRBool& aMadeNewFrame) + nsLineBox* aLine, + nsIFrame* aFrame, + PRBool& aMadeNewFrame) { aMadeNewFrame = PR_FALSE; nsresult rv; @@ -3837,7 +3910,9 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, } if (nsnull != nextInFlow) { aMadeNewFrame = PR_TRUE; - aLine->SetChildCount(aLine->GetChildCount() + 1); + if (aLine) { + aLine->SetChildCount(aLine->GetChildCount() + 1); + } } #ifdef DEBUG VerifyLines(PR_FALSE); @@ -3845,6 +3920,25 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState, return rv; } +nsresult +nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder) +{ + nsIFrame* nextInFlow; + nsresult rv = CreateNextInFlow(aState.mPresContext, this, &aPlaceholder, nextInFlow); + if (NS_FAILED(rv)) + return rv; + // put the sibling list back to what it was before the continuation was created + nsIFrame *contFrame, *next; + aPlaceholder.GetNextSibling(&contFrame); + contFrame->GetNextSibling(&next); + aPlaceholder.SetNextSibling(next); + contFrame->SetNextSibling(nsnull); + // add the placehoder to the overflow floaters + aState.mOverflowFloaters.AppendFrames(this, contFrame); + return NS_OK; +} + nsresult nsBlockFrame::SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, @@ -4164,10 +4258,19 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, // Any below current line floaters to place? if (aState.mBelowCurrentLineFloaters.NotEmpty()) { + // keep track of the last overflow floater in case we need to undo and push the line + nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild(); // Reflow the below-current-line floaters, then add them to the - // lines floater list. - aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters); - aLine->AppendFloaters(aState.mBelowCurrentLineFloaters); + // lines floater list if there aren't any truncated floaters. + if (aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters)) { + aLine->AppendFloaters(aState.mBelowCurrentLineFloaters); + } + else { + // At least one floater is truncated, so fix up any placeholders that got split and + // push the line. XXX It may be better to put the floater on the next line, but this + // is not common enough to justify the complexity. + PushTruncatedPlaceholderLine(aState, aLine, lastPlaceholder, *aKeepReflowGoing); + } } // When a line has floaters, factor them into the combined-area @@ -4825,10 +4928,56 @@ nsBlockFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +void +nsBlockFrame::DoRemoveOutOfFlowFrame(nsIPresContext* aPresContext, + nsIFrame* aFrame) +{ + // First remove aFrame's next in flow + nsIFrame* nextInFlow; + aFrame->GetNextInFlow(&nextInFlow); + if (nextInFlow) { + nsBlockFrame::DoRemoveOutOfFlowFrame(aPresContext, nextInFlow); + } + // Now remove aFrame + const nsStyleDisplay* display = nsnull; + aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); + NS_ASSERTION(display, "program error"); + nsIFrame* parent; + aFrame->GetParent(&parent); +#ifdef DEBUG + NS_ASSERTION(parent, "program error"); + nsCOMPtr parentType; + parent->GetFrameType(getter_AddRefs(parentType)); + NS_ASSERTION((nsLayoutAtoms::blockFrame == parentType) || + (nsLayoutAtoms::areaFrame == parentType), "program error"); +#endif + nsBlockFrame* block = (nsBlockFrame*)parent; + // Remove aFrame from the appropriate list. + if (display->IsAbsolutelyPositioned()) { + nsCOMPtr presShell; + aPresContext->GetShell(getter_AddRefs(presShell)); + block->mAbsoluteContainer.RemoveFrame(block, aPresContext, *presShell, + nsLayoutAtoms::absoluteList, aFrame); + } + else { + block->mFloaters.RemoveFrame(aFrame); + } + // Destroy aFrame + nsSplittableFrame::RemoveFromFlow(aFrame); + aFrame->Destroy(aPresContext); +} + nsresult nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext, nsIFrame* aDeletedFrame) { + nsFrameState state; + aDeletedFrame->GetFrameState(&state); + if (state & NS_FRAME_OUT_OF_FLOW) { + DoRemoveOutOfFlowFrame(aPresContext, aDeletedFrame); + return NS_OK; + } + nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); @@ -5001,9 +5150,14 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext, void nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aChild) + nsIFrame* aChild) { - NS_PRECONDITION(IsChild(aPresContext, aChild), "bad geometric parent"); +#ifdef DEBUG + nsFrameState childState; + aChild->GetFrameState(&childState); + NS_PRECONDITION((childState & NS_FRAME_OUT_OF_FLOW) || IsChild(aPresContext, aChild), + "bad geometric parent"); +#endif nsIFrame* nextInFlow; aChild->GetNextInFlow(&nextInFlow); NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow"); @@ -5030,12 +5184,23 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsresult nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsRect& aCombinedRectResult, - nsMargin& aMarginResult, - nsMargin& aComputedOffsetsResult) + nsRect& aCombinedRectResult, + nsMargin& aMarginResult, + nsMargin& aComputedOffsetsResult, + nsReflowStatus& aReflowStatus) { + // Delete the placeholder's next in flows, if any + nsIFrame* nextInFlow; + aPlaceholder->GetNextInFlow(&nextInFlow); + if (nextInFlow) { + nsHTMLContainerFrame* parent; + aPlaceholder->GetParent((nsIFrame**)&parent); + NS_ASSERTION(parent, "no parent"); + parent->DeleteChildsNextInFlow(aState.mPresContext, aPlaceholder); + } // Reflow the floater. nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame(); + aReflowStatus = NS_FRAME_COMPLETE; #ifdef NOISY_FLOATER printf("Reflow Floater %p in parent %p, availSpace(%d,%d,%d,%d)\n", @@ -5048,19 +5213,29 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Compute the available width. By default, assume the width of the // containing block. nscoord availWidth; - if(aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)){ + if (aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)) { availWidth = NS_UNCONSTRAINEDSIZE; - }else{ + } + else { const nsStyleDisplay* floaterDisplay; floater->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)floaterDisplay); nsCompatibility mode; aState.mPresContext->GetCompatibilityMode(&mode); - if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || - eCompatibility_NavQuirks != mode ) { + nsIFrame* prevInFlow; + floater->GetPrevInFlow(&prevInFlow); + // if the floater is continued, constrain its width to the prev-in-flow's width + if (prevInFlow) { + nsRect rect; + prevInFlow->GetRect(rect); + availWidth = rect.width; + } + else if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { availWidth = aState.mContentArea.width; - }else{ + } + else { // give tables only the available space // if they can shrink we may not be constrained to place // them in the next line @@ -5076,6 +5251,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, availWidth -= availWidth % twp; } } + nscoord availHeight = (NS_UNCONSTRAINEDSIZE == aState.mAvailSpaceRect.height) + ? NS_UNCONSTRAINEDSIZE + : PR_MAX(0, aState.mContentArea.height - aState.mY); // If the floater's width is automatic, we can't let the floater's // width shrink below its maxElementSize. @@ -5091,7 +5269,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsRect availSpace(aState.BorderPadding().left, aState.BorderPadding().top, - availWidth, NS_UNCONSTRAINEDSIZE); + availWidth, availHeight); // Setup a block reflow state to reflow the floater. nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState, @@ -5101,11 +5279,10 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Reflow the floater PRBool isAdjacentWithTop = aState.IsAdjacentWithTop(); - nsReflowStatus frameReflowStatus; nsCollapsingMargin margin; nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, margin, isAdjacentWithTop, - aComputedOffsetsResult, frameReflowStatus); + aComputedOffsetsResult, aReflowStatus); if (NS_SUCCEEDED(rv) && isAutoWidth) { nscoord maxElementWidth = brc.GetMaxElementSize().width; if (maxElementWidth > availSpace.width) { @@ -5116,7 +5293,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsCollapsingMargin marginMES; rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, marginMES, isAdjacentWithTop, - aComputedOffsetsResult, frameReflowStatus); + aComputedOffsetsResult, aReflowStatus); } } @@ -5950,7 +6127,7 @@ nsBlockFrame::IsChild(nsIPresContext* aPresContext, nsIFrame* aFrame) return PR_TRUE; } nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE); - if (InLineList(*overflowLines, aFrame) && InSiblingList(*overflowLines, aFrame)) { + if (overflowLines && InLineList(*overflowLines, aFrame) && InSiblingList(*overflowLines, aFrame)) { return PR_TRUE; } return PR_FALSE; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.h b/mozilla/layout/html/base/src/nsBlockFrame.h index 68daff1f07c..411d5e0397e 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.h +++ b/mozilla/layout/html/base/src/nsBlockFrame.h @@ -270,6 +270,9 @@ protected: nsresult DoRemoveFrame(nsIPresContext* aPresContext, nsIFrame* aDeletedFrame); + // Remove a floater, abs, rel positioned frame from the appropriate block's list + static void DoRemoveOutOfFlowFrame(nsIPresContext* aPresContext, + nsIFrame* aFrame); /** set up the conditions necessary for an initial reflow */ nsresult PrepareInitialReflow(nsBlockReflowState& aState); @@ -403,17 +406,30 @@ protected: nsresult ReflowFloater(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsRect& aCombinedRectResult, - nsMargin& aMarginResult, - nsMargin& aComputedOffsetsResult); + nsRect& aCombinedRectResult, + nsMargin& aMarginResult, + nsMargin& aComputedOffsetsResult, + nsReflowStatus& aReflowStatus); //---------------------------------------- // Methods for pushing/pulling lines/frames virtual nsresult CreateContinuationFor(nsBlockReflowState& aState, - nsLineBox* aLine, - nsIFrame* aFrame, - PRBool& aMadeNewFrame); + nsLineBox* aLine, + nsIFrame* aFrame, + PRBool& aMadeNewFrame); + + // Push aLine which contains a positioned element that was truncated. Clean up any + // placeholders on the same line that were continued. Set aKeepReflowGoing to false. + void PushTruncatedPlaceholderLine(nsBlockReflowState& aState, + line_iterator aLine, + nsIFrame* aLastPlaceholder, + PRBool& aKeepReflowGoing); + + // Create a contination for aPlaceholder and its out of flow frame and + // add it to the list of overflow floaters + nsresult SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder); nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, diff --git a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp index 661bd1ea693..ffa0fcf55c9 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp @@ -641,11 +641,12 @@ nsBlockReflowContext::DoReflowBlock(nsHTMLReflowState &aReflowState, aFrame->SetFrameState(state & ~NS_FRAME_FIRST_REFLOW); } - if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { + if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus) || + (state | NS_FRAME_OUT_OF_FLOW)) { // If frame is complete and has a next-in-flow, we need to delete // them now. Do not do this when a break-before is signaled because // the frame is going to get reflowed again (and may end up wanting - // a next-in-flow where it ends up). + // a next-in-flow where it ends up), unless it is an out of flow frame. if (NS_FRAME_IS_COMPLETE(aFrameReflowStatus)) { nsIFrame* kidNextInFlow; aFrame->GetNextInFlow(&kidNextInFlow); diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 96d06adb5c9..7a86e2d8a7a 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -123,6 +123,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState, } } mHaveRightFloaters = PR_FALSE; + mOverflowFloaters.SetFrames(nsnull); // Compute content area height. Unlike the width, if we have a // specified style height we ignore it since extra content is @@ -618,8 +619,9 @@ nsBlockReflowState::IsImpactedByFloater() const void -nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, - nsPlaceholderFrame* aPlaceholder) +nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, + nsPlaceholderFrame* aPlaceholder, + nsReflowStatus& aReflowStatus) { // Set the geometric parent of the floater nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame(); @@ -627,7 +629,7 @@ nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, // Then add the floater to the current line and place it when // appropriate - AddFloater(aLineLayout, aPlaceholder, PR_TRUE); + AddFloater(aLineLayout, aPlaceholder, PR_TRUE, aReflowStatus); } // This is called by the line layout's AddFloater method when a @@ -641,12 +643,14 @@ nsBlockReflowState::InitFloater(nsLineLayout& aLineLayout, // float as well unless it won't fit next to what we already have. // But nobody else implements it that way... void -nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, +nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, nsPlaceholderFrame* aPlaceholder, - PRBool aInitialReflow) + PRBool aInitialReflow, + nsReflowStatus& aReflowStatus) { NS_PRECONDITION(mBlock->end_lines() != mCurrentLine, "null ptr"); + aReflowStatus = NS_FRAME_COMPLETE; // Allocate a nsFloaterCache for the floater nsFloaterCache* fc = mFloaterCacheFreeList.Alloc(); fc->mPlaceholder = aPlaceholder; @@ -671,7 +675,7 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // And then place it PRBool isLeftFloater; - FlowAndPlaceFloater(fc, &isLeftFloater); + FlowAndPlaceFloater(fc, &isLeftFloater, aReflowStatus); // Pass on updated available space to the current inline reflow engine GetAvailableSpace(); @@ -825,8 +829,10 @@ nsBlockReflowState::CanPlaceFloater(const nsRect& aFloaterRect, void nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, - PRBool* aIsLeftFloater) + PRBool* aIsLeftFloater, + nsReflowStatus& aReflowStatus) { + aReflowStatus = NS_FRAME_COMPLETE; // Save away the Y coordinate before placing the floater. We will // restore mY at the end after placing the floater. This is // necessary because any adjustments to mY during the floater @@ -867,7 +873,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, // Reflow the floater mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, - aFloaterCache->mMargins, aFloaterCache->mOffsets); + aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus); // Get the floaters bounding box and margin information floater->GetRect(region); @@ -951,7 +957,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, GetAvailableSpace(); // reflow the floater again now since we have more space mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, - aFloaterCache->mMargins, aFloaterCache->mOffsets); + aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus); // Get the floaters bounding box and margin information floater->GetRect(region); // Adjust the floater size by its margin. That's the area that will @@ -973,14 +979,23 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, } else { isLeftFloater = PR_FALSE; - if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) - if(!keepFloaterOnSameLine) { + if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) { + nsIFrame* prevInFlow; + floater->GetPrevInFlow(&prevInFlow); + if (prevInFlow) { + nsRect rect; + prevInFlow->GetRect(rect); + region.x = rect.x; + } + else if (!keepFloaterOnSameLine) { region.x = mAvailSpaceRect.XMost() - region.width; - } else { + } + else { // this is the IE quirk (see few lines above) // the table is keept in the same line: don't let it overlap the previous floater region.x = mAvailSpaceRect.x; } + } else { okToAddRectRegion = PR_FALSE; region.x = mAvailSpaceRect.x; @@ -1102,7 +1117,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, /** * Place below-current-line floaters. */ -void +PRBool nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList) { nsFloaterCache* fc = aList.Head(); @@ -1119,10 +1134,23 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList) // Place the floater PRBool isLeftFloater; - FlowAndPlaceFloater(fc, &isLeftFloater); + nsReflowStatus reflowStatus; + FlowAndPlaceFloater(fc, &isLeftFloater, reflowStatus); + + if (NS_FRAME_IS_TRUNCATED(reflowStatus)) { + // return before processing all of the floaters, since the line will be pushed. + return PR_FALSE; + } + else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) { + // Create a continuation for the incomplete floater and its placeholder. + nsresult rv = mBlock->SplitPlaceholder(*this, *fc->mPlaceholder); + if (NS_FAILED(rv)) + return PR_FALSE; + } } fc = fc->Next(); } + return PR_TRUE; } void diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index caf95518cf4..c82f058c2e5 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -43,6 +43,7 @@ #include "nsBlockBandData.h" #include "nsLineBox.h" +#include "nsFrameList.h" class nsBlockFrame; @@ -67,19 +68,22 @@ public: void GetAvailableSpace(nscoord aY); - void InitFloater(nsLineLayout& aLineLayout, - nsPlaceholderFrame* aPlaceholderFrame); + void InitFloater(nsLineLayout& aLineLayout, + nsPlaceholderFrame* aPlaceholderFrame, + nsReflowStatus& aReflowStatus); - void AddFloater(nsLineLayout& aLineLayout, + void AddFloater(nsLineLayout& aLineLayout, nsPlaceholderFrame* aPlaceholderFrame, - PRBool aInitialReflow); + PRBool aInitialReflow, + nsReflowStatus& aReflowStatus); PRBool CanPlaceFloater(const nsRect& aFloaterRect, PRUint8 aFloats); void FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, - PRBool* aIsLeftFloater); + PRBool* aIsLeftFloater, + nsReflowStatus& aReflowStatus); - void PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters); + PRBool PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters); void ClearFloaters(nscoord aY, PRUint8 aBreakType); @@ -195,6 +199,9 @@ public: nsFloaterCacheFreeList mFloaterCacheFreeList; + // next-in-flows of incomplete floaters which get put into overflow lines + nsFrameList mOverflowFloaters; + // Previous child. This is used when pulling up a frame to update // the sibling list. nsIFrame* mPrevChild; diff --git a/mozilla/layout/html/base/src/nsBulletFrame.cpp b/mozilla/layout/html/base/src/nsBulletFrame.cpp index cc1b98a53be..018effd4f32 100644 --- a/mozilla/layout/html/base/src/nsBulletFrame.cpp +++ b/mozilla/layout/html/base/src/nsBulletFrame.cpp @@ -1501,6 +1501,7 @@ nsBulletFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->height = aMetrics.height; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp b/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp index b7dea53b466..bc72bcc3e93 100644 --- a/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp +++ b/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp @@ -302,6 +302,7 @@ nsFirstLetterFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aReflowStatus, aReflowState, aMetrics); return rv; } diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index c5f86f9dfaa..d519cf5fa43 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -1900,6 +1900,7 @@ nsFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = 0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } @@ -5098,7 +5099,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext, DR_state.PrettyUC(aMetrics.mMaximumWidth, width); printf("m=%s ", width); } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { printf("status=%d", aStatus); } printf("\n"); diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp index 11810b3dad6..1b1bbf9073c 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp @@ -792,6 +792,7 @@ nsGfxScrollFrame::Reflow(nsIPresContext* aPresContext, mInner->mMaxElementSize.height = size->height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/base/src/nsHRFrame.cpp b/mozilla/layout/html/base/src/nsHRFrame.cpp index a0cb40a6859..6d704176e19 100644 --- a/mozilla/layout/html/base/src/nsHRFrame.cpp +++ b/mozilla/layout/html/base/src/nsHRFrame.cpp @@ -289,6 +289,7 @@ HRuleFrame::Reflow(nsIPresContext* aPresContext, } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp index a8d9274a16b..5674a0ab0df 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -142,9 +142,9 @@ nsHTMLContainerFrame::Paint(nsIPresContext* aPresContext, */ nsresult nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aOuterFrame, - nsIFrame* aFrame, - nsIFrame*& aNextInFlowResult) + nsIFrame* aOuterFrame, + nsIFrame* aFrame, + nsIFrame*& aNextInFlowResult) { aNextInFlowResult = nsnull; diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h index 277a27a6cc8..13b4e9d110d 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h @@ -73,12 +73,14 @@ public: * already has a next-in-flow then this method does * nothing. Otherwise, a new continuation frame is created and * linked into the flow. In addition, the new frame becomes the - * next-sibling of aFrame. + * next-sibling of aFrame. If aPlaceholderResult is not null and + * aFrame is a float or positioned, then *aPlaceholderResult holds + * a placeholder. */ static nsresult CreateNextInFlow(nsIPresContext* aPresContext, - nsIFrame* aOuterFrame, - nsIFrame* aFrame, - nsIFrame*& aNextInFlowResult); + nsIFrame* aOuterFrame, + nsIFrame* aFrame, + nsIFrame*& aNextInFlowResult); /** * Helper method to wrap views around frames. Used by containers diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp index b66181a93ad..87538fcc00d 100644 --- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp @@ -620,6 +620,7 @@ CanvasFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsImageFrame.cpp b/mozilla/layout/html/base/src/nsImageFrame.cpp index 4b99c0858ca..4a5c6a4b90c 100644 --- a/mozilla/layout/html/base/src/nsImageFrame.cpp +++ b/mozilla/layout/html/base/src/nsImageFrame.cpp @@ -986,6 +986,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsImageFrame::Reflow: size=%d,%d", aMetrics.width, aMetrics.height)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsInlineFrame.cpp b/mozilla/layout/html/base/src/nsInlineFrame.cpp index c4b5fffca99..ea49a4fdab9 100644 --- a/mozilla/layout/html/base/src/nsInlineFrame.cpp +++ b/mozilla/layout/html/base/src/nsInlineFrame.cpp @@ -433,6 +433,7 @@ nsInlineFrame::Reflow(nsIPresContext* aPresContext, // Note: the line layout code will properly compute our // NS_FRAME_OUTSIDE_CHILDREN state for us. + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } @@ -522,7 +523,7 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext, done = PR_TRUE; break; } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (!reflowingFirstLetter || NS_INLINE_IS_BREAK(aStatus)) { done = PR_TRUE; break; @@ -552,7 +553,7 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext, done = PR_TRUE; break; } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { if (!reflowingFirstLetter || NS_INLINE_IS_BREAK(aStatus)) { done = PR_TRUE; break; diff --git a/mozilla/layout/html/base/src/nsLeafFrame.cpp b/mozilla/layout/html/base/src/nsLeafFrame.cpp index 649736224a8..636bf4cc979 100644 --- a/mozilla/layout/html/base/src/nsLeafFrame.cpp +++ b/mozilla/layout/html/base/src/nsLeafFrame.cpp @@ -115,6 +115,7 @@ nsLeafFrame::Reflow(nsIPresContext* aPresContext, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsLeafFrame::Reflow: size=%d,%d", aMetrics.width, aMetrics.height)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index d1e0165d63b..ffc3675ba54 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -1097,6 +1097,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, } #endif // IBMBIDI + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + rv = aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus); if (NS_FAILED(rv)) { NS_WARNING( "Reflow of frame failed in nsLineLayout" ); @@ -1109,9 +1112,6 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, } #endif // IBMBIDI - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); - // SEC: added this next block for bug 45152 // text frames don't know how to invalidate themselves on initial reflow. Do it for them here. // This only shows up in textareas, so do a quick check to see if we're inside one @@ -1168,10 +1168,10 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, outOfFlowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); if (!display->IsAbsolutelyPositioned()) { if (eReflowReason_Incremental == reason) { - InitFloater((nsPlaceholderFrame*)aFrame); + InitFloater((nsPlaceholderFrame*)aFrame, aReflowStatus); } else { - AddFloater((nsPlaceholderFrame*)aFrame); + AddFloater((nsPlaceholderFrame*)aFrame, aReflowStatus); } nsIAtom* oofft; outOfFlowFrame->GetFrameType(&oofft); diff --git a/mozilla/layout/html/base/src/nsLineLayout.h b/mozilla/layout/html/base/src/nsLineLayout.h index 62ebcefa0b9..24d0c624807 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.h +++ b/mozilla/layout/html/base/src/nsLineLayout.h @@ -226,12 +226,12 @@ public: //---------------------------------------- // Inform the line-layout about the presence of a floating frame // XXX get rid of this: use get-frame-type? - void InitFloater(nsPlaceholderFrame* aFrame) { - mBlockRS->InitFloater(*this, aFrame); + void InitFloater(nsPlaceholderFrame* aFrame, nsReflowStatus& aReflowStatus) { + mBlockRS->InitFloater(*this, aFrame, aReflowStatus); } - void AddFloater(nsPlaceholderFrame* aFrame) { - mBlockRS->AddFloater(*this, aFrame, PR_FALSE); + void AddFloater(nsPlaceholderFrame* aFrame, nsReflowStatus& aReflowStatus) { + mBlockRS->AddFloater(*this, aFrame, PR_FALSE, aReflowStatus); } //---------------------------------------- diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index 1ccba8cf844..fe7e35f29e2 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -1142,6 +1142,7 @@ nsObjectFrame::Reflow(nsIPresContext* aPresContext, } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return rv; } diff --git a/mozilla/layout/html/base/src/nsPageContentFrame.cpp b/mozilla/layout/html/base/src/nsPageContentFrame.cpp index 63befac9f39..bc99a3b6084 100644 --- a/mozilla/layout/html/base/src/nsPageContentFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageContentFrame.cpp @@ -127,6 +127,7 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsPageFrame.cpp b/mozilla/layout/html/base/src/nsPageFrame.cpp index fda9e0267b4..e8d77983f53 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageFrame.cpp @@ -268,6 +268,7 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, PRINT_DEBUG_MSG2("PageFrame::Reflow %p ", this); PRINT_DEBUG_MSG3("[%d,%d]\n", aReflowState.availableWidth, aReflowState.availableHeight); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp index 12c7f5658fc..7f8d18d9c6f 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp @@ -75,6 +75,7 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.h b/mozilla/layout/html/base/src/nsPlaceholderFrame.h index 57099b6e8fc..37ef364163b 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.h +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.h @@ -37,7 +37,7 @@ #ifndef nsPlaceholderFrame_h___ #define nsPlaceholderFrame_h___ -#include "nsFrame.h" +#include "nsSplittableFrame.h" nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstancePtrResult); @@ -45,7 +45,7 @@ nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstanceP * Implementation of a frame that's used as a placeholder for a frame that * has been moved out of the flow */ -class nsPlaceholderFrame : public nsFrame { +class nsPlaceholderFrame : public nsSplittableFrame { public: /** * Create a new placeholder frame diff --git a/mozilla/layout/html/base/src/nsScrollFrame.cpp b/mozilla/layout/html/base/src/nsScrollFrame.cpp index a71a027f5ae..d5e4d94e3d8 100644 --- a/mozilla/layout/html/base/src/nsScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsScrollFrame.cpp @@ -986,6 +986,7 @@ nsScrollFrame::Reflow(nsIPresContext* aPresContext, NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS, ("exit nsScrollFrame::Reflow: status=%d width=%d height=%d", aStatus, aDesiredSize.width, aDesiredSize.height)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp index d56c7c7bc2a..44194a0f634 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp @@ -551,6 +551,7 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsSpacerFrame.cpp b/mozilla/layout/html/base/src/nsSpacerFrame.cpp index 473f90b19fc..f6e3380e7d0 100644 --- a/mozilla/layout/html/base/src/nsSpacerFrame.cpp +++ b/mozilla/layout/html/base/src/nsSpacerFrame.cpp @@ -166,6 +166,7 @@ SpacerFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->height = aMetrics.height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 81ae5fc6a38..4e8c28b7ec3 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -5412,7 +5412,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext, // - we fit in the available space. We may be complete, but if we // return a larger desired width than is available we may get pushed // and our frame width won't get set - if ((NS_FRAME_COMPLETE == aStatus) && (aMetrics.width <= maxWidth)) { + if (NS_FRAME_IS_COMPLETE(aStatus) && (aMetrics.width <= maxWidth)) { mState |= TEXT_OPTIMIZE_RESIZE; mRect.width = aMetrics.width; } @@ -5450,6 +5450,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext, aMetrics.width, aMetrics.height, aMetrics.ascent, aMetrics.descent, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsViewportFrame.cpp b/mozilla/layout/html/base/src/nsViewportFrame.cpp index db706b84291..4b52a821c92 100644 --- a/mozilla/layout/html/base/src/nsViewportFrame.cpp +++ b/mozilla/layout/html/base/src/nsViewportFrame.cpp @@ -618,6 +618,7 @@ ViewportFrame::Reflow(nsIPresContext* aPresContext, } NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/document/src/html.css b/mozilla/layout/html/document/src/html.css index ed405f688a6..b0f107db357 100644 --- a/mozilla/layout/html/document/src/html.css +++ b/mozilla/layout/html/document/src/html.css @@ -531,15 +531,6 @@ noembed, noscript, param { @media print { - /* undo floats on aligned tables since we cannot print them correctly: see bug 74738 and bug 85768 */ - table[align="left"] { - float: none; - } - - table[align="right"] { - float: none; - } - * { cursor: default !important; } diff --git a/mozilla/layout/html/document/src/nsFrameFrame.cpp b/mozilla/layout/html/document/src/nsFrameFrame.cpp index 7714a736760..d7294b5fa55 100644 --- a/mozilla/layout/html/document/src/nsFrameFrame.cpp +++ b/mozilla/layout/html/document/src/nsFrameFrame.cpp @@ -571,6 +571,7 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext, ("exit nsHTMLFrameOuterFrame::Reflow: size=%d,%d status=%x", aDesiredSize.width, aDesiredSize.height, aStatus)); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/document/src/nsFrameSetFrame.cpp b/mozilla/layout/html/document/src/nsFrameSetFrame.cpp index 04f88aa38ae..d91a256e473 100644 --- a/mozilla/layout/html/document/src/nsFrameSetFrame.cpp +++ b/mozilla/layout/html/document/src/nsFrameSetFrame.cpp @@ -1400,6 +1400,8 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; mDrag.UnSet(); + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index 5172ee73766..daf7c31f544 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -1738,6 +1738,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mOverflowArea.y = 0; aDesiredSize.mOverflowArea.width = aDesiredSize.width; aDesiredSize.mOverflowArea.height = aDesiredSize.height; + + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp index 8f1762723b7..cee73219e7d 100644 --- a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp @@ -597,6 +597,7 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext, printf(" and preferred size = %d\n", aDesiredSize.mMaximumWidth); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index 6abf831c1e9..fe55e7987d6 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -428,6 +428,7 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext* aPresContext, } } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index f24c84bc704..7303b3cbedb 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -567,6 +567,7 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp index 561200a046b..7ad9224a4d9 100644 --- a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp @@ -613,6 +613,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = aDesiredSize.height; } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp index 86a36c4a4ba..89dcf110a43 100644 --- a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp @@ -287,6 +287,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13) + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } #endif diff --git a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp index 89f0ae2c598..ab541bb0515 100644 --- a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp @@ -270,6 +270,7 @@ nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxRadioControlFrame", 12, 11) + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } #endif diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp index 30306836cce..38894b4e389 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp @@ -1650,6 +1650,7 @@ nsGfxTextControlFrame2::ReflowStandard(nsIPresContext* aPresContext, aDesiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right; aDesiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index fc92bf64212..de537912a6e 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -686,6 +686,7 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp index dfd1539f272..a193371a7ce 100644 --- a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp +++ b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp @@ -327,9 +327,9 @@ nsIsIndexFrame::ScrollIntoView(nsIPresContext* aPresContext) NS_IMETHODIMP nsIsIndexFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { DO_GLOBAL_REFLOW_COUNT("nsIsIndexFrame", aReflowState.reason); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); @@ -337,6 +337,7 @@ NS_IMETHODIMP nsIsIndexFrame::Reflow(nsIPresContext* aPresContext, // The Areaframe takes care of all our reflow // (except for when style is used to change its size?) nsresult rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index e3e8d182c12..910a18069de 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -1316,6 +1316,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE"); NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE"); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index cbef1342416..84c1ba6c0e8 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -2726,7 +2726,7 @@ nsCSSFrameConstructor::ConstructTableRowFrame(nsIPresShell* aPresShel return rv; } - + nsresult nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell, nsIPresContext* aPresContext, @@ -3941,6 +3941,10 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, // The placeholder frame has a pointer back to the out-of-flow frame placeholderFrame->SetOutOfFlowFrame(aFrame); + nsFrameState frameState; + aFrame->GetFrameState(&frameState); + aFrame->SetFrameState(frameState | NS_FRAME_OUT_OF_FLOW); + // Add mapping from absolutely positioned frame to its placeholder frame aFrameManager->RegisterPlaceholderFrame(placeholderFrame); @@ -11560,22 +11564,22 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell, } NS_IMETHODIMP -nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, +nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, nsIPresContext* aPresContext, nsIFrame* aFrame, nsIFrame* aParentFrame, nsIFrame** aContinuingFrame) { - nsIAtom* frameType; - nsIContent* content; - nsIStyleContext* styleContext; - nsIFrame* newFrame = nsnull; - nsresult rv; + nsCOMPtr frameType; + nsCOMPtr content; + nsCOMPtr styleContext; + nsIFrame* newFrame = nsnull; + nsresult rv; // Use the frame type to determine what type of frame to create - aFrame->GetFrameType(&frameType); - aFrame->GetContent(&content); - aFrame->GetStyleContext(&styleContext); + aFrame->GetFrameType(getter_AddRefs(frameType)); + aFrame->GetContent(getter_AddRefs(content)); + aFrame->GetStyleContext(getter_AddRefs(styleContext)); if (nsLayoutAtoms::textFrame == frameType) { rv = NS_NewContinuingTextFrame(aPresShell, &newFrame); @@ -11727,16 +11731,29 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell, if (NS_SUCCEEDED(rv)) { newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame); } - + } else if (nsLayoutAtoms::placeholderFrame == frameType) { + // create a continuing out of flow frame + nsIFrame* oofFrame = ((nsPlaceholderFrame*)aFrame)->GetOutOfFlowFrame(); + nsIFrame* oofContFrame; + CreateContinuingFrame(aPresShell, aPresContext, oofFrame, aParentFrame, &oofContFrame); + if (!oofContFrame) + return NS_ERROR_NULL_POINTER; + // create a continuing placeholder frame + nsCOMPtr frameManager; + aPresShell->GetFrameManager(getter_AddRefs(frameManager)); + NS_ASSERTION(frameManager, "no frame manager"); + CreatePlaceholderFrameFor(aPresShell, aPresContext, frameManager, content, + oofContFrame, styleContext, aParentFrame, &newFrame); + if (!newFrame) + return NS_ERROR_NULL_POINTER; + newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame); } else { NS_ASSERTION(PR_FALSE, "unexpected frame type"); rv = NS_ERROR_UNEXPECTED; } - *aContinuingFrame = newFrame; - NS_RELEASE(styleContext); - NS_IF_RELEASE(content); - NS_IF_RELEASE(frameType); + *aContinuingFrame = newFrame; + return rv; } diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index a3a2705bb59..4f7acf79a3a 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -1125,6 +1125,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, SetNeedPass2Reflow(PR_FALSE); } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp index ba8b5b36bc6..1ef4b05e871 100644 --- a/mozilla/layout/html/table/src/nsTableColFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp @@ -178,6 +178,7 @@ NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height=0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index 9e61106a271..74040ac055f 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -479,6 +479,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height=0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index df1d01224d9..4032ddfc460 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -2159,6 +2159,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -7197,7 +7198,7 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, PrettyUC(aMetrics->mMaximumWidth, width); printf("m=%s ", width); } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { printf("status=%d", aStatus); } printf("\n"); @@ -7303,7 +7304,7 @@ void DebugReflowPrint(nsReflowTimer& aTimer, PrettyUC(aTimer.mMaxWidth, avWidth); printf(" m=%s", avWidth); } - if (NS_FRAME_COMPLETE != aTimer.mStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aTimer.mStatus)) { printf(" status=%d", aTimer.mStatus); } printf(" cnt=%d", aTimer.mCount); diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index 70179dd014e..dab6c079d16 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -1687,6 +1687,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aOuterRS, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index c540ff51564..6f4165eb84f 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -1464,6 +1464,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 6f97020a5bc..c17d8167a79 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -1262,6 +1262,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index 3691049828d..f10860bd8ae 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -1150,6 +1150,7 @@ printf("\n"); NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->FinalizeReflow(aPresContext, *aReflowState.rendContext, aDesiredSize); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } @@ -1332,6 +1333,7 @@ printf("\n"); FinalizeReflow(aPresContext, *aReflowState.rendContext, aDesiredSize); aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.cpp b/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.cpp index 640a03abf13..76ada2e263e 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLForeignFrameWrapper.cpp @@ -92,5 +92,6 @@ nsMathMLForeignFrameWrapper::Reflow(nsIPresContext* aPresContext, mBoundingMetrics.rightBearing = aDesiredSize.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp index 6ec26a8baec..6ff8ea65ed1 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp @@ -345,6 +345,7 @@ nsMathMLmactionFrame::Reflow(nsIPresContext* aPresContext, mBoundingMetrics = aDesiredSize.mBoundingMetrics; FinalizeReflow(aPresContext, *aReflowState.rendContext, aDesiredSize); } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp index 27315b72a73..b75b43dd02a 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp @@ -477,6 +477,7 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext, mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent)); aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp index 27c68699eb9..7e7bd476a47 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp @@ -435,5 +435,6 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext, mReference.x = 0; mReference.y = aDesiredSize.ascent; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp index 97f3c43985d..e270f50bdfb 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp @@ -375,6 +375,7 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = aDesiredSize.height; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmspaceFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmspaceFrame.cpp index b3ed9ecc1d2..c2a9b4193d9 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmspaceFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmspaceFrame.cpp @@ -138,5 +138,6 @@ nsMathMLmspaceFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mBoundingMetrics = mBoundingMetrics; aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp index 09a1c08455c..8e2a695a2d9 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp @@ -298,6 +298,7 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext, } aDesiredSize.mBoundingMetrics = mBoundingMetrics; aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp index 4c86b9bf29d..7aa9445dc08 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp @@ -590,6 +590,7 @@ nsMathMLmtableOuterFrame::Reflow(nsIPresContext* aPresContext, mBoundingMetrics.rightBearing = aDesiredSize.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/style/html.css b/mozilla/layout/style/html.css index ed405f688a6..b0f107db357 100644 --- a/mozilla/layout/style/html.css +++ b/mozilla/layout/style/html.css @@ -531,15 +531,6 @@ noembed, noscript, param { @media print { - /* undo floats on aligned tables since we cannot print them correctly: see bug 74738 and bug 85768 */ - table[align="left"] { - float: none; - } - - table[align="right"] { - float: none; - } - * { cursor: default !important; } diff --git a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index d498781ed3b..b6d52c3922b 100644 --- a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -456,6 +456,7 @@ nsSVGOuterSVGFrame::Reflow(nsIPresContext* aPresContext, // XXX add in CSS borders ?? aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index a3a2705bb59..4f7acf79a3a 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -1125,6 +1125,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, SetNeedPass2Reflow(PR_FALSE); } + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp index ba8b5b36bc6..1ef4b05e871 100644 --- a/mozilla/layout/tables/nsTableColFrame.cpp +++ b/mozilla/layout/tables/nsTableColFrame.cpp @@ -178,6 +178,7 @@ NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height=0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index 9e61106a271..74040ac055f 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -479,6 +479,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height=0; } aStatus = NS_FRAME_COMPLETE; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index df1d01224d9..4032ddfc460 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -2159,6 +2159,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -7197,7 +7198,7 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, PrettyUC(aMetrics->mMaximumWidth, width); printf("m=%s ", width); } - if (NS_FRAME_COMPLETE != aStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { printf("status=%d", aStatus); } printf("\n"); @@ -7303,7 +7304,7 @@ void DebugReflowPrint(nsReflowTimer& aTimer, PrettyUC(aTimer.mMaxWidth, avWidth); printf(" m=%s", avWidth); } - if (NS_FRAME_COMPLETE != aTimer.mStatus) { + if (NS_FRAME_IS_NOT_COMPLETE(aTimer.mStatus)) { printf(" status=%d", aTimer.mStatus); } printf(" cnt=%d", aTimer.mCount); diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index 70179dd014e..dab6c079d16 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -1687,6 +1687,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aOuterRS, aDesiredSize); return rv; } diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index c540ff51564..6f4165eb84f 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -1464,6 +1464,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 6f97020a5bc..c17d8167a79 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -1262,6 +1262,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index 338c1081000..ee045f12184 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -888,10 +888,10 @@ nsBoxFrame::IsInitialReflowForPrintPreview(nsBoxLayoutState& aState, } NS_IMETHODIMP -nsBoxFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) +nsBoxFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { // If you make changes to this method, please keep nsLeafBoxFrame::Reflow // in sync, if the changes are applicable there. @@ -1063,6 +1063,7 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, } #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/xul/base/src/nsBoxToBlockAdaptor.cpp b/mozilla/layout/xul/base/src/nsBoxToBlockAdaptor.cpp index d8681a093e5..e17812e7881 100644 --- a/mozilla/layout/xul/base/src/nsBoxToBlockAdaptor.cpp +++ b/mozilla/layout/xul/base/src/nsBoxToBlockAdaptor.cpp @@ -687,15 +687,15 @@ PruneReflowPathFor(nsIFrame *aFrame, nsReflowPath *aReflowPath) nsresult nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState, - nsIPresContext* aPresContext, + nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, - nscoord aX, - nscoord aY, - nscoord aWidth, - nscoord aHeight, - PRBool aMoveFrame) + nscoord aX, + nscoord aY, + nscoord aWidth, + nscoord aHeight, + PRBool aMoveFrame) { DO_GLOBAL_REFLOW_COUNT("nsBoxToBlockAdaptor", aReflowState.reason); @@ -990,6 +990,7 @@ nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState, gIndent2--; #endif + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; } diff --git a/mozilla/layout/xul/base/src/nsRootBoxFrame.cpp b/mozilla/layout/xul/base/src/nsRootBoxFrame.cpp index d497b962f08..e26438cb964 100644 --- a/mozilla/layout/xul/base/src/nsRootBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsRootBoxFrame.cpp @@ -228,9 +228,9 @@ PRInt32 gReflows = 0; NS_IMETHODIMP nsRootBoxFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame", aReflowState.reason);