Bug 1247929 patch 2 - Hard-code the Web-compatible set of form controls whose intrinsic minimum inline-size shrinks to 0 when inline-size (width) is specified as a percentage. r=dholbert
authorL. David Baron <dbaron@dbaron.org>
Wed, 24 Feb 2016 10:40:29 -0800
changeset 285423 89e5af841e9d162217257489c05aa2fbe45e8a17
parent 285422 7defbcbde4ced37e43e45c646c28fc4eca93d87b
child 285424 87b9d21672a8dc7aaf376be217ac62eb4c128610
push id30030
push usercbook@mozilla.com
push dateThu, 25 Feb 2016 10:58:04 +0000
treeherdermozilla-central@c1e0d1890cfe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1247929, 823483
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1247929 patch 2 - Hard-code the Web-compatible set of form controls whose intrinsic minimum inline-size shrinks to 0 when inline-size (width) is specified as a percentage. r=dholbert This adjusts the behavior previously modified by bug 823483 patch 2 and bug 823483 patch 5. MozReview-Commit-ID: 5IjYhFLUr68
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4501,16 +4501,53 @@ GetIntrinsicCoord(const nsStyleCoord& aS
 }
 
 #undef  DEBUG_INTRINSIC_WIDTH
 
 #ifdef DEBUG_INTRINSIC_WIDTH
 static int32_t gNoiseIndent = 0;
 #endif
 
+// Return true for form controls whose minimum intrinsic inline-size
+// shrinks to 0 when they have a percentage inline-size (but not
+// percentage max-inline-size).  (Proper replaced elements, whose
+// intrinsic minimium inline-size shrinks to 0 for both percentage
+// inline-size and percentage max-inline-size, are handled elsewhere.)
+inline static bool
+FormControlShrinksForPercentISize(nsIFrame* aFrame)
+{
+  if (!aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
+    // Quick test to reject most frames.
+    return false;
+  }
+
+  nsIAtom* fType = aFrame->GetType();
+  if (fType == nsGkAtoms::meterFrame || fType == nsGkAtoms::progressFrame) {
+    // progress and meter do have this shrinking behavior
+    // FIXME: Maybe these should be nsIFormControlFrame?
+    return true;
+  }
+
+  if (!static_cast<nsIFormControlFrame*>(do_QueryFrame(aFrame))) {
+    // Not a form control.  This includes fieldsets, which do not
+    // shrink.
+    return false;
+  }
+
+  if (fType == nsGkAtoms::gfxButtonControlFrame ||
+      fType == nsGkAtoms::HTMLButtonControlFrame) {
+    // Buttons don't have this shrinking behavior.  (Note that color
+    // inputs do, even though they inherit from button, so we can't use
+    // do_QueryFrame here.)
+    return false;
+  }
+
+  return true;
+}
+
 /**
  * Add aOffsets which describes what to add on outside of the content box
  * aContentSize (controlled by 'box-sizing') and apply min/max properties.
  * We have to account for these properties after getting all the offsets
  * (margin, border, padding) because percentages do not operate linearly.
  * Doing this is ok because although percentages aren't handled linearly,
  * they are handled monotonically.
  *
@@ -4581,17 +4618,17 @@ AddIntrinsicSizeOffset(nsRenderingContex
   result = NSCoordSaturatingAdd(result, coordOutsideSize);
   pctTotal += pctOutsideSize;
 
   nscoord size;
   if (aType == nsLayoutUtils::MIN_ISIZE &&
       (((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) &&
         aFrame->IsFrameOfType(nsIFrame::eReplacedSizing)) ||
        (aStyleSize.HasPercent() &&
-        aFrame->GetType() == nsGkAtoms::textInputFrame))) {
+        FormControlShrinksForPercentISize(aFrame)))) {
     // A percentage width or max-width on replaced elements means they
     // can shrink to 0.
     // This is also true for percentage widths (but not max-widths) on
     // text inputs.
     // Note that if this is max-width, this overrides the fixed-width
     // rule in the next condition.
     result = 0; // let |min| handle padding/border/margin
   } else if (GetAbsoluteCoord(aStyleSize, size) ||