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
--- 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)