Bug 1269017 part 2 - [css-grid] Give grid an implementation of CSSAlignmentForAbsPosChild(). r=mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 07 Nov 2016 11:58:13 -0800
changeset 435074 6381f10d8409479ed52a843b677feaa06a663c13
parent 435073 2903a0426fa0f3e6d38ede01f08dcf6139db2055
child 435075 26e6b54fe3ba382815bb517a1d118fb452df3171
push id34928
push userdholbert@mozilla.com
push dateTue, 08 Nov 2016 00:57:02 +0000
reviewersmats
bugs1269017
milestone52.0a1
Bug 1269017 part 2 - [css-grid] Give grid an implementation of CSSAlignmentForAbsPosChild(). r=mats This grid implementation is similar to the one on nsFlexContainerFrame, with a few simplifications: - We can simply use the LogicalAxis to decide between align-* vs justify-* prpoerties (whereas flexbox has extra abstraction from the flex axes). - We don't have to bother with "align-content" or "justify-content", since those apply to grid areas rather than to children. (And any grid area that's involved will be sized/positioned separately.) - Grid can unconditionally treat "flex-start" & "flex-end" as "start" & "end". MozReview-Commit-ID: 9l1Wq9Cq5T0
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -6627,16 +6627,68 @@ nsGridContainerFrame::RemoveFrame(ChildL
         frameThatMayLie->GetPrevInFlow());
     } while (frameThatMayLie);
   }
 #endif
 
   nsContainerFrame::RemoveFrame(aListID, aOldFrame);
 }
 
+uint16_t
+nsGridContainerFrame::CSSAlignmentForAbsPosChild(const ReflowInput& aChildRI,
+                                                 LogicalAxis aLogicalAxis) const
+{
+  MOZ_ASSERT(aChildRI.mFrame->IsAbsolutelyPositioned(),
+             "This method should only be called for abspos children");
+
+  uint16_t alignment = (aLogicalAxis == eLogicalAxisInline) ?
+    aChildRI.mStylePosition->UsedJustifySelf(nullptr) :
+    aChildRI.mStylePosition->UsedAlignSelf(nullptr);
+
+  // XXX strip off <overflow-position> bits until we implement it
+  // (bug 1311892)
+  alignment &= ~NS_STYLE_ALIGN_FLAG_BITS;
+
+  // We group 'auto' with 'normal', because the spec says:
+  //    "The 'auto' keyword is interpreted as 'normal'
+  //     if the box is absolutely positioned [...]"
+  // https://drafts.csswg.org/css-align-3/#valdef-align-self-auto
+  // https://drafts.csswg.org/css-align-3/#valdef-justify-self-auto
+  if (alignment == NS_STYLE_ALIGN_AUTO ||
+      alignment == NS_STYLE_ALIGN_NORMAL) {
+    // "the 'normal' keyword behaves as 'start' on replaced
+    // absolutely-positioned boxes, and behaves as 'stretch' on all other
+    // absolutely-positioned boxes."
+    // https://drafts.csswg.org/css-align/#align-abspos
+    // https://drafts.csswg.org/css-align/#justify-abspos
+    alignment = aChildRI.mFrame->IsFrameOfType(nsIFrame::eReplaced) ?
+      NS_STYLE_ALIGN_START : NS_STYLE_ALIGN_STRETCH;
+  } else if (alignment == NS_STYLE_ALIGN_FLEX_START) {
+    alignment = NS_STYLE_ALIGN_START;
+  } else if (alignment == NS_STYLE_ALIGN_FLEX_END) {
+    alignment = NS_STYLE_ALIGN_END;
+  } else if (alignment == NS_STYLE_ALIGN_LEFT ||
+             alignment == NS_STYLE_ALIGN_RIGHT) {
+    if (aLogicalAxis == eLogicalAxisInline) {
+      const bool isLeft = (alignment == NS_STYLE_ALIGN_LEFT);
+      WritingMode wm = GetWritingMode();
+      alignment = (isLeft == wm.IsBidiLTR()) ? NS_STYLE_ALIGN_START
+                                             : NS_STYLE_ALIGN_END;
+    } else {
+      alignment = NS_STYLE_ALIGN_START;
+    }
+  } else if (alignment == NS_STYLE_ALIGN_BASELINE) {
+    alignment = NS_STYLE_ALIGN_START;
+  } else if (alignment == NS_STYLE_ALIGN_LAST_BASELINE) {
+    alignment = NS_STYLE_ALIGN_END;
+  }
+
+  return alignment;
+}
+
 nscoord
 nsGridContainerFrame::SynthesizeBaseline(
   const FindItemInGridOrderResult& aGridOrderItem,
   LogicalAxis          aAxis,
   BaselineSharingGroup aGroup,
   const nsSize&        aCBPhysicalSize,
   nscoord              aCBSize,
   WritingMode          aCBWM)
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -121,16 +121,19 @@ public:
 #endif
 
   // nsContainerFrame overrides
   bool DrainSelfOverflowList() override;
   void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) override;
   void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
                     nsFrameList& aFrameList) override;
   void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
+  uint16_t CSSAlignmentForAbsPosChild(
+            const ReflowInput& aChildRI,
+            mozilla::LogicalAxis aLogicalAxis) const override;
 
 #ifdef DEBUG
   void SetInitialChildList(ChildListID  aListID,
                            nsFrameList& aChildList) override;
 #endif
 
   /**
    * Return the containing block for aChild which MUST be an abs.pos. child