Report incomplete reflow status as appropriate when frame tree is too deep. (Bug 619021) r=roc a1.9.1.18=dveditz
authorL. David Baron <dbaron@dbaron.org>
Wed, 02 Feb 2011 11:05:09 -0800
changeset 27330 8dd77caa5068d7f4402207aebfe96e71d2dc345b
parent 27329 8e040c1af89048b1888f026be43d81c60d533a08
child 27331 cf6f4bb351f72f02648b328086760f1aeaca6d5f
push id2665
push userdbaron@mozilla.com
push dateWed, 02 Feb 2011 19:05:30 +0000
reviewersroc
bugs619021
milestone1.9.1.18pre
Report incomplete reflow status as appropriate when frame tree is too deep. (Bug 619021) r=roc a1.9.1.18=dveditz
layout/generic/nsBlockFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsInlineFrame.cpp
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -903,18 +903,17 @@ nsBlockFrame::Reflow(nsPresContext*     
   if (needFloatManager)
     autoFloatManager.CreateFloatManager(aPresContext);
 
   // OK, some lines may be reflowed. Blow away any saved line cursor because
   // we may invalidate the nondecreasing combinedArea.y/yMost invariant,
   // and we may even delete the line with the line cursor.
   ClearLineCursor();
 
-  if (IsFrameTreeTooDeep(aReflowState, aMetrics)) {
-    aStatus = NS_FRAME_COMPLETE;
+  if (IsFrameTreeTooDeep(aReflowState, aMetrics, aStatus)) {
     return NS_OK;
   }
 
   PRBool marginRoot = BlockIsMarginRoot(this);
   nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
                            marginRoot, marginRoot, needFloatManager);
 
 #ifdef IBMBIDI
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4051,30 +4051,41 @@ nsIFrame::CheckInvalidateSizeChange(cons
 
 // Define the MAX_FRAME_DEPTH to be the ContentSink's MAX_REFLOW_DEPTH plus
 // 4 for the frames above the document's frames: 
 //  the Viewport, GFXScroll, ScrollPort, and Canvas
 #define MAX_FRAME_DEPTH (MAX_REFLOW_DEPTH+4)
 
 PRBool
 nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
-                            nsHTMLReflowMetrics& aMetrics)
+                            nsHTMLReflowMetrics& aMetrics,
+                            nsReflowStatus& aStatus)
 {
   if (aReflowState.mReflowDepth >  MAX_FRAME_DEPTH) {
     NS_WARNING("frame tree too deep; setting zero size and returning");
     mState |= NS_FRAME_TOO_DEEP_IN_FRAME_TREE;
     mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
     aMetrics.width = 0;
     aMetrics.height = 0;
     aMetrics.ascent = 0;
     aMetrics.mCarriedOutBottomMargin.Zero();
     aMetrics.mOverflowArea.x = 0;
     aMetrics.mOverflowArea.y = 0;
     aMetrics.mOverflowArea.width = 0;
     aMetrics.mOverflowArea.height = 0;
+
+    if (GetNextInFlow()) {
+      // Reflow depth might vary between reflows, so we might have
+      // successfully reflowed and split this frame before.  If so, we
+      // shouldn't delete its continuations.
+      aStatus = NS_FRAME_NOT_COMPLETE;
+    } else {
+      aStatus = NS_FRAME_COMPLETE;
+    }
+
     return PR_TRUE;
   }
   mState &= ~NS_FRAME_TOO_DEEP_IN_FRAME_TREE;
   return PR_FALSE;
 }
 
 /* virtual */ PRBool nsFrame::IsContainingBlock() const
 {
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -383,23 +383,24 @@ public:
    * desired size indicates that the size has changed (specifically border,
    * background and outline).
    * We assume that the difference between the old frame area and the new
    * frame area is invalidated by some other means.
    * @param aDesiredSize the new size of the frame
    */
   void CheckInvalidateSizeChange(nsHTMLReflowMetrics&     aNewDesiredSize);
 
-  // Helper function that tests if the frame tree is too deep; if it
-  // is it marks the frame as "unflowable" and zeros out the metrics
-  // and returns PR_TRUE. Otherwise, the frame is unmarked
-  // "unflowable" and the metrics are not touched and PR_FALSE is
-  // returned.
+  // Helper function that tests if the frame tree is too deep; if it is
+  // it marks the frame as "unflowable", zeroes out the metrics, sets
+  // the reflow status, and returns PR_TRUE. Otherwise, the frame is
+  // unmarked "unflowable" and the metrics and reflow status are not
+  // touched and PR_FALSE is returned.
   PRBool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
-                            nsHTMLReflowMetrics& aMetrics);
+                            nsHTMLReflowMetrics& aMetrics,
+                            nsReflowStatus& aStatus);
 
   // Do the work for getting the parent style context frame so that
   // other frame's |GetParentStyleContextFrame| methods can call this
   // method on *another* frame.  (This function handles out-of-flow
   // frames by using the frame manager's placeholder map and it also
   // handles block-within-inline and generated content wrappers.)
   nsresult DoGetParentStyleContextFrame(nsPresContext* aPresContext,
                                         nsIFrame**      aProviderFrame,
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -358,18 +358,17 @@ nsInlineFrame::Reflow(nsPresContext*    
 
       // Because we lazily set the parent pointer of child frames we get from
       // our prev-in-flow's overflow list, it's possible that we have not set
       // the parent pointer for these frames.
       mFrames.AppendFrames(this, overflowFrames);
     }
   }
 
-  if (IsFrameTreeTooDeep(aReflowState, aMetrics)) {
-    aStatus = NS_FRAME_COMPLETE;
+  if (IsFrameTreeTooDeep(aReflowState, aMetrics, aStatus)) {
     return NS_OK;
   }
 
   // Set our own reflow state (additional state above and beyond
   // aReflowState)
   InlineReflowState irs;
   irs.mPrevFrame = nsnull;
   irs.mLineContainer = lineContainer;