Bug 1269017 part 1 - [css-grid] Adjust OffsetToAlignedStaticPos() to use correct alignment container for abpsos children of grid containers. r=mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 07 Nov 2016 11:58:13 -0800
changeset 435073 2903a0426fa0f3e6d38ede01f08dcf6139db2055
parent 434838 060f80b690b8aaa5d927e03578673a3eff3b4c64
child 435074 6381f10d8409479ed52a843b677feaa06a663c13
push id34928
push userdholbert@mozilla.com
push dateTue, 08 Nov 2016 00:57:02 +0000
reviewersmats
bugs1269017
milestone52.0a1
Bug 1269017 part 1 - [css-grid] Adjust OffsetToAlignedStaticPos() to use correct alignment container for abpsos children of grid containers. r=mats MozReview-Commit-ID: LItIGLH5GJP
layout/generic/nsAbsoluteContainingBlock.cpp
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -360,29 +360,31 @@ GetPlaceholderContainer(nsPresContext* a
  * This function returns the offset of an abs/fixed-pos child's static
  * position, with respect to the "start" corner of its alignment container,
  * according to CSS Box Alignment.  This function only operates in a single
  * axis at a time -- callers can choose which axis via the |aAbsPosCBAxis|
  * parameter.
  *
  * @param aKidReflowInput The ReflowInput for the to-be-aligned abspos child.
  * @param aKidSizeInAbsPosCBWM The child frame's size (after it's been given
- *                             the opportunity to reflow), in terms of the
- *                             containing block's WritingMode.
+ *                             the opportunity to reflow), in terms of
+ *                             aAbsPosCBWM.
+ * @param aAbsPosCBSize The abspos CB size, in terms of aAbsPosCBWM.
  * @param aPlaceholderContainer The parent of the child frame's corresponding
  *                              placeholder frame, cast to a nsContainerFrame.
  *                              (This will help us choose which alignment enum
  *                              we should use for the child.)
  * @param aAbsPosCBWM The child frame's containing block's WritingMode.
  * @param aAbsPosCBAxis The axis (of the containing block) that we should
  *                      be doing this computation for.
  */
 static nscoord
 OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
                          const LogicalSize& aKidSizeInAbsPosCBWM,
+                         const LogicalSize& aAbsPosCBSize,
                          nsContainerFrame* aPlaceholderContainer,
                          WritingMode aAbsPosCBWM,
                          LogicalAxis aAbsPosCBAxis)
 {
   if (!aPlaceholderContainer) {
     // (The placeholder container should be the thing that kicks this whole
     // process off, by setting PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN.  So it
     // should exist... but bail gracefully if it doesn't.)
@@ -405,20 +407,40 @@ OffsetToAlignedStaticPos(const ReflowInp
   // writing-mode.
   LogicalAxis pcAxis = (pcWM.IsOrthogonalTo(aAbsPosCBWM)
                         ? GetOrthogonalAxis(aAbsPosCBAxis)
                         : aAbsPosCBAxis);
 
   nsIAtom* parentType = aPlaceholderContainer->GetType();
   LogicalSize alignAreaSize(pcWM);
   if (parentType == nsGkAtoms::flexContainerFrame) {
+    // The alignment container is the flex container's content box:
     alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
     LogicalMargin pcBorderPadding =
       aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
     alignAreaSize -= pcBorderPadding.Size(pcWM);
+  } else if (parentType == nsGkAtoms::gridContainerFrame) {
+    // This abspos elem's parent is a grid container. Per CSS Grid 10.1 & 10.2:
+    //  - If the grid container *also* generates the abspos containing block (a
+    // grid area) for this abspos child, we use that abspos containing block as
+    // the alignment container, too. (And its size is aAbsPosCBSize.)
+    //  - Otherwise, we use the grid's padding box as the alignment container.
+    // https://drafts.csswg.org/css-grid/#static-position
+    if (aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame) {
+      // The alignment container is the grid area that we're using as the
+      // absolute containing block.
+      alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
+    } else {
+      // The alignment container is a the grid container's padding box (which
+      // we can get by subtracting away its border from frame's size):
+      alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
+      LogicalMargin pcBorder =
+        aPlaceholderContainer->GetLogicalUsedBorder(pcWM);
+      alignAreaSize -= pcBorder.Size(pcWM);
+    }
   } else {
     NS_ERROR("Unsupported container for abpsos CSS Box Alignment");
     return 0; // (leave the child at the start of its alignment container)
   }
 
   nscoord alignAreaSizeInAxis = (pcAxis == eLogicalAxisInline)
     ? alignAreaSize.ISize(pcWM)
     : alignAreaSize.BSize(pcWM);
@@ -517,16 +539,17 @@ nsAbsoluteContainingBlock::ResolveSizeDe
       aOffsets->IStart(outerWM) =
         logicalCBSizeOuterWM.ISize(outerWM) -
         aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) -
         aKidSize.ISize(outerWM);
     } else if (aKidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
       placeholderContainer = GetPlaceholderContainer(aPresContext,
                                                      aKidReflowInput.mFrame);
       nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
+                                                logicalCBSizeOuterWM,
                                                 placeholderContainer,
                                                 outerWM, eLogicalAxisInline);
       // Shift IStart from its current position (at start corner of the
       // alignment container) by the returned offset.  And set IEnd to the
       // distance between the kid's end edge to containing block's end edge.
       aOffsets->IStart(outerWM) += offset;
       aOffsets->IEnd(outerWM) =
         logicalCBSizeOuterWM.ISize(outerWM) -
@@ -539,16 +562,17 @@ nsAbsoluteContainingBlock::ResolveSizeDe
         aOffsets->BEnd(outerWM) - aMargin.BStartEnd(outerWM) -
         aKidSize.BSize(outerWM);
     } else if (aKidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
       if (!placeholderContainer) {
         placeholderContainer = GetPlaceholderContainer(aPresContext,
                                                        aKidReflowInput.mFrame);
       }
       nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
+                                                logicalCBSizeOuterWM,
                                                 placeholderContainer,
                                                 outerWM, eLogicalAxisBlock);
       // Shift BStart from its current position (at start corner of the
       // alignment container) by the returned offset.  And set BEnd to the
       // distance between the kid's end edge to containing block's end edge.
       aOffsets->BStart(outerWM) += offset;
       aOffsets->BEnd(outerWM) =
         logicalCBSizeOuterWM.BSize(outerWM) -