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 324730 c024721d9b03fac54eee5730a34f8e7bfbff2129
parent 324729 056f728704e77c6ddc3cf9fc0f0ae8e539d73dc9
child 324731 65fa05989b391912d3c69d0b693dbd03a87cb1b0
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersdbaron
bugs504622
milestone53.0a1
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