Bug 1522898: Account for box-sizing (add border & padding) when setting a main-size property value override on a flex item (which it uses for aspect ratio calculations). r=mats a=lizzard
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 04 Feb 2019 23:06:16 +0000
changeset 513049 2af591523036
parent 513048 a5083352550a
child 513050 cea43c1728b9
push id10697
push usernbeleuzu@mozilla.com
push dateThu, 14 Feb 2019 01:25:42 +0000
treeherdermozilla-beta@f47db91d62e1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats, lizzard
bugs1522898
milestone66.0
Bug 1522898: Account for box-sizing (add border & padding) when setting a main-size property value override on a flex item (which it uses for aspect ratio calculations). r=mats a=lizzard For elements that have box-sizing:border-box specified, the aspect ratio calculation code subtracts out border & padding from any specified property values. So, when we create a fake "override" specified property value for a flex item whose main size has been resolved, we need to add in the border and padding to account for the fact that they're going to be subtracted out later. Differential Revision: https://phabricator.services.mozilla.com/D17712
layout/generic/nsFlexContainerFrame.cpp
layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007v.html
layout/reftests/w3c-css/submitted/flexbox/reftest.list
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -4287,29 +4287,40 @@ void nsFlexContainerFrame::Reflow(nsPres
 // CSS property ('width' or 'height') on a flex item, for use in
 // nsFrame::ComputeSizeWithIntrinsicDimensions.
 // (We could use this overridden size more broadly, too, but it's probably
 // better to avoid property-table accesses.  So, where possible, we communicate
 // the resolved main-size to the child via modifying its reflow state directly,
 // instead of using this class.)
 class MOZ_RAII AutoFlexItemMainSizeOverride final {
  public:
-  explicit AutoFlexItemMainSizeOverride(
-      FlexItem& aItem MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+  explicit AutoFlexItemMainSizeOverride(FlexItem& aItem,
+                                        const FlexboxAxisTracker& aAxisTracker
+                                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
       : mItemFrame(aItem.Frame()) {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
     MOZ_ASSERT(!mItemFrame->HasProperty(nsIFrame::FlexItemMainSizeOverride()),
                "FlexItemMainSizeOverride prop shouldn't be set already; "
                "it should only be set temporarily (& not recursively)");
     NS_ASSERTION(aItem.HasIntrinsicRatio(),
                  "This should only be needed for items with an aspect ratio");
 
+    nscoord mainSizeOverrideVal = aItem.GetMainSize();
+    // Note: aItem.GetMainSize() is the item's *content-box* main-size.  If we
+    // have 'box-sizing: border-box', then we have to add our main-axis border
+    // and padding in order to produce an appopriate "override" value that
+    // gets us the content-box size that we expect.
+    if (aItem.Frame()->StylePosition()->mBoxSizing == StyleBoxSizing::Border) {
+      mainSizeOverrideVal +=
+          aItem.GetBorderPaddingSizeInAxis(aAxisTracker.GetMainAxis());
+    }
+
     mItemFrame->SetProperty(nsIFrame::FlexItemMainSizeOverride(),
-                            aItem.GetMainSize());
+                            mainSizeOverrideVal);
   }
 
   ~AutoFlexItemMainSizeOverride() {
     mItemFrame->RemoveProperty(nsIFrame::FlexItemMainSizeOverride());
   }
 
  private:
   nsIFrame* mItemFrame;
@@ -4624,17 +4635,17 @@ void nsFlexContainerFrame::DoFlexLayout(
         if (item->HasIntrinsicRatio()) {
           // For flex items with an aspect ratio, we have to impose an override
           // for the main-size property *before* we even instantiate the reflow
           // state, in order for aspect ratio calculations to produce the right
           // cross size in the reflow state. (For other flex items, it's OK
           // (and cheaper) to impose our main size *after* the reflow state has
           // been constructed, since the main size shouldn't influence anything
           // about cross-size measurement until we actually reflow the child.)
-          sizeOverride.emplace(*item);
+          sizeOverride.emplace(*item, aAxisTracker);
         }
 
         WritingMode wm = item->Frame()->GetWritingMode();
         LogicalSize availSize = aReflowInput.ComputedSize(wm);
         availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
         ReflowInput childReflowInput(aPresContext, aReflowInput, item->Frame(),
                                      availSize);
         if (!sizeOverride) {
copy from layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001-ref.html
copy to layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007-ref.html
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001-ref.html
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007-ref.html
@@ -12,16 +12,22 @@
       .flexbox {
         border: 1px solid black;
         margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
         width: 40px;
         height: 40px;
 
         float: left; /* For testing in "rows" */
       }
+      img {
+        padding: 1px 2px 3px 4px;
+        box-sizing: border-box;
+        background: pink;
+      }
+
       br { clear: both; }
 
       .flexbox > * {
         /* Disable "min-width:auto"/"min-height:auto" to focus purely on
            later channels of influence. */
         min-width: 0;
         min-height: 0;
         vertical-align: top;
@@ -35,63 +41,63 @@
     <div class="flexbox">
       <img src="support/solidblue.png">
     </div>
     <br>
 
     <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
     <div class="flexbox">
       <img src="support/solidblue.png" style="width: 30px;
+                                              height: 28px">
+    </div>
+    <div class="flexbox">
+      <img src="support/solidblue.png" style="width: 32px;
                                               height: 30px">
     </div>
     <div class="flexbox">
       <img src="support/solidblue.png" style="width: 30px;
-                                              height: 30px">
-    </div>
-    <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 30px;
-                                              height: 30px">
+                                              height: 28px">
     </div>
     <br>
 
     <!-- Row 3: min main-size OR min cross-size, or both -->
     <div class="flexbox">
       <img src="support/solidblue.png" style="width: 34px;
+                                              height: 32px">
+    </div>
+    <div class="flexbox">
+      <img src="support/solidblue.png" style="width: 36px;
+                                              height: 34px">
+    </div>
+    <div class="flexbox">
+      <img src="support/solidblue.png" style="width: 36px;
                                               height: 34px">
     </div>
     <div class="flexbox">
       <img src="support/solidblue.png" style="width: 34px;
-                                              height: 34px">
-    </div>
-    <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 34px;
-                                              height: 34px">
-    </div>
-    <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 34px;
-                                              height: 34px">
+                                              height: 32px">
     </div>
     <br>
 
     <!-- Row 4: max main-size OR max cross-size, or both -->
     <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 10px;
-                                              height: 10px">
+      <img src="support/solidblue.png" style="width: 16px;
+                                              height: 14px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 10px;
-                                              height: 10px">
+      <img src="support/solidblue.png" style="width: 18px;
+                                              height: 16px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 6px;
-                                              height: 6px">
+      <img src="support/solidblue.png" style="width: 16px;
+                                              height: 14px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="width: 6px;
-                                              height: 6px">
+      <img src="support/solidblue.png" style="width: 14px;
+                                              height: 12px">
     </div>
     <br>
 
     <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
     <div class="flexbox">
       <img src="support/solidblue.png" style="width: 30px;
                                               height: 10px">
     </div>
copy from layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001.html
copy to layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007.html
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001.html
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007.html
@@ -3,36 +3,43 @@
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <html>
   <head>
     <meta charset="utf-8">
     <title>
       CSS Test: Testing how explicit main-size & cross-size constraints
-      influence sizing on non-stretched flex item w/ intrinsic ratio.
+      influence sizing on non-stretched flex item w/ intrinsic ratio,
+      some padding, and box-sizing:border-box.
     </title>
     <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
     <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
     <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
-    <link rel="match" href="flexbox-intrinsic-ratio-001-ref.html">
+    <link rel="match" href="flexbox-intrinsic-ratio-007-ref.html">
     <style>
       .flexbox {
         display: flex;
         flex-direction: row;
         border: 1px solid black;
         margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
         width: 40px;
         height: 40px;
 
         justify-content: flex-start;
         align-items: flex-start;
 
         float: left; /* For testing in "rows" */
       }
+      img {
+        padding: 1px 2px 3px 4px;
+        box-sizing: border-box;
+        background: pink;
+      }
+
       br { clear: both; }
 
       .flexbox > * {
         /* Disable "min-width:auto"/"min-height:auto" to focus purely on
            later channels of influence. */
         min-width: 0;
         min-height: 0;
       }
@@ -73,28 +80,28 @@
     <div class="flexbox">
       <img src="support/solidblue.png" style="min-width: 34px;
                                               min-height: 30px">
     </div>
     <br>
 
     <!-- Row 4: max main-size OR max cross-size, or both -->
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 10px">
+      <img src="support/solidblue.png" style="max-width: 16px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-height: 10px">
+      <img src="support/solidblue.png" style="max-height: 16px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 10px;
-                                              max-height: 6px">
+      <img src="support/solidblue.png" style="max-width: 20px;
+                                              max-height: 14px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 6px;
-                                              max-height: 10px">
+      <img src="support/solidblue.png" style="max-width: 14px;
+                                              max-height: 20px">
     </div>
     <br>
 
     <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
     <div class="flexbox">
       <img src="support/solidblue.png" style="min-width: 30px;
                                               max-height: 10px">
     </div>
copy from layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html
copy to layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007v.html
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-007v.html
@@ -3,37 +3,43 @@
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <html>
   <head>
     <meta charset="utf-8">
     <title>
       CSS Test: Testing how explicit main-size & cross-size constraints
-      influence sizing on non-stretched flex item w/ intrinsic ratio
-      (with a vertical writing-mode on the flex items).
+      influence sizing on non-stretched flex item w/ intrinsic ratio,
+      some padding, box-sizing:border-box, and a vertical writing-mode.
     </title>
     <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
     <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
     <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
-    <link rel="match" href="flexbox-intrinsic-ratio-001-ref.html">
+    <link rel="match" href="flexbox-intrinsic-ratio-007-ref.html">
     <style>
       .flexbox {
         display: flex;
         flex-direction: row;
         border: 1px solid black;
         margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
         width: 40px;
         height: 40px;
 
         justify-content: flex-start;
         align-items: flex-start;
 
         float: left; /* For testing in "rows" */
       }
+      img {
+        padding: 1px 2px 3px 4px;
+        box-sizing: border-box;
+        background: pink;
+      }
+
       br { clear: both; }
 
       .flexbox > * {
         writing-mode: vertical-lr;
 
         /* Disable "min-width:auto"/"min-height:auto" to focus purely on
            later channels of influence. */
         min-width: 0;
@@ -76,28 +82,28 @@
     <div class="flexbox">
       <img src="support/solidblue.png" style="min-width: 34px;
                                               min-height: 30px">
     </div>
     <br>
 
     <!-- Row 4: max main-size OR max cross-size, or both -->
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 10px">
+      <img src="support/solidblue.png" style="max-width: 16px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-height: 10px">
+      <img src="support/solidblue.png" style="max-height: 16px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 10px;
-                                              max-height: 6px">
+      <img src="support/solidblue.png" style="max-width: 20px;
+                                              max-height: 14px">
     </div>
     <div class="flexbox">
-      <img src="support/solidblue.png" style="max-width: 6px;
-                                              max-height: 10px">
+      <img src="support/solidblue.png" style="max-width: 14px;
+                                              max-height: 20px">
     </div>
     <br>
 
     <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
     <div class="flexbox">
       <img src="support/solidblue.png" style="min-width: 30px;
                                               max-height: 10px">
     </div>
--- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list
+++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list
@@ -141,16 +141,18 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 == flexbox-intrinsic-ratio-003.html flexbox-intrinsic-ratio-003-ref.html
 == flexbox-intrinsic-ratio-003v.html flexbox-intrinsic-ratio-003-ref.html
 == flexbox-intrinsic-ratio-004.html flexbox-intrinsic-ratio-004-ref.html
 == flexbox-intrinsic-ratio-004v.html flexbox-intrinsic-ratio-004-ref.html
 == flexbox-intrinsic-ratio-005.html flexbox-intrinsic-ratio-005-ref.html
 == flexbox-intrinsic-ratio-005v.html flexbox-intrinsic-ratio-005-ref.html
 == flexbox-intrinsic-ratio-006.html flexbox-intrinsic-ratio-006-ref.html
 == flexbox-intrinsic-ratio-006v.html flexbox-intrinsic-ratio-006-ref.html
+== flexbox-intrinsic-ratio-007.html flexbox-intrinsic-ratio-007-ref.html
+== flexbox-intrinsic-ratio-007v.html flexbox-intrinsic-ratio-007-ref.html
 
 # Test for definite and indefinite sizes.
 == flexbox-definite-sizes-001.html flexbox-definite-sizes-001-ref.html
 == flexbox-definite-sizes-002.html flexbox-definite-sizes-001-ref.html
 == flexbox-definite-sizes-003.html flexbox-definite-sizes-001-ref.html
 == flexbox-definite-sizes-004.html flexbox-definite-sizes-001-ref.html
 
 # Tests for flex items as (pseudo) stacking contexts