mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-27 04:05:32 +00:00
Bug 1547560 - [css-grid-2] Add subgrid gaps to its items contributions in track sizing and recompute the subgrid tracks size/position to center the subgrid gaps. r=dholbert
Differential Revision: https://phabricator.services.mozilla.com/D31630 --HG-- extra : rebase_source : 5357831ac1395ae8f8f9252bb5a75b4c08eab25d
This commit is contained in:
parent
a697823fed
commit
29ee64cea5
@ -4466,27 +4466,52 @@ static nscoord ContentContribution(
|
||||
nscoord aMinSizeClamp = NS_MAXSIZE, uint32_t aFlags = 0) {
|
||||
nsIFrame* child = aGridItem.mFrame;
|
||||
|
||||
// If |child| is a subgrid descendant, then it contributes its subgrids'
|
||||
// margin+border+padding for any edge tracks that it spans.
|
||||
nscoord extraMargin = 0;
|
||||
nsGridContainerFrame::Subgrid* subgrid = nullptr;
|
||||
if (child->GetParent() != aState.mFrame &&
|
||||
(aGridItem.mState[aAxis] & ItemState::eEdgeBits)) {
|
||||
if (child->GetParent() != aState.mFrame) {
|
||||
// |child| is a subgrid descendant, so it contributes its subgrids'
|
||||
// margin+border+padding for any edge tracks that it spans.
|
||||
auto* subgridFrame = child->GetParent();
|
||||
subgrid = subgridFrame->GetProperty(Subgrid::Prop());
|
||||
LogicalMargin mbp = SubgridAccumulatedMarginBorderPadding(
|
||||
subgridFrame, subgrid, aCBWM, aAxis);
|
||||
auto state = aGridItem.mState[aAxis];
|
||||
if (state & ItemState::eStartEdge) {
|
||||
extraMargin += mbp.Start(aAxis, aCBWM);
|
||||
const auto itemEdgeBits = aGridItem.mState[aAxis] & ItemState::eEdgeBits;
|
||||
if (itemEdgeBits) {
|
||||
LogicalMargin mbp = SubgridAccumulatedMarginBorderPadding(
|
||||
subgridFrame, subgrid, aCBWM, aAxis);
|
||||
if (itemEdgeBits & ItemState::eStartEdge) {
|
||||
extraMargin += mbp.Start(aAxis, aCBWM);
|
||||
}
|
||||
if (itemEdgeBits & ItemState::eEndEdge) {
|
||||
extraMargin += mbp.End(aAxis, aCBWM);
|
||||
}
|
||||
}
|
||||
if (state & ItemState::eEndEdge) {
|
||||
extraMargin += mbp.End(aAxis, aCBWM);
|
||||
// It also contributes (half of) the subgrid's gap on its edges (if any)
|
||||
// subtracted by the non-subgrid ancestor grid container's gap.
|
||||
// Note that this can also be negative since it's considered a margin.
|
||||
if (itemEdgeBits != ItemState::eEdgeBits) {
|
||||
auto subgridAxis = aCBWM.IsOrthogonalTo(subgridFrame->GetWritingMode())
|
||||
? GetOrthogonalAxis(aAxis) : aAxis;
|
||||
auto& gapStyle = subgridAxis == eLogicalAxisBlock ?
|
||||
subgridFrame->StylePosition()->mRowGap :
|
||||
subgridFrame->StylePosition()->mColumnGap;
|
||||
if (!gapStyle.IsNormal()) {
|
||||
auto subgridExtent =
|
||||
subgridAxis == eLogicalAxisBlock ? subgrid->mGridRowEnd
|
||||
: subgrid->mGridColEnd;
|
||||
if (subgridExtent > 1) {
|
||||
nscoord subgridGap =
|
||||
nsLayoutUtils::ResolveGapToLength(gapStyle, NS_UNCONSTRAINEDSIZE);
|
||||
auto& tracks = aAxis == eLogicalAxisBlock ? aState.mRows : aState.mCols;
|
||||
auto gapDelta = subgridGap - tracks.mGridGap;
|
||||
if (!itemEdgeBits) {
|
||||
extraMargin += gapDelta;
|
||||
} else {
|
||||
extraMargin += gapDelta / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX add in subgrid gap contribution here... (bug 1547560)
|
||||
|
||||
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
|
||||
nscoord size = nsLayoutUtils::IntrinsicForAxis(
|
||||
axis, aRC, child, aConstraint, aPercentageBasis,
|
||||
@ -5588,23 +5613,73 @@ void nsGridContainerFrame::Tracks::StretchFlexibleTracks(
|
||||
void nsGridContainerFrame::Tracks::AlignJustifyContent(
|
||||
const nsStylePosition* aStyle, WritingMode aWM, nscoord aContentSize,
|
||||
bool aIsSubgriddedAxis) {
|
||||
const bool isAlign = mAxis == eLogicalAxisBlock;
|
||||
// Align-/justify-content doesn't apply in a subgridded axis.
|
||||
// Gap properties do apply though so we need to stretch/position the tracks
|
||||
// to center-align the gaps with the parent's gaps.
|
||||
if (MOZ_UNLIKELY(aIsSubgriddedAxis)) {
|
||||
auto& gap = isAlign ? aStyle->mRowGap : aStyle->mColumnGap;
|
||||
if (gap.IsNormal()) {
|
||||
return;
|
||||
}
|
||||
auto len = mSizes.Length();
|
||||
if (len <= 1) {
|
||||
return;
|
||||
}
|
||||
// This stores the gap deltas between the subgrid gap and the gaps in
|
||||
// the used track sizes (as encoded in its tracks' mPosition):
|
||||
nsTArray<nscoord> gapDeltas;
|
||||
const size_t numGaps = len - 1;
|
||||
gapDeltas.SetLength(numGaps);
|
||||
for (size_t i = 0; i < numGaps; ++i) {
|
||||
TrackSize& sz1 = mSizes[i];
|
||||
TrackSize& sz2 = mSizes[i + 1];
|
||||
nscoord currentGap = sz2.mPosition - (sz1.mPosition + sz1.mBase);
|
||||
gapDeltas[i] = mGridGap - currentGap;
|
||||
}
|
||||
// Recompute the tracks' size/position so that they end up with
|
||||
// a subgrid-gap centered on the original track gap.
|
||||
nscoord currentPos = mSizes[0].mPosition;
|
||||
nscoord lastHalfDelta(0);
|
||||
for (size_t i = 0; i < numGaps; ++i) {
|
||||
TrackSize& sz = mSizes[i];
|
||||
nscoord delta = gapDeltas[i];
|
||||
nscoord halfDelta;
|
||||
nscoord roundingError = NSCoordDivRem(delta, 2, &halfDelta);
|
||||
auto newSize = sz.mBase - (halfDelta + roundingError) - lastHalfDelta;
|
||||
lastHalfDelta = halfDelta;
|
||||
if (newSize >= 0) {
|
||||
sz.mBase = newSize;
|
||||
sz.mPosition = currentPos;
|
||||
currentPos += newSize + mGridGap;
|
||||
} else {
|
||||
sz.mBase = nscoord(0);
|
||||
sz.mPosition = currentPos + newSize;
|
||||
currentPos = sz.mPosition + mGridGap;
|
||||
}
|
||||
}
|
||||
auto& lastTrack = mSizes.LastElement();
|
||||
auto newSize = lastTrack.mBase - lastHalfDelta;
|
||||
if (newSize >= 0) {
|
||||
lastTrack.mBase = newSize;
|
||||
lastTrack.mPosition = currentPos;
|
||||
} else {
|
||||
lastTrack.mBase = nscoord(0);
|
||||
lastTrack.mPosition = currentPos + newSize;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSizes.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isAlign = mAxis == eLogicalAxisBlock;
|
||||
auto valueAndFallback =
|
||||
isAlign ? aStyle->mAlignContent : aStyle->mJustifyContent;
|
||||
bool overflowSafe;
|
||||
auto alignment =
|
||||
::GetAlignJustifyValue(valueAndFallback, aWM, isAlign, &overflowSafe);
|
||||
if (alignment == NS_STYLE_ALIGN_NORMAL) {
|
||||
if (aIsSubgriddedAxis) {
|
||||
auto& gap = isAlign ? aStyle->mRowGap : aStyle->mColumnGap;
|
||||
if (gap.IsNormal()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(valueAndFallback == NS_STYLE_ALIGN_NORMAL,
|
||||
"*-content:normal cannot be specified with explicit fallback");
|
||||
alignment = NS_STYLE_ALIGN_STRETCH;
|
||||
@ -5616,10 +5691,14 @@ void nsGridContainerFrame::Tracks::AlignJustifyContent(
|
||||
nscoord space;
|
||||
if (alignment != NS_STYLE_ALIGN_START) {
|
||||
nscoord trackSizeSum = 0;
|
||||
for (const TrackSize& sz : mSizes) {
|
||||
trackSizeSum += sz.mBase;
|
||||
if (sz.mState & TrackSize::eAutoMaxSizing) {
|
||||
++numAutoTracks;
|
||||
if (aIsSubgriddedAxis) {
|
||||
numAutoTracks = mSizes.Length();
|
||||
} else {
|
||||
for (const TrackSize& sz : mSizes) {
|
||||
trackSizeSum += sz.mBase;
|
||||
if (sz.mState & TrackSize::eAutoMaxSizing) {
|
||||
++numAutoTracks;
|
||||
}
|
||||
}
|
||||
}
|
||||
space = aContentSize - trackSizeSum - SumOfGridGaps();
|
||||
@ -7032,20 +7111,17 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
if (!prevInFlow) {
|
||||
const auto& rowSizes = gridReflowInput.mRows.mSizes;
|
||||
if (computedBSize == NS_AUTOHEIGHT &&
|
||||
stylePos->mRowGap.IsLengthPercentage() &&
|
||||
stylePos->mRowGap.AsLengthPercentage().HasPercent()) {
|
||||
// Re-resolve the row-gap now that we know our intrinsic block-size.
|
||||
gridReflowInput.mRows.mGridGap =
|
||||
nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, bSize);
|
||||
}
|
||||
if (!IsRowSubgrid()) {
|
||||
// Apply 'align-content' to the grid.
|
||||
if (computedBSize == NS_AUTOHEIGHT &&
|
||||
stylePos->mRowGap.IsLengthPercentage() &&
|
||||
stylePos->mRowGap.AsLengthPercentage().HasPercent()) {
|
||||
// Re-resolve the row-gap now that we know our intrinsic block-size.
|
||||
gridReflowInput.mRows.mGridGap =
|
||||
nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, bSize);
|
||||
}
|
||||
gridReflowInput.mRows.AlignJustifyContent(stylePos, wm, bSize, false);
|
||||
} else if (!rowSizes.IsEmpty()) {
|
||||
gridReflowInput.mRows.mGridGap =
|
||||
nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, bSize);
|
||||
gridReflowInput.mRows.AlignJustifyContent(stylePos, wm, bSize, true);
|
||||
} else {
|
||||
if (computedBSize == NS_AUTOHEIGHT) {
|
||||
bSize = gridReflowInput.mRows.GridLineEdge(rowSizes.Length(),
|
||||
GridLineSide::BeforeGridGap);
|
||||
|
Loading…
Reference in New Issue
Block a user