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 draft
authorL. David Baron <dbaron@dbaron.org>
Tue, 23 Feb 2016 22:53:47 -0800
changeset 334025 336c8533eb3ae80e7e97e94e9b639a0dd02d96e6
parent 334024 77d78dc408ca10baaaf4df063cd2ddb1ea3c3086
child 334026 9d24bcc76014b7a4e441ea055f230f137deee52d
push id11430
push userdbaron@mozilla.com
push dateWed, 24 Feb 2016 06:53:56 +0000
reviewersdholbert
bugs1247929, 823483
milestone47.0a1
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
@@ -4498,16 +4498,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
+FormControlShrinksForPercentWidth(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.
  *
@@ -4578,17 +4615,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))) {
+        FormControlShrinksForPercentWidth(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) ||