Bug 1151243 part 3 - [css-grid] Add a generic nsHTMLReflowState::STATIC_POS_IS_CB_ORIGIN flag to place the static-position at the CB origin, and make nsAbsoluteContainingBlock use it in Grid containers where the placeholder is a child too. r=dholbert

This commit is contained in:
Mats Palmgren 2015-12-22 23:03:16 +01:00
parent 1300a00556
commit 8f920d800e
4 changed files with 42 additions and 11 deletions

View File

@ -383,10 +383,21 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
aReflowState.ComputedSizeWithPadding(wm).ISize(wm);
}
uint32_t rsFlags = 0;
if (aFlags & AbsPosReflowFlags::eIsGridContainerCB) {
// When a grid container generates the abs.pos. CB for a *child* then
// the static-position is the CB origin (i.e. of the grid area rect).
// https://drafts.csswg.org/css-grid/#static-position
nsIFrame* placeholder =
aPresContext->PresShell()->GetPlaceholderFrameFor(aKidFrame);
if (placeholder && placeholder->GetParent() == aDelegatingFrame) {
rsFlags |= nsHTMLReflowState::STATIC_POS_IS_CB_ORIGIN;
}
}
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
LogicalSize(wm, availISize,
NS_UNCONSTRAINEDSIZE),
&logicalCBSize);
&logicalCBSize, rsFlags);
// Get the border values
WritingMode outerWM = aReflowState.GetWritingMode();
@ -464,15 +475,18 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// Offset the frame rect by the given origin of the absolute containing block.
// If the frame is auto-positioned on both sides of an axis, it will be
// positioned based on its containing block and we don't need to offset.
// positioned based on its containing block and we don't need to offset
// (unless the caller demands it (the STATIC_POS_IS_CB_ORIGIN case)).
if (aContainingBlock.TopLeft() != nsPoint(0, 0)) {
const nsStyleSides& offsets = kidReflowState.mStylePosition->mOffset;
if (!(offsets.GetLeftUnit() == eStyleUnit_Auto &&
offsets.GetRightUnit() == eStyleUnit_Auto)) {
offsets.GetRightUnit() == eStyleUnit_Auto) ||
(rsFlags & nsHTMLReflowState::STATIC_POS_IS_CB_ORIGIN)) {
r.x += aContainingBlock.x;
}
if (!(offsets.GetTopUnit() == eStyleUnit_Auto &&
offsets.GetBottomUnit() == eStyleUnit_Auto)) {
offsets.GetBottomUnit() == eStyleUnit_Auto) ||
(rsFlags & nsHTMLReflowState::STATIC_POS_IS_CB_ORIGIN)) {
r.y += aContainingBlock.y;
}
}

View File

@ -3139,6 +3139,8 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
aState.mReflowState->ComputedLogicalBorderPadding().Size(wm)).GetPhysicalSize(wm);
nsPresContext* pc = PresContext();
nsStyleContext* containerSC = StyleContext();
LogicalMargin pad(aState.mReflowState->ComputedLogicalPadding());
const LogicalPoint padStart(wm, pad.IStart(wm), pad.BStart(wm));
for (; !aState.mIter.AtEnd(); aState.mIter.Next()) {
nsIFrame* child = *aState.mIter;
const bool isGridItem = child->GetType() != nsGkAtoms::placeholderFrame;
@ -3207,6 +3209,9 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
ReflowChild(child, pc, *childSize, *childRS, childWM,
LogicalPoint(childWM), dummyContainerSize, 0, childStatus);
}
} else {
// Put a placeholder at the padding edge, in case an ancestor is its CB.
childPos -= padStart;
}
childRS->ApplyRelativePositioning(&childPos, containerSize);
FinishReflowChild(child, pc, *childSize, childRS.ptr(), childWM, childPos,
@ -3218,11 +3223,8 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
if (IsAbsoluteContainer()) {
nsFrameList children(GetChildList(GetAbsoluteListID()));
if (!children.IsEmpty()) {
LogicalMargin pad(aState.mReflowState->ComputedLogicalPadding());
pad.ApplySkipSides(GetLogicalSkipSides(aState.mReflowState));
// 'gridOrigin' is the origin of the grid (the start of the first track),
// 'padStart' is the origin of the grid (the start of the first track),
// with respect to the grid container's padding-box (CB).
const LogicalPoint gridOrigin(wm, pad.IStart(wm), pad.BStart(wm));
const LogicalRect gridCB(wm, 0, 0,
aContentArea.ISize(wm) + pad.IStartEnd(wm),
aContentArea.BSize(wm) + pad.BStartEnd(wm));
@ -3234,7 +3236,7 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
MOZ_ASSERT(mAbsPosItems[i].mFrame == child);
GridArea& area = mAbsPosItems[i].mArea;
LogicalRect itemCB =
ContainingBlockForAbsPos(aState, area, gridOrigin, gridCB);
ContainingBlockForAbsPos(aState, area, padStart, gridCB);
// nsAbsoluteContainingBlock::Reflow uses physical coordinates.
nsRect* cb = static_cast<nsRect*>(child->Properties().Get(
GridItemContainingBlockRect()));

View File

@ -82,6 +82,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext,
if (aFlags & COMPUTE_SIZE_SHRINK_WRAP) {
mFlags.mShrinkWrap = true;
}
if (aFlags & STATIC_POS_IS_CB_ORIGIN) {
mFlags.mStaticPosIsCBOrigin = true;
}
if (!(aFlags & CALLER_WILL_INIT)) {
Init(aPresContext);
@ -223,6 +226,7 @@ nsHTMLReflowState::nsHTMLReflowState(
mFlags.mIsFlexContainerMeasuringHeight = false;
mFlags.mDummyParentReflowState = false;
mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
mFlags.mStaticPosIsCBOrigin = !!(aFlags & STATIC_POS_IS_CB_ORIGIN);
mDiscoveredClearance = nullptr;
mPercentBSizeObserver = (aParentReflowState.mPercentBSizeObserver &&
@ -1520,8 +1524,14 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
(eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) ||
((eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) &&
(eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()))) {
CalculateHypotheticalPosition(aPresContext, placeholderFrame, cbrs,
hypotheticalPos, aFrameType);
if (mFlags.mStaticPosIsCBOrigin) {
hypotheticalPos.mWritingMode = cbwm;
hypotheticalPos.mIStart = nscoord(0);
hypotheticalPos.mBStart = nscoord(0);
} else {
CalculateHypotheticalPosition(aPresContext, placeholderFrame, cbrs,
hypotheticalPos, aFrameType);
}
}
// Initialize the 'left' and 'right' computed offsets

View File

@ -584,6 +584,7 @@ public:
// (e.g. columns), it should always
// reflow its placeholder children.
uint16_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag
uint16_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag
} mFlags;
// Logical and physical accessors for the resize flags. All users should go
@ -679,6 +680,10 @@ public:
// The caller wants shrink-wrap behavior (i.e. ComputeSizeFlags::eShrinkWrap
// will be passed to ComputeSize()).
COMPUTE_SIZE_SHRINK_WRAP = (1<<2),
// The caller wants the abs.pos. static-position resolved at the origin
// of the containing block, i.e. at LogicalPoint(0, 0).
STATIC_POS_IS_CB_ORIGIN = (1<<3),
};
// This method initializes various data members. It is automatically