Bug 1316051 part 3 - [css-grid] Store the CB size that we give to table-wrappers on a frame property, then propagate that later (minus margins) to the inner table frame. r=dholbert
authorMats Palmgren <mats@mozilla.com>
Fri, 18 Nov 2016 19:08:31 +0100
changeset 323464 e4719fb7438421eccecce2d410dcebf344f4c945
parent 323463 333774e147eea104d923743cb315d8daa449a0cf
child 323465 ca1c1dc37eb521f55ea779b3de8472562994c93f
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1316051
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 1316051 part 3 - [css-grid] Store the CB size that we give to table-wrappers on a frame property, then propagate that later (minus margins) to the inner table frame. r=dholbert
layout/generic/nsGridContainerFrame.cpp
layout/tables/nsTableWrapperFrame.cpp
layout/tables/nsTableWrapperFrame.h
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -6,34 +6,35 @@
 
 /* rendering object for CSS "display: grid | inline-grid" */
 
 #include "nsGridContainerFrame.h"
 
 #include <algorithm> // for std::stable_sort
 #include <limits>
 #include "mozilla/CSSAlignUtils.h"
+#include "mozilla/dom/GridBinding.h"
 #include "mozilla/Function.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/PodOperations.h" // for PodZero
 #include "mozilla/Poison.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "nsAlgorithm.h" // for clamped()
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsDataHashtable.h"
 #include "nsDisplayList.h"
 #include "nsHashKeys.h"
 #include "nsIFrameInlines.h"
 #include "nsPresContext.h"
+#include "nsReadableUtils.h"
 #include "nsRenderingContext.h"
-#include "nsReadableUtils.h"
 #include "nsRuleNode.h"
 #include "nsStyleContext.h"
-#include "mozilla/dom/GridBinding.h"
+#include "nsTableWrapperFrame.h"
 
 #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 8
 #define CLANG_CRASH_BUG 1
 #endif
 
 using namespace mozilla;
 
 typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
@@ -5142,17 +5143,18 @@ nsGridContainerFrame::ReflowInFlowChild(
                                         nsReflowStatus&        aStatus)
 {
   nsPresContext* pc = PresContext();
   nsStyleContext* containerSC = StyleContext();
   WritingMode wm = aState.mReflowInput->GetWritingMode();
   LogicalMargin pad(aState.mReflowInput->ComputedLogicalPadding());
   const LogicalPoint padStart(wm, pad.IStart(wm), pad.BStart(wm));
   const bool isGridItem = !!aGridItemInfo;
-  MOZ_ASSERT(isGridItem == (aChild->GetType() != nsGkAtoms::placeholderFrame));
+  auto childType = aChild->GetType();
+  MOZ_ASSERT(isGridItem == (childType != nsGkAtoms::placeholderFrame));
   LogicalRect cb(wm);
   WritingMode childWM = aChild->GetWritingMode();
   bool isConstrainedBSize = false;
   nscoord toFragmentainerEnd;
   // The part of the child's grid area that's in previous container fragments.
   nscoord consumedGridAreaBSize = 0;
   const bool isOrthogonal = wm.IsOrthogonalTo(childWM);
   if (MOZ_LIKELY(isGridItem)) {
@@ -5245,16 +5247,28 @@ nsGridContainerFrame::ReflowInFlowChild(
   if (!isConstrainedBSize) {
     childCBSize.BSize(childWM) = NS_UNCONSTRAINEDSIZE;
   }
   LogicalSize percentBasis(cb.Size(wm).ConvertTo(childWM, wm));
   ReflowInput childRI(pc, *aState.mReflowInput, aChild, childCBSize,
                       &percentBasis, flags);
   childRI.mFlags.mIsTopOfPage = aFragmentainer ? aFragmentainer->mIsTopOfPage : false;
 
+  // A table-wrapper needs to propagate the CB size we give it to its
+  // inner table frame later.  @see nsTableWrapperFrame::InitChildReflowInput.
+  if (childType == nsGkAtoms::tableWrapperFrame) {
+    const auto& props = aChild->Properties();
+    LogicalSize* cb = props.Get(nsTableWrapperFrame::GridItemCBSizeProperty());
+    if (!cb) {
+      cb = new LogicalSize(childWM);
+      props.Set(nsTableWrapperFrame::GridItemCBSizeProperty(), cb);
+    }
+    *cb = percentBasis;
+  }
+
   // If the child is stretching in its block axis, and we might be fragmenting
   // it in that axis, then setup a frame property to tell
   // nsBlockFrame::ComputeFinalSize the size.
   if (isConstrainedBSize && !wm.IsOrthogonalTo(childWM)) {
     bool stretch = false;
     if (!childRI.mStyleMargin->HasBlockAxisAuto(childWM) &&
         childRI.mStylePosition->BSize(childWM).GetUnit() == eStyleUnit_Auto) {
       auto blockAxisAlignment =
--- a/layout/tables/nsTableWrapperFrame.cpp
+++ b/layout/tables/nsTableWrapperFrame.cpp
@@ -223,32 +223,43 @@ nsTableWrapperFrame::GetParentStyleConte
   // the table wrapper's style context is a leaf.
 
   return (*aProviderFrame = InnerTableFrame())->StyleContext();
 }
 
 // INCREMENTAL REFLOW HELPER FUNCTIONS 
 
 void
-nsTableWrapperFrame::InitChildReflowInput(nsPresContext&     aPresContext,
-                                          ReflowInput& aReflowInput)
+nsTableWrapperFrame::InitChildReflowInput(nsPresContext& aPresContext,
+                                          ReflowInput&   aReflowInput)
 {
   nsMargin collapseBorder;
   nsMargin collapsePadding(0,0,0,0);
   nsMargin* pCollapseBorder  = nullptr;
   nsMargin* pCollapsePadding = nullptr;
-  if (aReflowInput.mFrame == InnerTableFrame() &&
-      InnerTableFrame()->IsBorderCollapse()) {
+  Maybe<LogicalSize> cbSize;
+  if (aReflowInput.mFrame == InnerTableFrame()) {
     WritingMode wm = aReflowInput.GetWritingMode();
-    LogicalMargin border = InnerTableFrame()->GetIncludedOuterBCBorder(wm);
-    collapseBorder = border.GetPhysicalMargin(wm);
-    pCollapseBorder = &collapseBorder;
-    pCollapsePadding = &collapsePadding;
+    if (InnerTableFrame()->IsBorderCollapse()) {
+      LogicalMargin border = InnerTableFrame()->GetIncludedOuterBCBorder(wm);
+      collapseBorder = border.GetPhysicalMargin(wm);
+      pCollapseBorder = &collapseBorder;
+      pCollapsePadding = &collapsePadding;
+    }
+    // Propagate our stored CB size if present, minus any margins.
+    if (!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
+      LogicalSize* cb = Properties().Get(GridItemCBSizeProperty());
+      if (cb) {
+        cbSize.emplace(*cb);
+        *cbSize -= aReflowInput.ComputedLogicalMargin().Size(wm);
+      }
+    }
   }
-  aReflowInput.Init(&aPresContext, nullptr, pCollapseBorder, pCollapsePadding);
+  aReflowInput.Init(&aPresContext, cbSize.ptrOr(nullptr), pCollapseBorder,
+                    pCollapsePadding);
 }
 
 // get the margin and padding data. ReflowInput doesn't handle the
 // case of auto margins
 void
 nsTableWrapperFrame::GetChildMargin(nsPresContext*           aPresContext,
                                     const ReflowInput& aOuterRI,
                                     nsIFrame*                aChildFrame,
--- a/layout/tables/nsTableWrapperFrame.h
+++ b/layout/tables/nsTableWrapperFrame.h
@@ -174,19 +174,23 @@ public:
    * Return the effective row span of the cell at the given row and column.
    */
   uint32_t GetEffectiveRowSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const
   {
     nsTableCellMap* map = InnerTableFrame()->GetCellMap();
     return map->GetEffectiveRowSpan(aRowIdx, aColIdx);
   }
 
+  /**
+   * The CB size to use for the inner table frame if we're a grid item.
+   */
+  NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemCBSizeProperty, mozilla::LogicalSize);
+
 protected:
 
-
   explicit nsTableWrapperFrame(nsStyleContext* aContext);
   virtual ~nsTableWrapperFrame();
 
   void InitChildReflowInput(nsPresContext&     aPresContext,
                             ReflowInput& aReflowInput);
 
   // Get a NS_STYLE_CAPTION_SIDE_* value, or NO_SIDE if no caption is present.
   // (Remember that caption-side values are interpreted logically, despite