Bug 233463, patch 0 - Use nsFrameList methods instead of nsIFrame::SetNextSibling. r=bzbarsky

This commit is contained in:
Mats Palmgren 2009-09-18 13:09:35 +02:00
Родитель 9456708e63
Коммит b97e6400ed
22 изменённых файлов: 225 добавлений и 208 удалений

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

@ -53,6 +53,7 @@
#include "nsHTMLContainerFrame.h"
#include "nsInlineFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsContainerFrame.h"
static const PRUnichar kSpace = 0x0020;
static const PRUnichar kLineSeparator = 0x2028;
@ -117,7 +118,6 @@ SplitInlineAncestors(nsIFrame* aFrame)
nsIPresShell *presShell = presContext->PresShell();
nsIFrame* frame = aFrame;
nsIFrame* parent = aFrame->GetParent();
nsIFrame* newFrame = aFrame->GetNextSibling();
nsIFrame* newParent;
while (IsBidiSplittable(parent)) {
@ -130,31 +130,29 @@ SplitInlineAncestors(nsIFrame* aFrame)
return rv;
}
// The new parent adopts the new frame
frame->SetNextSibling(nsnull);
// XXXbz this thing should be rewritten on top of nsFrameList on a
// much higher level...
nsFrameList temp(newFrame);
// Split the child list after |frame|.
nsContainerFrame* container = do_QueryFrame(parent);
nsFrameList tail = container->StealFramesAfter(frame);
// Reparent views as necessary
rv = nsHTMLContainerFrame::ReparentFrameViewList(presContext, temp, parent, newParent);
rv = nsHTMLContainerFrame::ReparentFrameViewList(presContext, tail, parent, newParent);
if (NS_FAILED(rv)) {
return rv;
}
rv = newParent->InsertFrames(nsGkAtoms::nextBidi, nsnull, temp);
// The parent's continuation adopts the siblings after the split.
rv = newParent->InsertFrames(nsGkAtoms::nextBidi, nsnull, tail);
if (NS_FAILED(rv)) {
return rv;
}
// The list name nsGkAtoms::nextBidi would indicate we don't want reflow
nsFrameList temp2(newParent);
rv = grandparent->InsertFrames(nsGkAtoms::nextBidi, parent, temp2);
nsFrameList temp(newParent, newParent);
rv = grandparent->InsertFrames(nsGkAtoms::nextBidi, parent, temp);
if (NS_FAILED(rv)) {
return rv;
}
frame = parent;
newFrame = newParent;
parent = grandparent;
}

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

@ -2179,7 +2179,7 @@ nsCSSFrameConstructor::ConstructTableCol(nsFrameConstructorState& aState,
nsStyleContext* const styleContext = aItem.mStyleContext;
nsTableColFrame* colFrame = NS_NewTableColFrame(mPresShell, styleContext);
if (NS_UNLIKELY(!aNewFrame)) {
if (NS_UNLIKELY(!colFrame)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, colFrame);
@ -2187,9 +2187,11 @@ nsCSSFrameConstructor::ConstructTableCol(nsFrameConstructorState& aState,
NS_ASSERTION(colFrame->GetStyleContext() == styleContext,
"Unexpected style context");
aFrameItems.AddChild(colFrame);
*aNewFrame = colFrame;
// construct additional col frames if the col frame has a span > 1
PRInt32 span = colFrame->GetSpan();
nsIFrame* lastCol = colFrame;
for (PRInt32 spanX = 1; spanX < span; spanX++) {
nsTableColFrame* newCol = NS_NewTableColFrame(mPresShell, styleContext);
if (NS_UNLIKELY(!newCol)) {
@ -2197,16 +2199,12 @@ nsCSSFrameConstructor::ConstructTableCol(nsFrameConstructorState& aState,
}
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newCol,
PR_FALSE);
lastCol->SetNextSibling(newCol);
lastCol->SetNextContinuation(newCol);
newCol->SetPrevContinuation(lastCol);
aFrameItems.LastChild()->SetNextContinuation(newCol);
newCol->SetPrevContinuation(aFrameItems.LastChild());
aFrameItems.AddChild(newCol);
newCol->SetColType(eColAnonymousCol);
lastCol = newCol;
}
aFrameItems.AddChild(colFrame);
*aNewFrame = colFrame;
return NS_OK;
}
@ -8470,6 +8468,8 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
nextContinuation->SetPrevContinuation(newFrame);
newFrame->SetNextContinuation(nextContinuation);
}
NS_POSTCONDITION(!newFrame->GetNextSibling(), "unexpected sibling");
return NS_OK;
}
@ -9894,10 +9894,10 @@ nsCSSFrameConstructor::InsertFirstLineFrames(
// Oy. We have work to do. Create a list of the new frames
// that are going into the block by stripping them away from
// the line-frame(s).
nsFrameList list(nextSibling);
if (nextSibling) {
nsLineFrame* lineFrame = (nsLineFrame*) prevSiblingParent;
lineFrame->StealFramesFrom(nextSibling);
nsFrameList tail = lineFrame->StealFramesAfter(aPrevSibling);
// XXX do something with 'tail'
}
nsLineFrame* nextLineFrame = (nsLineFrame*) lineFrame;
@ -11027,8 +11027,7 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
// Try to find one after all
nsIFrame* parentPrevCont = aFrame->GetPrevContinuation();
while (parentPrevCont) {
prevSibling =
nsFrameList(parentPrevCont->GetFirstChild(nsnull)).LastChild();
prevSibling = parentPrevCont->GetLastChild(nsnull);
if (prevSibling) {
break;
}

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

@ -47,6 +47,8 @@
#include "nsHTMLContainerFrame.h"
#include "nsHTMLParts.h"
#include "nsPresContext.h"
#include "nsFrameManager.h"
#include "nsCSSFrameConstructor.h"
#ifdef DEBUG
#include "nsBlockFrame.h"
@ -159,11 +161,9 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame,
if (!NS_FRAME_IS_FULLY_COMPLETE(kidStatus)) {
// Need a continuation
if (!nextFrame) {
nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
aDelegatingFrame, kidFrame, nextFrame);
nsresult rv = aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, kidFrame, aDelegatingFrame, &nextFrame);
NS_ENSURE_SUCCESS(rv, rv);
kidFrame->SetNextSibling(nextFrame->GetNextSibling());
nextFrame->SetNextSibling(nsnull);
}
// Add it as an overflow container.
//XXXfr This is a hack to fix some of our printing dataloss.
@ -549,7 +549,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
aKidFrame->GetFrameName(name);
printf("%s ", NS_LossyConvertUTF16toASCII(name).get());
}
printf("%p rect=%d,%d,%d,%d\n", (void*)aKidFrame,
printf("%p rect=%d,%d,%d,%d\n", static_cast<void*>(aKidFrame),
rect.x, rect.y, rect.width, rect.height);
}
#endif

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

@ -86,6 +86,7 @@
#include "nsDisplayList.h"
#include "nsContentErrors.h"
#include "nsCSSAnonBoxes.h"
#include "nsCSSFrameConstructor.h"
#include "nsCSSRendering.h"
#ifdef IBMBIDI
@ -3846,10 +3847,6 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
return NS_OK;
}
/**
* 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,
@ -3857,20 +3854,29 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState,
PRBool& aMadeNewFrame)
{
aMadeNewFrame = PR_FALSE;
nsresult rv;
nsIFrame* nextInFlow;
rv = CreateNextInFlow(aState.mPresContext, this, aFrame, nextInFlow);
NS_ENSURE_SUCCESS(rv, rv);
if (nsnull != nextInFlow) {
aMadeNewFrame = PR_TRUE;
if (!aFrame->GetNextInFlow()) {
nsIFrame* newFrame;
nsresult rv = aState.mPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aState.mPresContext, aFrame, this, &newFrame);
if (NS_FAILED(rv)) {
return rv;
}
nsIFrame* sib = aFrame->GetNextSibling();
aFrame->SetNextSibling(newFrame);
newFrame->SetNextSibling(sib);
if (aLine) {
aLine->SetChildCount(aLine->GetChildCount() + 1);
}
aMadeNewFrame = PR_TRUE;
}
#ifdef DEBUG
VerifyLines(PR_FALSE);
#endif
return rv;
return NS_OK;
}
nsresult
@ -3878,9 +3884,12 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState,
nsIFrame* aFloat,
nsReflowStatus aFloatStatus)
{
nsIFrame* nextInFlow;
nsresult rv = CreateNextInFlow(aState.mPresContext, this, aFloat, nextInFlow);
NS_ENSURE_SUCCESS(rv, rv);
nsIFrame* nextInFlow = nsnull;
if (!aFloat->GetNextInFlow()) {
nsresult rv = aState.mPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aState.mPresContext, aFloat, this, &nextInFlow);
NS_ENSURE_SUCCESS(rv, rv);
}
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus))
aFloat->GetNextInFlow()->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
@ -3889,18 +3898,10 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState,
// Make sure the containing block knows about the float's status
NS_MergeReflowStatusInto(&aState.mReflowStatus, aFloatStatus);
if (!nextInFlow) {
// Next in flow was not created because it already exists.
return NS_OK;
if (nextInFlow) {
// Next in flow was created above.
aState.AppendFloatContinuation(nextInFlow);
}
// put the sibling list back to what it was before the continuation was created
nsIFrame *contFrame = aFloat->GetNextSibling();
nsIFrame *next = contFrame->GetNextSibling();
aFloat->SetNextSibling(next);
contFrame->SetNextSibling(nsnull);
aState.AppendFloatContinuation(contFrame);
return NS_OK;
}

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

@ -591,6 +591,15 @@ protected:
//----------------------------------------
// Methods for pushing/pulling lines/frames
/**
* Create a next-in-flow, if necessary, for aFrame. If a new frame is
* created, place it in aLine if aLine is not null.
* @param aState the block reflow state
* @param aLine where to put a new frame
* @param aFrame the frame
* @param aMadeNewFrame PR_TRUE if a new frame was created, PR_FALSE if not
* @return NS_OK if a next-in-flow already exists or is successfully created
*/
virtual nsresult CreateContinuationFor(nsBlockReflowState& aState,
nsLineBox* aLine,
nsIFrame* aFrame,

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

@ -721,7 +721,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
"We have to create a continuation, but the block doesn't want us to reflow it?");
// We need to create a continuing column
nsresult rv = CreateNextInFlow(PresContext(), this, child, kidNextInFlow);
nsresult rv = CreateNextInFlow(PresContext(), child, kidNextInFlow);
if (NS_FAILED(rv)) {
NS_NOTREACHED("Couldn't create continuation");
@ -752,10 +752,9 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
// Move any of our leftover columns to our overflow list. Our
// next-in-flow will eventually pick them up.
nsIFrame* continuationColumns = child->GetNextSibling();
if (continuationColumns) {
const nsFrameList& continuationColumns = mFrames.RemoveFramesAfter(child);
if (continuationColumns.NotEmpty()) {
SetOverflowFrames(PresContext(), continuationColumns);
child->SetNextSibling(nsnull);
}
child = nsnull;
break;

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

@ -86,6 +86,10 @@ nsContainerFrame::~nsContainerFrame()
{
}
NS_QUERYFRAME_HEAD(nsContainerFrame)
NS_QUERYFRAME_ENTRY(nsContainerFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsSplittableFrame)
NS_IMETHODIMP
nsContainerFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
@ -1020,13 +1024,11 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
// Acquire a next-in-flow, creating it if necessary
nsIFrame* nif = frame->GetNextInFlow();
if (!nif) {
rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext, this,
frame, nif);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(frameStatus & NS_FRAME_REFLOW_NEXTINFLOW,
"Someone forgot a REFLOW_NEXTINFLOW flag");
frame->SetNextSibling(nif->GetNextSibling());
nif->SetNextSibling(nsnull);
rv = aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, frame, this, &nif);
NS_ENSURE_SUCCESS(rv, rv);
}
else if (!(nif->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
// used to be a normal next-in-flow; steal it from the child list
@ -1100,6 +1102,43 @@ nsContainerFrame::StealFrame(nsPresContext* aPresContext,
return (removed) ? NS_OK : NS_ERROR_UNEXPECTED;
}
nsFrameList
nsContainerFrame::StealFramesAfter(nsIFrame* aChild)
{
NS_ASSERTION(!aChild ||
!(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER),
"StealFramesAfter doesn't handle overflow containers");
NS_ASSERTION(GetType() != nsGkAtoms::blockFrame, "unexpected call");
if (!aChild) {
nsFrameList copy(mFrames);
mFrames.Clear();
return copy;
}
for (nsFrameList::FrameLinkEnumerator iter(mFrames); !iter.AtEnd();
iter.Next()) {
if (iter.PrevFrame() == aChild) {
return mFrames.ExtractTail(iter);
}
}
// We didn't find the child in the principal child list.
// Maybe it's on the overflow list?
nsFrameList* overflowFrames = GetOverflowFrames();
if (overflowFrames) {
for (nsFrameList::FrameLinkEnumerator iter(*overflowFrames); !iter.AtEnd();
iter.Next()) {
if (iter.PrevFrame() == aChild) {
return overflowFrames->ExtractTail(iter);
}
}
}
NS_ERROR("StealFramesAfter: can't find aChild");
return nsFrameList::EmptyList();
}
void
nsContainerFrame::DestroyOverflowList(nsPresContext* aPresContext)
{
@ -1273,24 +1312,25 @@ nsContainerFrame::PushChildren(nsPresContext* aPresContext,
nsIFrame* aFromChild,
nsIFrame* aPrevSibling)
{
NS_PRECONDITION(nsnull != aFromChild, "null pointer");
NS_PRECONDITION(nsnull != aPrevSibling, "pushing first child");
NS_PRECONDITION(aFromChild, "null pointer");
NS_PRECONDITION(aPrevSibling, "pushing first child");
NS_PRECONDITION(aPrevSibling->GetNextSibling() == aFromChild, "bad prev sibling");
// Disconnect aFromChild from its previous sibling
aPrevSibling->SetNextSibling(nsnull);
nsFrameList tail = mFrames.RemoveFramesAfter(aPrevSibling);
if (nsnull != GetNextInFlow()) {
nsContainerFrame* nextInFlow =
static_cast<nsContainerFrame*>(GetNextInFlow());
if (nextInFlow) {
// XXX This is not a very good thing to do. If it gets removed
// then remove the copy of this routine that doesn't do this from
// nsInlineFrame.
nsContainerFrame* nextInFlow = (nsContainerFrame*)GetNextInFlow();
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
for (nsIFrame* f = aFromChild; f; f = f->GetNextSibling()) {
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, this, nextInFlow);
}
nextInFlow->mFrames.InsertFrames(nextInFlow, nsnull, aFromChild);
nextInFlow->mFrames.InsertFrames(nextInFlow, nsnull, tail);
}
else {
// Add the frames to our overflow list

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

@ -74,6 +74,8 @@ class nsContainerFrame : public nsSplittableFrame
{
public:
NS_DECL_FRAMEARENA_HELPERS
NS_DECL_QUERYFRAME_TARGET(nsContainerFrame)
NS_DECL_QUERYFRAME
// nsIFrame overrides
NS_IMETHOD Init(nsIContent* aContent,
@ -297,6 +299,17 @@ public:
nsIFrame* aChild,
PRBool aForceNormal = PR_FALSE);
/**
* Removes the next-siblings of aChild without destroying them and without
* requesting reflow. Checks the principal and overflow lists (not
* overflow containers / excess overflow containers). Does not check any
* other auxiliary lists.
* @param aChild a child frame or nsnull
* @return If aChild is non-null, the next-siblings of aChild, if any.
* If aChild is null, all child frames on the principal list, if any.
*/
nsFrameList StealFramesAfter(nsIFrame* aChild);
/**
* Add overflow containers to the display list
*/

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

@ -268,20 +268,20 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
// Create a continuation for the child frame if it doesn't already
// have one.
nsIFrame* nextInFlow;
rv = CreateNextInFlow(aPresContext, this, kid, nextInFlow);
rv = CreateNextInFlow(aPresContext, kid, nextInFlow);
if (NS_FAILED(rv)) {
return rv;
}
// And then push it to our overflow list
if (nextInFlow) {
kid->SetNextSibling(nsnull);
mFrames.RemoveFramesAfter(kid);
SetOverflowFrames(aPresContext, nextInFlow);
}
else {
nsIFrame* nextSib = kid->GetNextSibling();
if (nextSib) {
kid->SetNextSibling(nsnull);
mFrames.RemoveFramesAfter(kid);
SetOverflowFrames(aPresContext, nextSib);
}
}

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

@ -108,6 +108,17 @@ nsFrameList::RemoveFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint)
return PR_FALSE;
}
nsFrameList
nsFrameList::RemoveFramesAfter(nsIFrame* aAfterFrame)
{
NS_PRECONDITION(NotEmpty(), "illegal operation on empty list");
NS_PRECONDITION(ContainsFrame(aAfterFrame), "wrong frame");
nsIFrame* tail = aAfterFrame->GetNextSibling();
aAfterFrame->SetNextSibling(nsnull);
return nsFrameList(tail);
}
PRBool
nsFrameList::RemoveFirstChild()
{

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

@ -68,6 +68,17 @@ public:
#endif
}
nsFrameList(nsIFrame* aFirstFrame, nsIFrame* aLastFrame) :
mFirstChild(aFirstFrame)
{
NS_ASSERTION(aLastFrame == LastChild(), "wrong last frame");
MOZ_COUNT_CTOR(nsFrameList);
#ifdef DEBUG
CheckForLoops();
#endif
}
nsFrameList(const nsFrameList& aOther) :
mFirstChild(aOther.mFirstChild)
{
@ -136,6 +147,13 @@ public:
*/
PRBool RemoveFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint = nsnull);
/**
* Take the frames after aAfterFrame out of the frame list.
* @param aAfterFrame a frame in this list
* @return the removed frames, if any
*/
nsFrameList RemoveFramesAfter(nsIFrame* aAfterFrame);
/**
* Remove the first child from the list. The caller is assumed to be
* holding a reference to the first child. This call is equivalent

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

@ -359,7 +359,6 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
return NS_ERROR_OUT_OF_MEMORY;
// create the children frames; skip content which isn't <frameset> or <frame>
nsIFrame* lastChild = nsnull;
mChildCount = 0; // number of <frame> or <frameset> children
nsIFrame* frame;
@ -420,12 +419,8 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
if (NS_FAILED(result))
return result;
if (lastChild)
lastChild->SetNextSibling(frame);
else
mFrames.SetFrames(frame);
lastChild = frame;
mFrames.AppendFrame(nsnull, frame);
mChildCount++;
}
}
@ -452,12 +447,8 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
return result;
}
if (lastChild)
lastChild->SetNextSibling(blankFrame);
else
mFrames.SetFrames(blankFrame);
lastChild = blankFrame;
mFrames.AppendFrame(nsnull, blankFrame);
mChildTypes[mChildCount] = BLANK;
mChildBorderColors[mChildCount].Set(NO_COLOR);
mChildCount++;
@ -1040,7 +1031,6 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
nsPoint offset(0,0);
nsSize size, lastSize;
nsIFrame* child = mFrames.FirstChild();
nsIFrame* lastChild = mFrames.LastChild();
for (PRInt32 childX = 0; childX < mNonBorderChildCount; childX++) {
nsIntPoint cellIndex;
@ -1063,8 +1053,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
if (NS_LIKELY(borderFrame != nsnull)) {
borderFrame->Init(mContent, this, nsnull);
mChildCount++;
lastChild->SetNextSibling(borderFrame);
lastChild = borderFrame;
mFrames.AppendFrame(nsnull, borderFrame);
mHorBorders[cellIndex.y-1] = borderFrame;
// set the neighbors for determining drag boundaries
borderFrame->mPrevNeighbor = lastRow;
@ -1100,8 +1089,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
if (NS_LIKELY(borderFrame != nsnull)) {
borderFrame->Init(mContent, this, nsnull);
mChildCount++;
lastChild->SetNextSibling(borderFrame);
lastChild = borderFrame;
mFrames.AppendFrame(nsnull, borderFrame);
mVerBorders[cellIndex.x-1] = borderFrame;
// set the neighbors for determining drag boundaries
borderFrame->mPrevNeighbor = lastCol;

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

@ -473,32 +473,32 @@ HasTextFrameDescendantOrInFlow(nsIFrame* aFrame)
return PR_FALSE;
}
/**
/*
* Create a next-in-flow for aFrame. Will return the newly created
* frame in aNextInFlowResult <b>if and only if</b> a new frame is
* created; otherwise nsnull is returned in aNextInFlowResult.
*/
nsresult
nsHTMLContainerFrame::CreateNextInFlow(nsPresContext* aPresContext,
nsIFrame* aOuterFrame,
nsIFrame* aFrame,
nsIFrame*& aNextInFlowResult)
{
NS_PRECONDITION(GetType() != nsGkAtoms::blockFrame,
"you should have called nsBlockFrame::CreateContinuationFor instead");
NS_PRECONDITION(mFrames.ContainsFrame(aFrame), "expected an in-flow child frame");
aNextInFlowResult = nsnull;
nsIFrame* nextInFlow = aFrame->GetNextInFlow();
if (nsnull == nextInFlow) {
// Create a continuation frame for the child frame and insert it
// into our lines child list.
nsIFrame* nextFrame = aFrame->GetNextSibling();
// into our child list.
nsresult rv = aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, aFrame, aOuterFrame, &nextInFlow);
CreateContinuingFrame(aPresContext, aFrame, this, &nextInFlow);
if (NS_FAILED(rv)) {
return rv;
}
aFrame->SetNextSibling(nextInFlow);
nextInFlow->SetNextSibling(nextFrame);
mFrames.InsertFrame(nsnull, aFrame, nextInFlow);
NS_FRAME_LOG(NS_FRAME_TRACE_NEW_FRAMES,
("nsHTMLContainerFrame::CreateNextInFlow: frame=%p nextInFlow=%p",

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

@ -71,20 +71,6 @@ class nsHTMLContainerFrame : public nsContainerFrame {
public:
NS_DECL_FRAMEARENA_HELPERS
/**
* Helper method to create next-in-flows if necessary. If aFrame
* 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. If aPlaceholderResult is not null and
* aFrame is a float or positioned, then *aPlaceholderResult holds
* a placeholder.
*/
static nsresult CreateNextInFlow(nsPresContext* aPresContext,
nsIFrame* aOuterFrame,
nsIFrame* aFrame,
nsIFrame*& aNextInFlowResult);
/**
* Helper method to wrap views around frames. Used by containers
* under special circumstances (can be used by leaf frames as well)
@ -102,6 +88,23 @@ public:
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
/**
* Helper method to create next-in-flows if necessary. If aFrame
* 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 is inserted
* into the principal child list after aFrame.
* @note calling this method on a block frame is illegal. Use
* nsBlockFrame::CreateContinuationFor() instead.
* @param aNextInFlowResult will contain the next-in-flow
* <b>if and only if</b> one is created. If a next-in-flow already
* exists aNextInFlowResult is set to nsnull.
* @return NS_OK if a next-in-flow already exists or is successfully created.
*/
nsresult CreateNextInFlow(nsPresContext* aPresContext,
nsIFrame* aFrame,
nsIFrame*& aNextInFlowResult);
/**
* Displays the standard border, background and outline for the frame
* and calls DisplayTextDecorationsAndChildren. This is suitable for

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

@ -55,6 +55,7 @@
#include "nsIScrollPositionListener.h"
#include "nsDisplayList.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsCSSFrameConstructor.h"
// for focus
#include "nsIDOMWindowInternal.h"
@ -670,11 +671,9 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
"If it's incomplete and has no nif yet, it must flag a nif reflow.");
if (!nextFrame) {
nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
this, kidFrame, nextFrame);
nsresult rv = aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, kidFrame, this, &nextFrame);
NS_ENSURE_SUCCESS(rv, rv);
kidFrame->SetNextSibling(nextFrame->GetNextSibling());
nextFrame->SetNextSibling(nsnull);
SetOverflowFrames(aPresContext, nextFrame);
// Root overflow containers will be normal children of
// the canvas frame, but that's ok because there

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

@ -692,7 +692,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
// Break-after
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
nsIFrame* newFrame;
rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame);
rv = CreateNextInFlow(aPresContext, aFrame, newFrame);
if (NS_FAILED(rv)) {
return rv;
}
@ -727,7 +727,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
}
else {
nsIFrame* newFrame;
rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame);
rv = CreateNextInFlow(aPresContext, aFrame, newFrame);
if (NS_FAILED(rv)) {
return rv;
}
@ -782,20 +782,18 @@ nsInlineFrame::PushFrames(nsPresContext* aPresContext,
nsIFrame* aFromChild,
nsIFrame* aPrevSibling)
{
NS_PRECONDITION(nsnull != aFromChild, "null pointer");
NS_PRECONDITION(nsnull != aPrevSibling, "pushing first child");
NS_PRECONDITION(aFromChild, "null pointer");
NS_PRECONDITION(aPrevSibling, "pushing first child");
NS_PRECONDITION(aPrevSibling->GetNextSibling() == aFromChild, "bad prev sibling");
#ifdef NOISY_PUSHING
printf("%p pushing aFromChild %p, disconnecting from prev sib %p\n",
this, aFromChild, aPrevSibling);
printf("%p pushing aFromChild %p, disconnecting from prev sib %p\n",
this, aFromChild, aPrevSibling);
#endif
// Disconnect aFromChild from its previous sibling
aPrevSibling->SetNextSibling(nsnull);
// Add the frames to our overflow list (let our next in flow drain
// our overflow list when it is ready)
SetOverflowFrames(aPresContext, aFromChild);
SetOverflowFrames(aPresContext, mFrames.RemoveFramesAfter(aPrevSibling));
}
@ -920,18 +918,6 @@ nsFirstLineFrame::GetType() const
return nsGkAtoms::lineFrame;
}
void
nsFirstLineFrame::StealFramesFrom(nsIFrame* aFrame)
{
nsIFrame* prevFrame = mFrames.GetPrevSiblingFor(aFrame);
if (prevFrame) {
prevFrame->SetNextSibling(nsnull);
}
else {
mFrames.SetFrames(nsnull);
}
}
nsIFrame*
nsFirstLineFrame::PullOneFrame(nsPresContext* aPresContext, InlineReflowState& irs,
PRBool* aIsComplete)

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

@ -126,12 +126,6 @@ public:
virtual void PullOverflowsFromPrevInFlow();
// Take all of the frames away from this frame. The caller is
// presumed to keep them alive.
void StealAllFrames() {
mFrames.SetFrames(nsnull);
}
/**
* Return true if the frame is leftmost frame or continuation.
*/
@ -229,10 +223,6 @@ public:
virtual void PullOverflowsFromPrevInFlow();
// Take frames starting at aFrame until the end of the frame-list
// away from this frame. The caller is presumed to keep them alive.
void StealFramesFrom(nsIFrame* aFrame);
protected:
nsFirstLineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {}

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

@ -145,17 +145,6 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
//----------------------------------------------------------------------
// Creates a continuing page frame
nsresult
nsSimplePageSequenceFrame::CreateContinuingPageFrame(nsPresContext* aPresContext,
nsIFrame* aPageFrame,
nsIFrame** aContinuingPage)
{
// Create the continuing frame
return aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, aPageFrame, this, aContinuingPage);
}
NS_IMETHODIMP
nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -300,19 +289,19 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext,
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
if (NS_FRAME_IS_FULLY_COMPLETE(status)) {
NS_ASSERTION(nsnull == kidNextInFlow, "bad child flow list");
} else if (nsnull == kidNextInFlow) {
NS_ASSERTION(!kidNextInFlow, "bad child flow list");
} else if (!kidNextInFlow) {
// The page isn't complete and it doesn't have a next-in-flow, so
// create a continuing page
// create a continuing page.
nsIFrame* continuingPage;
nsresult rv = CreateContinuingPageFrame(aPresContext, kidFrame,
&continuingPage);
nsresult rv = aPresContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(aPresContext, kidFrame, this, &continuingPage);
if (NS_FAILED(rv)) {
break;
}
// Add it to our child list
kidFrame->SetNextSibling(continuingPage);
mFrames.InsertFrame(nsnull, kidFrame, continuingPage);
}
// Get the next page

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

@ -139,10 +139,6 @@ protected:
nsSimplePageSequenceFrame(nsStyleContext* aContext);
virtual ~nsSimplePageSequenceFrame();
nsresult CreateContinuingPageFrame(nsPresContext* aPresContext,
nsIFrame* aPageFrame,
nsIFrame** aContinuingFrame);
void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, PRBool aPageNumOnly);
// SharedPageData Helper methods

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

@ -325,8 +325,6 @@ nsTableFrame::SetInitialChildList(nsIAtom* aListName,
// form for two reasons:
// 1) Both rowgroups and column groups come in on the principal child list.
// 2) Getting the last frame of a frame list is slow.
// Once #2 is fixed, it should be pretty easy to get rid of the
// SetNextSibling usage here, at least.
nsIFrame *prevMainChild = nsnull;
nsIFrame *prevColGroupChild = nsnull;
while (aChildList.NotEmpty())
@ -2923,29 +2921,25 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
if (!kidNextInFlow) {
// The child doesn't have a next-in-flow so create a continuing
// frame. This hooks the child into the flow
nsIFrame* continuingFrame;
rv = presContext->PresShell()->FrameConstructor()->
CreateContinuingFrame(presContext, kidFrame, this,
&continuingFrame);
CreateContinuingFrame(presContext, kidFrame, this, &kidNextInFlow);
if (NS_FAILED(rv)) {
aStatus = NS_FRAME_COMPLETE;
break;
}
// Add the continuing frame to the sibling list
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
kidFrame->SetNextSibling(continuingFrame);
// Update rowGroups with the new rowgroup, just as it
// would have been if we had called OrderRowGroups
// again. Note that rowGroups doesn't get used again after
// we PushChildren below, anyway.
rowGroups.InsertElementAt(childX + 1, continuingFrame);
}
else {
// put the nextinflow so that it will get pushed
rowGroups.InsertElementAt(childX + 1, kidNextInFlow);
// Insert the continuing frame into the sibling list.
mFrames.InsertFrame(nsnull, kidFrame, kidNextInFlow);
// Fall through and update |rowGroups| with the new rowgroup, just as
// it would have been if we had called OrderRowGroups again.
// Note that rowGroups doesn't get used again after we PushChildren
// below, anyway.
}
// Put the nextinflow so that it will get pushed
rowGroups.InsertElementAt(childX + 1, kidNextInFlow);
// We've used up all of our available space so push the remaining
// children to the next-in-flow
nsIFrame* nextSibling = kidFrame->GetNextSibling();

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

@ -936,11 +936,8 @@ nsTableRowGroupFrame::CreateContinuingRowFrame(nsPresContext& aPresContext,
}
// Add the continuing row frame to the child list
nsIFrame* nextRow;
GetNextFrame(&aRowFrame, &nextRow);
(*aContRowFrame)->SetNextSibling(nextRow);
aRowFrame.SetNextSibling(*aContRowFrame);
mFrames.InsertFrame(nsnull, &aRowFrame, *aContRowFrame);
// Push the continuing row frame and the frames that follow
PushChildren(&aPresContext, *aContRowFrame, &aRowFrame);
}

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

@ -2118,24 +2118,11 @@ nsBoxFrame::RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIBox* aChild)
return NS_OK;
}
// Take aChild out of its old position in the child list.
if (curPrevSib)
curPrevSib->SetNextSibling(aChild->GetNextSibling());
else
mFrames.SetFrames(aChild->GetNextSibling());
// Take |aChild| out of its old position in the child list.
mFrames.RemoveFrame(aChild, curPrevSib);
nsIBox* newNextSib;
if (newPrevSib) {
// insert |aChild| between |newPrevSib| and its next sibling
newNextSib = newPrevSib->GetNextSibling();
newPrevSib->SetNextSibling(aChild);
} else {
// no |newPrevSib| found, so this box will become |mFirstChild|
newNextSib = mFrames.FirstChild();
mFrames.SetFrames(aChild);
}
aChild->SetNextSibling(newNextSib);
// Insert it after |newPrevSib| or at the start if it's null.
mFrames.InsertFrame(nsnull, newPrevSib, aChild);
return NS_OK;
}