Bug 504622 part 2. Allow fieldsets to shrink below their intrinsic min-width and below the width of their legend if their min-width is explicitly overridden. r=dbaron
☠☠ backed out by f6961e572571 ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 29 Nov 2016 15:52:55 -0500
changeset 324674 c024721d9b03fac54eee5730a34f8e7bfbff2129
parent 324673 056f728704e77c6ddc3cf9fc0f0ae8e539d73dc9
child 324675 65fa05989b391912d3c69d0b693dbd03a87cb1b0
push id84469
push userbzbarsky@mozilla.com
push dateTue, 29 Nov 2016 21:01:12 +0000
treeherdermozilla-inbound@c024721d9b03 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs504622
milestone53.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 504622 part 2. Allow fieldsets to shrink below their intrinsic min-width and below the width of their legend if their min-width is explicitly overridden. r=dbaron
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsFieldSetFrame.h
layout/reftests/bugs/433700-ref.html
layout/reftests/forms/fieldset/fieldset-min-width-1-ref.html
layout/reftests/forms/fieldset/fieldset-min-width-1a.html
layout/reftests/forms/fieldset/fieldset-min-width-1b.html
layout/reftests/forms/fieldset/fieldset-min-width-2-ref.html
layout/reftests/forms/fieldset/fieldset-min-width-2a.html
layout/reftests/forms/fieldset/fieldset-min-width-2b.html
layout/reftests/forms/fieldset/legend-overlapping-right-border-1-ref.html
layout/reftests/forms/fieldset/legend-overlapping-right-border-1.html
layout/reftests/forms/fieldset/reftest.list
layout/style/res/forms.css
testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html.ini
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -336,52 +336,16 @@ nsFieldSetFrame::GetPrefISize(nsRenderin
   nscoord result = 0;
   DISPLAY_PREF_WIDTH(this, result);
 
   result = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::PREF_ISIZE);
   return result;
 }
 
 /* virtual */
-LogicalSize
-nsFieldSetFrame::ComputeSize(nsRenderingContext *aRenderingContext,
-                             WritingMode aWM,
-                             const LogicalSize& aCBSize,
-                             nscoord aAvailableISize,
-                             const LogicalSize& aMargin,
-                             const LogicalSize& aBorder,
-                             const LogicalSize& aPadding,
-                             ComputeSizeFlags aFlags)
-{
-  LogicalSize result =
-    nsContainerFrame::ComputeSize(aRenderingContext, aWM,
-                                  aCBSize, aAvailableISize,
-                                  aMargin, aBorder, aPadding, aFlags);
-
-  // XXX The code below doesn't make sense if the caller's writing mode
-  // is orthogonal to this frame's. Not sure yet what should happen then;
-  // for now, just bail out.
-  if (aWM.IsVertical() != GetWritingMode().IsVertical()) {
-    return result;
-  }
-
-  // Fieldsets never shrink below their min width.
-
-  // If we're a container for font size inflation, then shrink
-  // wrapping inside of us should not apply font size inflation.
-  AutoMaybeDisableFontInflation an(this);
-
-  nscoord minISize = GetMinISize(aRenderingContext);
-  if (minISize > result.ISize(aWM)) {
-    result.ISize(aWM) = minISize;
-  }
-
-  return result;
-}
-
 void
 nsFieldSetFrame::Reflow(nsPresContext*           aPresContext,
                         ReflowOutput&     aDesiredSize,
                         const ReflowInput& aReflowInput,
                         nsReflowStatus&          aStatus)
 {
   MarkInReflow();
   DO_GLOBAL_REFLOW_COUNT("nsFieldSetFrame");
@@ -419,28 +383,16 @@ nsFieldSetFrame::Reflow(nsPresContext*  
   // to compute the available width for our children.
   WritingMode wm = GetWritingMode();
   WritingMode innerWM = inner ? inner->GetWritingMode() : wm;
   WritingMode legendWM = legend ? legend->GetWritingMode() : wm;
   LogicalSize innerAvailSize = aReflowInput.ComputedSizeWithPadding(innerWM);
   LogicalSize legendAvailSize = aReflowInput.ComputedSizeWithPadding(legendWM);
   innerAvailSize.BSize(innerWM) = legendAvailSize.BSize(legendWM) =
     NS_UNCONSTRAINEDSIZE;
-  NS_ASSERTION(!inner ||
-      nsLayoutUtils::IntrinsicForContainer(aReflowInput.mRenderingContext,
-                                           inner,
-                                           nsLayoutUtils::MIN_ISIZE) <=
-               innerAvailSize.ISize(innerWM),
-               "Bogus availSize.ISize; should be bigger");
-  NS_ASSERTION(!legend ||
-      nsLayoutUtils::IntrinsicForContainer(aReflowInput.mRenderingContext,
-                                           legend,
-                                           nsLayoutUtils::MIN_ISIZE) <=
-               legendAvailSize.ISize(legendWM),
-               "Bogus availSize.ISize; should be bigger");
 
   // get our border and padding
   LogicalMargin border = aReflowInput.ComputedLogicalBorderPadding() -
                          aReflowInput.ComputedLogicalPadding();
 
   // Figure out how big the legend is if there is one.
   // get the legend's margin
   LogicalMargin legendMargin(wm);
@@ -594,21 +546,18 @@ nsFieldSetFrame::Reflow(nsPresContext*  
         case NS_STYLE_VERTICAL_ALIGN_TOP:
         case NS_STYLE_VERTICAL_ALIGN_BOTTOM:
           mLegendRect.IStart(wm) = innerContentRect.IStart(wm);
           break;
         default:
           MOZ_ASSERT_UNREACHABLE("unexpected GetLogicalAlign value");
       }
     } else {
-      // otherwise make place for the legend
+      // otherwise just start-align it.
       mLegendRect.IStart(wm) = innerContentRect.IStart(wm);
-      innerContentRect.ISize(wm) = mLegendRect.ISize(wm);
-      contentRect.ISize(wm) = mLegendRect.ISize(wm) +
-        aReflowInput.ComputedLogicalPadding().IStartEnd(wm);
     }
 
     // place the legend
     LogicalRect actualLegendRect = mLegendRect;
     actualLegendRect.Deflate(wm, legendMargin);
     LogicalPoint actualLegendPos(actualLegendRect.Origin(wm));
 
     // Note that legend's writing mode may be different from the fieldset's,
--- a/layout/forms/nsFieldSetFrame.h
+++ b/layout/forms/nsFieldSetFrame.h
@@ -19,25 +19,16 @@ public:
 
   explicit nsFieldSetFrame(nsStyleContext* aContext);
 
   nscoord
     GetIntrinsicISize(nsRenderingContext* aRenderingContext,
                       nsLayoutUtils::IntrinsicISizeType);
   virtual nscoord GetMinISize(nsRenderingContext* aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext* aRenderingContext) override;
-  virtual mozilla::LogicalSize
-  ComputeSize(nsRenderingContext *aRenderingContext,
-              mozilla::WritingMode aWritingMode,
-              const mozilla::LogicalSize& aCBSize,
-              nscoord aAvailableISize,
-              const mozilla::LogicalSize& aMargin,
-              const mozilla::LogicalSize& aBorder,
-              const mozilla::LogicalSize& aPadding,
-              ComputeSizeFlags aFlags) override;
   virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
 
   /**
    * The area to paint box-shadows around.  It's the border rect except
    * when there's a <legend> we offset the y-position to the center of it.
    */
   virtual nsRect VisualBorderRectRelativeToSelf() const override;
 
--- a/layout/reftests/bugs/433700-ref.html
+++ b/layout/reftests/bugs/433700-ref.html
@@ -21,17 +21,20 @@ fieldset { border-right:7px solid blue; 
 #test3 .legend  { margin-left: 80px; background:pink; }
 
 #test4 { position:fixed; top:9em; width:200px; }
 #test4 fieldset { background:lime; width:260px; }
 #test4 .legend  { margin-left: 80px; background:pink; }
 
 #test5 { position:fixed; top:12em; width:200px; }
 #test5 fieldset { background:lime;}
-#test5 .legend  { margin-left: 193px; background:pink; }
+/* Percentage margins don't get counted in intrinsic width, so make sure that
+   our fixed-size margins sum to 0, so they also do not affect intrinsic width
+   either. */
+#test5 .legend  { margin-left: 193px; background:pink; margin-right: -193px; }
 
 #test6 { position:fixed; left:20px; top:15em; width:400px; }
 #test6 fieldset { width:300px; }
 #test6 fieldset div { position:relative; left:100px; padding-left:0px; width:200px; background:lime; }
 #test6 legend  { margin-left:0; background:pink; }
 
 fieldset div { padding-left:60px; }
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-1-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset style="width: -moz-fit-content">
+  Longwordgoeshere
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-1a.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset style="width: 0">
+  Longwordgoeshere
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-1b.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body style="width: 0">
+  <fieldset style="width: 0">
+    Longwordgoeshere
+  </fieldset>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-2-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<fieldset style="width: -moz-fit-content">&zwnj;<!-- To give us the right height --></fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-2a.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset style="width: 0; min-width: 0">
+  <div style="visibility: hidden">Longwordgoeshere</div>
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/fieldset-min-width-2b.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body style="width: 0">
+  <fieldset style="min-width: 0">
+    <div style="visibility: hidden">Longwordgoeshere</div>
+  </fieldset>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/legend-overlapping-right-border-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+  fieldset {
+    min-width: 0;
+    width: 0;
+  }
+  legend {
+    width: 100px;
+    height: 20px;
+    background: white;
+  }
+</style>
+<fieldset>
+  <legend></legend>
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/fieldset/legend-overlapping-right-border-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+  fieldset {
+    min-width: 0;
+    width: 0;
+  }
+  legend {
+    width: 100px;
+    height: 20px;
+  }
+</style>
+<fieldset>
+  <legend></legend>
+</fieldset>
--- a/layout/reftests/forms/fieldset/reftest.list
+++ b/layout/reftests/forms/fieldset/reftest.list
@@ -11,12 +11,17 @@ fuzzy-if(winWidget&&!layersGPUAccelerate
 == relpos-legend-3.html relpos-legend-3-ref.html
 == relpos-legend-4.html relpos-legend-4-ref.html
 == sticky-legend-1.html sticky-legend-1-ref.html
 fuzzy-if(skiaContent,1,40768) == abs-pos-child-sizing.html abs-pos-child-sizing-ref.html
 == overflow-hidden.html overflow-hidden-ref.html
 == legend-rtl.html legend-rtl-ref.html
 == fieldset-grid-001.html fieldset-grid-001-ref.html
 == fieldset-flexbox-001.html fieldset-flexbox-001-ref.html
+== fieldset-min-width-1a.html fieldset-min-width-1-ref.html
+== fieldset-min-width-1b.html fieldset-min-width-1-ref.html
+== fieldset-min-width-2a.html fieldset-min-width-2-ref.html
+== fieldset-min-width-2b.html fieldset-min-width-2-ref.html
+== legend-overlapping-right-border-1.html legend-overlapping-right-border-1-ref.html
 == fieldset-border-image-1a.html fieldset-border-image-1-ref.html
 == fieldset-border-image-1b.html fieldset-border-image-1-ref.html
 == fieldset-border-image-2a.html fieldset-border-image-2-ref.html
 == fieldset-border-image-2b.html fieldset-border-image-2-ref.html
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -66,16 +66,17 @@ fieldset {
   display: block;
   margin-inline-start: 2px;
   margin-inline-end: 2px;
   padding-block-start: 0.35em;
   padding-block-end: 0.75em;
   padding-inline-start: 0.625em;
   padding-inline-end: 0.625em;
   border: 2px groove ThreeDLightShadow;
+  min-width: -moz-min-content;
 }
 
 label {
   cursor: default;
 }
 
 /* default inputs, text inputs, and selects */
 
deleted file mode 100644
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[min-width-not-important.html]
-  type: reftest
-  expected: FAIL