Bug 544472, eliminate duplicate calls to AddCSS*** methods, plus some minor related code cleanup, r=dbaron
authorNeil Deakin <neil@mozilla.com>
Thu, 18 Mar 2010 15:58:15 -0400
changeset 39604 a35c6813e87dca7391c851e90e844fee8e33534f
parent 39603 4ee96dc6499cb069cb93d8eebe25b55029211f71
child 39605 bdb90006f262637e8726b858ec3033a6b9110de9
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs544472
milestone1.9.3a4pre
Bug 544472, eliminate duplicate calls to AddCSS*** methods, plus some minor related code cleanup, r=dbaron
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsIFrame.h
layout/xul/base/src/grid/nsGrid.cpp
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsBox.h
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsImageBoxFrame.cpp
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsTextBoxFrame.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6223,34 +6223,37 @@ nsSize
 nsFrame::GetPrefSize(nsBoxLayoutState& aState)
 {
   nsSize size(0,0);
   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)) {
-    size = metrics->mPrefSize;
-    return size;
+    return metrics->mPrefSize;
   }
 
   if (IsCollapsed(aState))
     return size;
 
   // get our size in CSS.
-  PRBool completelyRedefined = nsIBox::AddCSSPrefSize(aState, this, size);
+  PRBool widthSet, heightSet;
+  PRBool completelyRedefined = nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
 
   // Refresh our caches with new sizes.
   if (!completelyRedefined) {
     RefreshSizeCache(aState);
-    size = metrics->mBlockPrefSize;
+    nsSize blockSize = metrics->mBlockPrefSize;
 
     // notice we don't need to add our borders or padding
     // in. That's because the block did it for us.
-    nsIBox::AddCSSPrefSize(aState, this, size);
+    if (!widthSet)
+      size.width = blockSize.width;
+    if (!heightSet)
+      size.height = blockSize.height;
   }
 
   metrics->mPrefSize = size;
   return size;
 }
 
 nsSize
 nsFrame::GetMinSize(nsBoxLayoutState& aState)
@@ -6263,23 +6266,29 @@ nsFrame::GetMinSize(nsBoxLayoutState& aS
     size = metrics->mMinSize;
     return size;
   }
 
   if (IsCollapsed(aState))
     return size;
 
   // get our size in CSS.
-  PRBool completelyRedefined = nsIBox::AddCSSMinSize(aState, this, size);
+  PRBool widthSet, heightSet;
+  PRBool completelyRedefined =
+    nsIBox::AddCSSMinSize(aState, this, size, widthSet, heightSet);
 
   // Refresh our caches with new sizes.
   if (!completelyRedefined) {
     RefreshSizeCache(aState);
-    size = metrics->mBlockMinSize;
-    nsIBox::AddCSSMinSize(aState, this, size);
+    nsSize blockSize = metrics->mBlockMinSize;
+
+    if (!widthSet)
+      size.width = blockSize.width;
+    if (!heightSet)
+      size.height = blockSize.height;
   }
 
   metrics->mMinSize = size;
   return size;
 }
 
 nsSize
 nsFrame::GetMaxSize(nsBoxLayoutState& aState)
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1089,17 +1089,18 @@ nsXULScrollFrame::GetPrefSize(nsBoxLayou
    
   if (mInner.mHScrollbarBox &&
       styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) {
     nsSize hSize = mInner.mHScrollbarBox->GetPrefSize(aState);
     pref.height += hSize.height;
   }
 
   AddBorderAndPadding(pref);
-  nsIBox::AddCSSPrefSize(aState, this, pref);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSPrefSize(this, pref, widthSet, heightSet);
   return pref;
 }
 
 nsSize
 nsXULScrollFrame::GetMinSize(nsBoxLayoutState& aState)
 {
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aState);
@@ -1121,31 +1122,33 @@ nsXULScrollFrame::GetMinSize(nsBoxLayout
       styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) {
      nsSize hSize = mInner.mHScrollbarBox->GetMinSize(aState);
      min.height += hSize.height;
      if (min.width < hSize.width)
         min.width = hSize.width;
   }
 
   AddBorderAndPadding(min);
-  nsIBox::AddCSSMinSize(aState, this, min);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMinSize(aState, this, min, widthSet, heightSet);
   return min;
 }
 
 nsSize
 nsXULScrollFrame::GetMaxSize(nsBoxLayoutState& aState)
 {
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aState);
 #endif
 
   nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
 
   AddBorderAndPadding(maxSize);
-  nsIBox::AddCSSMaxSize(aState, this, maxSize);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMaxSize(this, maxSize, widthSet, heightSet);
   return maxSize;
 }
 
 #if 0 // XXXldb I don't think this is even needed
 /* virtual */ nscoord
 nsXULScrollFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
 {
   nsStyleUnit widthUnit = GetStylePosition()->mWidth.GetUnit();
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2287,22 +2287,21 @@ NS_PTR_TO_INT32(frame->GetProperty(nsGkA
 #endif
 
   /**
    * @return PR_TRUE if this text frame ends with a newline character.  It
    * should return PR_FALSE if this is not a text frame.
    */
   virtual PRBool HasTerminalNewline() const;
 
-  static PRBool AddCSSPrefSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
-  static PRBool AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
-  static PRBool AddCSSMaxSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
+  static PRBool AddCSSPrefSize(nsIBox* aBox, nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
+  static PRBool AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox,
+                              nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
+  static PRBool AddCSSMaxSize(nsIBox* aBox, nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
   static PRBool AddCSSFlex(nsBoxLayoutState& aState, nsIBox* aBox, nscoord& aFlex);
-  static PRBool AddCSSCollapsed(nsBoxLayoutState& aState, nsIBox* aBox, PRBool& aCollapsed);
-  static PRBool AddCSSOrdinal(nsBoxLayoutState& aState, nsIBox* aBox, PRUint32& aOrdinal);
 
   // END OF BOX LAYOUT METHODS
   // The above methods have been migrated from nsIBox and are in the process of
   // being refactored. DO NOT USE OUTSIDE OF XUL.
 
   /**
    * gets the first or last possible caret position within the frame
    *
--- a/layout/xul/base/src/grid/nsGrid.cpp
+++ b/layout/xul/base/src/grid/nsGrid.cpp
@@ -889,18 +889,19 @@ nsGrid::GetPrefRowHeight(nsBoxLayoutStat
   if (row->IsPrefSet()) 
     return row->mPref;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
   if (box) 
   {
+    PRBool widthSet, heightSet;
     nsSize cssSize(-1, -1);
-    nsIBox::AddCSSPrefSize(aState, box, cssSize);
+    nsIBox::AddCSSPrefSize(box, cssSize, widthSet, heightSet);
 
     row->mPref = GET_HEIGHT(cssSize, aIsHorizontal);
 
     // yep do nothing.
     if (row->mPref != -1)
       return row->mPref;
   }
 
@@ -964,18 +965,19 @@ nsGrid::GetMinRowHeight(nsBoxLayoutState
 
   if (row->IsMinSet()) 
     return row->mMin;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
   if (box) {
+    PRBool widthSet, heightSet;
     nsSize cssSize(-1, -1);
-    nsIBox::AddCSSMinSize(aState, box, cssSize);
+    nsIBox::AddCSSMinSize(aState, box, cssSize, widthSet, heightSet);
 
     row->mMin = GET_HEIGHT(cssSize, aIsHorizontal);
 
     // yep do nothing.
     if (row->mMin != -1)
       return row->mMin;
   }
 
@@ -1038,21 +1040,20 @@ nsGrid::GetMaxRowHeight(nsBoxLayoutState
 
   if (row->IsMaxSet()) 
     return row->mMax;
 
   nsIBox* box = row->mBox;
 
   // set in CSS?
   if (box) {
-    nsSize cssSize;
-    cssSize.width = -1;
-    cssSize.height = -1;
-    nsIBox::AddCSSMaxSize(aState, box, cssSize);
-    
+    PRBool widthSet, heightSet;
+    nsSize cssSize(-1, -1);
+    nsIBox::AddCSSMaxSize(box, cssSize, widthSet, heightSet);
+
     row->mMax = GET_HEIGHT(cssSize, aIsHorizontal);
 
     // yep do nothing.
     if (row->mMax != -1)
       return row->mMax;
   }
 
   // get the offsets so they are cached.
--- a/layout/xul/base/src/nsBox.cpp
+++ b/layout/xul/base/src/nsBox.cpp
@@ -447,17 +447,18 @@ nsBox::GetPrefSize(nsBoxLayoutState& aSt
 
   nsSize pref(0,0);
   DISPLAY_PREF_SIZE(this, pref);
 
   if (IsCollapsed(aState))
     return pref;
 
   AddBorderAndPadding(pref);
-  nsIBox::AddCSSPrefSize(aState, this, pref);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSPrefSize(this, pref, widthSet, heightSet);
 
   nsSize minSize = GetMinSize(aState);
   nsSize maxSize = GetMaxSize(aState);
   return BoundsCheck(minSize, pref, maxSize);
 }
 
 nsSize
 nsBox::GetMinSize(nsBoxLayoutState& aState)
@@ -466,17 +467,18 @@ nsBox::GetMinSize(nsBoxLayoutState& aSta
 
   nsSize min(0,0);
   DISPLAY_MIN_SIZE(this, min);
 
   if (IsCollapsed(aState))
     return min;
 
   AddBorderAndPadding(min);
-  nsIBox::AddCSSMinSize(aState, this, min);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMinSize(aState, this, min, widthSet, heightSet);
   return min;
 }
 
 nsSize
 nsBox::GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState)
 {
   return nsSize(0, 0);
 }
@@ -488,56 +490,71 @@ nsBox::GetMaxSize(nsBoxLayoutState& aSta
 
   nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
   DISPLAY_MAX_SIZE(this, maxSize);
 
   if (IsCollapsed(aState))
     return maxSize;
 
   AddBorderAndPadding(maxSize);
-  nsIBox::AddCSSMaxSize(aState, this, maxSize);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMaxSize(this, maxSize, widthSet, heightSet);
   return maxSize;
 }
 
 nscoord
 nsBox::GetFlex(nsBoxLayoutState& aState)
 {
   nscoord flex = 0;
 
-  GetDefaultFlex(flex);
   nsIBox::AddCSSFlex(aState, this, flex);
 
   return flex;
 }
 
 PRUint32
 nsIFrame::GetOrdinal(nsBoxLayoutState& aState)
 {
   PRUint32 ordinal = DEFAULT_ORDINAL_GROUP;
-  nsIBox::AddCSSOrdinal(aState, this, ordinal);
+
+  nsIContent* content = GetContent();
+  if (content) {
+    PRInt32 error;
+    nsAutoString value;
+
+    content->GetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, value);
+    if (!value.IsEmpty()) {
+      ordinal = value.ToInteger(&error);
+    }
+    else {
+      // No attribute value.  Check CSS.
+      const nsStyleXUL* boxInfo = GetStyleXUL();
+      if (boxInfo->mBoxOrdinal > 1) {
+        // The ordinal group was defined in CSS.
+        ordinal = (nscoord)boxInfo->mBoxOrdinal;
+      }
+    }
+  }
 
   return ordinal;
 }
 
 nscoord
 nsBox::GetBoxAscent(nsBoxLayoutState& aState)
 {
   if (IsCollapsed(aState))
     return 0;
 
   return GetPrefSize(aState).height;
 }
 
 PRBool
 nsBox::IsCollapsed(nsBoxLayoutState& aState)
 {
-  PRBool collapsed = PR_FALSE;
-  nsIBox::AddCSSCollapsed(aState, this, collapsed);
-
-  return collapsed;
+  return GetStyleVisibility()->mVisible == NS_STYLE_VISIBILITY_COLLAPSE;
 }
 
 nsresult
 nsIFrame::Layout(nsBoxLayoutState& aState)
 {
   NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");
 
   nsBox *box = static_cast<nsBox*>(this);
@@ -643,224 +660,227 @@ nsIFrame::Redraw(nsBoxLayoutState& aStat
   else
     damageRect = GetOverflowRect();
 
   InvalidateWithFlags(damageRect, aImmediate ? INVALIDATE_IMMEDIATE : 0);
 
   return NS_OK;
 }
 
-PRBool 
-nsIBox::AddCSSPrefSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize)
+PRBool
+nsIBox::AddCSSPrefSize(nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &aHeightSet)
 {
-    PRBool widthSet = PR_FALSE, heightSet = PR_FALSE;
+    aWidthSet = PR_FALSE;
+    aHeightSet = PR_FALSE;
 
     // add in the css min, max, pref
     const nsStylePosition* position = aBox->GetStylePosition();
 
     // see if the width or height was specifically set
     // XXX Handle eStyleUnit_Enumerated?
     // (Handling the eStyleUnit_Enumerated types requires
     // GetPrefSize/GetMinSize methods that don't consider
     // (min-/max-/)(width/height) properties.)
     if (position->mWidth.GetUnit() == eStyleUnit_Coord) {
         aSize.width = position->mWidth.GetCoordValue();
-        widthSet = PR_TRUE;
+        aWidthSet = PR_TRUE;
     }
 
     if (position->mHeight.GetUnit() == eStyleUnit_Coord) {
         aSize.height = position->mHeight.GetCoordValue();     
-        heightSet = PR_TRUE;
+        aHeightSet = PR_TRUE;
     }
     
     nsIContent* content = aBox->GetContent();
     // ignore 'height' and 'width' attributes if the actual element is not XUL
     // For example, we might be magic XUL frames whose primary content is an HTML
     // <select>
     if (content && content->IsXUL()) {
         nsAutoString value;
         PRInt32 error;
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value);
         if (!value.IsEmpty()) {
             value.Trim("%");
 
             aSize.width =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
-            widthSet = PR_TRUE;
+            aWidthSet = PR_TRUE;
         }
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value);
         if (!value.IsEmpty()) {
             value.Trim("%");
 
             aSize.height =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
-            heightSet = PR_TRUE;
+            aHeightSet = PR_TRUE;
         }
     }
 
-    return (widthSet && heightSet);
+    return (aWidthSet && aHeightSet);
 }
 
 
-PRBool 
-nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize)
+PRBool
+nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize,
+                      PRBool &aWidthSet, PRBool &aHeightSet)
 {
+    aWidthSet = PR_FALSE;
+    aHeightSet = PR_FALSE;
 
-    PRBool widthSet = PR_FALSE;
-    PRBool heightSet = PR_FALSE;
     PRBool canOverride = PR_TRUE;
 
     // See if a native theme wants to supply a minimum size.
     const nsStyleDisplay* display = aBox->GetStyleDisplay();
     if (display->mAppearance) {
       nsITheme *theme = aState.PresContext()->GetTheme();
       if (theme && theme->ThemeSupportsWidget(aState.PresContext(), aBox, display->mAppearance)) {
         nsIntSize size;
         nsIRenderingContext* rendContext = aState.GetRenderingContext();
         if (rendContext) {
           theme->GetMinimumWidgetSize(rendContext, aBox,
                                       display->mAppearance, &size, &canOverride);
           if (size.width) {
             aSize.width = aState.PresContext()->DevPixelsToAppUnits(size.width);
-            widthSet = PR_TRUE;
+            aWidthSet = PR_TRUE;
           }
           if (size.height) {
             aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height);
-            heightSet = PR_TRUE;
+            aHeightSet = PR_TRUE;
           }
         }
       }
     }
 
     // add in the css min, max, pref
     const nsStylePosition* position = aBox->GetStylePosition();
 
     // same for min size. Unfortunately min size is always set to 0. So for now
     // we will assume 0 means not set.
     if (position->mMinWidth.GetUnit() == eStyleUnit_Coord) {
         nscoord min = position->mMinWidth.GetCoordValue();
-        if (min && (!widthSet || (min > aSize.width && canOverride))) {
+        if (min && (!aWidthSet || (min > aSize.width && canOverride))) {
            aSize.width = min;
-           widthSet = PR_TRUE;
+           aWidthSet = PR_TRUE;
         }
     } else if (position->mMinWidth.GetUnit() == eStyleUnit_Percent) {
         NS_ASSERTION(position->mMinWidth.GetPercentValue() == 0.0f,
           "Non-zero percentage values not currently supported");
         aSize.width = 0;
-        widthSet = PR_TRUE;
+        aWidthSet = PR_TRUE;
     }
     // XXX Handle eStyleUnit_Enumerated?
     // (Handling the eStyleUnit_Enumerated types requires
     // GetPrefSize/GetMinSize methods that don't consider
     // (min-/max-/)(width/height) properties.
 
     if (position->mMinHeight.GetUnit() == eStyleUnit_Coord) {
         nscoord min = position->mMinHeight.GetCoordValue();
-        if (min && (!heightSet || (min > aSize.height && canOverride))) {
+        if (min && (!aHeightSet || (min > aSize.height && canOverride))) {
            aSize.height = min;
-           heightSet = PR_TRUE;
+           aHeightSet = PR_TRUE;
         }
     } else if (position->mMinHeight.GetUnit() == eStyleUnit_Percent) {
         NS_ASSERTION(position->mMinHeight.GetPercentValue() == 0.0f,
           "Non-zero percentage values not currently supported");
         aSize.height = 0;
-        heightSet = PR_TRUE;
+        aHeightSet = PR_TRUE;
     }
 
     nsIContent* content = aBox->GetContent();
     if (content) {
         nsAutoString value;
         PRInt32 error;
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::minwidth, value);
         if (!value.IsEmpty())
         {
             value.Trim("%");
 
             nscoord val =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
             if (val > aSize.width)
               aSize.width = val;
-            widthSet = PR_TRUE;
+            aWidthSet = PR_TRUE;
         }
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::minheight, value);
         if (!value.IsEmpty())
         {
             value.Trim("%");
 
             nscoord val =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
             if (val > aSize.height)
               aSize.height = val;
 
-            heightSet = PR_TRUE;
+            aHeightSet = PR_TRUE;
         }
     }
 
-    return (widthSet && heightSet);
+    return (aWidthSet && aHeightSet);
 }
 
-PRBool 
-nsIBox::AddCSSMaxSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize)
-{  
-    PRBool widthSet = PR_FALSE, heightSet = PR_FALSE;
+PRBool
+nsIBox::AddCSSMaxSize(nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &aHeightSet)
+{
+    aWidthSet = PR_FALSE;
+    aHeightSet = PR_FALSE;
 
     // add in the css min, max, pref
     const nsStylePosition* position = aBox->GetStylePosition();
 
     // and max
     // see if the width or height was specifically set
     // XXX Handle eStyleUnit_Enumerated?
     // (Handling the eStyleUnit_Enumerated types requires
     // GetPrefSize/GetMinSize methods that don't consider
     // (min-/max-/)(width/height) properties.)
     if (position->mMaxWidth.GetUnit() == eStyleUnit_Coord) {
         aSize.width = position->mMaxWidth.GetCoordValue();
-        widthSet = PR_TRUE;
+        aWidthSet = PR_TRUE;
     }
 
     if (position->mMaxHeight.GetUnit() == eStyleUnit_Coord) {
         aSize.height = position->mMaxHeight.GetCoordValue();
-        heightSet = PR_TRUE;
+        aHeightSet = PR_TRUE;
     }
 
     nsIContent* content = aBox->GetContent();
     if (content) {
         nsAutoString value;
         PRInt32 error;
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::maxwidth, value);
         if (!value.IsEmpty()) {
             value.Trim("%");
 
             nscoord val =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
             aSize.width = val;
-            widthSet = PR_TRUE;
+            aWidthSet = PR_TRUE;
         }
 
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::maxheight, value);
         if (!value.IsEmpty()) {
             value.Trim("%");
 
             nscoord val =
               nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error));
             aSize.height = val;
 
-            heightSet = PR_TRUE;
+            aHeightSet = PR_TRUE;
         }
     }
 
-    return (widthSet || heightSet);
+    return (aWidthSet || aHeightSet);
 }
 
-PRBool 
+PRBool
 nsIBox::AddCSSFlex(nsBoxLayoutState& aState, nsIBox* aBox, nscoord& aFlex)
 {
     PRBool flexSet = PR_FALSE;
 
     // get the flexibility
     nsIContent* content = aBox->GetContent();
     if (content) {
         PRInt32 error;
@@ -886,54 +906,16 @@ nsIBox::AddCSSFlex(nsBoxLayoutState& aSt
     if (aFlex < 0)
       aFlex = 0;
     if (aFlex >= nscoord_MAX)
       aFlex = nscoord_MAX - 1;
 
     return flexSet;
 }
 
-PRBool 
-nsIBox::AddCSSCollapsed(nsBoxLayoutState& aState, nsIBox* aBox, PRBool& aCollapsed)
-{
-  aCollapsed = aBox->GetStyleVisibility()->mVisible ==
-               NS_STYLE_VISIBILITY_COLLAPSE;
-  return PR_TRUE;
-}
-
-PRBool 
-nsIBox::AddCSSOrdinal(nsBoxLayoutState& aState, nsIBox* aBox, PRUint32& aOrdinal)
-{
-  PRBool ordinalSet = PR_FALSE;
-  
-  // get the flexibility
-  nsIContent* content = aBox->GetContent();
-  if (content) {
-    PRInt32 error;
-    nsAutoString value;
-
-    content->GetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, value);
-    if (!value.IsEmpty()) {
-      aOrdinal = value.ToInteger(&error);
-      ordinalSet = PR_TRUE;
-    }
-    else {
-      // No attribute value.  Check CSS.
-      const nsStyleXUL* boxInfo = aBox->GetStyleXUL();
-      if (boxInfo->mBoxOrdinal > 1) {
-        // The ordinal group was defined in CSS.
-        aOrdinal = (nscoord)boxInfo->mBoxOrdinal;
-        ordinalSet = PR_TRUE;
-      }
-    }
-  }
-
-  return ordinalSet;
-}
-
 void
 nsBox::AddBorderAndPadding(nsSize& aSize)
 {
   AddBorderAndPadding(this, aSize);
 }
 
 void
 nsBox::AddMargin(nsSize& aSize)
@@ -1042,15 +1024,8 @@ nsBox::GetDebug(PRBool& aDebug)
 PRBool
 nsBox::GetMouseThrough() const
 {
   if (mParent && mParent->IsBoxFrame())
     return mParent->GetMouseThrough();
 
   return PR_FALSE;
 }
-
-PRBool
-nsBox::GetDefaultFlex(PRInt32& aFlex) 
-{ 
-  aFlex = 0; 
-  return PR_TRUE; 
-}
--- a/layout/xul/base/src/nsBox.h
+++ b/layout/xul/base/src/nsBox.h
@@ -124,17 +124,16 @@ rollbox.
 protected:
 
 #ifdef DEBUG_LAYOUT
   virtual void AppendAttribute(const nsAutoString& aAttribute, const nsAutoString& aValue, nsAutoString& aResult);
 
   virtual void ListBox(nsAutoString& aResult);
 #endif
   
-  virtual PRBool GetDefaultFlex(PRInt32& aFlex);
   virtual void GetLayoutFlags(PRUint32& aFlags);
 
   NS_HIDDEN_(nsresult) BeginLayout(nsBoxLayoutState& aState);
   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
   NS_HIDDEN_(nsresult) EndLayout(nsBoxLayoutState& aState);
 
 #ifdef DEBUG_LAYOUT
   virtual void GetBoxName(nsAutoString& aName);
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -785,35 +785,40 @@ nsSize
 nsBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState)
 {
   NS_ASSERTION(aBoxLayoutState.GetRenderingContext(),
                "must have rendering context");
 
   nsSize size(0,0);
   DISPLAY_PREF_SIZE(this, size);
   if (!DoesNeedRecalc(mPrefSize)) {
-     size = mPrefSize;
-     return size;
+     return mPrefSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
   if (IsCollapsed(aBoxLayoutState))
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
-  if (!nsIBox::AddCSSPrefSize(aBoxLayoutState, this, size))
+  PRBool widthSet, heightSet;
+  if (!nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
-      size = mLayoutManager->GetPrefSize(this, aBoxLayoutState);
-      nsIBox::AddCSSPrefSize(aBoxLayoutState, this, size);
-    } else
+      nsSize layoutSize = mLayoutManager->GetPrefSize(this, aBoxLayoutState);
+      if (!widthSet)
+        size.width = layoutSize.width;
+      if (!heightSet)
+        size.height = layoutSize.height;
+    }
+    else {
       size = nsBox::GetPrefSize(aBoxLayoutState);
+    }
   }
 
   nsSize minSize = GetMinSize(aBoxLayoutState);
   nsSize maxSize = GetMaxSize(aBoxLayoutState);
   mPrefSize = BoundsCheck(minSize, size, maxSize);
  
   return mPrefSize;
 }
@@ -843,34 +848,38 @@ nsSize
 nsBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState)
 {
   NS_ASSERTION(aBoxLayoutState.GetRenderingContext(),
                "must have rendering context");
 
   nsSize size(0,0);
   DISPLAY_MIN_SIZE(this, size);
   if (!DoesNeedRecalc(mMinSize)) {
-    size = mMinSize;
-    return size;
+    return mMinSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
   if (IsCollapsed(aBoxLayoutState))
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
-  if (!nsIBox::AddCSSMinSize(aBoxLayoutState, this, size))
+  PRBool widthSet, heightSet;
+  if (!nsIBox::AddCSSMinSize(aBoxLayoutState, this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
-      size = mLayoutManager->GetMinSize(this, aBoxLayoutState);
-      nsIBox::AddCSSMinSize(aBoxLayoutState, this, size);
-    } else {
+      nsSize layoutSize = mLayoutManager->GetMinSize(this, aBoxLayoutState);
+      if (!widthSet)
+        size.width = layoutSize.width;
+      if (!heightSet)
+        size.height = layoutSize.height;
+    }
+    else {
       size = nsBox::GetMinSize(aBoxLayoutState);
     }
   }
   
   mMinSize = size;
 
   return size;
 }
@@ -879,34 +888,38 @@ nsSize
 nsBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState)
 {
   NS_ASSERTION(aBoxLayoutState.GetRenderingContext(),
                "must have rendering context");
 
   nsSize size(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
   DISPLAY_MAX_SIZE(this, size);
   if (!DoesNeedRecalc(mMaxSize)) {
-    size = mMaxSize;
-    return size;
+    return mMaxSize;
   }
 
 #ifdef DEBUG_LAYOUT
   PropagateDebug(aBoxLayoutState);
 #endif
 
   if (IsCollapsed(aBoxLayoutState))
     return size;
 
   // if the size was not completely redefined in CSS then ask our children
-  if (!nsIBox::AddCSSMaxSize(aBoxLayoutState, this, size))
+  PRBool widthSet, heightSet;
+  if (!nsIBox::AddCSSMaxSize(this, size, widthSet, heightSet))
   {
     if (mLayoutManager) {
-      size = mLayoutManager->GetMaxSize(this, aBoxLayoutState);
-      nsIBox::AddCSSMaxSize(aBoxLayoutState, this, size);
-    } else {
+      nsSize layoutSize = mLayoutManager->GetMaxSize(this, aBoxLayoutState);
+      if (!widthSet)
+        size.width = layoutSize.width;
+      if (!heightSet)
+        size.height = layoutSize.height;
+    }
+    else {
       size = nsBox::GetMaxSize(aBoxLayoutState);
     }
   }
 
   mMaxSize = size;
 
   return size;
 }
@@ -1720,19 +1733,20 @@ nsBoxFrame::DisplayDebugInfoFor(nsIBox* 
 
                     mDebugChild = child;
 
                     nsSize prefSizeCSS(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
                     nsSize minSizeCSS (NS_INTRINSICSIZE, NS_INTRINSICSIZE);
                     nsSize maxSizeCSS (NS_INTRINSICSIZE, NS_INTRINSICSIZE);
                     nscoord flexCSS = NS_INTRINSICSIZE;
 
-                    nsIBox::AddCSSPrefSize(state, child, prefSizeCSS);
-                    nsIBox::AddCSSMinSize (state, child, minSizeCSS);
-                    nsIBox::AddCSSMaxSize (state, child, maxSizeCSS);
+                    PRBool widthSet, heightSet;
+                    nsIBox::AddCSSPrefSize(child, prefSizeCSS, widthSet, heightSet);
+                    nsIBox::AddCSSMinSize (state, child, minSizeCSS, widthSet, heightSet);
+                    nsIBox::AddCSSMaxSize (child, maxSizeCSS, widthSet, heightSet);
                     nsIBox::AddCSSFlex    (state, child, flexCSS);
 
                     nsSize prefSize = child->GetPrefSize(state);
                     nsSize minSize = child->GetMinSize(state);
                     nsSize maxSize = child->GetMaxSize(state);
                     nscoord flexSize = child->GetFlex(state);
                     nscoord ascentSize = child->GetBoxAscent(state);
 
--- a/layout/xul/base/src/nsImageBoxFrame.cpp
+++ b/layout/xul/base/src/nsImageBoxFrame.cpp
@@ -452,32 +452,34 @@ nsImageBoxFrame::GetPrefSize(nsBoxLayout
   if (DoesNeedRecalc(mImageSize))
      GetImageSize();
 
   if (!mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0))
     size = nsSize(mSubRect.width, mSubRect.height);
   else
     size = mImageSize;
   AddBorderAndPadding(size);
-  nsIBox::AddCSSPrefSize(aState, this, size);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
 
   nsSize minSize = GetMinSize(aState);
   nsSize maxSize = GetMaxSize(aState);  
 
   return BoundsCheck(minSize, size, maxSize);
 }
 
 nsSize
 nsImageBoxFrame::GetMinSize(nsBoxLayoutState& aState)
 {
   // An image can always scale down to (0,0).
   nsSize size(0,0);
   DISPLAY_MIN_SIZE(this, size);
   AddBorderAndPadding(size);
-  nsIBox::AddCSSMinSize(aState, this, size);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMinSize(aState, this, size, widthSet, heightSet);
   return size;
 }
 
 nscoord
 nsImageBoxFrame::GetBoxAscent(nsBoxLayoutState& aState)
 {
   return GetPrefSize(aState).height;
 }
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -1254,19 +1254,20 @@ nsMenuFrame::AppendFrames(nsIAtom*      
 
   return nsBoxFrame::AppendFrames(aListName, aFrameList); 
 }
 
 PRBool
 nsMenuFrame::SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize)
 {
   if (!IsCollapsed(aState)) {
+    PRBool widthSet, heightSet;
     nsSize tmpSize(-1, 0);
-    nsIBox::AddCSSPrefSize(aState, this, tmpSize);
-    if (tmpSize.width == -1 && GetFlex(aState) == 0) {
+    nsIBox::AddCSSPrefSize(this, tmpSize, widthSet, heightSet);
+    if (!widthSet && GetFlex(aState) == 0) {
       if (!mPopupFrame)
         return PR_FALSE;
       tmpSize = mPopupFrame->GetPrefSize(aState);
       aSize.width = tmpSize.width;
       return PR_TRUE;
     }
   }
 
--- a/layout/xul/base/src/nsTextBoxFrame.cpp
+++ b/layout/xul/base/src/nsTextBoxFrame.cpp
@@ -1041,17 +1041,18 @@ nsSize
 nsTextBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState)
 {
     CalcTextSize(aBoxLayoutState);
 
     nsSize size = mTextSize;
     DISPLAY_PREF_SIZE(this, size);
 
     AddBorderAndPadding(size);
-    nsIBox::AddCSSPrefSize(aBoxLayoutState, this, size);
+    PRBool widthSet, heightSet;
+    nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
 
     return size;
 }
 
 /**
  * Ok return our dimensions
  */
 nsSize
@@ -1062,17 +1063,18 @@ nsTextBoxFrame::GetMinSize(nsBoxLayoutSt
     nsSize size = mTextSize;
     DISPLAY_MIN_SIZE(this, size);
 
     // if there is cropping our min width becomes our border and padding
     if (mCropType != CropNone)
         size.width = 0;
 
     AddBorderAndPadding(size);
-    nsIBox::AddCSSMinSize(aBoxLayoutState, this, size);
+    PRBool widthSet, heightSet;
+    nsIBox::AddCSSMinSize(aBoxLayoutState, this, size, widthSet, heightSet);
 
     return size;
 }
 
 nscoord
 nsTextBoxFrame::GetBoxAscent(nsBoxLayoutState& aBoxLayoutState)
 {
     CalcTextSize(aBoxLayoutState);
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -245,17 +245,18 @@ nsTreeBodyFrame::GetMinSize(nsBoxLayoutS
     else {
       desiredRows = 0;
     }
   }
 
   min.height = mRowHeight * desiredRows;
 
   AddBorderAndPadding(min);
-  nsIBox::AddCSSMinSize(aBoxLayoutState, this, min);
+  PRBool widthSet, heightSet;
+  nsIBox::AddCSSMinSize(aBoxLayoutState, this, min, widthSet, heightSet);
 
   return min;
 }
 
 nscoord
 nsTreeBodyFrame::CalcMaxRowWidth()
 {
   if (mStringWidth != -1)