Bug 1269046 part 4: Set flags on nsPlaceholderFrame & ReflowInput to track abspos frames that need CSS Box Alignment to resolve static position. r=mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Sun, 30 Oct 2016 12:18:26 -0700
changeset 431584 0b1deadb8b64e4c2a5384e904253e453250f8fc9
parent 431583 18d4fb0d5143e94d85504877b59f7244654563f3
child 431585 7552dd6923a95b1b236de998ae2dfd0abf701454
child 431690 62a4dde39d8e561427edc6986d7511147680caf9
push id34071
push userdholbert@mozilla.com
push dateSun, 30 Oct 2016 20:01:42 +0000
reviewersmats
bugs1269046
milestone52.0a1
Bug 1269046 part 4: Set flags on nsPlaceholderFrame & ReflowInput to track abspos frames that need CSS Box Alignment to resolve static position. r=mats (We'll react to the ReflowInput flags and do the actual CSS Box Alignment in a later patch in this series.) MozReview-Commit-ID: EZd7npWSzQI
layout/generic/ReflowInput.cpp
layout/generic/ReflowInput.h
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFrameStateBits.h
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -228,16 +228,17 @@ ReflowInput::ReflowInput(
     CheckNextInFlowParenthood(aFrame, aParentReflowInput.mFrame);
   mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false;
   mFlags.mIsColumnBalancing = false;
   mFlags.mIsFlexContainerMeasuringHeight = false;
   mFlags.mDummyParentReflowInput = false;
   mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
   mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE);
   mFlags.mStaticPosIsCBOrigin = !!(aFlags & STATIC_POS_IS_CB_ORIGIN);
+  mFlags.mIOffsetsNeedCSSAlign = mFlags.mBOffsetsNeedCSSAlign = false;
 
   mDiscoveredClearance = nullptr;
   mPercentBSizeObserver = (aParentReflowInput.mPercentBSizeObserver &&
                             aParentReflowInput.mPercentBSizeObserver->NeedsToObserve(*this))
                            ? aParentReflowInput.mPercentBSizeObserver : nullptr;
 
   if ((aFlags & DUMMY_PARENT_REFLOW_STATE) ||
       (mParentReflowInput->mFlags.mDummyParentReflowInput &&
@@ -1551,25 +1552,41 @@ ReflowInput::InitAbsoluteConstraints(nsP
   bool bEndIsAuto   = styleOffset.GetBEndUnit(cbwm) == eStyleUnit_Auto;
 
   // If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are
   // 'auto', then compute the hypothetical box position where the element would
   // have been if it had been in the flow
   nsHypotheticalPosition hypotheticalPos;
   if ((iStartIsAuto && iEndIsAuto) || (bStartIsAuto && bEndIsAuto)) {
     if (mFlags.mStaticPosIsCBOrigin) {
+      // XXXdholbert This whole clause should be removed in bug 1269017, where
+      // we'll be making abpsos grid children share our CSS Box Alignment code.
       hypotheticalPos.mWritingMode = cbwm;
       hypotheticalPos.mIStart = nscoord(0);
       hypotheticalPos.mBStart = nscoord(0);
     } else {
       nsIFrame* placeholderFrame =
         aPresContext->PresShell()->GetPlaceholderFrameFor(mFrame);
       NS_ASSERTION(placeholderFrame, "no placeholder frame");
       CalculateHypotheticalPosition(aPresContext, placeholderFrame, cbrs,
                                     hypotheticalPos, aFrameType);
+
+      if (placeholderFrame->HasAnyStateBits(
+            PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN)) {
+        DebugOnly<nsIFrame*> placeholderParent = placeholderFrame->GetParent();
+        MOZ_ASSERT(placeholderParent, "shouldn't have unparented placeholders");
+        MOZ_ASSERT(placeholderParent->IsFlexOrGridContainer(),
+                   "This flag should only be set on grid/flex children");
+
+        // If the (as-yet unknown) static position will determine the inline
+        // and/or block offsets, set flags to note those offsets aren't valid
+        // until we can do CSS Box Alignment on the OOF frame.
+        mFlags.mIOffsetsNeedCSSAlign = (iStartIsAuto && iEndIsAuto);
+        mFlags.mBOffsetsNeedCSSAlign = (bStartIsAuto && bEndIsAuto);
+      }
     }
   }
 
   // Initialize the 'left' and 'right' computed offsets
   // XXX Handle new 'static-position' value...
 
   // Size of the containing block in its writing mode
   LogicalSize cbSize = aCBSize;
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -213,16 +213,34 @@ public:
                                         // holder children? If the available
                                         // height of this frame didn't change,
                                         // but its in a paginated environment
                                         // (e.g. columns), it should always
                                         // reflow its placeholder children.
     uint32_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag
     uint32_t mUseAutoBSize:1; // stores the COMPUTE_SIZE_USE_AUTO_BSIZE ctor flag
     uint32_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag
+
+    // If set, the following two flags indicate that:
+    // (1) this frame is absolutely-positioned (or fixed-positioned).
+    // (2) this frame's static position depends on the CSS Box Alignment.
+    // (3) we do need to compute the static position, because the frame's
+    //     {Inline and/or Block} offsets actually depend on it.
+    // When these bits are set, the offset values (IStart/IEnd, BStart/BEnd)
+    // represent the "start" edge of the frame's CSS Box Alignment container
+    // area, in that axis -- and these offsets need to be further-resolved
+    // (with CSS Box Alignment) after we know the OOF frame's size.
+    // NOTE: The "I" and "B" (for "Inline" and "Block") refer the axes of the
+    // *containing block's writing-mode*, NOT mFrame's own writing-mode. This
+    // is purely for convenience, since that's the writing-mode we're dealing
+    // with when we set & react to these bits.
+    // XXXdholbert These new bits will probably make the "mStaticPosIsCBOrigin"
+    // bit obsolete -- consider removing it in bug 1269017.
+    uint32_t mIOffsetsNeedCSSAlign:1;
+    uint32_t mBOffsetsNeedCSSAlign:1;
   };
 
 #ifdef DEBUG
   // Reflow trace methods.  Defined in nsFrame.cpp so they have access
   // to the display-reflow infrastructure.
   static void* DisplayInitOffsetsEnter(
                                      nsIFrame* aFrame,
                                      SizeComputationInput* aState,
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -4507,16 +4507,20 @@ nsFlexContainerFrame::ReflowPlaceholders
                 childDesiredSize, childReflowInput,
                 outerWM, aContentBoxOrigin, aContainerSize, 0,
                 childReflowStatus);
 
     FinishReflowChild(placeholder, aPresContext,
                       childDesiredSize, &childReflowInput,
                       outerWM, aContentBoxOrigin, aContainerSize, 0);
 
+    // Mark the placeholder frame to indicate that it's not actually at the
+    // element's static position, because we need to apply CSS Alignment after
+    // we determine the OOF's size:
+    placeholder->AddStateBits(PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN);
   }
 }
 
 /* virtual */ nscoord
 nsFlexContainerFrame::GetMinISize(nsRenderingContext* aRenderingContext)
 {
   nscoord minISize = 0;
   DISPLAY_MIN_WIDTH(this, minISize);
--- a/layout/generic/nsFrameStateBits.h
+++ b/layout/generic/nsFrameStateBits.h
@@ -586,16 +586,25 @@ FRAME_STATE_GROUP(Placeholder, nsPlaceho
 // placeholder for.
 
 FRAME_STATE_BIT(Placeholder, 20, PLACEHOLDER_FOR_FLOAT)
 FRAME_STATE_BIT(Placeholder, 21, PLACEHOLDER_FOR_ABSPOS)
 FRAME_STATE_BIT(Placeholder, 22, PLACEHOLDER_FOR_FIXEDPOS)
 FRAME_STATE_BIT(Placeholder, 23, PLACEHOLDER_FOR_POPUP)
 FRAME_STATE_BIT(Placeholder, 24, PLACEHOLDER_FOR_TOPLAYER)
 
+// This bit indicates that the out-of-flow frame's static position needs to be
+// determined using the CSS Box Alignment properties
+// ([align,justify]-[self,content]).  When this is set, the placeholder frame's
+// position doesn't represent the static position, as it usually would --
+// rather, it represents the logical start corner of the alignment containing
+// block.  Then, after we've determined the out-of-flow frame's size, we can
+// resolve the actual static position using the alignment properties.
+FRAME_STATE_BIT(Placeholder, 25, PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN)
+
 
 // == Frame state bits that apply to table cell frames ========================
 
 FRAME_STATE_GROUP(TableCell, nsTableCellFrame)
 
 FRAME_STATE_BIT(TableCell, 28, NS_TABLE_CELL_HAS_PCT_OVER_BSIZE)
 FRAME_STATE_BIT(TableCell, 29, NS_TABLE_CELL_HAD_SPECIAL_REFLOW)
 FRAME_STATE_BIT(TableCell, 31, NS_TABLE_CELL_CONTENT_EMPTY)