nsAutoOOFFrameList oofs(prevBlock); if (oofs.mList.NotEmpty()) { for (nsIFrame* f = oofs.mList.FirstChild(); f; f = f->GetNextSibling()) { ReparentFrame(f, prevBlock, this); } mFloats.InsertFrames(nsnull, nsnull, oofs.mList.FirstChild()); oofs.mList.SetFrames(nsnull);
if (nsnull == mLines) { mLines = line;
nsBlockFrame::DrainOverflowLines(nsBlockReflowState& aState){#ifdef DEBUG  VerifyOverflowSituation();#endif  nsLineList* overflowLines = nsnull;  nsLineList* ourOverflowLines = nsnull;  // First grab the prev-in-flows overflow lines  nsBlockFrame* prevBlock = (nsBlockFrame*) mPrevInFlow;  if (prevBlock) {    overflowLines = prevBlock->RemoveOverflowLines();    if (overflowLines) {      NS_ASSERTION(! overflowLines->empty(),                   "overflow lines should never be set and empty");      // Make all the frames on the overflow line list mine      nsIFrame* frame = overflowLines->front()->mFirstChild;      while (nsnull != frame) {        ReparentFrame(frame, prevBlock, this);        // Get the next frame        frame = frame->GetNextSibling();      }      // make the overflow out-of-flow frames mine too      nsAutoOOFFrameList oofs(prevBlock);      if (oofs.mList.NotEmpty()) {        for (nsIFrame* f = oofs.mList.FirstChild(); f; f = f->GetNextSibling()) {          ReparentFrame(f, prevBlock, this);        }        mFloats.InsertFrames(nsnull, nsnull, oofs.mList.FirstChild());        oofs.mList.SetFrames(nsnull);      }    }        // The lines on the overflow list have already been marked dirty and their    // previous margins marked dirty also.  }  // Don't need to reparent frames in our own overflow lines/oofs, because they're  // already ours. But we should put overflow floats back in mFloats.  ourOverflowLines = RemoveOverflowLines();  if (ourOverflowLines) {    nsAutoOOFFrameList oofs(this);    if (oofs.mList.NotEmpty()) {      mFloats.InsertFrames(nsnull, nsnull, oofs.mList.FirstChild());      oofs.mList.SetFrames(nsnull);    }  }  if (!overflowLines && !ourOverflowLines) {    // nothing to do; always the case for non-constrained-height reflows    return PR_FALSE;  }  NS_ASSERTION(aState.mOverflowPlaceholders.IsEmpty(),               "Should have no overflow placeholders yet");  // All continuation placeholders need to be moved to the front of  // our line list. We also need to maintain the invariant that at  // most one frame for a given piece of content is in our normal  // child list, by pushing all but the first placeholder to our  // overflow placeholders list  //   // One problem we have to deal with is that some of these  // continuation placeholders may have been donated to us by a  // descendant block that was complete. We need to push them down to  // a lower block if possible.  //  // We keep the lists ordered so that prev in flows come before their  // next in flows. We do not worry about properly ordering the  // placeholders for different content relative to each other until  // the end. Then we sort them.  nsIFrame* lastOP = nsnull;  nsFrameList keepPlaceholders;  nsIFrame* lastKP = nsnull;  nsLineList* lineLists[3] = { overflowLines, &mLines, ourOverflowLines };  static const PRPackedBool searchFirstLinesOnly[3] = { PR_FALSE, PR_TRUE, PR_FALSE };  for (PRInt32 i = 0; i < 3; ++i) {    nsLineList* ll = lineLists[i];    if (ll && !ll->empty()) {      line_iterator iter = ll->begin();      line_iterator iter_end = ll->end();      nsIFrame* lastFrame = nsnull;      while (iter != iter_end) {        PRUint32 n = iter->GetChildCount();        if (n == 0 || !IsContinuationPlaceholder(iter->mFirstChild)) {          if (lastFrame) {            lastFrame->SetNextSibling(iter->mFirstChild);          }          if (searchFirstLinesOnly[i]) {            break;          }          lastFrame = iter->LastChild();          ++iter;        } else {          nsLineBox* line = iter;          iter = ll->erase(iter);          nsIFrame* next;          for (nsPlaceholderFrame* f = NS_STATIC_CAST(nsPlaceholderFrame*, line->mFirstChild);               n > 0; --n, f = NS_STATIC_CAST(nsPlaceholderFrame*, next)) {            NS_ASSERTION(IsContinuationPlaceholder(f),                         "Line frames should all be continuation placeholders");            next = f->GetNextSibling();            nsIFrame* fpif = f->GetPrevInFlow();            PRBool isAncestor = nsLayoutUtils::IsProperAncestorFrame(this, fpif);            if (isAncestor) {              // oops. we already have a prev-in-flow for this              // placeholder. We have to move this frame out of here. We              // can put it in our overflow placeholders.              aState.mOverflowPlaceholders.InsertFrame(nsnull, lastOP, f);              lastOP = f;            } else {              if (fpif->GetParent() == prevBlock) {                keepPlaceholders.InsertFrame(nsnull, lastKP, f);                lastKP = f;              } else {                // Ok, now we're in the tough situation where some child                // of prevBlock was complete and pushed its overflow                // placeholders up to prevBlock's overflow. We might be                // able to find a more appropriate parent for f somewhere                // down in our descendants.                NS_ASSERTION(nsLayoutUtils::IsProperAncestorFrame(prevBlock, fpif),                             "bad prev-in-flow ancestor chain");                // Find the first ancestor of f's prev-in-flow that has a next in flow                // that can contain the float.                // That next in flow should become f's parent.                nsIFrame* fpAncestor;                for (fpAncestor = fpif->GetParent();                     !fpAncestor->GetNextInFlow() || !fpAncestor->IsFloatContainingBlock();                     fpAncestor = fpAncestor->GetParent())                  ;                if (fpAncestor == prevBlock) {                  // We're still the best parent.                  keepPlaceholders.InsertFrame(nsnull, lastKP, f);                  lastKP = f;                } else {                  // Just put it at the front of                  // fpAncestor->GetNextInFlow()'s lines.                  nsLineBox* newLine = aState.NewLineBox(f, 1, PR_FALSE);                  if (newLine) {                    nsBlockFrame* target =                      NS_STATIC_CAST(nsBlockFrame*, fpAncestor->GetNextInFlow());                    if (!target->mLines.empty()) {                      f->SetNextSibling(target->mLines.front()->mFirstChild);                    } else {                      f->SetNextSibling(nsnull);                    }                    target->mLines.push_front(newLine);                    ReparentFrame(f, this, target);                    nsIFrame* oof = f->GetOutOfFlowFrame();#ifdef DEBUG                    PRBool found =#endif                      mFloats.RemoveFrame(oof);                    NS_ASSERTION(found, "Float should have been put in our mFloats list");                    target->mFloats.InsertFrame(nsnull, nsnull, oof);                    ReparentFrame(oof, this, target);                  }                }              }            }          }          aState.FreeLineBox(line);        }      }      if (lastFrame) {        lastFrame->SetNextSibling(nsnull);      }    }  }  // Now join the line lists into mLines  if (overflowLines) {    if (!overflowLines->empty()) {      // Join the line lists      if (! mLines.empty())         {          // Remember to recompute the margins on the first line. This will          // also recompute the correct deltaY if necessary.          mLines.front()->MarkPreviousMarginDirty();          // Join the sibling lists together          nsIFrame* lastFrame = overflowLines->back()->LastChild();          lastFrame->SetNextSibling(mLines.front()->mFirstChild);        }      // Place overflow lines at the front of our line list      mLines.splice(mLines.begin(), *overflowLines);      NS_ASSERTION(overflowLines->empty(), "splice should empty list");    }    delete overflowLines;  }  if (ourOverflowLines) {    if (!ourOverflowLines->empty()) {      if (!mLines.empty()) {        mLines.back()->LastChild()->          SetNextSibling(ourOverflowLines->front()->mFirstChild);      }      // append the overflow to mLines      mLines.splice(mLines.end(), *ourOverflowLines);    }    delete ourOverflowLines;  }  // store the placeholders that we're keeping in our frame list  if (keepPlaceholders.NotEmpty()) {    keepPlaceholders.SortByContentOrder();    nsLineBox* newLine = aState.NewLineBox(keepPlaceholders.FirstChild(),                                           keepPlaceholders.GetLength(), PR_FALSE);    if (newLine) {      if (!mLines.empty()) {        keepPlaceholders.LastChild()->SetNextSibling(mLines.front()->mFirstChild);      }      mLines.push_front(newLine);    }  }  return PR_TRUE;}