зеркало из https://github.com/mozilla/pjs.git
Bug 233463, patch 0 - Use nsFrameList methods instead of nsIFrame::SetNextSibling. r=bzbarsky
This commit is contained in:
Родитель
9456708e63
Коммит
b97e6400ed
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче