--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -5264,28 +5264,28 @@ nsGridContainerFrame::ReflowInFlowChild(
props.Set(nsTableWrapperFrame::GridItemCBSizeProperty(), cb);
}
*cb = percentBasis;
}
// If the child is stretching in its block axis, and we might be fragmenting
// it in that axis, then setup a frame property to tell
// nsBlockFrame::ComputeFinalSize the size.
+ bool stretchedAndFragmenting = false;
if (isConstrainedBSize && !wm.IsOrthogonalTo(childWM)) {
- bool stretch = false;
if (!childRI.mStyleMargin->HasBlockAxisAuto(childWM) &&
childRI.mStylePosition->BSize(childWM).GetUnit() == eStyleUnit_Auto) {
auto blockAxisAlignment =
childRI.mStylePosition->UsedAlignSelf(StyleContext());
if (blockAxisAlignment == NS_STYLE_ALIGN_NORMAL ||
blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) {
- stretch = true;
+ stretchedAndFragmenting = true;
}
}
- if (stretch) {
+ if (stretchedAndFragmenting) {
aChild->Properties().Set(FragStretchBSizeProperty(), *aStretchBSize);
} else {
aChild->Properties().Delete(FragStretchBSizeProperty());
}
}
// We need the width of the child before we can correctly convert
// the writing-mode of its origin, so we reflow at (0, 0) using a dummy
@@ -5295,33 +5295,66 @@ nsGridContainerFrame::ReflowInFlowChild(
ReflowChild(aChild, pc, childSize, childRI, childWM, LogicalPoint(childWM),
dummyContainerSize, 0, aStatus);
LogicalPoint childPos =
cb.Origin(wm).ConvertTo(childWM, wm,
aContainerSize - childSize.PhysicalSize());
// Apply align/justify-self and reflow again if that affects the size.
if (MOZ_LIKELY(isGridItem)) {
LogicalSize size = childSize.Size(childWM); // from the ReflowChild()
- if (NS_FRAME_IS_COMPLETE(aStatus)) {
- auto align = childRI.mStylePosition->UsedAlignSelf(containerSC);
- auto state = aGridItemInfo->mState[eLogicalAxisBlock];
- if (state & ItemState::eContentBaseline) {
- align = (state & ItemState::eFirstBaseline) ? NS_STYLE_ALIGN_SELF_START
- : NS_STYLE_ALIGN_SELF_END;
+
+ bool childIsContinuation = aChild->GetPrevInFlow();
+ bool childHasContinuation = aChild->GetNextInFlow();
+ auto align = childIsContinuation ?
+ (stretchedAndFragmenting ? NS_STYLE_ALIGN_SELF_END
+ : NS_STYLE_ALIGN_SELF_START) :
+ childRI.mStylePosition->UsedAlignSelf(containerSC);
+
+ auto state = aGridItemInfo->mState[eLogicalAxisBlock];
+ if (state & ItemState::eContentBaseline) {
+ align = (state & ItemState::eFirstBaseline) ? NS_STYLE_ALIGN_SELF_START
+ : NS_STYLE_ALIGN_SELF_END;
+ }
+ nscoord cbsz = cb.BSize(wm) - consumedGridAreaBSize;
+ nscoord offset = AlignSelf(*aGridItemInfo, align, cbsz, wm,
+ childRI, size, &childPos);
+
+ // If we're stretched and fragmenting, modify child block size by the
+ // offset amount, since the stretch size given to us by our caller
+ // is the maximum size we should consume, and offset will apply at either
+ // start or end.
+ if (stretchedAndFragmenting) {
+ // Adjust size in the block direction.
+ if (!childIsContinuation) {
+ // In the start case, offset should be subtracted from size, since
+ // positive offsets will push the child beyond container bounds.
+ childSize.BSize(wm) -= offset;
+ } else {
+ // In the middle and end cases, position has to be adjusted back
+ // to zero, since this child needs to start at the edge of the
+ // container bounds.
+ childPos.B(wm) = 0;
+
+ if (!childHasContinuation) {
+ // Additionally, in the end case, offset should be added to size,
+ // since negative offsets will pull the child up before the
+ // container bounds.
+ childSize.BSize(wm) += offset;
+ }
}
- nscoord cbsz = cb.BSize(wm) - consumedGridAreaBSize;
- AlignSelf(*aGridItemInfo, align, cbsz, wm, childRI, size, &childPos);
- }
+ }
+
+ // Now do inline alignment.
auto justify = childRI.mStylePosition->UsedJustifySelf(containerSC);
- auto state = aGridItemInfo->mState[eLogicalAxisInline];
+ state = aGridItemInfo->mState[eLogicalAxisInline];
if (state & ItemState::eContentBaseline) {
justify = (state & ItemState::eFirstBaseline) ? NS_STYLE_JUSTIFY_SELF_START
: NS_STYLE_JUSTIFY_SELF_END;
}
- nscoord cbsz = cb.ISize(wm);
+ cbsz = cb.ISize(wm);
JustifySelf(*aGridItemInfo, justify, cbsz, wm, childRI, size, &childPos);
} // else, nsAbsoluteContainingBlock.cpp will handle align/justify-self.
childRI.ApplyRelativePositioning(&childPos, aContainerSize);
FinishReflowChild(aChild, pc, childSize, &childRI, childWM, childPos,
aContainerSize, 0);
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, aChild);
}