Bug 524925 - Recompute overflow without reflowing for transforms. part=1/6 r=dbaron
authorBenjamin Stover <bstover@mozilla.com>
Wed, 15 Jun 2011 14:03:49 -0700
changeset 87249 8651133cd19662053356aa499f2b0248b04e5bf0
parent 87248 1b9c27fad1b935b7a280c78f0182717567fa3caa
child 87250 9d0e181c6aa41d15d5bba8a7ac60ca7a7e7cf8b5
push id674
push userffxbld
push dateTue, 13 Mar 2012 21:17:50 +0000
treeherdermozilla-beta@e3c4c92dec31 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs524925
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 524925 - Recompute overflow without reflowing for transforms. part=1/6 r=dbaron Add an extra change hint, UpdateOverflow, that can be used to specify that a frame's overflow areas may have changed and that they need to be recalculated. When a transform on a frame changes, instead of marking it for reflow, set this hint instead. There is an added virtual function on nsIFrame, UpdateOverflow, which is called recursively on a frame when the corresponding hint is set, to allow it to update its overflow areas.
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsChangeHint.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIFrame.h
layout/mathml/nsMathMLContainerFrame.cpp
layout/mathml/nsMathMLContainerFrame.h
layout/style/nsStyleContext.cpp
layout/style/nsStyleStruct.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/xul/base/src/grid/nsGrid.cpp
layout/xul/base/src/grid/nsGridCell.cpp
layout/xul/base/src/grid/nsGridCell.h
layout/xul/base/src/grid/nsGridRow.cpp
layout/xul/base/src/grid/nsGridRow.h
layout/xul/base/src/grid/nsGridRowLeafLayout.cpp
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsBox.h
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsSprocketLayout.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8014,16 +8014,40 @@ nsCSSFrameConstructor::ProcessRestyledFr
         StyleChangeReflow(frame, hint);
         didReflow = true;
       }
       if (hint & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView |
                   nsChangeHint_UpdateOpacityLayer | nsChangeHint_UpdateTransformLayer)) {
         ApplyRenderingChangeToTree(presContext, frame, hint);
         didInvalidate = true;
       }
+      if (hint & nsChangeHint_UpdateOverflow) {
+        nsOverflowAreas overflowAreas;
+        nsOverflowAreas* pre = static_cast<nsOverflowAreas*>
+          (frame->Properties().Get(frame->PreTransformOverflowAreasProperty()));
+        if (pre) {
+          // FinishAndStoreOverflow will change the overflow areas passed in,
+          // so make a copy.
+          overflowAreas = *pre;
+        } else {
+          // There is no transform yet on this frame, so we can just use its
+          // current overflow areas.
+          overflowAreas = frame->GetOverflowAreas();
+        }
+
+        frame->FinishAndStoreOverflow(overflowAreas, frame->GetSize());
+
+        // Ancestors' oveflow areas may be affected.
+        for (nsIFrame* ancestor = frame->GetParent(); ancestor;
+             ancestor = ancestor->GetParent()) {
+          if (!ancestor->UpdateOverflow()) {
+            break;
+          }
+        }
+      }
       if (hint & nsChangeHint_UpdateCursor) {
         mPresShell->SynthesizeMouseMove(false);
       }
     }
   }
 
   EndUpdate();
 
--- a/layout/base/nsChangeHint.h
+++ b/layout/base/nsChangeHint.h
@@ -86,17 +86,21 @@ enum nsChangeHint {
    * Visual change only, but the change can be handled entirely by
    * updating the layer(s) for the frame.
    */
   nsChangeHint_UpdateOpacityLayer = 0x100,
   nsChangeHint_UpdateTransformLayer = 0x200,
 
   // change requires frame change (e.g., display:).
   // This subsumes all the above.
-  nsChangeHint_ReconstructFrame = 0x400
+  nsChangeHint_ReconstructFrame = 0x400,
+
+  // The frame's effect on its ancestors' overflow areas has changed,
+  // either through a change in its transform or a change in its position.
+  nsChangeHint_UpdateOverflow = 0x800
 };
 
 // Redefine these operators to return nothing. This will catch any use
 // of these operators on hints. We should not be using these operators
 // on nsChangeHints
 inline void operator<(nsChangeHint s1, nsChangeHint s2) {}
 inline void operator>(nsChangeHint s1, nsChangeHint s2) {}
 inline void operator!=(nsChangeHint s1, nsChangeHint s2) {}
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -158,16 +158,37 @@ nsLayoutUtils::Are3DTransformsEnabled()
     s3DTransformPrefCached = true;
     mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled, 
                                           "layout.3d-transforms.enabled");
   }
 
   return s3DTransformsEnabled;
 }
 
+void
+nsLayoutUtils::UnionChildOverflow(nsIFrame* aFrame,
+                                  nsOverflowAreas& aOverflowAreas)
+{
+  // Iterate over all children except pop-ups
+  for (nsIFrame::ChildListIterator childLists(aFrame);
+       !childLists.IsDone(); childLists.Next()) {
+    if (childLists.CurrentID() == nsIFrame::kPopupList ||
+        childLists.CurrentID() == nsIFrame::kSelectPopupList)
+      continue;
+
+    nsFrameList children = childLists.CurrentList();
+    for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
+      nsIFrame* child = e.get();
+      nsOverflowAreas childOverflow =
+        child->GetOverflowAreas() + child->GetPosition();
+      aOverflowAreas.UnionWith(childOverflow);
+    }
+  }
+}
+
 static void DestroyViewID(void* aObject, nsIAtom* aPropertyName,
                           void* aPropertyValue, void* aData)
 {
   ViewID* id = static_cast<ViewID*>(aPropertyValue);
   GetContentMap().Remove(*id);
   delete id;
 }
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1471,16 +1471,23 @@ public:
                                         bool clear);
 
   /**
    * Checks if CSS 3D transforms are currently enabled.
    */
   static bool Are3DTransformsEnabled();
 
   /**
+   * Unions the overflow areas of all non-popup children of aFrame with
+   * aOverflowAreas.
+   */
+  static void UnionChildOverflow(nsIFrame* aFrame,
+                                 nsOverflowAreas& aOverflowAreas);
+
+  /**
    * Return whether this is a frame whose width is used when computing
    * the font size inflation of its descendants.
    */
   static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame);
 
   /**
    * Return the font size inflation *ratio* for a given frame.  This is
    * the factor by which font sizes should be inflated; it is never
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -649,17 +649,17 @@ nsTextControlFrame::GetBoxAscent(nsBoxLa
 
   // Now adjust for our borders and padding
   ascent += clientRect.y;
 
   return ascent;
 }
 
 bool
-nsTextControlFrame::IsCollapsed(nsBoxLayoutState& aBoxLayoutState)
+nsTextControlFrame::IsCollapsed()
 {
   // We're never collapsed in the box sense.
   return false;
 }
 
 bool
 nsTextControlFrame::IsLeaf() const
 {
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -90,17 +90,17 @@ public:
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
   virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
-  virtual bool IsCollapsed(nsBoxLayoutState& aBoxLayoutState);
+  virtual bool IsCollapsed();
 
   DECL_DO_GLOBAL_REFLOW_COUNT_DSP(nsTextControlFrame, nsStackFrame)
 
   virtual bool IsLeaf() const;
   
 #ifdef ACCESSIBILITY
   virtual already_AddRefed<nsAccessible> CreateAccessible();
 #endif
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -916,19 +916,19 @@ CalculateContainingBlockSizeForAbsolutes
       }
     }
   }
 
   return cbSize;
 }
 
 static inline bool IsClippingChildren(nsIFrame* aFrame,
-                                        const nsHTMLReflowState& aReflowState)
+                                      const nsStyleDisplay* display)
 {
-  return aReflowState.mStyleDisplay->mOverflowX == NS_STYLE_OVERFLOW_CLIP ||
+  return display->mOverflowX == NS_STYLE_OVERFLOW_CLIP ||
     nsFrame::ApplyPaginatedOverflowClipping(aFrame);
 }
 
 NS_IMETHODIMP
 nsBlockFrame::Reflow(nsPresContext*           aPresContext,
                      nsHTMLReflowMetrics&     aMetrics,
                      const nsHTMLReflowState& aReflowState,
                      nsReflowStatus&          aStatus)
@@ -953,17 +953,17 @@ nsBlockFrame::Reflow(nsPresContext*     
 #endif
 
   const nsHTMLReflowState *reflowState = &aReflowState;
   nsAutoPtr<nsHTMLReflowState> mutableReflowState;
   // If we have non-auto height, we're clipping our kids and we fit,
   // make sure our kids fit too.
   if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE &&
       aReflowState.ComputedHeight() != NS_AUTOHEIGHT &&
-      IsClippingChildren(this, aReflowState)) {
+      IsClippingChildren(this, aReflowState.mStyleDisplay)) {
     nsMargin heightExtras = aReflowState.mComputedBorderPadding;
     if (GetSkipSides() & NS_SIDE_TOP) {
       heightExtras.top = 0;
     } else {
       // Bottom margin never causes us to create continuations, so we
       // don't need to worry about whether it fits in its entirety.
       heightExtras.top += aReflowState.mComputedMargin.top;
     }
@@ -1117,17 +1117,19 @@ nsBlockFrame::Reflow(nsPresContext*     
       mBullet->SetRect(bbox);
     }
     // Otherwise just leave the bullet where it is, up against our top padding.
   }
 
   // Compute our final size
   nscoord bottomEdgeOfChildren;
   ComputeFinalSize(*reflowState, state, aMetrics, &bottomEdgeOfChildren);
-  ComputeOverflowAreas(*reflowState, aMetrics, bottomEdgeOfChildren);
+  nsRect areaBounds = nsRect(0, 0, aMetrics.width, aMetrics.height);
+  ComputeOverflowAreas(areaBounds, reflowState->mStyleDisplay,
+                       bottomEdgeOfChildren, aMetrics.mOverflowAreas);
   // Factor overflow container child bounds into the overflow area
   aMetrics.mOverflowAreas.UnionWith(ocBounds);
   // Factor pushed float child bounds into the overflow area
   aMetrics.mOverflowAreas.UnionWith(fcBounds);
 
   // Let the absolutely positioned container reflow any absolutely positioned
   // child frames that need to be reflowed, e.g., elements with a percentage
   // based width/height
@@ -1447,27 +1449,26 @@ nsBlockFrame::ComputeFinalSize(const nsH
   if (CRAZY_WIDTH(aMetrics.width) || CRAZY_HEIGHT(aMetrics.height)) {
     ListTag(stdout);
     printf(": WARNING: desired:%d,%d\n", aMetrics.width, aMetrics.height);
   }
 #endif
 }
 
 void
-nsBlockFrame::ComputeOverflowAreas(const nsHTMLReflowState& aReflowState,
-                                   nsHTMLReflowMetrics&     aMetrics,
-                                   nscoord                  aBottomEdgeOfChildren)
+nsBlockFrame::ComputeOverflowAreas(const nsRect&         aBounds,
+                                   const nsStyleDisplay* aDisplay,
+                                   nscoord               aBottomEdgeOfChildren,
+                                   nsOverflowAreas&      aOverflowAreas)
 {
   // Compute the overflow areas of our children
   // XXX_perf: This can be done incrementally.  It is currently one of
   // the things that makes incremental reflow O(N^2).
-  nsRect bounds(0, 0, aMetrics.width, aMetrics.height);
-  nsOverflowAreas areas(bounds, bounds);
-
-  if (!IsClippingChildren(this, aReflowState)) {
+  nsOverflowAreas areas(aBounds, aBounds);
+  if (!IsClippingChildren(this, aDisplay)) {
     for (line_iterator line = begin_lines(), line_end = end_lines();
          line != line_end;
          ++line) {
       areas.UnionWith(line->GetOverflowAreas());
     }
 
     // Factor the bullet in; normally the bullet will be factored into
     // the line-box's overflow areas. However, if the line is a block
@@ -1489,17 +1490,41 @@ nsBlockFrame::ComputeOverflowAreas(const
       o.height = NS_MAX(o.YMost(), aBottomEdgeOfChildren) - o.y;
     }
   }
 #ifdef NOISY_COMBINED_AREA
   ListTag(stdout);
   printf(": ca=%d,%d,%d,%d\n", area.x, area.y, area.width, area.height);
 #endif
 
-  aMetrics.mOverflowAreas = areas;
+  aOverflowAreas = areas;
+}
+
+bool
+nsBlockFrame::UpdateOverflow()
+{
+  // We need to update the overflow areas of lines manually, as they
+  // get cached and re-used otherwise. Lines aren't exposed as normal
+  // frame children, so calling UnionChildOverflow alone will end up
+  // using the old cached values.
+  for (line_iterator line = begin_lines(), line_end = end_lines();
+       line != line_end;
+       ++line) {
+    nsOverflowAreas lineAreas;
+
+    PRInt32 n = line->GetChildCount();
+    for (nsIFrame* lineFrame = line->mFirstChild;
+         n > 0; lineFrame = lineFrame->GetNextSibling(), --n) {
+      ConsiderChildOverflow(lineAreas, lineFrame);
+    }
+
+    line->SetOverflowAreas(lineAreas);
+  }
+
+  return nsBlockFrameSuper::UpdateOverflow();
 }
 
 nsresult
 nsBlockFrame::MarkLineDirty(line_iterator aLine, const nsLineList* aLineList)
 {
   // Mark aLine dirty
   aLine->MarkDirty();
   aLine->SetInvalidateTextRuns(true);
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -379,19 +379,20 @@ protected:
 
   virtual PRIntn GetSkipSides() const;
 
   virtual void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
                                 nsBlockReflowState&      aState,
                                 nsHTMLReflowMetrics&     aMetrics,
                                 nscoord*                 aBottomEdgeOfChildren);
 
-  void ComputeOverflowAreas(const nsHTMLReflowState& aReflowState,
-                            nsHTMLReflowMetrics&     aMetrics,
-                            nscoord                  aBottomEdgeOfChildren);
+  void ComputeOverflowAreas(const nsRect&         aBounds,
+                            const nsStyleDisplay* aDisplay,
+                            nscoord               aBottomEdgeOfChildren,
+                            nsOverflowAreas&      aOverflowAreas);
 
   /** add the frames in aFrameList to this block after aPrevSibling
     * this block thinks in terms of lines, but the frame construction code
     * knows nothing about lines at all. So we need to find the line that
     * contains aPrevSibling and add aFrameList after aPrevSibling on that line.
     * new lines are created as necessary to handle block data in aFrameList.
     * This function will clear aFrameList.
     */
@@ -430,16 +431,18 @@ public:
     FRAMES_ARE_EMPTY           = 0x04
   };
   nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, PRUint32 aFlags);
 
   void ReparentFloats(nsIFrame* aFirstFrame,
                       nsBlockFrame* aOldParent, bool aFromOverflow,
                       bool aReparentSiblings);
 
+  virtual bool UpdateOverflow();
+
   /** Load all of aFrame's floats into the float manager iff aFrame is not a
    *  block formatting context. Handles all necessary float manager translations;
    *  assumes float manager is in aFrame's parent's coord system.
    *  Safe to call on non-blocks (does nothing).
    */
   static void RecoverFloatsFor(nsIFrame*       aFrame,
                                nsFloatManager& aFloatManager);
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4844,24 +4844,54 @@ nsIFrame::GetScrollableOverflowRectRelat
 {
   return GetScrollableOverflowRect() + mRect.TopLeft();
 }
 
 nsRect
 nsIFrame::GetVisualOverflowRectRelativeToSelf() const
 {
   if (IsTransformed()) {
-    nsRect* preTransformBBox = static_cast<nsRect*>
-      (Properties().Get(PreTransformBBoxProperty()));
-    if (preTransformBBox)
-      return *preTransformBBox;
+    nsOverflowAreas* preTransformOverflows = static_cast<nsOverflowAreas*>
+      (Properties().Get(PreTransformOverflowAreasProperty()));
+    if (preTransformOverflows)
+      return preTransformOverflows->VisualOverflow();
   }
   return GetVisualOverflowRect();
 }
 
+/* virtual */ bool
+nsFrame::UpdateOverflow()
+{
+  nsRect rect(nsPoint(0, 0), GetSize());
+  nsOverflowAreas overflowAreas(rect, rect);
+
+  bool isBox = IsBoxFrame() || IsBoxWrapped();
+  if (!isBox || (!IsCollapsed() && !DoesClipChildren())) {
+    nsLayoutUtils::UnionChildOverflow(this, overflowAreas);
+  }
+
+  if (FinishAndStoreOverflow(overflowAreas, GetSize())) {
+    nsIView* view = GetView();
+    if (view) {
+      PRUint32 flags = 0;
+      GetLayoutFlags(flags);
+
+      if ((flags & NS_FRAME_NO_SIZE_VIEW) == 0) {
+        // Make sure the frame's view is properly sized.
+        nsIViewManager* vm = view->GetViewManager();
+        vm->ResizeView(view, overflowAreas.VisualOverflow(), true);
+      }
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
 void
 nsFrame::CheckInvalidateSizeChange(nsHTMLReflowMetrics& aNewDesiredSize)
 {
   nsIFrame::CheckInvalidateSizeChange(mRect, GetVisualOverflowRect(),
       nsSize(aNewDesiredSize.width, aNewDesiredSize.height));
 }
 
 static void
@@ -6579,16 +6609,17 @@ nsIFrame::FinishAndStoreOverflow(nsOverf
   // children are actually clipped to the padding-box, but since the
   // overflow area should include the entire border-box, just set it to
   // the border-box here.
   const nsStyleDisplay *disp = GetStyleDisplay();
   NS_ASSERTION((disp->mOverflowY == NS_STYLE_OVERFLOW_CLIP) ==
                (disp->mOverflowX == NS_STYLE_OVERFLOW_CLIP),
                "If one overflow is clip, the other should be too");
   if (disp->mOverflowX == NS_STYLE_OVERFLOW_CLIP ||
+      disp->IsTableClip() ||
       nsFrame::ApplyPaginatedOverflowClipping(this)) {
     // The contents are actually clipped to the padding area 
     aOverflowAreas.SetAllTo(bounds);
   }
 
   // Overflow area must always include the frame's top-left and bottom-right,
   // even if the frame rect is empty.
   // Pending a real fix for bug 426879, don't do this for inline frames
@@ -6643,31 +6674,33 @@ nsIFrame::FinishAndStoreOverflow(nsOverf
     AddStateBits(NS_FRAME_HAS_CLIP);
   } else {
     RemoveStateBits(NS_FRAME_HAS_CLIP);
   }
 
   /* If we're transformed, transform the overflow rect by the current transformation. */
   bool hasTransform = IsTransformed();
   if (hasTransform) {
-    Properties().Set(nsIFrame::PreTransformBBoxProperty(),
-                     new nsRect(aOverflowAreas.VisualOverflow()));
+    Properties().Set(nsIFrame::PreTransformOverflowAreasProperty(),
+                     new nsOverflowAreas(aOverflowAreas));
     /* Since our size might not actually have been computed yet, we need to make sure that we use the
      * correct dimensions by overriding the stored bounding rectangle with the value the caller has
      * ensured us we'll use.
      */
     nsRect newBounds(nsPoint(0, 0), aNewSize);
     // Transform affects both overflow areas.
     NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
       nsRect& o = aOverflowAreas.Overflow(otype);
       o = nsDisplayTransform::TransformRect(o, this, nsPoint(0, 0), &newBounds);
     }
     if (Preserves3DChildren()) {
       ComputePreserve3DChildrenOverflow(aOverflowAreas, newBounds);
     }
+  } else {
+    Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty());
   }
 
   bool visualOverflowChanged =
     !GetVisualOverflowRect().IsEqualInterior(aOverflowAreas.VisualOverflow());
   bool anyOverflowChanged;
   if (aOverflowAreas != nsOverflowAreas(bounds, bounds)) {
     anyOverflowChanged = SetOverflowAreas(aOverflowAreas);
   } else {
@@ -6818,25 +6851,18 @@ nsIFrame::ComputePreserve3DChildrenOverf
   aOverflowAreas.Overflow(eVisualOverflow) = aOverflowAreas.Overflow(eVisualOverflow).Union(childVisual);
   aOverflowAreas.Overflow(eScrollableOverflow) = aOverflowAreas.Overflow(eScrollableOverflow).Union(childScrollable);
 }
 
 void
 nsFrame::ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
                                nsIFrame* aChildFrame)
 {
-  const nsStyleDisplay* disp = GetStyleDisplay();
-  // check here also for hidden as table frames (table, tr and td) currently 
-  // don't wrap their content into a scrollable frame if overflow is specified
-  // FIXME: Why do we check this here rather than in
-  // FinishAndStoreOverflow (where we check NS_STYLE_OVERFLOW_CLIP)?
-  if (!disp->IsTableClip()) {
-    aOverflowAreas.UnionWith(aChildFrame->GetOverflowAreas() +
-                             aChildFrame->GetPosition());
-  }
+  aOverflowAreas.UnionWith(aChildFrame->GetOverflowAreas() +
+                           aChildFrame->GetPosition());
 }
 
 /**
  * This function takes a "special" frame and _if_ that frame is an anonymous
  * block created by an ib split it returns the block's preceding inline.  This
  * is needed because the split inline's style context is the parent of the
  * anonymous block's style context.
  *
@@ -7249,17 +7275,17 @@ nsFrame::GetPrefSize(nsBoxLayoutState& a
   DISPLAY_PREF_SIZE(this, size);
   // If the size is cached, and there are no HTML constraints that we might
   // be depending on, then we just return the cached size.
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   if (!DoesNeedRecalc(metrics->mPrefSize)) {
     return metrics->mPrefSize;
   }
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return size;
 
   // get our size in CSS.
   bool widthSet, heightSet;
   bool completelyRedefined = nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
 
   // Refresh our caches with new sizes.
   if (!completelyRedefined) {
@@ -7285,17 +7311,17 @@ nsFrame::GetMinSize(nsBoxLayoutState& aS
   DISPLAY_MIN_SIZE(this, size);
   // Don't use the cache if we have HTMLReflowState constraints --- they might have changed
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   if (!DoesNeedRecalc(metrics->mMinSize)) {
     size = metrics->mMinSize;
     return size;
   }
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return size;
 
   // get our size in CSS.
   bool widthSet, heightSet;
   bool completelyRedefined =
     nsIBox::AddCSSMinSize(aState, this, size, widthSet, heightSet);
 
   // Refresh our caches with new sizes.
@@ -7320,17 +7346,17 @@ nsFrame::GetMaxSize(nsBoxLayoutState& aS
   DISPLAY_MAX_SIZE(this, size);
   // Don't use the cache if we have HTMLReflowState constraints --- they might have changed
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   if (!DoesNeedRecalc(metrics->mMaxSize)) {
     size = metrics->mMaxSize;
     return size;
   }
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return size;
 
   size = nsBox::GetMaxSize(aState);
   metrics->mMaxSize = size;
 
   return size;
 }
 
@@ -7348,17 +7374,17 @@ nsFrame::GetFlex(nsBoxLayoutState& aStat
 
 nscoord
 nsFrame::GetBoxAscent(nsBoxLayoutState& aState)
 {
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   if (!DoesNeedRecalc(metrics->mAscent))
     return metrics->mAscent;
 
-  if (IsCollapsed(aState)) {
+  if (IsCollapsed()) {
     metrics->mAscent = 0;
   } else {
     // Refresh our caches with new sizes.
     RefreshSizeCache(aState);
     metrics->mAscent = metrics->mBlockAscent;
   }
 
   return metrics->mAscent;
@@ -7374,17 +7400,17 @@ nsFrame::DoLayout(nsBoxLayoutState& aSta
   nsHTMLReflowMetrics desiredSize;
   nsresult rv = NS_OK;
  
   if (rendContext) {
 
     rv = BoxReflow(aState, presContext, desiredSize, rendContext,
                    ourRect.x, ourRect.y, ourRect.width, ourRect.height);
 
-    if (IsCollapsed(aState)) {
+    if (IsCollapsed()) {
       SetSize(nsSize(0, 0));
     } else {
 
       // if our child needs to be bigger. This might happend with
       // wrapping text. There is no way to predict its height until we
       // reflow it. Now that we know the height reshuffle upward.
       if (desiredSize.width > ourRect.width ||
           desiredSize.height > ourRect.height) {
@@ -7635,17 +7661,17 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
        Redraw(aState, &r);
     }
 
     PRUint32 layoutFlags = aState.LayoutFlags();
     nsContainerFrame::FinishReflowChild(this, aPresContext, &reflowState,
                                         aDesiredSize, aX, aY, layoutFlags | NS_FRAME_NO_MOVE_FRAME);
 
     // Save the ascent.  (bug 103925)
-    if (IsCollapsed(aState)) {
+    if (IsCollapsed()) {
       metrics->mAscent = 0;
     } else {
       if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
         if (!nsLayoutUtils::GetFirstLineBaseline(this, &metrics->mAscent))
           metrics->mAscent = GetBaseline();
       } else
         metrics->mAscent = aDesiredSize.ascent;
     }
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -341,16 +341,18 @@ public:
                             nsReflowStatus&          aStatus);
   void FinishReflowWithAbsoluteFrames(nsPresContext*           aPresContext,
                                       nsHTMLReflowMetrics&     aDesiredSize,
                                       const nsHTMLReflowState& aReflowState,
                                       nsReflowStatus&          aStatus);
   void DestroyAbsoluteFrames(nsIFrame* aDestructRoot);
   virtual bool CanContinueTextRun() const;
 
+  virtual bool UpdateOverflow();
+
   // Selection Methods
   // XXX Doc me... (in nsIFrame.h puhleeze)
   // XXX If these are selection specific, then the name should imply selection
   // rather than generic event processing, e.g., SelectionHandlePress...
   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
                          nsGUIEvent *    aEvent,
                          nsEventStatus*  aEventStatus);
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -794,17 +794,17 @@ nsHTMLScrollFrame::GetPadding(nsMargin& 
   // reaize that.  If we're stuck inside a XUL box, we need to claim no
   // padding.
   // @see also nsXULScrollFrame::GetPadding.
   aMargin.SizeTo(0,0,0,0);
   return NS_OK;
 }
 
 bool
-nsHTMLScrollFrame::IsCollapsed(nsBoxLayoutState& aBoxLayoutState)
+nsHTMLScrollFrame::IsCollapsed()
 {
   // We're never collapsed in the box sense.
   return false;
 }
 
 // Return the <browser> if the scrollframe is for the root frame directly
 // inside a <browser>.
 static nsIContent*
@@ -3264,16 +3264,37 @@ static void LayoutAndInvalidate(nsBoxLay
       aBox->GetParent()->Invalidate(aBox->GetVisualOverflowRect() +
                                     aBox->GetPosition());
     } else {
       aBox->InvalidateFrameSubtree();
     }
   }
 }
 
+bool
+nsGfxScrollFrameInner::UpdateOverflow()
+{
+  nsIScrollableFrame* sf = do_QueryFrame(mOuter);
+  ScrollbarStyles ss = sf->GetScrollbarStyles();
+
+  if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN ||
+      ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
+      GetScrollPosition() != nsPoint()) {
+    // If there are scrollbars, or we're not at the beginning of the pane,
+    // the scroll position may change. In this case, mark the frame as
+    // needing reflow.
+    mOuter->PresContext()->PresShell()->FrameNeedsReflow(
+      mOuter, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
+  }
+
+  // Scroll frames never have overflow area because they always clip their
+  // children, so return false.
+  return false;
+}
+
 void
 nsGfxScrollFrameInner::AdjustScrollbarRectForResizer(
                          nsIFrame* aFrame, nsPresContext* aPresContext,
                          nsRect& aRect, bool aHasResizer, bool aVertical)
 {
   if ((aVertical ? aRect.width : aRect.height) == 0)
     return;
 
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -240,16 +240,19 @@ public:
     return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) |
            (mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0);
   }
   nsMargin GetActualScrollbarSizes() const;
   nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
   bool IsLTR() const;
   bool IsScrollbarOnRight() const;
   bool IsScrollingActive() const { return mScrollingActive || ShouldBuildLayer(); }
+
+  bool UpdateOverflow();
+
   // adjust the scrollbar rectangle aRect to account for any visible resizer.
   // aHasResizer specifies if there is a content resizer, however this method
   // will also check if a widget resizer is present as well.
   void AdjustScrollbarRectForResizer(nsIFrame* aFrame, nsPresContext* aPresContext,
                                      nsRect& aRect, bool aHasResizer, bool aVertical);
   // returns true if a resizer should be visible
   bool HasResizer() { return mResizerBox && !mCollapsedResizer; }
   void LayoutScrollbars(nsBoxLayoutState& aState,
@@ -380,17 +383,17 @@ public:
 
   virtual bool GetBorderRadii(nscoord aRadii[8]) const {
     return mInner.GetBorderRadii(aRadii);
   }
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
   NS_IMETHOD GetPadding(nsMargin& aPadding);
-  virtual bool IsCollapsed(nsBoxLayoutState& aBoxLayoutState);
+  virtual bool IsCollapsed();
   
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
   // Because there can be only one child frame, these two function return
   // NS_ERROR_FAILURE
@@ -492,16 +495,19 @@ public:
   }
   NS_IMETHOD PostScrolledAreaEventForCurrentArea() {
     mInner.PostScrolledAreaEvent();
     return NS_OK;
   }
   virtual bool IsScrollingActive() {
     return mInner.IsScrollingActive();
   }
+  virtual bool UpdateOverflow() {
+    return mInner.UpdateOverflow();
+  }
 
   // nsIStatefulFrame
   NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) {
     NS_ENSURE_ARG_POINTER(aState);
     *aState = mInner.SaveState(aStateID);
     return NS_OK;
   }
   NS_IMETHOD RestoreState(nsPresState* aState) {
@@ -727,16 +733,19 @@ public:
   }
   NS_IMETHOD PostScrolledAreaEventForCurrentArea() {
     mInner.PostScrolledAreaEvent();
     return NS_OK;
   }
   virtual bool IsScrollingActive() {
     return mInner.IsScrollingActive();
   }
+  virtual bool UpdateOverflow() {
+    return mInner.UpdateOverflow();
+  }
 
   // nsIStatefulFrame
   NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState) {
     NS_ENSURE_ARG_POINTER(aState);
     *aState = mInner.SaveState(aStateID);
     return NS_OK;
   }
   NS_IMETHOD RestoreState(nsPresState* aState) {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -905,17 +905,18 @@ public:
 
   NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialSibling, nsnull)
   NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialPrevSibling, nsnull)
 
   NS_DECLARE_FRAME_PROPERTY(ComputedOffsetProperty, DestroyPoint)
 
   NS_DECLARE_FRAME_PROPERTY(OutlineInnerRectProperty, DestroyRect)
   NS_DECLARE_FRAME_PROPERTY(PreEffectsBBoxProperty, DestroyRect)
-  NS_DECLARE_FRAME_PROPERTY(PreTransformBBoxProperty, DestroyRect)
+  NS_DECLARE_FRAME_PROPERTY(PreTransformOverflowAreasProperty,
+                            DestroyOverflowAreas)
 
   // The initial overflow area passed to FinishAndStoreOverflow. This is only set
   // on frames that Preserve3D(), and when at least one of the overflow areas
   // differs from the frame bound rect.
   NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, DestroyOverflowAreas);
 
   NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin)
   NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin)
@@ -1778,16 +1779,23 @@ public:
    */
   NS_IMETHOD  DidReflow(nsPresContext*           aPresContext,
                         const nsHTMLReflowState*  aReflowState,
                         nsDidReflowStatus         aStatus) = 0;
 
   // XXX Maybe these three should be a separate interface?
 
   /**
+   * Updates the overflow areas of the frame. This can be called if an
+   * overflow area of the frame's children has changed without reflowing.
+   * @return true if either of the overflow areas for this frame have changed.
+   */
+  virtual bool UpdateOverflow() = 0;
+
+  /**
    * Helper method used by block reflow to identify runs of text so
    * that proper word-breaking can be done.
    *
    * @return 
    *    true if we can continue a "text run" through the frame. A
    *    text run is text that should be treated contiguously for line
    *    and word breaking.
    */
@@ -2599,17 +2607,17 @@ NS_PTR_TO_INT32(frame->Properties().Get(
    */
   virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) = 0;
 
   // Implemented in nsBox, used in nsBoxFrame
   PRUint32 GetOrdinal(nsBoxLayoutState& aBoxLayoutState);
 
   virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) = 0;
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) = 0;
-  virtual bool IsCollapsed(nsBoxLayoutState& aBoxLayoutState) = 0;
+  virtual bool IsCollapsed() = 0;
   // This does not alter the overflow area. If the caller is changing
   // the box size, the caller is responsible for updating the overflow
   // area. It's enough to just call Layout or SyncLayout on the
   // box. You can pass true to aRemoveOverflowArea as a
   // convenience.
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                          bool aRemoveOverflowAreas = false) = 0;
   NS_HIDDEN_(nsresult) Layout(nsBoxLayoutState& aBoxLayoutState);
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -871,16 +871,27 @@ nsMathMLContainerFrame::GatherAndStoreOv
   while (childFrame) {
     ConsiderChildOverflow(aMetrics->mOverflowAreas, childFrame);
     childFrame = childFrame->GetNextSibling();
   }
 
   FinishAndStoreOverflow(aMetrics);
 }
 
+bool
+nsMathMLContainerFrame::UpdateOverflow()
+{
+  // Our overflow areas may have changed, so reflow the frame.
+  PresContext()->PresShell()->FrameNeedsReflow(
+    this, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
+
+  // As we're reflowing, there's no need to propagate this change.
+  return false;
+}
+
 nsresult 
 nsMathMLContainerFrame::ReflowChild(nsIFrame*                aChildFrame,
                                     nsPresContext*           aPresContext,
                                     nsHTMLReflowMetrics&     aDesiredSize,
                                     const nsHTMLReflowState& aReflowState,
                                     nsReflowStatus&          aStatus)
 {
   // Having foreign/hybrid children, e.g., from html markups, is not defined by
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -166,16 +166,18 @@ public:
     mPresentationData.flags &= ~NS_MATHML_STRETCH_DONE;
     return nsContainerFrame::DidReflow(aPresContext, aReflowState, aStatus);
   }
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
+  virtual bool UpdateOverflow();
+
   // Notification when an attribute is changed. The MathML module uses the
   // following paradigm:
   //
   // 1. If the MathML frame class doesn't have any cached automatic data that
   //    depends on the attribute: we just reflow (e.g., this happens with <msub>,
   //    <msup>, <mmultiscripts>, etc). This is the default behavior implemented
   //    by this base class.
   //
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -432,17 +432,18 @@ nsStyleContext::CalcStyleDifference(nsSt
     }                                                                         \
   PR_END_MACRO
 
   // We begin by examining those style structs that are capable of
   // causing the maximal difference, a FRAMECHANGE.
   // FRAMECHANGE Structs: Display, XUL, Content, UserInterface,
   // Visibility, Outline, TableBorder, Table, Text, UIReset, Quotes
   nsChangeHint maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
-      nsChangeHint_UpdateTransformLayer | nsChangeHint_UpdateOpacityLayer);
+      nsChangeHint_UpdateTransformLayer | nsChangeHint_UpdateOpacityLayer |
+      nsChangeHint_UpdateOverflow);
   DO_STRUCT_DIFFERENCE(Display);
 
   maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
       nsChangeHint_UpdateCursor);
   DO_STRUCT_DIFFERENCE(XUL);
   DO_STRUCT_DIFFERENCE(Column);
   DO_STRUCT_DIFFERENCE(Content);
   DO_STRUCT_DIFFERENCE(UserInterface);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2233,25 +2233,27 @@ nsChangeHint nsStyleDisplay::CalcDiffere
    * or remove the view object, and also to handle abs-pos and fixed-pos containers.
    */
   if (HasTransform() != aOther.HasTransform()) {
     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
   }
   else if (HasTransform()) {
     /* Otherwise, if we've kept the property lying around and we already had a
      * transform, we need to see whether or not we've changed the transform.
-     * If so, we need to do a reflow and a repaint. The reflow is to recompute
-     * the overflow rect (which probably changed if the transform changed)
-     * and to redraw within the bounds of that new overflow rect.
+     * If so, we need to recompute its overflow rect (which probably changed
+     * if the transform changed) and to redraw within the bounds of that new
+     * overflow rect.
      */
     if (!mSpecifiedTransform != !aOther.mSpecifiedTransform ||
-        (mSpecifiedTransform && *mSpecifiedTransform != *aOther.mSpecifiedTransform))
-      NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_NeedReflow,
+        (mSpecifiedTransform &&
+         *mSpecifiedTransform != *aOther.mSpecifiedTransform)) {
+      NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow,
                                          nsChangeHint_UpdateTransformLayer));
-    
+    }
+
     for (PRUint8 index = 0; index < 3; ++index)
       if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) {
         NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_NeedReflow,
                                            nsChangeHint_RepaintFrame));
         break;
       }
     
     for (PRUint8 index = 0; index < 2; ++index)
@@ -2290,18 +2292,20 @@ nsChangeHint nsStyleDisplay::CalcDiffere
   return hint;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleDisplay::MaxDifference()
 {
   // All the parts of FRAMECHANGE are present above in CalcDifference.
-  return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE | nsChangeHint_UpdateOpacityLayer |
-                      nsChangeHint_UpdateTransformLayer);
+  return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
+                      nsChangeHint_UpdateOpacityLayer |
+                      nsChangeHint_UpdateTransformLayer |
+                      nsChangeHint_UpdateOverflow);
 }
 #endif
 
 // --------------------
 // nsStyleVisibility
 //
 
 nsStyleVisibility::nsStyleVisibility(nsPresContext* aPresContext)
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -613,16 +613,28 @@ void nsTableCellFrame::VerticallyAlignCh
   }
   if (HasView()) {
     nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
                                                GetView(),
                                                desiredSize.VisualOverflow(), 0);
   }
 }
 
+bool
+nsTableCellFrame::UpdateOverflow()
+{
+  nsRect bounds(nsPoint(0,0), GetSize());
+  bounds.Inflate(GetBorderOverflow());
+  nsOverflowAreas overflowAreas(bounds, bounds);
+
+  nsLayoutUtils::UnionChildOverflow(this, overflowAreas);
+
+  return FinishAndStoreOverflow(overflowAreas, GetSize());
+}
+
 // Per CSS 2.1, we map 'sub', 'super', 'text-top', 'text-bottom',
 // length, percentage, and calc() values to 'baseline'.
 PRUint8
 nsTableCellFrame::GetVerticalAlign() const
 {
   const nsStyleCoord& verticalAlign = GetStyleTextReset()->mVerticalAlign;
   if (verticalAlign.GetUnit() == eStyleUnit_Enumerated) {
     PRUint8 value = verticalAlign.GetIntValue();
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -235,16 +235,18 @@ public:
   virtual void PaintBackground(nsRenderingContext& aRenderingContext,
                                const nsRect&        aDirtyRect,
                                nsPoint              aPt,
                                PRUint32             aFlags);
 
   void DecorateForSelection(nsRenderingContext& aRenderingContext,
                             nsPoint              aPt);
 
+  virtual bool UpdateOverflow();
+
 protected:
   /** implement abstract method on nsContainerFrame */
   virtual PRIntn GetSkipSides() const;
 
   /**
    * GetBorderOverflow says how far the cell's own borders extend
    * outside its own bounds.  In the separated borders model this should
    * just be zero (as it is for most frames), but in the collapsed
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1843,16 +1843,34 @@ NS_METHOD nsTableFrame::Reflow(nsPresCon
     CheckInvalidateSizeChange(aDesiredSize);
   }
 
   FinishAndStoreOverflow(&aDesiredSize);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return rv;
 }
 
+bool
+nsTableFrame::UpdateOverflow()
+{
+  nsRect bounds(nsPoint(0, 0), GetSize());
+
+  // As above in Reflow, make sure the table overflow area includes the table
+  // rect, and check for collapsed borders leaking out.
+  if (!GetStyleDisplay()->IsTableClip()) {
+    nsMargin bcMargin = GetExcludedOuterBCBorder();
+    bounds.Inflate(bcMargin);
+  }
+
+  nsOverflowAreas overflowAreas(bounds, bounds);
+  nsLayoutUtils::UnionChildOverflow(this, overflowAreas);
+
+  return FinishAndStoreOverflow(overflowAreas, GetSize());
+}
+
 nsresult
 nsTableFrame::ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
                           nscoord                  aAvailHeight,
                           nsIFrame*&               aLastChildReflowed,
                           nsReflowStatus&          aStatus)
 {
   nsresult rv = NS_OK;
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -501,16 +501,18 @@ public:
    * @param aIsFirstReflow True if the size/position change is due to the
    *                       first reflow of aFrame.
    */
   static void InvalidateFrame(nsIFrame* aFrame,
                               const nsRect& aOrigRect,
                               const nsRect& aOrigVisualOverflow,
                               bool aIsFirstReflow);
 
+  virtual bool UpdateOverflow();
+
 protected:
 
   /** protected constructor. 
     * @see NewFrame
     */
   nsTableFrame(nsStyleContext* aContext);
 
   /** destructor, responsible for mColumnLayoutData */
--- a/layout/xul/base/src/grid/nsGrid.cpp
+++ b/layout/xul/base/src/grid/nsGrid.cpp
@@ -647,28 +647,28 @@ nsGrid::GetFirstAndLastRow(nsBoxLayoutSt
   // collaped we become the first row. Or if we are the 9th row and
   // 10 up to the last row are collapsed we then become the last.
 
   // see if we are first
   PRInt32 i;
   for (i=0; i < count; i++)
   {
      nsGridRow* row = GetRowAt(i,aIsHorizontal);
-     if (!row->IsCollapsed(aState)) {
+     if (!row->IsCollapsed()) {
        aFirstIndex = i;
        aFirstRow = row;
        break;
      }
   }
 
   // see if we are last
   for (i=count-1; i >= 0; i--)
   {
      nsGridRow* row = GetRowAt(i,aIsHorizontal);
-     if (!row->IsCollapsed(aState)) {
+     if (!row->IsCollapsed()) {
        aLastIndex = i;
        aLastRow = row;
        break;
      }
 
   }
 }
 
@@ -701,17 +701,17 @@ nsGrid::GetRowOffsets(nsBoxLayoutState& 
   nsMargin padding(0,0,0,0);
   nsMargin totalBorderPadding(0,0,0,0);
   nsMargin totalMargin(0,0,0,0);
 
   // if there is a box and it's not bogus take its
   // borders padding into account
   if (box && !row->mIsBogus)
   {
-    if (!box->IsCollapsed(aState))
+    if (!box->IsCollapsed())
     {
        // get real border and padding. GetBorderAndPadding
        // is redefined on nsGridRowLeafFrame. If we called it here
        // we would be in finite recurson.
        box->GetBorder(border);
        box->GetPadding(padding);
 
        totalBorderPadding += border;
@@ -766,17 +766,17 @@ nsGrid::GetRowOffsets(nsBoxLayoutState& 
       nsMargin totalChildBorderPadding(0,0,0,0);
 
       nsGridRow* column = GetColumnAt(i,aIsHorizontal);
       nsIBox* box = column->GetBox();
 
       if (box) 
       {
         // ignore collapsed children
-        if (!box->IsCollapsed(aState))
+        if (!box->IsCollapsed())
         {
            // include the margin of the columns. To the row
            // at this point border/padding and margins all added
            // up to more needed space.
            margin = GetBoxTotalMargin(box, !aIsHorizontal);
            // get real border and padding. GetBorderAndPadding
            // is redefined on nsGridRowLeafFrame. If we called it here
            // we would be in finite recurson.
@@ -841,17 +841,17 @@ nsGrid::GetRowOffsets(nsBoxLayoutState& 
  */
 nscoord
 nsGrid::GetPrefRowHeight(nsBoxLayoutState& aState, PRInt32 aIndex, bool aIsHorizontal)
 {
   RebuildIfNeeded();
 
   nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);
 
-  if (row->IsCollapsed(aState))
+  if (row->IsCollapsed())
     return 0;
 
   if (row->IsPrefSet()) 
     return row->mPref;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
@@ -898,17 +898,17 @@ nsGrid::GetPrefRowHeight(nsBoxLayoutStat
   for (PRInt32 i=0; i < count; i++)
   {  
     if (aIsHorizontal)
      child = GetCellAt(i,aIndex);
     else
      child = GetCellAt(aIndex,i);
 
     // ignore collapsed children
-    if (!child->IsCollapsed(aState))
+    if (!child->IsCollapsed())
     {
       nsSize childSize = child->GetPrefSize(aState);
 
       nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
     }
   }
 
   row->mPref = GET_HEIGHT(size, aIsHorizontal) + top + bottom;
@@ -918,17 +918,17 @@ nsGrid::GetPrefRowHeight(nsBoxLayoutStat
 
 nscoord
 nsGrid::GetMinRowHeight(nsBoxLayoutState& aState, PRInt32 aIndex, bool aIsHorizontal)
 {
   RebuildIfNeeded();
 
   nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);
 
-  if (row->IsCollapsed(aState))
+  if (row->IsCollapsed())
     return 0;
 
   if (row->IsMinSet()) 
     return row->mMin;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
@@ -973,17 +973,17 @@ nsGrid::GetMinRowHeight(nsBoxLayoutState
   for (PRInt32 i=0; i < count; i++)
   {  
     if (aIsHorizontal)
      child = GetCellAt(i,aIndex);
     else
      child = GetCellAt(aIndex,i);
 
     // ignore collapsed children
-    if (!child->IsCollapsed(aState))
+    if (!child->IsCollapsed())
     {
       nsSize childSize = child->GetMinSize(aState);
 
       nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
     }
   }
 
   row->mMin = GET_HEIGHT(size, aIsHorizontal);
@@ -993,17 +993,17 @@ nsGrid::GetMinRowHeight(nsBoxLayoutState
 
 nscoord
 nsGrid::GetMaxRowHeight(nsBoxLayoutState& aState, PRInt32 aIndex, bool aIsHorizontal)
 {
   RebuildIfNeeded();
 
   nsGridRow* row = GetRowAt(aIndex, aIsHorizontal);
 
-  if (row->IsCollapsed(aState))
+  if (row->IsCollapsed())
     return 0;
 
   if (row->IsMaxSet()) 
     return row->mMax;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
@@ -1048,17 +1048,17 @@ nsGrid::GetMaxRowHeight(nsBoxLayoutState
   for (PRInt32 i=0; i < count; i++)
   {  
     if (aIsHorizontal)
      child = GetCellAt(i,aIndex);
     else
      child = GetCellAt(aIndex,i);
 
     // ignore collapsed children
-    if (!child->IsCollapsed(aState))
+    if (!child->IsCollapsed())
     {
       nsSize min = child->GetMinSize(aState);
       nsSize childSize = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
       nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal);
     }
   }
 
   row->mMax = GET_HEIGHT(size, aIsHorizontal) + top + bottom;
--- a/layout/xul/base/src/grid/nsGridCell.cpp
+++ b/layout/xul/base/src/grid/nsGridCell.cpp
@@ -145,15 +145,15 @@ nsGridCell::GetMaxSize(nsBoxLayoutState&
     nsBoxLayout::AddSmallestSize(sum, max);
   }
 
   return sum;
 }
 
 
 bool
-nsGridCell::IsCollapsed(nsBoxLayoutState& aState)
+nsGridCell::IsCollapsed()
 {
-  return ((mBoxInColumn && mBoxInColumn->IsCollapsed(aState)) ||
-          (mBoxInRow && mBoxInRow->IsCollapsed(aState)));
+  return ((mBoxInColumn && mBoxInColumn->IsCollapsed()) ||
+          (mBoxInRow && mBoxInRow->IsCollapsed()));
 }
 
 
--- a/layout/xul/base/src/grid/nsGridCell.h
+++ b/layout/xul/base/src/grid/nsGridCell.h
@@ -62,17 +62,17 @@ class nsGridCell
 {
 public:
     nsGridCell();
     virtual ~nsGridCell();
 
     nsSize      GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
     nsSize      GetMinSize(nsBoxLayoutState& aBoxLayoutState);
     nsSize      GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
-    bool        IsCollapsed(nsBoxLayoutState& aBoxLayoutState);
+    bool        IsCollapsed();
 
 // accessors
     nsIBox*     GetBoxInColumn()             { return mBoxInColumn; }
     nsIBox*     GetBoxInRow()                { return mBoxInRow; }
     void        SetBoxInRow(nsIBox* aBox)    { mBoxInRow = aBox; }
     void        SetBoxInColumn(nsIBox* aBox) { mBoxInColumn = aBox; }
 
 private:
--- a/layout/xul/base/src/grid/nsGridRow.cpp
+++ b/layout/xul/base/src/grid/nsGridRow.cpp
@@ -77,13 +77,13 @@ nsGridRow::Init(nsIBox* aBox, bool aIsBo
 }
 
 nsGridRow::~nsGridRow()
 {
    MOZ_COUNT_DTOR(nsGridRow);
 }
 
 bool 
-nsGridRow::IsCollapsed(nsBoxLayoutState& aState)
+nsGridRow::IsCollapsed()
 {
-  return mBox && mBox->IsCollapsed(aState);
+  return mBox && mBox->IsCollapsed();
 }
 
--- a/layout/xul/base/src/grid/nsGridRow.h
+++ b/layout/xul/base/src/grid/nsGridRow.h
@@ -63,17 +63,17 @@ public:
 
 // accessors
    nsIBox* GetBox()   { return mBox;          }
    bool IsPrefSet() { return (mPref != -1); }
    bool IsMinSet()  { return (mMin  != -1); }
    bool IsMaxSet()  { return (mMax  != -1); } 
    bool IsFlexSet() { return (mFlex != -1); }
    bool IsOffsetSet() { return (mTop != -1 && mBottom != -1); }
-   bool IsCollapsed(nsBoxLayoutState& aState);
+   bool IsCollapsed();
 
 public:
 
    bool    mIsBogus;
    nsIBox* mBox;
    nscoord mFlex;
    nscoord mPref;
    nscoord mMin;
--- a/layout/xul/base/src/grid/nsGridRowLeafLayout.cpp
+++ b/layout/xul/base/src/grid/nsGridRowLeafLayout.cpp
@@ -165,17 +165,17 @@ nsGridRowLeafLayout::PopulateBoxSizes(ns
       nscoord right  = 0;
       grid->GetRowOffsets(aState, i, left, right, !isHorizontal); // GetColumnOffsets
       nsIBox* box = column->GetBox();
       bool collapsed = false;
       nscoord topMargin = column->mTopMargin;
       nscoord bottomMargin = column->mBottomMargin;
 
       if (box) 
-        collapsed = box->IsCollapsed(aState);
+        collapsed = box->IsCollapsed();
 
       pref = pref - (left + right);
       if (pref < 0)
         pref = 0;
 
       // if this is the first or last column. Take into account that
       // our row could have a border that could affect our left or right
       // padding from our columns. If the row has padding subtract it.
--- a/layout/xul/base/src/nsBox.cpp
+++ b/layout/xul/base/src/nsBox.cpp
@@ -48,16 +48,17 @@
 #include "nsGkAtoms.h"
 #include "nsFrameManager.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNamedNodeMap.h"
 #include "nsIDOMAttr.h"
 #include "nsIDocument.h"
 #include "nsITheme.h"
 #include "nsIServiceManager.h"
+#include "nsIViewManager.h"
 #include "nsBoxLayout.h"
 #include "FrameLayerBuilder.h"
 
 using namespace mozilla;
 
 #ifdef DEBUG_LAYOUT
 PRInt32 gIndent = 0;
 #endif
@@ -430,17 +431,17 @@ nsBox::DoesNeedRecalc(nscoord aCoord)
 nsSize
 nsBox::GetPrefSize(nsBoxLayoutState& aState)
 {
   NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");
 
   nsSize pref(0,0);
   DISPLAY_PREF_SIZE(this, pref);
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return pref;
 
   AddBorderAndPadding(pref);
   bool widthSet, heightSet;
   nsIBox::AddCSSPrefSize(this, pref, widthSet, heightSet);
 
   nsSize minSize = GetMinSize(aState);
   nsSize maxSize = GetMaxSize(aState);
@@ -450,17 +451,17 @@ nsBox::GetPrefSize(nsBoxLayoutState& aSt
 nsSize
 nsBox::GetMinSize(nsBoxLayoutState& aState)
 {
   NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");
 
   nsSize min(0,0);
   DISPLAY_MIN_SIZE(this, min);
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return min;
 
   AddBorderAndPadding(min);
   bool widthSet, heightSet;
   nsIBox::AddCSSMinSize(aState, this, min, widthSet, heightSet);
   return min;
 }
 
@@ -473,17 +474,17 @@ nsBox::GetMinSizeForScrollArea(nsBoxLayo
 nsSize
 nsBox::GetMaxSize(nsBoxLayoutState& aState)
 {
   NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");
 
   nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
   DISPLAY_MAX_SIZE(this, maxSize);
 
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return maxSize;
 
   AddBorderAndPadding(maxSize);
   bool widthSet, heightSet;
   nsIBox::AddCSSMaxSize(this, maxSize, widthSet, heightSet);
   return maxSize;
 }
 
@@ -515,24 +516,24 @@ nsIFrame::GetOrdinal(nsBoxLayoutState& a
   }
 
   return ordinal;
 }
 
 nscoord
 nsBox::GetBoxAscent(nsBoxLayoutState& aState)
 {
-  if (IsCollapsed(aState))
+  if (IsCollapsed())
     return 0;
 
   return GetPrefSize(aState).height;
 }
 
 bool
-nsBox::IsCollapsed(nsBoxLayoutState& aState)
+nsBox::IsCollapsed()
 {
   return GetStyleVisibility()->mVisible == NS_STYLE_VISIBILITY_COLLAPSE;
 }
 
 nsresult
 nsIFrame::Layout(nsBoxLayoutState& aState)
 {
   NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");
@@ -558,19 +559,17 @@ nsBox::DoesClipChildren()
                "If one overflow is clip, the other should be too");
   return display->mOverflowX == NS_STYLE_OVERFLOW_CLIP;
 }
 
 nsresult
 nsBox::SyncLayout(nsBoxLayoutState& aState)
 {
   /*
-  bool collapsed = false;
-  IsCollapsed(aState, collapsed);
-  if (collapsed) {
+  if (IsCollapsed()) {
     CollapseChild(aState, this, true);
     return NS_OK;
   }
   */
   
 
   if (GetStateBits() & NS_FRAME_IS_DIRTY)
      Redraw(aState);
@@ -590,27 +589,23 @@ nsBox::SyncLayout(nsBoxLayoutState& aSta
   nsRect visualOverflow;
 
   if (ComputesOwnOverflowArea()) {
     visualOverflow = GetVisualOverflowRect();
   }
   else {
     nsRect rect(nsPoint(0, 0), GetSize());
     nsOverflowAreas overflowAreas(rect, rect);
-    if (!DoesClipChildren() && !IsCollapsed(aState)) {
+    if (!DoesClipChildren() && !IsCollapsed()) {
       // See if our child frames caused us to overflow after being laid
       // out. If so, store the overflow area.  This normally can't happen
       // in XUL, but it can happen with the CSS 'outline' property and
       // possibly with other exotic stuff (e.g. relatively positioned
       // frames in HTML inside XUL).
-      for (nsIFrame* kid = GetChildBox(); kid; kid = kid->GetNextBox()) {
-        nsOverflowAreas kidOverflow =
-          kid->GetOverflowAreas() + kid->GetPosition();
-        overflowAreas.UnionWith(kidOverflow);
-      }
+      nsLayoutUtils::UnionChildOverflow(this, overflowAreas);
     }
 
     FinishAndStoreOverflow(overflowAreas, GetSize());
     visualOverflow = overflowAreas.VisualOverflow();
   }
 
   nsIView* view = GetView();
   if (view) {
--- a/layout/xul/base/src/nsBox.h
+++ b/layout/xul/base/src/nsBox.h
@@ -57,17 +57,17 @@ public:
   virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState);
   virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState);
   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState);
 
   virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState);
 
-  virtual bool IsCollapsed(nsBoxLayoutState& aBoxLayoutState);
+  virtual bool IsCollapsed();
 
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                          bool aRemoveOverflowAreas = false);
 
   NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding);
   NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding);
   NS_IMETHOD GetMargin(nsMargin& aMargin);
 
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -774,17 +774,17 @@ nsBoxFrame::GetPrefSize(nsBoxLayoutState
   if (!DoesNeedRecalc(mPrefSize)) {
      return mPrefSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
-  if (IsCollapsed(aBoxLayoutState))
+  if (IsCollapsed())
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
   bool widthSet, heightSet;
   if (!nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
       nsSize layoutSize = mLayoutManager->GetPrefSize(this, aBoxLayoutState);
@@ -810,17 +810,17 @@ nsBoxFrame::GetBoxAscent(nsBoxLayoutStat
 {
   if (!DoesNeedRecalc(mAscent))
      return mAscent;
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
-  if (IsCollapsed(aBoxLayoutState))
+  if (IsCollapsed())
     return 0;
 
   if (mLayoutManager)
     mAscent = mLayoutManager->GetAscent(this, aBoxLayoutState);
   else
     mAscent = nsBox::GetBoxAscent(aBoxLayoutState);
 
   return mAscent;
@@ -837,17 +837,17 @@ nsBoxFrame::GetMinSize(nsBoxLayoutState&
   if (!DoesNeedRecalc(mMinSize)) {
     return mMinSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
-  if (IsCollapsed(aBoxLayoutState))
+  if (IsCollapsed())
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
   bool widthSet, heightSet;
   if (!nsIBox::AddCSSMinSize(aBoxLayoutState, this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
       nsSize layoutSize = mLayoutManager->GetMinSize(this, aBoxLayoutState);
@@ -877,17 +877,17 @@ nsBoxFrame::GetMaxSize(nsBoxLayoutState&
   if (!DoesNeedRecalc(mMaxSize)) {
     return mMaxSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
-  if (IsCollapsed(aBoxLayoutState))
+  if (IsCollapsed())
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
   bool widthSet, heightSet;
   if (!nsIBox::AddCSSMaxSize(this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
       nsSize layoutSize = mLayoutManager->GetMaxSize(this, aBoxLayoutState);
@@ -1497,17 +1497,17 @@ nsBoxFrame::PaintXULDebugOverlay(nsRende
         x = cr.y;
         y = cr.x + onePixel;
         spacerSize = debugBorder.left - onePixel*4;
     }
 
     nsBoxLayoutState state(GetPresContext());
     nscoord flex = kid->GetFlex(state);
 
-    if (!kid->IsCollapsed(state)) {
+    if (!kid->IsCollapsed()) {
       aRenderingContext.SetColor(NS_RGB(255,255,255));
 
       if (isHorizontal) 
           borderSize = cr.width;
       else 
           borderSize = cr.height;
     
       DrawSpacer(GetPresContext(), aRenderingContext, isHorizontal, flex, x, y, borderSize, spacerSize);
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -1316,17 +1316,17 @@ nsMenuFrame::AppendFrames(ChildListID   
     return NS_OK;
 
   return nsBoxFrame::AppendFrames(aListID, aFrameList); 
 }
 
 bool
 nsMenuFrame::SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize)
 {
-  if (!IsCollapsed(aState)) {
+  if (!IsCollapsed()) {
     bool widthSet, heightSet;
     nsSize tmpSize(-1, 0);
     nsIBox::AddCSSPrefSize(this, tmpSize, widthSet, heightSet);
     if (!widthSet && GetFlex(aState) == 0) {
       if (!mPopupFrame)
         return false;
       tmpSize = mPopupFrame->GetPrefSize(aState);
 
--- a/layout/xul/base/src/nsSprocketLayout.cpp
+++ b/layout/xul/base/src/nsSprocketLayout.cpp
@@ -199,17 +199,17 @@ HandleBoxPack(nsIBox* aBox, const nsFram
   }
 }
 
 NS_IMETHODIMP
 nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
 {
   // See if we are collapsed. If we are, then simply iterate over all our
   // children and give them a rect of 0 width and height.
-  if (aBox->IsCollapsed(aState)) {
+  if (aBox->IsCollapsed()) {
     nsIBox* child = aBox->GetChildBox();
     while(child) 
     {
       nsBoxFrame::LayoutChildAt(aState, child, nsRect(0,0,0,0));  
       child = child->GetNextBox();
     }
     return NS_OK;
   }
@@ -736,17 +736,17 @@ nsSprocketLayout::PopulateBoxSizes(nsIBo
         currentBox->next      = new (aState) nsBoxSize();
         currentBox      = currentBox->next;
       }
     
 
       flex = child->GetFlex(aState);
 
       currentBox->flex = flex;
-      currentBox->collapsed = child->IsCollapsed(aState);
+      currentBox->collapsed = child->IsCollapsed();
     } else {
       flex = start->flex;
       start = start->next;
     }
     
     if (flex > 0) 
        aFlexes++;
    
@@ -768,17 +768,17 @@ nsSprocketLayout::PopulateBoxSizes(nsIBo
       last = currentBox;
       currentBox = currentBox->next;
     }
     ++childCount;
     nsSize pref(0,0);
     nsSize minSize(0,0);
     nsSize maxSize(NS_INTRINSICSIZE,NS_INTRINSICSIZE);
     nscoord ascent = 0;
-    bool collapsed = child->IsCollapsed(aState);
+    bool collapsed = child->IsCollapsed();
 
     if (!collapsed) {
     // only one flexible child? Cool we will just make its preferred size
     // 0 then and not even have to ask for it.
     //if (flexes != 1)  {
 
       pref = child->GetPrefSize(aState);
       minSize = child->GetMinSize(aState);
@@ -1356,17 +1356,17 @@ nsSprocketLayout::GetPrefSize(nsIBox* aB
    nsFrameState frameState = 0;
    GetFrameState(aBox, frameState);
    bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
    PRInt32 count = 0;
    
    while (child) 
    {  
       // ignore collapsed children
-      if (!child->IsCollapsed(aState))
+      if (!child->IsCollapsed())
       {
         nsSize pref = child->GetPrefSize(aState);
         AddMargin(child, pref);
 
         if (isEqual) {
           if (isHorizontal)
           {
             if (pref.width > biggestPref)
@@ -1413,17 +1413,17 @@ nsSprocketLayout::GetMinSize(nsIBox* aBo
    nsFrameState frameState = 0;
    GetFrameState(aBox, frameState);
    bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
    PRInt32 count = 0;
 
    while (child) 
    {  
        // ignore collapsed children
-      if (!child->IsCollapsed(aState))
+      if (!child->IsCollapsed())
       {
         nsSize min = child->GetMinSize(aState);
         nsSize pref(0,0);
         
         // if the child is not flexible then
         // its min size is its pref size.
         if (child->GetFlex(aState) == 0) {
             pref = child->GetPrefSize(aState);
@@ -1482,17 +1482,17 @@ nsSprocketLayout::GetMaxSize(nsIBox* aBo
    nsFrameState frameState = 0;
    GetFrameState(aBox, frameState);
    bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
    PRInt32 count = 0;
 
    while (child) 
    {  
       // ignore collapsed children
-      if (!child->IsCollapsed(aState))
+      if (!child->IsCollapsed())
       {
         // if completely redefined don't even ask our child for its size.
         nsSize min = child->GetMinSize(aState);
         nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
 
         AddMargin(child, max);
         AddSmallestSize(maxSize, max, isHorizontal);
 
@@ -1543,17 +1543,17 @@ nsSprocketLayout::GetAscent(nsIBox* aBox
    // run through all the children and get their min, max, and preferred sizes
    // return us the size of the box
    
    nsIBox* child = aBox->GetChildBox();
    
    while (child) 
    {  
       // ignore collapsed children
-      //if (!child->IsCollapsed(aState))
+      //if (!child->IsCollapsed())
       //{
         // if completely redefined don't even ask our child for its size.
         nscoord ascent = child->GetBoxAscent(aState);
 
         nsMargin margin;
         child->GetMargin(margin);
         ascent += margin.top;