Bug 492627 - Remove Placeholder Continuations [Part III: Remove current float-splitting code.] r=roc

This commit is contained in:
fantasai 2009-08-31 11:25:35 -07:00
Родитель 8877548019
Коммит a56a409be0
7 изменённых файлов: 42 добавлений и 461 удалений

Просмотреть файл

@ -598,12 +598,6 @@ nsBlockFrame::IsFloatContainingBlock() const
return PR_TRUE;
}
static PRBool IsContinuationPlaceholder(nsIFrame* aFrame)
{
return aFrame->GetPrevInFlow() &&
nsGkAtoms::placeholderFrame == aFrame->GetType();
}
static void ReparentFrame(nsIFrame* aFrame, nsIFrame* aOldParent,
nsIFrame* aNewParent) {
NS_ASSERTION(aOldParent == aFrame->GetParent(),
@ -989,55 +983,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// If the block is complete put continued floats at the beginning
// of the first overflow line.
if (state.mOverflowPlaceholders.NotEmpty()) {
NS_ASSERTION(aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE,
"Somehow we failed to fit all content, even though we have unlimited space!");
state.mOverflowPlaceholders.SortByContentOrder();
PRInt32 numOverflowPlace = state.mOverflowPlaceholders.GetLength();
nsLineBox* newLine =
state.NewLineBox(state.mOverflowPlaceholders.FirstChild(),
numOverflowPlace, PR_FALSE);
if (newLine) {
nsLineList* overflowLines = GetOverflowLines();
if (overflowLines) {
// Need to put the overflow placeholders' floats into our
// overflow-out-of-flows list, since the overflow placeholders are
// going onto our overflow line list. Put them last, because that's
// where the placeholders are going.
nsFrameList floats;
nsIFrame* lastFloat = nsnull;
for (nsIFrame* f = state.mOverflowPlaceholders.FirstChild();
f; f = f->GetNextSibling()) {
NS_ASSERTION(IsContinuationPlaceholder(f),
"Overflow placeholders must be continuation placeholders");
nsIFrame* oof = nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
// oof is not currently in any child list
floats.InsertFrames(nsnull, lastFloat, oof);
lastFloat = oof;
}
// Put the new placeholders *last* in the overflow lines
// because they might have previnflows in the overflow lines.
nsIFrame* lastChild = overflowLines->back()->LastChild();
lastChild->SetNextSibling(state.mOverflowPlaceholders.FirstChild());
// Create a new line as the last line and put the
// placeholders there
overflowLines->push_back(newLine);
nsAutoOOFFrameList oofs(this);
oofs.mList.AppendFrames(nsnull, floats.FirstChild());
}
else {
mLines.push_back(newLine);
nsLineList::iterator nextToLastLine = ----end_lines();
PushLines(state, nextToLastLine);
}
state.mOverflowPlaceholders.Clear();
}
state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
if (NS_FRAME_IS_COMPLETE(state.mReflowStatus))
NS_FRAME_SET_OVERFLOW_INCOMPLETE(state.mReflowStatus);
}
NS_ASSERTION(state.mOverflowPlaceholders.IsEmpty(), "Where are these coming from? XXXfr");
if (!NS_FRAME_IS_FULLY_COMPLETE(state.mReflowStatus)) {
if (GetOverflowLines()) {
@ -2134,21 +2080,12 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
nsLineBox *toMove;
PRBool collectOverflowFloats;
if (nifLine != nextInFlow->end_lines()) {
if (HandleOverflowPlaceholdersOnPulledLine(aState, nifLine)) {
// go around again in case the line was deleted
continue;
}
toMove = nifLine;
nextInFlow->mLines.erase(nifLine);
collectOverflowFloats = PR_FALSE;
} else {
// Grab an overflow line if there are any
nsLineList* overflowLines = nextInFlow->GetOverflowLines();
if (overflowLines &&
HandleOverflowPlaceholdersOnPulledLine(aState, overflowLines->front())) {
// go around again in case the line was deleted
continue;
}
if (!overflowLines) {
aState.mNextInFlow =
static_cast<nsBlockFrame*>(nextInFlow->GetNextInFlow());
@ -2560,11 +2497,6 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
nsIFrame* frame = fromLine->mFirstChild;
if (aFromContainer != this) {
if (HandleOverflowPlaceholdersForPulledFrame(aState, frame)) {
// we lost this one, retry
return PR_TRUE;
}
aLine->LastChild()->SetNextSibling(frame);
}
// when aFromContainer is 'this', then aLine->LastChild()'s next sibling
@ -3537,10 +3469,6 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
PRInt32 i;
nsIFrame* frame = aLine->mFirstChild;
// Determine whether this is a line of placeholders for out-of-flow
// continuations
PRBool isContinuingPlaceholders = PR_FALSE;
if (aFloatAvailableSpace.mHasFloats) {
// There is a soft break opportunity at the start of the line, because
// we can always move this line down below float(s).
@ -3553,9 +3481,6 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
// count can change during the loop!
for (i = 0; LINE_REFLOW_OK == lineReflowStatus && i < aLine->GetChildCount();
i++, frame = frame->GetNextSibling()) {
if (IsContinuationPlaceholder(frame)) {
isContinuingPlaceholders = PR_TRUE;
}
rv = ReflowInlineFrame(aState, aLineLayout, aLine, frame,
&lineReflowStatus);
NS_ENSURE_SUCCESS(rv, rv);
@ -3582,7 +3507,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
}
// Don't pull up new frames into lines with continuation placeholders
if (!isContinuingPlaceholders && aAllowPullUp) {
if (aAllowPullUp) {
// Pull frames and reflow them until we can't
while (LINE_REFLOW_OK == lineReflowStatus) {
rv = PullFrame(aState, aLine, frame);
@ -3864,9 +3789,9 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
nsIAtom* frameType = aFrame->GetType();
PRBool madeContinuation;
rv = (nsGkAtoms::placeholderFrame == frameType)
? SplitPlaceholder(aState, aFrame)
: CreateContinuationFor(aState, aLine, aFrame, madeContinuation);
if (nsGkAtoms::placeholderFrame == frameType)
NS_ASSERTION(0, "float splitting unimplemented"); //XXXfr SplitFloat(aState, aPlaceholder)
rv = CreateContinuationFor(aState, aLine, aFrame, madeContinuation);
NS_ENSURE_SUCCESS(rv, rv);
// Remember that the line has wrapped
@ -3926,6 +3851,7 @@ nsresult
nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
nsIFrame* aPlaceholder)
{
NS_PRECONDITION(0,"Unexpected call to SplitPlaceholder, replace with SplitFloat XXXfr");
nsIFrame* nextInFlow;
nsresult rv = CreateNextInFlow(aState.mPresContext, this, aPlaceholder, nextInFlow);
NS_ENSURE_SUCCESS(rv, rv);
@ -3941,12 +3867,8 @@ nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
aPlaceholder->SetNextSibling(next);
contFrame->SetNextSibling(nsnull);
NS_ASSERTION(IsContinuationPlaceholder(contFrame),
"Didn't create the right kind of frame");
// The new out of flow frame does not get put anywhere; the out-of-flows
// for placeholders in mOverflowPlaceholders are not kept in any child list
aState.mOverflowPlaceholders.AppendFrame(this, contFrame);
return NS_OK;
}
@ -4362,132 +4284,6 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
#endif
}
/**
* Call this when a frame will be pulled from the block's
* next-in-flow into this frame. If it's a continuation placeholder,
* it should not be here so we push it into our overflow placeholders
* list. To avoid creating holes (e.g., the following block doesn't
* have a placeholder but the block after it does) we also need to
* pull all the following placeholders and put them in our overflow
* placeholders list too.
*
* If it's a first-in-flow placeholder, or it contains one, then we
* need to do this to the continuation placeholders.
*
* We return PR_TRUE if we removed the frame and it cannot be used.
* If we return PR_FALSE then the frame *must* be pulled immediately.
*/
PRBool
nsBlockFrame::HandleOverflowPlaceholdersForPulledFrame(
nsBlockReflowState& aState, nsIFrame* aFrame)
{
if (nsGkAtoms::placeholderFrame != aFrame->GetType()) {
// Descend into children that are not float containing blocks.
// We should encounter only first-in-flow placeholders, so the
// frame subtree rooted at aFrame should not change.
if (!aFrame->IsFloatContainingBlock()) {
for (nsIFrame* f = aFrame->GetFirstChild(nsnull); f; f = f->GetNextSibling()) {
#ifdef DEBUG
PRBool changed =
#endif
HandleOverflowPlaceholdersForPulledFrame(aState, f);
NS_ASSERTION(!changed, "Shouldn't find any continuation placeholders inside inlines");
}
}
return PR_FALSE;
}
PRBool taken = PR_TRUE;
nsIFrame* frame = aFrame;
if (!aFrame->GetPrevInFlow()) {
// First in flow frame. We only want to deal with its
// next in flows, if there are any.
taken = PR_FALSE;
frame = frame->GetNextInFlow();
if (!frame)
return PR_FALSE;
}
nsBlockFrame* parent = static_cast<nsBlockFrame*>(frame->GetParent());
// Remove aFrame and all its next in flows from their parents, but
// don't destroy the frames.
#ifdef DEBUG
nsresult rv =
#endif
parent->DoRemoveFrame(frame, PRESERVE_REMOVED_FRAMES);
NS_ASSERTION(NS_SUCCEEDED(rv), "frame should be in parent's lists");
nsIFrame* lastOverflowPlace = aState.mOverflowPlaceholders.LastChild();
while (frame) {
NS_ASSERTION(IsContinuationPlaceholder(frame),
"Should only be dealing with continuation placeholders here");
parent = static_cast<nsBlockFrame*>(frame->GetParent());
ReparentFrame(frame, parent, this);
// continuation placeholders are always direct children of a block
nsIFrame* outOfFlow = nsPlaceholderFrame::GetRealFrameForPlaceholder(frame);
if (!parent->mFloats.RemoveFrame(outOfFlow)) {
nsAutoOOFFrameList oofs(parent);
#ifdef DEBUG
PRBool found =
#endif
oofs.mList.RemoveFrame(outOfFlow);
NS_ASSERTION(found, "Must have the out of flow in some child list");
}
ReparentFrame(outOfFlow, parent, this);
// XXXbz should this be InsertFrame? Or can |frame| really have
// following siblings here?
aState.mOverflowPlaceholders.InsertFrames(nsnull, lastOverflowPlace, frame);
// outOfFlow isn't inserted anywhere yet. Eventually the overflow
// placeholders get put into the overflow lines, and at the same time we
// insert the placeholders' out of flows into the overflow out-of-flows
// list.
lastOverflowPlace = frame;
frame = frame->GetNextInFlow();
}
return taken;
}
/**
* Call this when a line will be pulled from the block's
* next-in-flow's line.
*
* @return PR_TRUE we consumed the entire line, delete it and try again
*/
PRBool
nsBlockFrame::HandleOverflowPlaceholdersOnPulledLine(
nsBlockReflowState& aState, nsLineBox* aLine)
{
// First, see if it's a line of continuation placeholders. If it
// is, remove one and retry.
if (aLine->mFirstChild && IsContinuationPlaceholder(aLine->mFirstChild)) {
#ifdef DEBUG
PRBool taken =
#endif
HandleOverflowPlaceholdersForPulledFrame(aState, aLine->mFirstChild);
NS_ASSERTION(taken, "We must have removed that frame");
return PR_TRUE;
}
// OK, it's a normal line. Scan it for floats with continuations that
// need to be taken care of. We won't need to change the line.
PRInt32 n = aLine->GetChildCount();
for (nsIFrame* f = aLine->mFirstChild; n > 0; f = f->GetNextSibling(), --n) {
#ifdef DEBUG
PRBool taken =
#endif
HandleOverflowPlaceholdersForPulledFrame(aState, f);
NS_ASSERTION(!taken, "Shouldn't be any continuation placeholders on this line");
}
return PR_FALSE;
}
// The overflowLines property is stored as a pointer to a line list,
// which must be deleted. However, the following functions all maintain
// the invariant that the property is never set if the list is empty.
@ -4551,95 +4347,6 @@ nsBlockFrame::DrainOverflowLines(nsBlockReflowState& aState)
NS_ASSERTION(aState.mOverflowPlaceholders.IsEmpty(),
"Should have no overflow placeholders yet");
// HANDLING CONTINUATION PLACEHOLDERS (floats only at the moment, because
// abs-pos frames don't have continuations)
//
// All continuation placeholders need to be moved to the front of
// our line list. We also need to maintain the invariant that at
// most one frame for a given piece of content is in our normal
// child list, by pushing all but the first placeholder to our
// overflow placeholders list.
//
// We keep the lists ordered so that prev in flows come before their
// next in flows. We do not worry about properly ordering the
// placeholders for different content relative to each other until
// the end. Then we sort them.
//
// When we're shuffling placeholders we also need to shuffle their out of
// flows to match. As we put placeholders into keepPlaceholders, we unhook
// their floats from mFloats. Later we put the floats back based on the
// order of the placeholders.
nsIFrame* lastOP = nsnull;
nsFrameList keepPlaceholders;
nsFrameList keepOutOfFlows;
nsIFrame* lastKP = nsnull;
nsIFrame* lastKOOF = nsnull;
nsLineList* lineLists[3] = { overflowLines, &mLines, ourOverflowLines };
static const PRPackedBool searchFirstLinesOnly[3] = { PR_FALSE, PR_TRUE, PR_FALSE };
for (PRInt32 i = 0; i < 3; ++i) {
nsLineList* ll = lineLists[i];
if (ll && !ll->empty()) {
line_iterator iter = ll->begin();
line_iterator iter_end = ll->end();
nsIFrame* lastFrame = nsnull;
while (iter != iter_end) {
PRUint32 n = iter->GetChildCount();
if (n == 0 || !IsContinuationPlaceholder(iter->mFirstChild)) {
if (lastFrame) {
lastFrame->SetNextSibling(iter->mFirstChild);
}
if (searchFirstLinesOnly[i]) {
break;
}
lastFrame = iter->LastChild();
++iter;
} else {
nsLineBox* line = iter;
iter = ll->erase(iter);
nsIFrame* next;
for (nsPlaceholderFrame* f = static_cast<nsPlaceholderFrame*>(line->mFirstChild);
n > 0; --n, f = static_cast<nsPlaceholderFrame*>(next)) {
NS_ASSERTION(IsContinuationPlaceholder(f),
"Line frames should all be continuation placeholders");
next = f->GetNextSibling();
f->SetNextSibling(nsnull);
nsIFrame* fpif = f->GetPrevInFlow();
nsIFrame* oof = f->GetOutOfFlowFrame();
// Take this out of mFloats for now. We may put it back later in
// this function
#ifdef DEBUG
PRBool found =
#endif
mFloats.RemoveFrame(oof);
NS_ASSERTION(found, "Float should have been put in our mFloats list");
PRBool isAncestor = nsLayoutUtils::IsProperAncestorFrame(this, fpif);
if (isAncestor) {
// oops. we already have a prev-in-flow for this
// placeholder. We have to move this frame out of here. We
// can put it in our overflow placeholders.
aState.mOverflowPlaceholders.InsertFrame(nsnull, lastOP, f);
// Let oof dangle for now, because placeholders in
// mOverflowPlaceholders do not keep their floats in any child list
lastOP = f;
} else {
NS_ASSERTION(fpif->GetParent() == prevBlock,
"Block has placeholders that don't belong to it.");
keepPlaceholders.InsertFrame(nsnull, lastKP, f);
keepOutOfFlows.InsertFrame(nsnull, lastKOOF, oof);
lastKP = f;
lastKOOF = oof;
}
}
aState.FreeLineBox(line);
}
}
if (lastFrame) {
lastFrame->SetNextSibling(nsnull);
}
}
}
// Now join the line lists into mLines
if (overflowLines) {
if (!overflowLines->empty()) {
@ -4671,23 +4378,6 @@ nsBlockFrame::DrainOverflowLines(nsBlockReflowState& aState)
delete ourOverflowLines;
}
// store the placeholders that we're keeping in our frame list
if (keepPlaceholders.NotEmpty()) {
keepPlaceholders.SortByContentOrder();
nsLineBox* newLine = aState.NewLineBox(keepPlaceholders.FirstChild(),
keepPlaceholders.GetLength(), PR_FALSE);
if (newLine) {
if (!mLines.empty()) {
keepPlaceholders.LastChild()->SetNextSibling(mLines.front()->mFirstChild);
}
mLines.push_front(newLine);
}
// Put the placeholders' out of flows into the float list
keepOutOfFlows.SortByContentOrder();
mFloats.InsertFrames(nsnull, nsnull, keepOutOfFlows);
}
return PR_TRUE;
}
@ -4920,8 +4610,6 @@ ShouldPutNextSiblingOnNewLine(nsIFrame* aLastFrame)
if (type == nsGkAtoms::textFrame)
return aLastFrame->HasTerminalNewline() &&
aLastFrame->GetStyleText()->NewlineIsSignificant();
if (type == nsGkAtoms::placeholderFrame)
return IsContinuationPlaceholder(aLastFrame);
return PR_FALSE;
}
@ -5015,9 +4703,9 @@ nsBlockFrame::AddFrames(const nsFrameList& aFrameList,
// If the frame is a block frame, or if there is no previous line or if the
// previous line is a block line we need to make a new line. We also make
// a new line, as an optimization, in the three cases we know we'll need it:
// if the previous line ended with a <br>, if it has significant whitespace and
// ended in a newline, or if it contains continuation placeholders.
// a new line, as an optimization, in the two cases we know we'll need it:
// if the previous line ended with a <br>, or if it has significant whitespace
// and ended in a newline.
if (isBlock || prevSibLine == end_lines() || prevSibLine->IsBlock() ||
(aPrevSibling && ShouldPutNextSiblingOnNewLine(aPrevSibling))) {
// Create a new line for the frame and add its line to the line
@ -5377,7 +5065,7 @@ nsBlockInFlowLineIterator::FindValidLine()
}
}
static nsresult RemoveBlockChild(nsIFrame* aFrame, PRBool aDestroyFrames,
static nsresult RemoveBlockChild(nsIFrame* aFrame,
PRBool aRemoveOnlyFluidContinuations)
{
if (!aFrame)
@ -5387,7 +5075,6 @@ static nsresult RemoveBlockChild(nsIFrame* aFrame, PRBool aDestroyFrames,
NS_ASSERTION(nextBlock,
"Our child's continuation's parent is not a block?");
return nextBlock->DoRemoveFrame(aFrame,
(aDestroyFrames ? 0 : nsBlockFrame::PRESERVE_REMOVED_FRAMES) |
(aRemoveOnlyFluidContinuations ? 0 : nsBlockFrame::REMOVE_FIXED_CONTINUATIONS));
}
@ -5406,7 +5093,6 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRUint32 aFlags)
nsPresContext* presContext = PresContext();
if (NS_FRAME_IS_OVERFLOW_CONTAINER & aDeletedFrame->GetStateBits()) {
if (!(aFlags & PRESERVE_REMOVED_FRAMES)) {
nsIFrame* nif = aDeletedFrame->GetNextInFlow();
if (nif)
static_cast<nsContainerFrame*>(nif->GetParent())
@ -5415,21 +5101,10 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRUint32 aFlags)
nsresult rv = nsContainerFrame::StealFrame(presContext, aDeletedFrame);
NS_ENSURE_SUCCESS(rv, rv);
aDeletedFrame->Destroy();
}
else {
PR_NOT_REACHED("We can't not destroy overflow containers");
return NS_ERROR_NOT_IMPLEMENTED;
//XXXfr It seems not destroying frames is only used for placeholder
// continuations; see nsBlockFrame::HandleOverflowPlaceholdersForPulledFrame.
// If we get rid of placeholder continuations, we can simplify this
// function by getting rid of that option.
}
return NS_OK;
}
if (aDeletedFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
NS_ASSERTION(!(aFlags & PRESERVE_REMOVED_FRAMES),
"We can't not destroy out of flows");
DoRemoveOutOfFlowFrame(aDeletedFrame);
return NS_OK;
}
@ -5440,14 +5115,8 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRUint32 aFlags)
if (isPlaceholder) {
nsFrameList* overflowPlaceholders = GetOverflowPlaceholders();
if (overflowPlaceholders && overflowPlaceholders->RemoveFrame(aDeletedFrame)) {
nsIFrame* nif = aDeletedFrame->GetNextInFlow();
if (!(aFlags & PRESERVE_REMOVED_FRAMES)) {
NS_ASSERTION(!aDeletedFrame->GetNextContinuation(), "Placeholders can't have continuations.");
aDeletedFrame->Destroy();
} else {
aDeletedFrame->SetNextSibling(nsnull);
}
return RemoveBlockChild(nif, !(aFlags & PRESERVE_REMOVED_FRAMES),
!(aFlags & REMOVE_FIXED_CONTINUATIONS));
}
}
@ -5554,11 +5223,7 @@ found_frame:;
printf(" prevSibling=%p deletedNextContinuation=%p\n", prevSibling, deletedNextContinuation);
#endif
if (aFlags & PRESERVE_REMOVED_FRAMES) {
aDeletedFrame->SetNextSibling(nsnull);
} else {
aDeletedFrame->Destroy();
}
aDeletedFrame = deletedNextContinuation;
PRBool haveAdvancedToNextLine = PR_FALSE;
@ -5611,14 +5276,6 @@ found_frame:;
}
if (deletedNextContinuation) {
// Continuations for placeholder frames don't always appear in
// consecutive lines. So for placeholders, just continue the slow easy way.
if (isPlaceholder) {
return RemoveBlockChild(deletedNextContinuation,
!(aFlags & PRESERVE_REMOVED_FRAMES),
!(aFlags & REMOVE_FIXED_CONTINUATIONS));
}
// See if we should keep looking in the current flow's line list.
if (deletedNextContinuation->GetParent() != this) {
// The deceased frames continuation is not a child of the
@ -5666,8 +5323,7 @@ found_frame:;
#endif
// Advance to next flow block if the frame has more continuations
return RemoveBlockChild(aDeletedFrame, !(aFlags & PRESERVE_REMOVED_FRAMES),
!(aFlags & REMOVE_FIXED_CONTINUATIONS));
return RemoveBlockChild(aDeletedFrame, !(aFlags & REMOVE_FIXED_CONTINUATIONS));
}
nsresult
@ -5807,6 +5463,7 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
availHeight = NS_UNCONSTRAINEDSIZE;
}
#endif
availHeight = NS_UNCONSTRAINEDSIZE; //XXXfr Disable float splitting
return nsRect(aState.BorderPadding().left,
aState.BorderPadding().top,
@ -5893,18 +5550,6 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
(NS_UNCONSTRAINEDSIZE == availSpace.height))
aReflowStatus = NS_FRAME_COMPLETE;
if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
// Float is now complete, so delete the placeholder's next in
// flows, if any; their floats (which are this float's continuations)
// have already been deleted.
// XXX won't this be done later in nsLineLayout::ReflowFrame anyway??
nsIFrame* nextInFlow = aPlaceholder->GetNextInFlow();
if (nextInFlow) {
static_cast<nsHTMLContainerFrame*>(nextInFlow->GetParent())
->DeleteNextInFlowChild(aState.mPresContext, nextInFlow, PR_TRUE);
// that takes care of all subsequent nextinflows too
}
}
if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
@ -5948,34 +5593,6 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
floatFrame, metrics.width, metrics.height);
#endif
// If the placeholder was continued and its first-in-flow was followed by a
// <BR>, then cache the <BR>'s break type in aState.mFloatBreakType so that
// the next frame after the placeholder can combine that break type with its own
nsIFrame* prevPlaceholder = aPlaceholder->GetPrevInFlow();
if (prevPlaceholder) {
// the break occurs only after the last continued placeholder
PRBool lastPlaceholder = PR_TRUE;
nsIFrame* next = aPlaceholder->GetNextSibling();
if (next) {
if (nsGkAtoms::placeholderFrame == next->GetType()) {
lastPlaceholder = PR_FALSE;
}
}
if (lastPlaceholder) {
// get the containing block of prevPlaceholder which is our prev-in-flow
if (GetPrevInFlow()) {
// get the break type of the last line in mPrevInFlow
nsBlockFrame* prevBlock = static_cast<nsBlockFrame*>(GetPrevInFlow());
line_iterator endLine = prevBlock->end_lines();
if (endLine != prevBlock->begin_lines()) {
--endLine;
if (endLine->HasFloatBreakAfter())
aState.mFloatBreakType = endLine->GetBreakTypeAfter();
}
}
else NS_ASSERTION(PR_FALSE, "no prev in flow");
}
}
return NS_OK;
}

Просмотреть файл

@ -281,12 +281,6 @@ public:
// add it to the list of overflow floats
nsresult SplitPlaceholder(nsBlockReflowState& aState, nsIFrame* aPlaceholder);
PRBool HandleOverflowPlaceholdersForPulledFrame(
nsBlockReflowState& aState, nsIFrame* aFrame);
PRBool HandleOverflowPlaceholdersOnPulledLine(
nsBlockReflowState& aState, nsLineBox* aLine);
static PRBool BlockIsMarginRoot(nsIFrame* aBlock);
static PRBool BlockNeedsFloatManager(nsIFrame* aBlock);
@ -425,14 +419,9 @@ public:
* -- marks lines dirty as needed
* -- marks textruns dirty (unless FRAMES_ARE_EMPTY is given, in which
* case textruns do not need to be dirtied)
* -- destroys all removed frames (unless PRESERVE_REMOVED_FRAMES is
* given)
*
* PRESERVE_REMOVED_FRAMES does NOT work on out of flow frames so
* don't use it for out of flows.
* -- destroys all removed frames
*/
enum {
PRESERVE_REMOVED_FRAMES = 0x01,
REMOVE_FIXED_CONTINUATIONS = 0x02,
FRAMES_ARE_EMPTY = 0x04
};

Просмотреть файл

@ -647,18 +647,6 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
// This float will be placed after the line is done (it is a
// below-current-line float).
mBelowCurrentLineFloats.Append(fc);
if (aPlaceholder->GetNextInFlow()) {
// If the float might not be complete, mark it incomplete now to
// prevent its next-in-flow placeholders being torn down. We will destroy any
// placeholders later if PlaceBelowCurrentLineFloats finds the
// float is complete.
// Note that we could have unconstrained height and yet have
// a next-in-flow placeholder --- for example columns can switch
// from constrained height to unconstrained height.
if (aPlaceholder->GetSplittableType() != NS_FRAME_NOT_SPLITTABLE) {
aReflowStatus = NS_FRAME_NOT_COMPLETE;
}
}
}
// Restore coordinate system
@ -1043,23 +1031,13 @@ nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList, PRB
return PR_FALSE;
}
else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) {
// Create a continuation for the incomplete float and its placeholder.
nsresult rv = mBlock->SplitPlaceholder(*this, fc->mPlaceholder);
if (NS_FAILED(rv))
return PR_FALSE;
// Create a continuation for the incomplete float XXXfr
} else {
// XXX We could deal with truncated frames better by breaking before
// the associated placeholder
NS_WARN_IF_FALSE(!NS_FRAME_IS_TRUNCATED(reflowStatus),
"This situation currently leads to data not printing");
// Float is complete. We need to delete any leftover placeholders now.
nsIFrame* nextPlaceholder = fc->mPlaceholder->GetNextInFlow();
if (nextPlaceholder) {
nsHTMLContainerFrame* parent =
static_cast<nsHTMLContainerFrame*>(nextPlaceholder->GetParent());
parent->DeleteNextInFlowChild(mPresContext, nextPlaceholder, PR_TRUE);
}
// Float is complete.
}
}
fc = fc->Next();

Просмотреть файл

@ -716,7 +716,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
else if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
if (nsGkAtoms::placeholderFrame == aFrame->GetType()) {
nsBlockReflowState* blockRS = lineLayout->mBlockRS;
blockRS->mBlock->SplitPlaceholder(*blockRS, aFrame);
NS_ASSERTION(0, "float splitting unimplemented"); // SplitFloat XXXfr
// Allow the parent to continue reflowing
aStatus = NS_FRAME_COMPLETE;
}

Просмотреть файл

@ -136,14 +136,7 @@ nsPlaceholderFrame::Destroy()
}
}
nsSplittableFrame::Destroy();
}
nsSplittableType
nsPlaceholderFrame::GetSplittableType() const
{
NS_ASSERTION(mOutOfFlowFrame, "GetSplittableType called at the wrong time");
return mOutOfFlowFrame->GetSplittableType();
nsFrame::Destroy();
}
nsIAtom*

Просмотреть файл

@ -74,7 +74,7 @@
#ifndef nsPlaceholderFrame_h___
#define nsPlaceholderFrame_h___
#include "nsSplittableFrame.h"
#include "nsFrame.h"
#include "nsGkAtoms.h"
nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
@ -83,18 +83,22 @@ nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsStyleContext* aCont
* Implementation of a frame that's used as a placeholder for a frame that
* has been moved out of the flow
*/
class nsPlaceholderFrame : public nsSplittableFrame {
class nsPlaceholderFrame : public nsFrame {
public:
/**
* Create a new placeholder frame
*/
friend nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsPlaceholderFrame(nsStyleContext* aContext) : nsSplittableFrame(aContext) {}
nsPlaceholderFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
virtual ~nsPlaceholderFrame();
// Get/Set the associated out of flow frame
nsIFrame* GetOutOfFlowFrame() const {return mOutOfFlowFrame;}
void SetOutOfFlowFrame(nsIFrame* aFrame) {mOutOfFlowFrame = aFrame;}
void SetOutOfFlowFrame(nsIFrame* aFrame) {
NS_ASSERTION(!aFrame || !aFrame->GetPrevContinuation(),
"OOF must be first continuation");
mOutOfFlowFrame = aFrame;
}
// nsIHTMLReflow overrides
// We need to override GetMinWidth and GetPrefWidth because XUL uses
@ -111,7 +115,6 @@ public:
nsReflowStatus& aStatus);
virtual void Destroy();
virtual nsSplittableType GetSplittableType() const;
// nsIFrame overrides
#if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))
@ -145,7 +148,7 @@ public:
{
nsIFrame *realFrame = GetRealFrameForPlaceholder(this);
return realFrame ? realFrame->GetAccessible(aAccessible) :
nsSplittableFrame::GetAccessible(aAccessible);
nsFrame::GetAccessible(aAccessible);
}
#endif

Просмотреть файл

@ -51,6 +51,7 @@
#define nsTextFrame_h__
#include "nsFrame.h"
#include "nsSplittableFrame.h"
#include "nsLineBox.h"
#include "gfxFont.h"
#include "gfxSkipChars.h"