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 86032 8651133cd19662053356aa499f2b0248b04e5bf0
parent 86031 1b9c27fad1b935b7a280c78f0182717567fa3caa
child 86033 9d0e181c6aa41d15d5bba8a7ac60ca7a7e7cf8b5
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs524925
milestone12.0a1
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;