prevSibling = nsnull;
nsCSSBlockFrame::CreateNewFrames(nsIPresContext* aPresContext){  NS_ASSERTION((nsnull == mOverflowLines) && (nsnull == mNextInFlow),               "bad call to CreateNewFrames");  // Get our last line and then get its last child. Use that  // information to determine our kidContentIndex.  LineData* lastLine = LastLine(mLines);  nsIFrame* lastFrame;  PRInt32 kidContentIndex;  if (nsnull != lastLine) {    lastFrame = lastLine->LastChild();    lastFrame->GetContentIndex(kidContentIndex);    if (lastLine->GetLastContentIsComplete()) {      kidContentIndex++;    }    else {#ifdef NS_DEBUG      // Because we always create continuations as we find them (XXX      // sigh) instead of when we need them, we can assert that if the      // last child is not complete then it already has a continuation.      nsIFrame* kidNextInFlow;      lastFrame->GetNextInFlow(kidNextInFlow);      NS_ASSERTION(nsnull != kidNextInFlow, "whoops");    }#endif  }  else {    // We can't have an empty line list and have a prev-in-flow. If we    // have a prev-in-flow then we are its continuation which means it    // must have pushed some lines into its overflow list; therefore    // we must have some lines.    NS_ASSERTION(nsnull == mPrevInFlow, "prev-in-flow without overflow lines");    lastFrame = nsnull;    kidContentIndex = 0;  }  // Make sure that new inlines go onto the end of the lastLine when  // the lastLine is mapping inline frames.  PRInt32 pendingInlines = 0;  if (nsnull != lastLine) {    if (!lastLine->IsBlock()) {      pendingInlines = 1;    }  }  // Now create frames for all of the new content.  nsresult rv;  PRInt32 lastContentIndex;  lastContentIndex = mContent->ChildCount();  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,     ("enter nsCSSBlockFrame::CreateNewFrames: kidContentIndex=%d lastContentIndex=%d",      kidContentIndex, lastContentIndex));  for (; kidContentIndex < lastContentIndex; kidContentIndex++) {    nsIContent* kid;    kid = mContent->ChildAt(kidContentIndex);    if (nsnull == kid) {      break;    }    // Create frame for our new child and add it to the sibling list    nsIFrame* frame;    rv = nsHTMLBase::CreateFrame(aPresContext, this, kid, nsnull, frame);    NS_RELEASE(kid);    if (NS_OK != rv) {      return rv;    }    if (nsnull != lastFrame) {      lastFrame->SetNextSibling(frame);    }    lastFrame = frame;//XXX    childPrevInFlow = nsnull;    NS_FRAME_TRACE(NS_FRAME_TRACE_NEW_FRAMES,       ("nsCSSBlockFrame::CreateNewFrames: new-frame=%p", frame));    // See if the child is a block or non-block    const nsStyleDisplay* kidDisplay;    rv = frame->GetStyleData(eStyleStruct_Display,                             (const nsStyleStruct*&) kidDisplay);    if (NS_OK != rv) {      return rv;    }    PRBool isBlock = TreatFrameAsBlock(kidDisplay);    // If the child is an inline then add it to the lastLine (if it's    // an inline line, otherwise make a new line). If the child is a    // block then make a new line and put the child in that line.    if (isBlock) {      // If the previous line has pending inline data to be reflowed,      // do so now.      if (0 != pendingInlines) {        // Set this to true in case we don't end up reflowing all of the        // frames on the line (because they end up being pushed).        lastLine->SetLastContentIsComplete();        lastLine->MarkDirty();        pendingInlines = 0;      }      // Create a line for the block      LineData* line = new LineData(frame, 1,                                    (LINE_IS_BLOCK |                                     LINE_LAST_CONTENT_IS_COMPLETE));      if (nsnull == line) {        return NS_ERROR_OUT_OF_MEMORY;      }      if (nsnull == lastLine) {        mLines = line;      }      else {        lastLine->mNext = line;      }      lastLine = line;    }    else {      // Queue up the inlines for reflow later on      if (0 == pendingInlines) {        LineData* line = new LineData(frame, 0, 0);        if (nsnull == line) {          return NS_ERROR_OUT_OF_MEMORY;        }        if (nsnull == lastLine) {          mLines = line;        }        else {          lastLine->mNext = line;        }        lastLine = line;      }      lastLine->mChildCount++;      pendingInlines++;    }  }  if (0 != pendingInlines) {    // Set this to true in case we don't end up reflowing all of the    // frames on the line (because they end up being pushed).    lastLine->SetLastContentIsComplete();    lastLine->MarkDirty();  }  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,     ("exit nsCSSBlockFrame::CreateNewFrames"));  return NS_OK;}// XXX keep the text-run data in the first-in-flow of the blocknsresultnsCSSBlockFrame::FindTextRuns(nsCSSBlockReflowState& aState){  // Destroy old run information first  nsCSSTextRun::DeleteTextRuns(mTextRuns);  mTextRuns = nsnull;  aState.mLineLayout.ResetTextRuns();  // Ask each child that implements nsIInlineReflow to find its text runs  LineData* line = mLines;  while (nsnull != line) {    if (!line->IsBlock()) {      nsIFrame* frame = line->mFirstChild;      PRInt32 n = line->mChildCount;      while (--n >= 0) {        nsIInlineReflow* inlineReflow;        if (NS_OK == frame->QueryInterface(kIInlineReflowIID,                                           (void**)&inlineReflow)) {          nsresult rv = inlineReflow->FindTextRuns(aState.mLineLayout,                                                   aState.reflowCommand);          if (NS_OK != rv) {            return rv;          }        }        else {          // A frame that doesn't implement nsIInlineReflow isn't text          // therefore it will end an open text run.          aState.mLineLayout.EndTextRun();        }        frame->GetNextSibling(frame);      }    }    else {      // A frame that doesn't implement nsIInlineReflow isn't text      // therefore it will end an open text run.      aState.mLineLayout.EndTextRun();    }    line = line->mNext;  }  aState.mLineLayout.EndTextRun();  // Now take the text-runs away from the line layout engine.  mTextRuns = aState.mLineLayout.TakeTextRuns();  return NS_OK;}nsresultnsCSSBlockFrame::FrameInsertedReflow(nsCSSBlockReflowState& aState){  LineData* line = mLines;  while (nsnull != line->mNext) {    if (line->IsDirty()) {      break;    }    line = line->mNext;  }  NS_ASSERTION(nsnull != line, "bad inserted reflow");  //XXX return ReflowDirtyLines(aState, line);  // XXX Correct implementation: reflow the dirty lines only; all  // other lines can be moved; recover state before first dirty line.  // XXX temporary  aState.GetAvailableSpace();  aState.mPrevLine = nsnull;  return ReflowLinesAt(aState, mLines);}// XXX Todo: some incremental reflows are passing through this block// and into a child block; those cannot impact our text-runs. In that// case skip the FindTextRuns work.// XXX easy optimizations: find the line that contains the next child// in the reflow-command path and mark it dirty and only reflow it;// recover state before it, slide lines down after it.nsresultnsCSSBlockFrame::ChildIncrementalReflow(nsCSSBlockReflowState& aState){  // Generate text-run information; this will also "fluff out" any  // inline children's frame tree.  nsresult rv = FindTextRuns(aState);  if (NS_OK != rv) {    return rv;  }  // XXX temporary  aState.GetAvailableSpace();  aState.mPrevLine = nsnull;  return ReflowLinesAt(aState, mLines);}nsresultnsCSSBlockFrame::ResizeReflow(nsCSSBlockReflowState& aState){  // Mark everything dirty  LineData* line = mLines;  while (nsnull != line) {    line->MarkDirty();    line = line->mNext;  }  // Reflow all of our lines  aState.GetAvailableSpace();  aState.mPrevLine = nsnull;  return ReflowLinesAt(aState, mLines);}nsresultnsCSSBlockFrame::ReflowLinesAt(nsCSSBlockReflowState& aState, LineData* aLine){  if ((nsnull != mRunInFloaters) && (aLine == mLines)) {    aState.PlaceBelowCurrentLineFloaters(mRunInFloaters);  }  // Reflow the lines that are already ours  while (nsnull != aLine) {    nsInlineReflowStatus rs;    if (!ReflowLine(aState, aLine, rs)) {      if (NS_IS_REFLOW_ERROR(rs)) {        return nsresult(rs);      }      return NS_FRAME_NOT_COMPLETE;    }    aState.mLineLayout.NextLine();    aState.mPrevLine = aLine;    aLine = aLine->mNext;  }  // Pull data from a next-in-flow if we can  while (nsnull != aState.mNextInFlow) {    // Grab first line from our next-in-flow    aLine = aState.mNextInFlow->mLines;    if (nsnull == aLine) {      aState.mNextInFlow = (nsCSSBlockFrame*) aState.mNextInFlow->mNextInFlow;      continue;    }    // XXX See if the line is not dirty; if it's not maybe we can    // avoid the pullup if it can't fit?    aState.mNextInFlow->mLines = aLine->mNext;    aLine->mNext = nsnull;    if (0 == aLine->mChildCount) {      // The line is empty. Try the next one.      NS_ASSERTION(nsnull == aLine->mChildCount, "bad empty line");      aLine->mNext = aState.mFreeList;      aState.mFreeList = aLine;      continue;    }    // Make the children in the line ours.    nsIFrame* frame = aLine->mFirstChild;    nsIFrame* lastFrame = nsnull;    PRInt32 n = aLine->mChildCount;    while (--n >= 0) {      nsIFrame* geometricParent;      nsIFrame* contentParent;      frame->GetGeometricParent(geometricParent);      frame->GetContentParent(contentParent);      if (contentParent == geometricParent) {        frame->SetContentParent(this);      }      frame->SetGeometricParent(this);      lastFrame = frame;      frame->GetNextSibling(frame);    }    lastFrame->SetNextSibling(nsnull);#ifdef NS_DEBUG    LastChild(lastFrame);    NS_ASSERTION(lastFrame == aState.mPrevChild, "bad aState.mPrevChild");#endif    // Add line to our line list    if (nsnull == aState.mPrevLine) {      NS_ASSERTION(nsnull == mLines, "bad aState.mPrevLine");      mLines = aLine;    }    else {      NS_ASSERTION(nsnull == aState.mPrevLine->mNext, "bad aState.mPrevLine");      aState.mPrevLine->mNext = aLine;      aState.mPrevChild->SetNextSibling(aLine->mFirstChild);    }#ifdef NS_DEBUG    if (GetVerifyTreeEnable()) {      VerifyChildCount(mLines);    }#endif    // Now reflow it and any lines that it makes during it's reflow.    while (nsnull != aLine) {      nsInlineReflowStatus rs;      if (!ReflowLine(aState, aLine, rs)) {        if (NS_IS_REFLOW_ERROR(rs)) {          return nsresult(rs);        }        return NS_FRAME_NOT_COMPLETE;      }      aState.mLineLayout.NextLine();      aState.mPrevLine = aLine;      aLine = aLine->mNext;    }  }  return NS_FRAME_COMPLETE;}/** * Reflow a line. The line will either contain a single block frame * or contain 1 or more inline frames. */PRBoolnsCSSBlockFrame::ReflowLine(nsCSSBlockReflowState& aState,                            LineData*              aLine,                            nsInlineReflowStatus&  aReflowResult){  PRBool keepGoing = PR_FALSE;  nsCSSBlockFrame* nextInFlow;  aState.mInlineLayoutPrepared = PR_FALSE;  aLine->ClearDirty();  // Reflow mapped frames in the line  PRInt32 n = aLine->mChildCount;  if (0 != n) {    nsIFrame* frame = aLine->mFirstChild;#ifdef NS_DEBUG    const nsStyleDisplay* display;    frame->GetStyleData(eStyleStruct_Display,                        (const nsStyleStruct*&) display);    PRBool isBlock = TreatFrameAsBlock(display);    NS_ASSERTION(isBlock == aLine->IsBlock(), "bad line isBlock");#endif    if (aLine->IsBlock()) {      keepGoing = ReflowBlockFrame(aState, aLine, frame, aReflowResult);      return keepGoing;    }    else {      while (--n >= 0) {        if (!ReflowInlineFrame(aState, aLine, frame, aReflowResult)) {          goto done;        }        frame->GetNextSibling(frame);      }    }  }  // Pull frames from the next line until we can't  while (nsnull != aLine->mNext) {    LineData** linep = &aLine->mNext;    keepGoing = PullFrame(aState, aLine, &aLine->mNext,                          PR_FALSE, aReflowResult);    if (!keepGoing) {      goto done;    }  }  // Pull frames from the next-in-flow(s) until we can't  nextInFlow = aState.mNextInFlow;  while (nsnull != nextInFlow) {    LineData* line = nextInFlow->mLines;    if (nsnull == line) {      nextInFlow = (nsCSSBlockFrame*) nextInFlow->mNextInFlow;      aState.mNextInFlow = nextInFlow;      continue;    }    keepGoing = PullFrame(aState, aLine, &nextInFlow->mLines,                          PR_TRUE, aReflowResult);    if (!keepGoing) {      goto done;    }  }  keepGoing = PR_TRUE;done:;  if (!aLine->IsBlock()) {    return PlaceLine(aState, aLine, aReflowResult);  }  return keepGoing;}PRBoolnsCSSBlockFrame::ReflowBlockFrame(nsCSSBlockReflowState& aState,                                  LineData*              aLine,                                  nsIFrame*              aFrame,                                  nsInlineReflowStatus&  aReflowResult){  NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW,     ("nsCSSBlockFrame::ReflowBlockFrame: line=%p frame=%p y=%d",      aLine, aFrame, aState.mY));  // Get the block's margins  nsMargin blockMargin;  const nsStyleSpacing* blockSpacing;  aFrame->GetStyleData(eStyleStruct_Spacing,                       (const nsStyleStruct*&)blockSpacing);  blockSpacing->CalcMarginFor(aFrame, blockMargin);  // XXX ebina margins...  nscoord posTopMargin, negTopMargin;  if (blockMargin.top < 0) {    negTopMargin = -blockMargin.top;    posTopMargin = 0;  }  else {    negTopMargin = 0;    posTopMargin = blockMargin.top;  }  nscoord prevPos = aState.mPrevPosBottomMargin;  nscoord prevNeg = aState.mPrevNegBottomMargin;  nscoord maxPos = PR_MAX(prevPos, posTopMargin);  nscoord maxNeg = PR_MAX(prevNeg, negTopMargin);  nscoord topMargin = maxPos - maxNeg;  // Remember bottom margin for next time  if (blockMargin.bottom < 0) {    aState.mPrevNegBottomMargin = -blockMargin.bottom;    aState.mPrevPosBottomMargin = 0;  }  else {    aState.mPrevNegBottomMargin = 0;    aState.mPrevPosBottomMargin = blockMargin.bottom;  }  nscoord x = aState.mX + blockMargin.left;  nscoord y = aState.mY + topMargin;  aFrame->WillReflow(*aState.mPresContext);  aFrame->MoveTo(x, y);  // Compute the available space that the child block can reflow into  nsSize availSize;  if (aState.mUnconstrainedWidth) {    // Never give a block an unconstrained width    if (!aState.mHaveBlockMaxWidth) {      const nsReflowState* rsp = aState.parentReflowState;      aState.mBlockMaxWidth = 0;      while (nsnull != rsp) {        if (NS_UNCONSTRAINEDSIZE != rsp->maxSize.width) {NS_ASSERTION(rsp->maxSize.width < 1000000, "whoops: bad parent");          aState.mBlockMaxWidth = rsp->maxSize.width;          const nsStyleSpacing* spacing = nsnull;          rsp->frame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);          if (nsnull!=spacing)          {            nsMargin borderPadding;            spacing->CalcBorderPaddingFor(rsp->frame, borderPadding);            aState.mBlockMaxWidth -= (borderPadding.right + borderPadding.left);          }          break;        }        rsp = rsp->parentReflowState;      }      NS_ASSERTION(0 != aState.mBlockMaxWidth, "no width for block found");      aState.mHaveBlockMaxWidth = PR_TRUE;    }    availSize.width = aState.mBlockMaxWidth;  }  else {    availSize.width = aState.mInnerSize.width -      (blockMargin.left + blockMargin.right);  }  availSize.height = aState.mBottomEdge - y;  NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW,     ("nsCSSBlockFrame::ReflowBlockFrame: availSize={%d,%d}",      availSize.width, availSize.height));  // Determine the reason for the reflow  nsReflowReason reason = eReflowReason_Resize;  nsFrameState state;  aFrame->GetFrameState(state);  if (NS_FRAME_FIRST_REFLOW & state) {    reason = eReflowReason_Initial;  }  else if (aState.mInlineLayout.mNextRCFrame == aFrame) {    reason = eReflowReason_Incremental;    // Make sure we only incrementally reflow once    aState.mInlineLayout.mNextRCFrame = nsnull;  }  // Reflow the block frame. Use the run-around API if possible;  // otherwise treat it as a rectangular lump and place it.  nsresult rv;  nsSize kidMaxElementSize;  nsReflowMetrics metrics(aState.mComputeMaxElementSize                          ? &kidMaxElementSize                          : nsnull);  nsReflowStatus reflowStatus;  nsIRunaround* runAround;  if ((nsnull != aState.mSpaceManager) &&      (NS_OK == aFrame->QueryInterface(kIRunaroundIID, (void**)&runAround))) {    // Reflow the block    nsReflowState reflowState(aFrame, aState, availSize);    reflowState.reason = reason;    nsRect r;    aState.mSpaceManager->Translate(x, y);    rv = runAround->Reflow(aState.mPresContext, aState.mSpaceManager,                           metrics, reflowState, r, reflowStatus);    aState.mSpaceManager->Translate(-x, -y);    metrics.width = r.width;    metrics.height = r.height;    metrics.ascent = r.height;    metrics.descent = 0;  }  else {    nsReflowState reflowState(aFrame, aState, availSize);    reflowState.reason = reason;    rv = aFrame->Reflow(aState.mPresContext, metrics, reflowState,                        reflowStatus);  }  if (NS_IS_REFLOW_ERROR(rv)) {    aReflowResult = nsInlineReflowStatus(rv);    return PR_FALSE;  }  if (NS_FRAME_IS_COMPLETE(reflowStatus)) {    nsIFrame* kidNextInFlow;    aFrame->GetNextInFlow(kidNextInFlow);    if (nsnull != kidNextInFlow) {      // Remove all of the childs next-in-flows. Make sure that we ask      // the right parent to do the removal (it's possible that the      // parent is not this because we are executing pullup code)      nsIFrame* parent;      aFrame->GetGeometricParent(parent);      ((nsCSSBlockFrame*)parent)->DeleteNextInFlowsFor(aFrame);    }    aLine->SetLastContentIsComplete();    aReflowResult = NS_FRAME_COMPLETE;  }  else {    aLine->ClearLastContentIsComplete();    aReflowResult = NS_FRAME_NOT_COMPLETE;  }  // See if it fit  nscoord newY = y + metrics.height;  NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW,     ("nsCSSBlockFrame::ReflowBlockFrame: metrics={%d,%d} newY=%d maxY=%d",      metrics.width, metrics.height, newY, aState.mBottomEdge));  if ((mLines != aLine) && (newY > aState.mBottomEdge)) {    // None of the block fit. Push aLine and any other lines that follow    PushLines(aState);    aReflowResult = NS_INLINE_LINE_BREAK_BEFORE(reflowStatus);    return PR_FALSE;  }  // Update max-element-size  if (aState.mComputeMaxElementSize) {    if (kidMaxElementSize.width > aState.mMaxElementSize.width) {      aState.mMaxElementSize.width = kidMaxElementSize.width;    }    if (kidMaxElementSize.height > aState.mMaxElementSize.height) {      aState.mMaxElementSize.height = kidMaxElementSize.height;    }  }  // Save away bounds before other adjustments  aLine->mBounds.x = x;  aLine->mBounds.y = y;  aLine->mBounds.width = metrics.width;  aLine->mBounds.height = metrics.height;  nscoord xmost = aLine->mBounds.XMost();NS_ASSERTION(xmost < 1000000, "bad line width");  if (xmost > aState.mKidXMost) {    aState.mKidXMost = xmost;  }  // Place child then align it and relatively position it  aFrame->SetRect(aLine->mBounds);  aState.mY = newY;  if (!aState.mUnconstrainedWidth) {    nsCSSLayout::HorizontallyPlaceChildren(aState.mPresContext,                                           aState.mBlock,                                           aState.mTextAlign,                                           aState.mDirection,                                           aFrame, 1,                                           metrics.width,                                           availSize.width);  }  nsCSSLayout::RelativePositionChildren(aState.mPresContext,                                        aState.mBlock,                                        aFrame, 1);  aState.mPrevChild = aFrame;  if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) {    // Some of the block fit. We need to have the block frame    // continued, so we make sure that it has a next-in-flow now.    nsIFrame* nextInFlow;    rv = aState.mInlineLayout.MaybeCreateNextInFlow(aFrame, nextInFlow);    if (NS_OK != rv) {      aReflowResult = nsInlineReflowStatus(rv);      return PR_FALSE;    }    if (nsnull != nextInFlow) {      // We made a next-in-flow for the block child frame. Create a      // line to map the block childs next-in-flow.      LineData* line = new LineData(nextInFlow, 1,                                    (LINE_IS_BLOCK |                                     LINE_LAST_CONTENT_IS_COMPLETE));      if (nsnull == line) {        aReflowResult = nsInlineReflowStatus(NS_ERROR_OUT_OF_MEMORY);        return PR_FALSE;      }      line->mNext = aLine->mNext;      aLine->mNext = line;    }    // Advance mPrevLine because we are keeping aLine (since some of    // the child block frame fit). Then push any remaining lines to    // our next-in-flow    aState.mPrevLine = aLine;    if (nsnull != aLine->mNext) {      PushLines(aState);    }    aReflowResult = NS_INLINE_LINE_BREAK_AFTER(reflowStatus);    return PR_FALSE;  }  return PR_TRUE;}PRBoolnsCSSBlockFrame::ReflowInlineFrame(nsCSSBlockReflowState& aState,                                   LineData*              aLine,                                   nsIFrame*              aFrame,                                   nsInlineReflowStatus&  aReflowResult){  if (!aState.mInlineLayoutPrepared) {    aState.mLineLayout.Prepare(aState.mX);    aState.mInlineLayout.Prepare(aState.mUnconstrainedWidth, aState.mNoWrap,                                 aState.mComputeMaxElementSize);    aState.mInlineLayout.SetReflowSpace(aState.mCurrentBand.availSpace.x,                                        aState.mY,                                        aState.mCurrentBand.availSpace.width,                                        aState.mCurrentBand.availSpace.height);    // If we we are a list-item container and we are positioning the    // first child on the line (which is true when !mInlineLayoutPrepared)    // and it's the first line, and we are not a continuation, then    // set the mIsBullet flag for the line layout code.    if (aState.mLineLayout.mListPositionOutside &&        (0 == aState.mLineLayout.mLineNumber) &&        (nsnull == mPrevInFlow)) {      aState.mInlineLayout.mIsBullet = PR_TRUE;    }    aState.mInlineLayoutPrepared = PR_TRUE;  }  nsresult rv;  nsIFrame* nextInFlow;  aReflowResult = aState.mInlineLayout.ReflowAndPlaceFrame(aFrame);  aState.mInlineLayout.mIsBullet = PR_FALSE;  if (NS_IS_REFLOW_ERROR(aReflowResult)) {    return PR_FALSE;  }  PRBool lineWasComplete = aLine->GetLastContentIsComplete();  if (!NS_INLINE_IS_BREAK(aReflowResult)) {    aState.mPrevChild = aFrame;    if (NS_FRAME_IS_COMPLETE(aReflowResult)) {      aFrame->GetNextSibling(aFrame);      aLine->SetLastContentIsComplete();      return PR_TRUE;    }    // Create continuation frame (if necessary); add it to the end of    // the current line so that it can be pushed to the next line    // properly.    aLine->ClearLastContentIsComplete();    rv = aState.mInlineLayout.MaybeCreateNextInFlow(aFrame, nextInFlow);    if (NS_OK != rv) {      aReflowResult = nsInlineReflowStatus(rv);      return PR_FALSE;    }    if (nsnull != nextInFlow) {      // Add new child to the line      aLine->mChildCount++;    }    aFrame->GetNextSibling(aFrame);  }  else {    if (NS_INLINE_IS_BREAK_AFTER(aReflowResult)) {      aState.mPrevChild = aFrame;      if (NS_FRAME_IS_COMPLETE(aReflowResult)) {        aLine->SetLastContentIsComplete();      }      else {        // Create continuation frame (if necessary); add it to the end of        // the current line so that it can be pushed to the next line        // properly.        aLine->ClearLastContentIsComplete();        rv = aState.mInlineLayout.MaybeCreateNextInFlow(aFrame, nextInFlow);        if (NS_OK != rv) {          aReflowResult = nsInlineReflowStatus(rv);          return PR_FALSE;        }        if (nsnull != nextInFlow) {          // Add new child to the line          aLine->mChildCount++;        }      }      aFrame->GetNextSibling(aFrame);    }    else {      NS_ASSERTION(aLine->GetLastContentIsComplete(), "bad mState");    }  }  // Split line since we aren't going to keep going  rv = SplitLine(aState, aLine, aFrame, lineWasComplete);  if (NS_IS_REFLOW_ERROR(rv)) {    aReflowResult = nsInlineReflowStatus(rv);  }  return PR_FALSE;}// XXX alloc lines using free-list in aState// XXX refactor this since the split NEVER has to deal with blocksnsresultnsCSSBlockFrame::SplitLine(nsCSSBlockReflowState& aState,                           LineData*              aLine,                           nsIFrame*              aFrame,                           PRBool                 aLineWasComplete){  PRInt32 pushCount = aLine->mChildCount - aState.mInlineLayout.mFrameNum;  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,     ("nsCSSBlockFrame::SplitLine: pushing %d frames",      pushCount));  if (0 != pushCount) {    NS_ASSERTION(nsnull != aFrame, "whoops");    LineData* to = aLine->mNext;    if (nsnull != to) {      // Only push into the next line if it's empty; otherwise we can      // end up pushing a frame which is continued into the same frame      // as it's continuation. This causes all sorts of bad side      // effects so we don't allow it.      if (to->mChildCount != 0) {        LineData* insertedLine = new LineData(aFrame, pushCount, 0);        aLine->mNext = insertedLine;        insertedLine->mNext = to;        to = insertedLine;      } else {        to->mFirstChild = aFrame;        to->mChildCount += pushCount;      }    } else {      to = new LineData(aFrame, pushCount, 0);      aLine->mNext = to;    }    if (nsnull == to) {      return NS_ERROR_OUT_OF_MEMORY;    }    to->SetLastContentIsComplete(aLineWasComplete);    aLine->mChildCount -= pushCount;#ifdef NS_DEBUG    if (GetVerifyTreeEnable()) {      aLine->Verify();    }#endif    NS_ASSERTION(0 != aLine->mChildCount, "bad push");  }  return NS_OK;}PRBoolnsCSSBlockFrame::PullFrame(nsCSSBlockReflowState& aState,                           LineData*              aLine,                           LineData**             aFromList,                           PRBool                 aUpdateGeometricParent,                           nsInlineReflowStatus&  aReflowResult){  LineData* fromLine = *aFromList;  NS_ASSERTION(nsnull != fromLine, "bad line to pull from");  if (0 == fromLine->mChildCount) {    // Discard empty lines immediately. Empty lines can happen here    // because of DeleteChildsNextInFlow not being able to delete    // lines.    *aFromList = fromLine->mNext;    NS_ASSERTION(nsnull == fromLine->mFirstChild, "bad empty line");    fromLine->mNext = aState.mFreeList;    aState.mFreeList = fromLine;    return PR_TRUE;  }  // If our line is not empty and the child in aFromLine is a block  // then we cannot pull up the frame into this line.  if ((0 != aLine->mChildCount) && fromLine->IsBlock()) {    aReflowResult = NS_INLINE_LINE_BREAK_BEFORE(0);    return PR_FALSE;  }  // Take frame from fromLine  nsIFrame* frame = fromLine->mFirstChild;  if (0 == aLine->mChildCount++) {    aLine->mFirstChild = frame;    aLine->SetIsBlock(fromLine->IsBlock());#ifdef NS_DEBUG    const nsStyleDisplay* display;    frame->GetStyleData(eStyleStruct_Display,                        (const nsStyleStruct*&) display);    PRBool isBlock = TreatFrameAsBlock(display);    NS_ASSERTION(isBlock == aLine->IsBlock(), "bad line isBlock");#endif  }  if (0 != --fromLine->mChildCount) {    frame->GetNextSibling(fromLine->mFirstChild);  }  else {    // Free up the fromLine now that it's empty    *aFromList = fromLine->mNext;    fromLine->mFirstChild = nsnull;    fromLine->mNext = aState.mFreeList;    aState.mFreeList = fromLine;  }  // Change geometric parents  if (aUpdateGeometricParent) {    nsIFrame* geometricParent;    nsIFrame* contentParent;    frame->GetGeometricParent(geometricParent);    frame->GetContentParent(contentParent);    if (contentParent == geometricParent) {      frame->SetContentParent(this);    }    frame->SetGeometricParent(this);    // The frame is being pulled from a next-in-flow; therefore we    // need to add it to our sibling list.    if (nsnull != aState.mPrevChild) {      aState.mPrevChild->SetNextSibling(frame);    }    frame->SetNextSibling(nsnull);  }  // Reflow the frame  if (aLine->IsBlock()) {    return ReflowBlockFrame(aState, aLine, frame, aReflowResult);  }  else {    return ReflowInlineFrame(aState, aLine, frame, aReflowResult);  }}PRBoolnsCSSBlockFrame::PlaceLine(nsCSSBlockReflowState& aState,                           LineData*              aLine,                           nsInlineReflowStatus   aReflowStatus){  // Align the children. This also determines the actual height and  // width of the line.  aState.mInlineLayout.AlignFrames(aLine->mFirstChild, aLine->mChildCount,                                   aLine->mBounds);  // See if the line fit. If it doesn't we need to push it. Our first  // line will always fit.  // XXX This is a good place to check and see if we have  // below-current-line floaters, and if we do make sure that they fit  // too.  nscoord newY = aState.mY + aLine->mBounds.height;  NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW,     ("nsCSSBlockFrame::PlaceLine: newY=%d limit=%d lineHeight=%d",      newY, aState.mBottomEdge, aLine->mBounds.height));  if ((mLines != aLine) && (newY > aState.mBottomEdge)) {    // Push this line and all of it's children and anything else that    // follows to our next-in-flow    PushLines(aState);    return PR_FALSE;  }  // Update max-element-size  if (aState.mComputeMaxElementSize) {    nsSize& lineMaxElementSize = aState.mInlineLayout.mMaxElementSize;    if (lineMaxElementSize.width > aState.mMaxElementSize.width) {      aState.mMaxElementSize.width = lineMaxElementSize.width;    }    if (lineMaxElementSize.height > aState.mMaxElementSize.height) {      aState.mMaxElementSize.height = lineMaxElementSize.height;    }  }  nscoord xmost = aLine->mBounds.XMost();NS_ASSERTION(xmost < 1000000, "bad line width");  if (xmost > aState.mKidXMost) {    aState.mKidXMost = xmost;  }  aState.mY = newY;  // Based on the last child we reflowed reflow status, we may need to  // clear past any floaters.  if (NS_INLINE_IS_BREAK_AFTER(aReflowStatus)) {    // Apply break to the line    PRUint8 breakType = NS_INLINE_GET_BREAK_TYPE(aReflowStatus);    switch (breakType) {    default:      break;    case NS_STYLE_CLEAR_LEFT:    case NS_STYLE_CLEAR_RIGHT:    case NS_STYLE_CLEAR_LEFT_AND_RIGHT:      NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,         ("nsCSSBlockFrame::PlaceLine: clearing floaters=%d",          breakType));      aState.ClearFloaters(breakType);      break;    }    // XXX page breaks, etc, need to be passed upwards too!  }  // Any below current line floaters to place?  // XXX We really want to know whether this is the initial reflow (reflow  // unmapped) or a subsequent reflow in which case we only need to offset  // the existing floaters...  if (aState.mPendingFloaters.Count() > 0) {    if (nsnull == aLine->mFloaters) {      aLine->mFloaters = new nsVoidArray;    }    aLine->mFloaters->operator=(aState.mPendingFloaters);    aState.mPendingFloaters.Clear();  }  if (nsnull != aLine->mFloaters) {    aState.PlaceBelowCurrentLineFloaters(aLine->mFloaters);    // XXX Factor in the height of the floaters as well when considering    // whether the line fits.    // The default policy is that if there isn't room for the floaters then    // both the line and the floaters are pushed to the next-in-flow...  }  if (aState.mY >= aState.mCurrentBand.availSpace.YMost()) {    // The current y coordinate is now past our available space    // rectangle. Get a new band of space.    aState.GetAvailableSpace();  }  return PR_TRUE;}voidnsCSSBlockFrame::PushLines(nsCSSBlockReflowState& aState){  NS_ASSERTION(nsnull != aState.mPrevLine, "bad push");  LineData* lastLine = aState.mPrevLine;  LineData* nextLine = lastLine->mNext;  lastLine->mNext = nsnull;  mOverflowLines = nextLine;  // Break frame sibling list  nsIFrame* lastFrame = lastLine->LastChild();  lastFrame->SetNextSibling(nsnull);  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,     ("nsCSSBlockFrame::PushLines: line=%p prevInFlow=%p nextInFlow=%p",      mOverflowLines, mPrevInFlow, mNextInFlow));#ifdef NS_DEBUG  if (GetVerifyTreeEnable()) {    VerifyChildCount(mLines);    VerifyChildCount(mOverflowLines, PR_TRUE);  }#endif}nsresultnsCSSBlockFrame::DrainOverflowLines(){  // First grab the prev-in-flows overflow lines  nsCSSBlockFrame* prevBlock = (nsCSSBlockFrame*) mPrevInFlow;  if (nsnull != prevBlock) {    LineData* line = prevBlock->mOverflowLines;    if (nsnull != line) {      NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,         ("nsCSSBlockFrame::DrainOverflowLines: line=%p prevInFlow=%p",          line, prevBlock));      prevBlock->mOverflowLines = nsnull;      // Make all the frames on the mOverflowLines list mine      nsIFrame* lastFrame = nsnull;      nsIFrame* frame = line->mFirstChild;      while (nsnull != frame) {        nsIFrame* geometricParent;        nsIFrame* contentParent;        frame->GetGeometricParent(geometricParent);        frame->GetContentParent(contentParent);        if (contentParent == geometricParent) {          frame->SetContentParent(this);        }        frame->SetGeometricParent(this);        lastFrame = frame;        frame->GetNextSibling(frame);      }      // Join the line lists      if (nsnull == mLines) {        mLines = line;      }      else {        // Join the sibling lists together        lastFrame->SetNextSibling(mLines->mFirstChild);        // Place overflow lines at the front of our line list        LineData* lastLine = LastLine(line);        lastLine->mNext = mLines;        mLines = line;      }      // Update our first-content-index now that we have a new first child      mLines->mFirstChild->GetContentIndex(mFirstContentOffset);    }  }  // Now grab our own overflow lines  if (nsnull != mOverflowLines) {    // This can happen when we reflow and not everything fits and then    // we are told to reflow again before a next-in-flow is created    // and reflows.    NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,       ("nsCSSBlockFrame::DrainOverflowLines: from me, line=%p",        mOverflowLines));    LineData* lastLine = LastLine(mLines);    if (nsnull == lastLine) {      mLines = mOverflowLines;      // Update our first-content-index now that we have a new first child      mLines->mFirstChild->GetContentIndex(mFirstContentOffset);    }    else {      lastLine->mNext = mOverflowLines;      nsIFrame* lastFrame = lastLine->LastChild();      lastFrame->SetNextSibling(mOverflowLines->mFirstChild);      // Update our last-content-index now that we have a new last child      lastLine = LastLine(mOverflowLines);      lastLine->LastChild()->GetContentIndex(mLastContentOffset);    }    mOverflowLines = nsnull;  }#ifdef NS_DEBUG  if (GetVerifyTreeEnable()) {    VerifyChildCount(mLines, PR_TRUE);  }#endif  return NS_OK;}// XXX a copy of nsHTMLContainerFrame'sNS_IMETHODIMPnsCSSBlockFrame::ContentAppended(nsIPresShell*   aShell,                                 nsIPresContext* aPresContext,                                 nsIContent*     aContainer){  // Get the last-in-flow  nsCSSBlockFrame* lastInFlow = (nsCSSBlockFrame*)GetLastInFlow();  // Generate a reflow command for the frame  nsIReflowCommand* cmd;  nsresult          result;                                                    result = NS_NewHTMLReflowCommand(&cmd, lastInFlow,                                   nsIReflowCommand::FrameAppended);  if (NS_OK == result) {    aShell->AppendReflowCommand(cmd);    NS_RELEASE(cmd);  }  return NS_OK;}// XXX we assume that the insertion is really an assertion and never an append// XXX what about zero lines caseNS_IMETHODIMPnsCSSBlockFrame::ContentInserted(nsIPresShell*   aShell,                                 nsIPresContext* aPresContext,                                 nsIContent*     aContainer,                                 nsIContent*     aChild,                                 PRInt32         aIndexInParent){  // Find the frame that precedes this frame  nsIFrame* prevSibling = nsnull;  if (aIndexInParent > 0) {    nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1);    prevSibling = aShell->FindFrameWithContent(precedingContent);    NS_ASSERTION(nsnull != prevSibling, "no frame for preceding content");    NS_RELEASE(precedingContent);    // The frame may have a next-in-flow. Get the last-in-flow; we do    // it the hard way because we can't assume that prevSibling is a    // subclass of nsSplittableFrame.    nsIFrame* nextInFlow;    do {      prevSibling->GetNextInFlow(nextInFlow);      if (nsnull != nextInFlow) {        prevSibling = nextInFlow;      }    } while (nsnull != nextInFlow);  }  // Get the parent of the previous sibling (which will be the proper  // next-in-flow for the child). We expect it to be this frame or one  // of our next-in-flow(s).  nsCSSBlockFrame* flow = this;  if (nsnull != prevSibling) {    prevSibling->GetGeometricParent((nsIFrame*&)flow);  }  // Now that we have the right flow block we can create the new  // frame; test and see if the inserted frame is a block or not.  // XXX create-frame could return that fact  nsIFrame* newFrame;  nsresult rv = nsHTMLBase::CreateFrame(aPresContext, flow, aChild,                                        nsnull, newFrame);  if (NS_OK != rv) {    return rv;  }  const nsStyleDisplay* display;  newFrame->GetStyleData(eStyleStruct_Display,                         (const nsStyleStruct*&) display);  PRUint16 newFrameIsBlock = TreatFrameAsBlock(display)    ? LINE_IS_BLOCK    : 0;  // Insert/append the frame into flows line list at the right spot  LineData* newLine;  LineData* line = flow->mLines;  if (nsnull == prevSibling) {    // Insert new frame into the sibling list    newFrame->SetNextSibling(line->mFirstChild);    if (line->IsBlock() || newFrameIsBlock) {      // Create a new line      newLine = new LineData(newFrame, 1, LINE_LAST_CONTENT_IS_COMPLETE |                             newFrameIsBlock);      if (nsnull == newLine) {        return NS_ERROR_OUT_OF_MEMORY;      }      newLine->mNext = flow->mLines;      flow->mLines = newLine;    } else {      // Insert frame at the front of the line      line->mFirstChild = newFrame;      line->mChildCount++;      line->MarkDirty();    }  }  else {    // Find line containing the previous sibling to the new frame    line = FindLineContaining(line, prevSibling);    NS_ASSERTION(nsnull != line, "no line contains the previous sibling");    if (nsnull != line) {      if (line->IsBlock()) {        // Create a new line just after line        newLine = new LineData(newFrame, 1, LINE_LAST_CONTENT_IS_COMPLETE |                               newFrameIsBlock);        if (nsnull == newLine) {          return NS_ERROR_OUT_OF_MEMORY;        }        newLine->mNext = line->mNext;        line->mNext = newLine;      }      else if (newFrameIsBlock) {        // Split line in two, if necessary. We can't allow a block to        // end up in an inline line.        if (line->IsLastChild(prevSibling)) {          // The new frame goes after prevSibling and prevSibling is          // the last frame on the line. Therefore we don't need to          // split the line, just create a new line.          newLine = new LineData(newFrame, 1, LINE_LAST_CONTENT_IS_COMPLETE |                                 newFrameIsBlock);          if (nsnull == newLine) {            return NS_ERROR_OUT_OF_MEMORY;          }          newLine->mNext = line->mNext;          line->mNext = newLine;        }        else {          // The new frame goes after prevSibling and prevSibling is          // somewhere in the line, but not at the end. Split the line          // just after prevSibling.          PRInt32 i, n = line->mChildCount;          nsIFrame* frame = line->mFirstChild;          for (i = 0; i < n; i++) {            if (frame == prevSibling) {              nsIFrame* nextSibling;              prevSibling->GetNextSibling(nextSibling);              // Create new line to hold the remaining frames              NS_ASSERTION(n - i - 1 > 0, "bad line count");              newLine = new LineData(nextSibling, n - i - 1,                               line->mState & LINE_LAST_CONTENT_IS_COMPLETE);              if (nsnull == newLine) {                return NS_ERROR_OUT_OF_MEMORY;              }              newLine->mNext = line->mNext;              line->mNext = newLine;              line->MarkDirty();              line->SetLastContentIsComplete();              line->mChildCount = i + 1;              break;            }            frame->GetNextSibling(frame);          }          // Now create a new line to hold the block          newLine = new LineData(newFrame, 1,                             newFrameIsBlock | LINE_LAST_CONTENT_IS_COMPLETE);          if (nsnull == newLine) {            return NS_ERROR_OUT_OF_MEMORY;          }          newLine->mNext = line->mNext;          line->mNext = newLine;        }      }      else {        // Insert frame into the line.        NS_ASSERTION(line->GetLastContentIsComplete(), "bad line LCIC");        line->mChildCount++;        line->MarkDirty();      }    }    // Insert new frame into the sibling list; note: this must be done    // after the above logic because the above logic depends on the    // sibling list being in the "before insertion" state.    nsIFrame* nextSibling;    prevSibling->GetNextSibling(nextSibling);    newFrame->SetNextSibling(nextSibling);    prevSibling->SetNextSibling(newFrame);  }  // Generate a reflow command  nsIReflowCommand* cmd;  rv = NS_NewHTMLReflowCommand(&cmd, flow, nsIReflowCommand::FrameInserted);  if (NS_OK != rv) {    return rv;  }  aShell->AppendReflowCommand(cmd);  NS_RELEASE(cmd);  // Update the content offsets of the flow block and all that follow  PRBool pseudos = flow->IsPseudoFrame();  flow->mLastContentOffset++;  if (pseudos) {    nsContainerFrame* flowParent = (nsContainerFrame*)flow->mGeometricParent;    flowParent->PropagateContentOffsets(flow, flow->mFirstContentOffset,                                        flow->mLastContentOffset,                                        flow->mLastContentIsComplete);  }  flow = (nsCSSBlockFrame*) flow->mNextInFlow;  while (nsnull != flow) {    flow->mFirstContentOffset++;    flow->mLastContentOffset++;    if (pseudos) {      nsContainerFrame* flowParent = (nsContainerFrame*)flow->mGeometricParent;      flowParent->PropagateContentOffsets(flow, flow->mFirstContentOffset,                                          flow->mLastContentOffset,                                          flow->mLastContentIsComplete);    }    flow = (nsCSSBlockFrame*) flow->mNextInFlow;  }  return NS_OK;}NS_IMETHODIMPnsCSSBlockFrame::ContentDeleted(nsIPresShell*   aShell,                                nsIPresContext* aPresContext,                                nsIContent*     aContainer,                                nsIContent*     aChild,                                PRInt32         aIndexInParent){  // Find the frame that precedes the frame to destroy and the frame  // to destroy (the first-in-flow if the frame is continued). We also  // find which of our next-in-flows contain the dead frame.  nsCSSBlockFrame* flow;  nsIFrame* deadFrame;  nsIFrame* prevSibling = nsnull;  if (aIndexInParent > 0) {    nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1);    prevSibling = aShell->FindFrameWithContent(precedingContent);    NS_RELEASE(precedingContent);    // The frame may have a next-in-flow. Get the last-in-flow; we do    // it the hard way because we can't assume that prevSibling is a    // subclass of nsSplittableFrame.    nsIFrame* nextInFlow;    do {      prevSibling->GetNextInFlow(nextInFlow);      if (nsnull != nextInFlow) {        prevSibling = nextInFlow;      }    } while (nsnull != nextInFlow);    // Get the dead frame (maybe)    prevSibling->GetGeometricParent((nsIFrame*&)flow);    prevSibling->GetNextSibling(deadFrame);    if (nsnull == deadFrame) {      // The deadFrame must be prevSibling's parent's next-in-flows      // first frame. Therefore it doesn't have a prevSibling.      flow = (nsCSSBlockFrame*) flow->mNextInFlow;      if (nsnull != flow) {        deadFrame = flow->mLines->mFirstChild;      }      prevSibling = nsnull;    }  }  else {    flow = this;    deadFrame = mLines->mFirstChild;  }  NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame");  if (nsnull == deadFrame) {    return NS_OK;  }  // Generate a reflow command for the appropriate flow frame  nsIReflowCommand* cmd;  nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow,                                        nsIReflowCommand::FrameDeleted);  if (NS_OK != rv) {    return rv;  }  aShell->AppendReflowCommand(cmd);  NS_RELEASE(cmd);  // Find line that contains deadFrame; we also find the pointer to  // the line.  nsCSSBlockFrame* block = flow;  LineData** linep = &block->mLines;  LineData* line = block->mLines;  while (nsnull != line) {    if (line->Contains(deadFrame)) {      break;    }    linep = &line->mNext;    line = line->mNext;  }  // Remove frame and its continuations  PRBool pseudos = flow->IsPseudoFrame();  nsIFrame* flowParent = flow->mGeometricParent;  while ((nsnull != block) && (nsnull != deadFrame)) {    while ((nsnull != line) && (nsnull != deadFrame)) {#ifdef NS_DEBUG      nsIFrame* parent;      deadFrame->GetGeometricParent(parent);      NS_ASSERTION(block == parent, "messed up delete code");#endif      // Remove deadFrame from the line      if (line->mFirstChild == deadFrame) {        nsIFrame* nextFrame;        deadFrame->GetNextSibling(nextFrame);        line->mFirstChild = nextFrame;      }      else {        nsIFrame* lastFrame = line->LastChild();        if (lastFrame == deadFrame) {          line->SetLastContentIsComplete();        }      }      // Take deadFrame out of the sibling list      if (nsnull != prevSibling) {        nsIFrame* nextFrame;        deadFrame->GetNextSibling(nextFrame);        prevSibling->SetNextSibling(nextFrame);        prevSibling = nsnull;      }      // Destroy frame; capture its next-in-flow first in case we need      // to destroy that too.      nsIFrame* nextInFlow;      deadFrame->GetNextInFlow(nextInFlow);      deadFrame->BreakFromNextFlow();      deadFrame->DeleteFrame();      deadFrame = nextInFlow;      // If line is empty, remove it now      LineData* next = line->mNext;      if (0 == --line->mChildCount) {        *linep = next;        line->mNext = nsnull;        delete line;      }      else {        linep = &line->mNext;      }      line = next;    }    // Update content offsets    block->mLastContentOffset--;    if (block != flow) {      block->mFirstContentOffset--;    }    if (pseudos) {      nsContainerFrame* parent = (nsContainerFrame*)block->mGeometricParent;      parent->PropagateContentOffsets(block, block->mFirstContentOffset,                                      block->mLastContentOffset,                                      block->mLastContentIsComplete);      if (parent != flowParent) {        nsIReflowCommand* cmd;        rv = NS_NewHTMLReflowCommand(&cmd, block,                                     nsIReflowCommand::FrameDeleted);        if (NS_OK != rv) {          return rv;        }        aShell->AppendReflowCommand(cmd);        NS_RELEASE(cmd);      }    }    // Advance to next flow block if the frame has more continuations    if (nsnull != deadFrame) {      block = (nsCSSBlockFrame*) block->mNextInFlow;      NS_ASSERTION(nsnull != block, "whoops, continuation with a parent");      line = block->mLines;      prevSibling = nsnull;    }  }  return rv;}PRBoolnsCSSBlockFrame::DeleteNextInFlowsFor(nsIFrame* aChild){  NS_PRECONDITION(IsChild(aChild), "bad geometric parent");  nsIFrame*         nextInFlow;  nsCSSBlockFrame*  parent;     aChild->GetNextInFlow(nextInFlow);  NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow");  nextInFlow->GetGeometricParent((nsIFrame*&)parent);  // If the next-in-flow has a next-in-flow then delete it, too (and  // delete it first).  nsIFrame* nextNextInFlow;  nextInFlow->GetNextInFlow(nextNextInFlow);  if (nsnull != nextNextInFlow) {    parent->DeleteNextInFlowsFor(nextInFlow);  }#ifdef NS_DEBUG  PRInt32   childCount;  nsIFrame* firstChild;  nextInFlow->ChildCount(childCount);  nextInFlow->FirstChild(firstChild);  NS_ASSERTION((0 == childCount) && (nsnull == firstChild),               "deleting !empty next-in-flow");#endif  // Disconnect the next-in-flow from the flow list  nextInFlow->BreakFromPrevFlow();  // Remove nextInFlow from the parents line list. Also remove it from  // the sibling list.  if (RemoveChild(parent->mLines, nextInFlow)) {    NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,       ("nsCSSBlockFrame::DeleteChildsNextInFlow: frame=%p (from mLines)",        nextInFlow));    goto done;  }  // If we get here then we didn't find the child on the line list. If  // it's not there then it has to be on the overflow lines list.  if (nsnull != mOverflowLines) {    if (RemoveChild(parent->mOverflowLines, nextInFlow)) {      NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,         ("nsCSSBlockFrame::DeleteChildsNextInFlow: frame=%p (from overflow)",          nextInFlow));      goto done;    }  }  NS_NOTREACHED("can't find next-in-flow in overflow list"); done:;  // If the parent is us then we will finish reflowing and update the  // content offsets of our parents when we are a pseudo-frame; if the  // parent is not us then it's a next-in-flow which means it will get  // reflowed by our parent and fix its content offsets. So there.#if XXX  if (parent->IsPseudoFrame()) {    parent->PropagateContentOffsets();  }#endif  // Delete the next-in-flow frame and adjust its parents child count  nextInFlow->DeleteFrame();#ifdef NS_DEBUG  aChild->GetNextInFlow(nextInFlow);  NS_POSTCONDITION(nsnull == nextInFlow, "non null next-in-flow");#endif  return PR_TRUE;}PRBoolnsCSSBlockFrame::RemoveChild(LineData* aLines, nsIFrame* aChild){  LineData* line = aLines;  nsIFrame* prevChild = nsnull;  while (nsnull != line) {    nsIFrame* child = line->mFirstChild;    PRInt32 n = line->mChildCount;    while (--n >= 0) {      nsIFrame* nextChild;      child->GetNextSibling(nextChild);      if (child == aChild) {        // Continuations HAVE to be at the start of a line        NS_ASSERTION(child == line->mFirstChild, "bad continuation");        line->mFirstChild = nextChild;        if (0 == --line->mChildCount) {          line->mFirstChild = nsnull;        }        if (nsnull != prevChild) {          // When nextInFlow and it's continuation are in the same          // container then we remove the nextInFlow from the sibling          // list.          prevChild->SetNextSibling(nextChild);        }        return PR_TRUE;      }      prevChild = child;      child = nextChild;    }    line = line->mNext;  }  return PR_FALSE;}NS_IMETHODIMPnsCSSBlockFrame::DidReflow(nsIPresContext& aPresContext,                           nsDidReflowStatus aStatus){  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,     ("enter nsCSSBlockFrame::DidReflow: status=%d",      aStatus));  if (NS_FRAME_REFLOW_FINISHED == aStatus) {    nsFrameState state;    nsIFrame* kid = (nsnull == mLines) ? nsnull : mLines->mFirstChild;    while (nsnull != kid) {      kid->GetFrameState(state);      if (0 != (state & NS_FRAME_IN_REFLOW)) {        kid->DidReflow(aPresContext, aStatus);      }      kid->GetNextSibling(kid);    }  }  NS_FRAME_TRACE_OUT("nsCSSBlockFrame::DidReflow");  // Let nsFrame position and size our view (if we have one), and clear  // the NS_FRAME_IN_REFLOW bit  return nsFrame::DidReflow(aPresContext, aStatus);}////////////////////////////////////////////////////////////////////////// Floater supportvoidnsCSSBlockFrame::ReflowFloater(nsIPresContext*        aPresContext,                               nsCSSBlockReflowState& aState,                               nsIFrame*              aFloaterFrame){//XXX fix_me: use the values already stored in the nsCSSBlockReflowState  // Compute the available space for the floater. Use the default  // 'auto' width and height values  nsSize kidAvailSize;  nsSize styleSize;  PRIntn styleSizeFlags =    nsCSSLayout::GetStyleSize(aPresContext, aState, styleSize);  // XXX The width and height are for the content area only. Add in space for  // border and padding  if (styleSizeFlags & NS_SIZE_HAS_WIDTH) {    kidAvailSize.width = styleSize.width;  }  else {    // If we are floating something and we don't know the width then    // find a maximum width for it to reflow into.    // XXX if the child is a block (instead of a table, say) then this    // will do the wrong thing. A better choice would be    // NS_UNCONSTRAINEDSIZE, but that has special meaning to tables.    const nsReflowState* rsp = &aState;    kidAvailSize.width = 0;    while (nsnull != rsp) {      if ((0 != rsp->maxSize.width) &&          (NS_UNCONSTRAINEDSIZE != rsp->maxSize.width)) {        kidAvailSize.width = rsp->maxSize.width;        break;      }      rsp = rsp->parentReflowState;    }    NS_ASSERTION(0 != kidAvailSize.width, "no width for block found");  }  if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) {    kidAvailSize.height = styleSize.height;  }  else {    kidAvailSize.height = NS_UNCONSTRAINEDSIZE;  }  // Resize reflow the anchored item into the available space  // XXX Check for complete?  nsReflowMetrics desiredSize(nsnull);  nsReflowState   reflowState(aFloaterFrame, aState, kidAvailSize,                              eReflowReason_Initial);  nsReflowStatus  status;  aFloaterFrame->WillReflow(*aPresContext);  aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status);  aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height);//XXX  aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED);}PRBoolnsCSSBlockFrame::AddFloater(nsIPresContext*      aPresContext,                            const nsReflowState& aReflowState,                            nsIFrame*            aFloater,                            nsPlaceholderFrame*  aPlaceholder){  // Walk up reflow state chain, looking for ourself  const nsReflowState* rs = &aReflowState;  while (nsnull != rs) {    if (rs->frame == this) {      break;    }    rs = rs->parentReflowState;  }  if (nsnull == rs) {    // Never mind    return PR_FALSE;  }  nsCSSBlockReflowState* state = (nsCSSBlockReflowState*) rs;  // Get the frame associated with the space manager, and get its  // nsIAnchoredItems interface  nsIFrame* frame = state->mSpaceManager->GetFrame();  nsIAnchoredItems* anchoredItems = nsnull;  frame->QueryInterface(kIAnchoredItemsIID, (void**)&anchoredItems);  NS_ASSERTION(nsnull != anchoredItems, "no anchored items interface");  if (nsnull != anchoredItems) {    anchoredItems->AddAnchoredItem(aFloater,                                   nsIAnchoredItems::anHTMLFloater,                                   this);    // Reflow the floater    ReflowFloater(aPresContext, *state, aFloater);    // Determine whether we place it at the top or we place it below the    // current line    if (IsLeftMostChild(aPlaceholder)) {      if (nsnull == mRunInFloaters) {        mRunInFloaters = new nsVoidArray;      }      mRunInFloaters->AppendElement(aPlaceholder);      state->PlaceCurrentLineFloater(aFloater);    } else {      // Add the placeholder to our to-do list      state->mPendingFloaters.AppendElement(aPlaceholder);    }    return PR_TRUE;  }  return PR_FALSE;}PRBoolnsCSSBlockFrame::IsLeftMostChild(nsIFrame* aFrame){  do {    nsIFrame* parent;    aFrame->GetGeometricParent(parent);      // See if there are any non-zero sized child frames that precede    // aFrame in the child list    nsIFrame* child;    parent->FirstChild(child);    while ((nsnull != child) && (aFrame != child)) {      nsSize  size;      // Is the child zero-sized?      child->GetSize(size);      if ((size.width > 0) || (size.height > 0)) {        // We found a non-zero sized child frame that precedes aFrame        return PR_FALSE;      }      child->GetNextSibling(child);    }      // aFrame is the left-most non-zero sized frame in its geometric parent.    // Walk up one level and check that its parent is left-most as well    aFrame = parent;  } while (aFrame != this);  return PR_TRUE;}// Used when placing run-in floaters (floaters displayed at the top of// the block as supposed to below the current line)voidnsCSSBlockReflowState::PlaceCurrentLineFloater(nsIFrame* aFloater){  nsISpaceManager* sm = mSpaceManager;  // Get the type of floater  const nsStyleDisplay* floaterDisplay;  aFloater->GetStyleData(eStyleStruct_Display,                         (const nsStyleStruct*&)floaterDisplay);  const nsStyleSpacing* floaterSpacing;  aFloater->GetStyleData(eStyleStruct_Spacing,                         (const nsStyleStruct*&)floaterSpacing);  // Commit some space in the space manager, and adjust our current  // band of available space.  nsRect region;  aFloater->GetRect(region);  region.y = mY;  switch (floaterDisplay->mFloats) {  default:    NS_NOTYETIMPLEMENTED("Unsupported floater type");    // FALL THROUGH  case NS_STYLE_FLOAT_LEFT:    region.x = mX;    break;  case NS_STYLE_FLOAT_RIGHT:    region.x = mCurrentBand.availSpace.XMost() - region.width;    if (region.x < 0) {      region.x = 0;    }  }  // Factor in the floaters margins  nsMargin floaterMargin;  floaterSpacing->CalcMarginFor(aFloater, floaterMargin);  region.width += floaterMargin.left + floaterMargin.right;  region.height += floaterMargin.top + floaterMargin.bottom;  sm->AddRectRegion(aFloater, region);  // Set the origin of the floater in world coordinates  nscoord worldX, worldY;  sm->GetTranslation(worldX, worldY);  aFloater->WillReflow(*mPresContext);  aFloater->MoveTo(region.x + worldX + floaterMargin.left,                   region.y + worldY + floaterMargin.top);  aFloater->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);  // Update the band of available space to reflect space taken up by  // the floater  GetAvailableSpace();  // XXX if the floater is a child of an inline frame then this won't  // work because we won't update the correct nsCSSInlineLayout.  mInlineLayout.SetReflowSpace(mCurrentBand.availSpace.x,                               mY,                               mCurrentBand.availSpace.width,                               mCurrentBand.availSpace.height);}voidnsCSSBlockReflowState::PlaceBelowCurrentLineFloaters(nsVoidArray* aFloaterList){  NS_PRECONDITION(aFloaterList->Count() > 0, "no floaters");  nsISpaceManager* sm = mSpaceManager;  // XXX Factor this code with PlaceCurrentLineFloater()...  nsRect region;  PRInt32 numFloaters = aFloaterList->Count();  for (PRInt32 i = 0; i < numFloaters; i++) {    nsPlaceholderFrame* placeholderFrame = (nsPlaceholderFrame*)      aFloaterList->ElementAt(i);    nsIFrame* floater = placeholderFrame->GetAnchoredItem();    // Get the band of available space    // XXX This is inefficient to do this inside the loop...    GetAvailableSpace();    // Get the type of floater    const nsStyleDisplay* floaterDisplay;    const nsStyleSpacing* floaterSpacing;    floater->GetStyleData(eStyleStruct_Display,                          (const nsStyleStruct*&)floaterDisplay);    floater->GetStyleData(eStyleStruct_Spacing,                          (const nsStyleStruct*&)floaterSpacing);    floater->GetRect(region);    region.y = mCurrentBand.availSpace.y;    switch (floaterDisplay->mFloats) {    default:      NS_NOTYETIMPLEMENTED("Unsupported floater type");      // FALL THROUGH    case NS_STYLE_FLOAT_LEFT:      region.x = mCurrentBand.availSpace.x;      break;    case NS_STYLE_FLOAT_RIGHT:      region.x = mCurrentBand.availSpace.XMost() - region.width;      if (region.x < 0) {        region.x = 0;      }    }    // XXX Temporary incremental hack (kipp asks: why is this    // temporary or an incremental hack?)    // Factor in the floaters margins    nsMargin floaterMargin;    floaterSpacing->CalcMarginFor(floater, floaterMargin);    region.width += floaterMargin.left + floaterMargin.right;    region.height += floaterMargin.top + floaterMargin.bottom;    sm->RemoveRegion(floater);/* XXX temporary code */    sm->AddRectRegion(floater, region);    // Set the origin of the floater in world coordinates    nscoord worldX, worldY;    sm->GetTranslation(worldX, worldY);    floater->MoveTo(region.x + worldX + floaterMargin.left,                    region.y + worldY + floaterMargin.top);  }  // Pass on updated available space to the current line  GetAvailableSpace();  mInlineLayout.SetReflowSpace(mCurrentBand.availSpace.x, mY,                               mCurrentBand.availSpace.width,                               mCurrentBand.availSpace.height);}voidnsCSSBlockReflowState::ClearFloaters(PRUint8 aBreakType){  for (;;) {    if (mCurrentBand.count <= 1) {      // No floaters in this band therefore nothing to clear      break;    }    // Find the Y coordinate to clear to. Note that the band trapezoid    // coordinates are relative to the last translation. Since we    // never translate by Y before getting a band, we can use absolute    // comparisons against mY.    NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,       ("nsCSSBlockReflowState::ClearFloaters: mY=%d trapCount=%d",        mY, mCurrentBand.count));    nscoord clearYMost = mY;    nsRect tmp;    PRInt32 i;    for (i = 0; i < mCurrentBand.count; i++) {      const nsStyleDisplay* display;      nsBandTrapezoid* trapezoid = &mCurrentBand.data[i];      NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,         ("nsCSSBlockReflowState::ClearFloaters: trap=%d state=%d",          i, trapezoid->state));      if (nsBandTrapezoid::Available != trapezoid->state) {        if (nsBandTrapezoid::OccupiedMultiple == trapezoid->state) {          PRInt32 fn, numFrames = trapezoid->frames->Count();          NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");          for (fn = 0; fn < numFrames; fn++) {            nsIFrame* frame = (nsIFrame*) trapezoid->frames->ElementAt(fn);            frame->GetStyleData(eStyleStruct_Display,                                (const nsStyleStruct*&)display);            NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,               ("nsCSSBlockReflowState::ClearFloaters: frame[%d]=%p floats=%d",                fn, frame, display->mFloats));            switch (display->mFloats) {            case NS_STYLE_FLOAT_LEFT:              if ((NS_STYLE_CLEAR_LEFT == aBreakType) ||                  (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType)) {                trapezoid->GetRect(tmp);                nscoord ym = tmp.YMost();                if (ym > clearYMost) {                  clearYMost = ym;                  NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,                   ("nsCSSBlockReflowState::ClearFloaters: left clearYMost=%d",                    clearYMost));                }              }              break;            case NS_STYLE_FLOAT_RIGHT:              if ((NS_STYLE_CLEAR_RIGHT == aBreakType) ||                  (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType)) {                trapezoid->GetRect(tmp);                nscoord ym = tmp.YMost();                if (ym > clearYMost) {                  clearYMost = ym;                  NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,                  ("nsCSSBlockReflowState::ClearFloaters: right clearYMost=%d",                   clearYMost));                }              }              break;            }          }        }        else {          trapezoid->frame->GetStyleData(eStyleStruct_Display,                                         (const nsStyleStruct*&)display);          NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,             ("nsCSSBlockReflowState::ClearFloaters: frame=%p floats=%d",              trapezoid->frame, display->mFloats));          switch (display->mFloats) {          case NS_STYLE_FLOAT_LEFT:            if ((NS_STYLE_CLEAR_LEFT == aBreakType) ||                (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType)) {              trapezoid->GetRect(tmp);              nscoord ym = tmp.YMost();NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,   ("nsCSSBlockReflowState::ClearFloaters: left? ym=%d clearYMost=%d",    ym, clearYMost));              if (ym > clearYMost) {                clearYMost = ym;                NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,                  ("nsCSSBlockReflowState::ClearFloaters: left clearYMost=%d",                   clearYMost));              }            }            break;          case NS_STYLE_FLOAT_RIGHT:            if ((NS_STYLE_CLEAR_RIGHT == aBreakType) ||                (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType)) {              trapezoid->GetRect(tmp);              nscoord ym = tmp.YMost();              if (ym > clearYMost) {                clearYMost = ym;                NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,                  ("nsCSSBlockReflowState::ClearFloaters: right clearYMost=%d",                   clearYMost));              }            }            break;          }        }      }    }    if (clearYMost == mY) {      // Nothing to clear      break;    }    NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,       ("nsCSSBlockReflowState::ClearFloaters: mY=%d clearYMost=%d",        mY, clearYMost));    mY = clearYMost + 1;    // Get a new band    GetAvailableSpace();  }}//////////////////////////////////////////////////////////////////////// Painting, event handlingPRIntnnsCSSBlockFrame::GetSkipSides() const{  PRIntn skip = 0;  if (nsnull != mPrevInFlow) {    skip |= 1 << NS_SIDE_TOP;  }  if (nsnull != mNextInFlow) {    skip |= 1 << NS_SIDE_BOTTOM;  }  return skip;}NS_IMETHODIMPnsCSSBlockFrame::Paint(nsIPresContext&      aPresContext,                       nsIRenderingContext& aRenderingContext,                       const nsRect&        aDirtyRect){  // Paint our background and border  const nsStyleDisplay* disp =    (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);  if (disp->mVisible && mRect.width && mRect.height) {    PRIntn skipSides = GetSkipSides();    const nsStyleColor* color =      (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);    const nsStyleSpacing* spacing =      (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);    nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,                                    aDirtyRect, mRect, *color);    nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,                                aDirtyRect, mRect, *spacing, skipSides);  }  PaintChildren(aPresContext, aRenderingContext, aDirtyRect);  if (nsIFrame::GetShowFrameBorders()) {    nsIView* view;    GetView(view);    if (nsnull != view) {      aRenderingContext.SetColor(NS_RGB(0,0,255));      NS_RELEASE(view);    }    else {      aRenderingContext.SetColor(NS_RGB(255,0,0));    }    aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);  }  return NS_OK;}// aDirtyRect is in our coordinate system// child rect's are also in our coordinate system// XXX take advantage of line information to skip entire linesvoidnsCSSBlockFrame::PaintChildren(nsIPresContext&      aPresContext,                               nsIRenderingContext& aRenderingContext,                               const nsRect&        aDirtyRect){  // Set clip rect so that children don't leak out of us  const nsStyleDisplay* disp =    (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);  PRBool hidden = PR_FALSE;  if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {    aRenderingContext.PushState();    aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height),                                  nsClipCombine_kIntersect);    hidden = PR_TRUE;  }  // XXX reminder: use the coordinates in the dirty rect to figure out  // which set of children are impacted and only do the intersection  // work for them. In addition, stop when we no longer overlap.  nsIFrame* kid = (nsnull == mLines) ? nsnull : mLines->mFirstChild;  while (nsnull != kid) {    nsIView *pView;         kid->GetView(pView);    if (nsnull == pView) {      nsRect kidRect;      kid->GetRect(kidRect);      nsRect damageArea;      PRBool overlap = damageArea.IntersectRect(aDirtyRect, kidRect);      if (overlap) {        // Translate damage area into kid's coordinate system        nsRect kidDamageArea(damageArea.x - kidRect.x,                             damageArea.y - kidRect.y,                             damageArea.width, damageArea.height);        aRenderingContext.PushState();        aRenderingContext.Translate(kidRect.x, kidRect.y);        kid->Paint(aPresContext, aRenderingContext, kidDamageArea);        if (nsIFrame::GetShowFrameBorders()) {          nsIView* view;          GetView(view);          if (nsnull != view) {            aRenderingContext.SetColor(NS_RGB(0,0,255));            NS_RELEASE(view);          }          else {            aRenderingContext.SetColor(NS_RGB(255,0,0));          }          aRenderingContext.DrawRect(0, 0, kidRect.width, kidRect.height);        }        aRenderingContext.PopState();      }    }    else {      NS_RELEASE(pView);    }    kid->GetNextSibling(kid);  }  if (hidden) {    aRenderingContext.PopState();  }}// XXX move into nsFrameNS_IMETHODIMPnsCSSBlockFrame::HandleEvent(nsIPresContext& aPresContext,                              nsGUIEvent*     aEvent,                             nsEventStatus&  aEventStatus){  aEventStatus = nsEventStatus_eIgnore;  nsIFrame* kid = (nsnull == mLines) ? nsnull : mLines->mFirstChild;  while (nsnull != kid) {    nsRect kidRect;    kid->GetRect(kidRect);    if (kidRect.Contains(aEvent->point)) {      aEvent->point.MoveBy(-kidRect.x, -kidRect.y);      kid->HandleEvent(aPresContext, aEvent, aEventStatus);      aEvent->point.MoveBy(kidRect.x, kidRect.y);      break;    }    kid->GetNextSibling(kid);  }  return NS_OK;}// XXX move into nsFrameNS_IMETHODIMPnsCSSBlockFrame::GetCursorAt(nsIPresContext& aPresContext,                             const nsPoint&  aPoint,                             nsIFrame**      aFrame,                             PRInt32&        aCursor){  aCursor = NS_STYLE_CURSOR_INHERIT;  nsIFrame* kid = (nsnull == mLines) ? nsnull : mLines->mFirstChild;  nsPoint tmp;  while (nsnull != kid) {    nsRect kidRect;    kid->GetRect(kidRect);    if (kidRect.Contains(aPoint)) {      tmp.MoveTo(aPoint.x - kidRect.x, aPoint.y - kidRect.y);      kid->GetCursorAt(aPresContext, tmp, aFrame, aCursor);      break;    }    kid->GetNextSibling(kid);  }  return NS_OK;}//////////////////////////////////////////////////////////////////////// Debugging#ifdef NS_DEBUGstatic PRBoolInLineList(LineData* aLines, nsIFrame* aFrame){  while (nsnull != aLines) {    nsIFrame* frame = aLines->mFirstChild;    PRInt32 n = aLines->mChildCount;    while (--n >= 0) {      if (frame == aFrame) {        return PR_TRUE;      }      frame->GetNextSibling(frame);    }    aLines = aLines->mNext;  }  return PR_FALSE;}static PRBoolInSiblingList(LineData* aLine, nsIFrame* aFrame){  if (nsnull != aLine) {    nsIFrame* frame = aLine->mFirstChild;    while (nsnull != frame) {      if (frame == aFrame) {        return PR_TRUE;      }      frame->GetNextSibling(frame);    }  }  return PR_FALSE;}PRBoolnsCSSBlockFrame::IsChild(nsIFrame* aFrame){  nsIFrame* parent;  aFrame->GetGeometricParent(parent);  if (parent != (nsIFrame*)this) {    return PR_FALSE;  }  if (InLineList(mLines, aFrame) && InSiblingList(mLines, aFrame)) {    return PR_TRUE;  }  if (InLineList(mOverflowLines, aFrame) &&      InSiblingList(mOverflowLines, aFrame)) {    return PR_TRUE;  }  return PR_FALSE;}#endif#define VERIFY_ASSERT(_expr, _msg)      \  if (!(_expr)) {                       \    DumpTree();                         \  }                                     \  NS_ASSERTION(_expr, _msg)NS_IMETHODIMPnsCSSBlockFrame::VerifyTree() const{#ifdef NS_DEBUG  NS_ASSERTION(0 == (mState & NS_FRAME_IN_REFLOW), "frame is in reflow");  VERIFY_ASSERT(nsnull == mOverflowLines, "bad overflow list");  // Verify that child count is the same as the line's mChildCount's  VerifyChildCount(mLines);  // Verify child content offsets and index-in-parents  PRInt32 offset = GetFirstContentOffset();  nsIFrame* child = (nsnull == mLines) ? nsnull : mLines->mFirstChild;  while (nsnull != child) {    // Make sure child is ours    nsIFrame* parent;    child->GetGeometricParent(parent);    VERIFY_ASSERT(parent == (nsIFrame*)this, "bad parent");    // Make sure that the child's tree is valid    child->VerifyTree();    // Make sure child's index-in-parent is correct    PRInt32 indexInParent;    child->GetContentIndex(indexInParent);    VERIFY_ASSERT(offset == indexInParent, "bad child offset");    nsIFrame* nextInFlow;    child->GetNextInFlow(nextInFlow);    if (nsnull == nextInFlow) {      offset++;    }    child->GetNextSibling(child);  }  // Verify that our last content offset is correct  if (0 != mChildCount) {    if (GetLastContentIsComplete()) {      VERIFY_ASSERT(offset == GetLastContentOffset() + 1, "bad last offset");    } else {      VERIFY_ASSERT(offset == GetLastContentOffset(), "bad last offset");    }  }#if XXX  // Make sure that our flow blocks offsets are all correct  if (nsnull == mPrevInFlow) {    PRInt32 nextOffset = NextChildOffset();    nsContainerFrame* nextInFlow = (nsContainerFrame*) mNextInFlow;    while (nsnull != nextInFlow) {      VERIFY_ASSERT(0 != nextInFlow->mChildCount, "empty next-in-flow");      VERIFY_ASSERT(nextInFlow->GetFirstContentOffset() == nextOffset,                    "bad next-in-flow first offset");      nextOffset = nextInFlow->NextChildOffset();      nextInFlow = (nsContainerFrame*) nextInFlow->mNextInFlow;    }  }#endif#endif  return NS_OK;}