commit 379011e6798ba6f23fab1fbd9ca35bb5a670728e
parent 997c4612a97971d64bf5318e9c1e50df4007a387
Author: Ting-Yu Lin <tlin@mozilla.com>
Date: Tue, 18 Nov 2025 18:53:06 +0000
Bug 2000759 - Add two convenience methods IsColMasonry() and IsRowMasonry(). r=jfkthame,layout-reviewers
We have `IsColSubgrid()` and `IsRowSubgrid()`. Masonry layout should have
similar convenience helpers.
Move `IsMasonry(LogicalAxis)` from `nsIFrame` into `nsGridContainerFrame` for
two reasons:
1. There are no external callers, and having it in grid container frame removes
the need to assert that the caller is a grid container.
2. `IsColSubgrid()` and `IsRowSubgrid()` depend on it.
Differential Revision: https://phabricator.services.mozilla.com/D272987
Diffstat:
4 files changed, 38 insertions(+), 40 deletions(-)
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
@@ -1321,16 +1321,14 @@ void GridItemInfo::InhibitSubgrid(nsGridContainerFrame* aParent,
void GridItemInfo::MaybeInhibitSubgridInMasonry(nsGridContainerFrame* aParent,
uint32_t aGridAxisTrackCount) {
- if (IsSubgrid(LogicalAxis::Inline) &&
- aParent->IsMasonry(LogicalAxis::Block) && mArea.mRows.mStart != 0 &&
- mArea.mCols.Extent() != aGridAxisTrackCount &&
+ if (IsSubgrid(LogicalAxis::Inline) && aParent->IsRowMasonry() &&
+ mArea.mRows.mStart != 0 && mArea.mCols.Extent() != aGridAxisTrackCount &&
(mState[LogicalAxis::Inline] & eAutoPlacement)) {
InhibitSubgrid(aParent, LogicalAxis::Inline);
return;
}
- if (IsSubgrid(LogicalAxis::Block) &&
- aParent->IsMasonry(LogicalAxis::Inline) && mArea.mCols.mStart != 0 &&
- mArea.mRows.Extent() != aGridAxisTrackCount &&
+ if (IsSubgrid(LogicalAxis::Block) && aParent->IsColMasonry() &&
+ mArea.mCols.mStart != 0 && mArea.mRows.Extent() != aGridAxisTrackCount &&
(mState[LogicalAxis::Block] & eAutoPlacement)) {
InhibitSubgrid(aParent, LogicalAxis::Block);
}
@@ -3224,8 +3222,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
}
}
}
- if (mStartRow == numRows ||
- aGridContainerFrame->IsMasonry(LogicalAxis::Block)) {
+ if (mStartRow == numRows || aGridContainerFrame->IsRowMasonry()) {
// All of the grid's rows fit inside of previous grid-container fragments,
// or it's a masonry axis.
mFragBStart = aConsumedBSize;
@@ -3638,8 +3635,8 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
mSkipSides = aFrame->PreReflowBlockLevelLogicalSkipSides();
mBorderPadding.ApplySkipSides(mSkipSides);
}
- mCols.mIsMasonry = aFrame->IsMasonry(LogicalAxis::Inline);
- mRows.mIsMasonry = aFrame->IsMasonry(LogicalAxis::Block);
+ mCols.mIsMasonry = aFrame->IsColMasonry();
+ mRows.mIsMasonry = aFrame->IsRowMasonry();
MOZ_ASSERT(!(mCols.mIsMasonry && mRows.mIsMasonry),
"can't have masonry layout in both axes");
}
@@ -5328,8 +5325,8 @@ void nsGridContainerFrame::Grid::PlaceGridItems(
aGridRI.mRowFunctions.mExplicitGridOffset = mExplicitGridOffsetRow;
const int32_t offsetToColZero = int32_t(mExplicitGridOffsetCol) - 1;
const int32_t offsetToRowZero = int32_t(mExplicitGridOffsetRow) - 1;
- const bool isRowMasonry = aGridRI.mFrame->IsMasonry(LogicalAxis::Block);
- const bool isColMasonry = aGridRI.mFrame->IsMasonry(LogicalAxis::Inline);
+ const bool isRowMasonry = aGridRI.mFrame->IsRowMasonry();
+ const bool isColMasonry = aGridRI.mFrame->IsColMasonry();
const bool isMasonry = isColMasonry || isRowMasonry;
mGridColEnd += offsetToColZero;
mGridRowEnd += offsetToRowZero;
@@ -8498,7 +8495,7 @@ nscoord nsGridContainerFrame::ReflowRowsInFragmentainer(
const auto rowCount = aGridRI.mRows.mSizes.Length();
nscoord masonryAxisGap = 0;
const auto wm = aGridRI.mWM;
- const bool isColMasonry = IsMasonry(LogicalAxis::Inline);
+ const bool isColMasonry = IsColMasonry();
if (isColMasonry) {
for (auto& sz : aGridRI.mCols.mSizes) {
sz.mPosition = 0;
@@ -9273,20 +9270,19 @@ nscoord nsGridContainerFrame::ReflowChildren(GridReflowInput& aGridRI,
// MasonryLayout() can only handle fragmentation in the masonry-axis,
// so we let ReflowInFragmentainer() deal with grid-axis fragmentation
// in the else-clause below.
- if (IsMasonry() &&
- !(IsMasonry(LogicalAxis::Inline) && fragmentainer.isSome())) {
+ if (IsMasonry() && !(IsColMasonry() && fragmentainer.isSome())) {
aGridRI.mInFragmentainer = fragmentainer.isSome();
nscoord sz = MasonryLayout(
aGridRI, aContentArea, SizingConstraint::NoConstraint, aDesiredSize,
aStatus, fragmentainer.ptrOr(nullptr), aContainerSize);
- if (IsMasonry(LogicalAxis::Block)) {
+ if (IsRowMasonry()) {
bSize = aGridRI.mReflowInput->ComputedBSize();
if (bSize == NS_UNCONSTRAINEDSIZE) {
bSize = aGridRI.mReflowInput->ApplyMinMaxBSize(sz);
}
}
} else if (MOZ_UNLIKELY(fragmentainer.isSome())) {
- if (IsMasonry(LogicalAxis::Inline) && !GetPrevInFlow()) {
+ if (IsColMasonry() && !GetPrevInFlow()) {
// First we do an unconstrained reflow to resolve the item placement
// which is then kept as-is in the constrained reflow below.
MasonryLayout(aGridRI, aContentArea, SizingConstraint::NoConstraint,
@@ -9403,7 +9399,7 @@ nscoord nsGridContainerFrame::ComputeIntrinsicContentBSize(
return *aContainIntrinsicBSize;
}
- if (IsMasonry(LogicalAxis::Block)) {
+ if (IsRowMasonry()) {
// There aren't any tracks to derive a block-size from, if we're doing
// masonry rather than forming rows in the block direction.
return aBSizeForResolvingRowSizes;
@@ -9525,8 +9521,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
// the sum of the row sizes we just resolved, then re-resolve the row
// sizes against that value. We skip this for masonry, which doesn't need
// two-pass row sizes resolution.
- if (bSizeForResolvingRowSizes == NS_UNCONSTRAINEDSIZE &&
- !IsMasonry(LogicalAxis::Block)) {
+ if (bSizeForResolvingRowSizes == NS_UNCONSTRAINEDSIZE && !IsRowMasonry()) {
bSizeForResolvingRowSizes =
std::max(gridRI.mRows.TotalTrackSizeWithoutAlignment(this),
gridRI.mReflowInput->ComputedMinBSize());
@@ -9695,8 +9690,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
}
// TODO: fix align-tracks alignment in fragments
- if ((IsMasonry(LogicalAxis::Block) && !prevInFlow) ||
- IsMasonry(LogicalAxis::Inline)) {
+ if ((IsRowMasonry() && !prevInFlow) || IsColMasonry()) {
gridRI.AlignJustifyTracksInMasonryAxis(contentArea.Size(wm),
aDesiredSize.PhysicalSize());
}
@@ -9827,7 +9821,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
std::move(colTrackStates), std::move(colRemovedRepeatTracks),
gridRI.mColFunctions.mRepeatAutoStart,
colLineNameMap.GetResolvedLineNamesForComputedGridTrackInfo(),
- IsColSubgrid(), IsMasonry(LogicalAxis::Inline));
+ IsColSubgrid(), IsColMasonry());
SetProperty(GridColTrackInfo(), colInfo);
const auto* subgridRowRange =
@@ -9870,7 +9864,7 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
std::move(rowRemovedRepeatTracks),
gridRI.mRowFunctions.mRepeatAutoStart,
rowLineNameMap.GetResolvedLineNamesForComputedGridTrackInfo(),
- IsRowSubgrid(), IsMasonry(LogicalAxis::Block));
+ IsRowSubgrid(), IsRowMasonry());
SetProperty(GridRowTrackInfo(), rowInfo);
if (prevInFlow) {
@@ -10189,7 +10183,7 @@ nscoord nsGridContainerFrame::ComputeIntrinsicISize(
}
if ((!IsRowSubgrid() && gridRI.mRowFunctions.mHasRepeatAuto &&
!(gridRI.mGridStyle->mGridAutoFlow & StyleGridAutoFlow::ROW)) ||
- IsMasonry(LogicalAxis::Inline)) {
+ IsColMasonry()) {
// Only 'grid-auto-flow:column' can create new implicit columns, so that's
// the only case where our block-size can affect the number of columns.
// Masonry layout always depends on how many rows we have though.
@@ -10212,7 +10206,7 @@ nscoord nsGridContainerFrame::ComputeIntrinsicISize(
auto constraint = aType == IntrinsicISizeType::MinISize
? SizingConstraint::MinContent
: SizingConstraint::MaxContent;
- if (IsMasonry(LogicalAxis::Inline)) {
+ if (IsColMasonry()) {
ReflowOutput desiredSize(gridRI.mWM);
nsSize containerSize;
LogicalRect contentArea(gridRI.mWM);
@@ -10626,6 +10620,12 @@ void nsGridContainerFrame::TrackSize::Dump() const {
#endif // DEBUG
+bool nsGridContainerFrame::IsMasonry(LogicalAxis aAxis) const {
+ return HasAnyStateBits(aAxis == mozilla::LogicalAxis::Block
+ ? NS_STATE_GRID_IS_ROW_MASONRY
+ : NS_STATE_GRID_IS_COL_MASONRY);
+}
+
bool nsGridContainerFrame::GridItemShouldStretch(const nsIFrame* aChild,
LogicalAxis aAxis) const {
MOZ_ASSERT(aChild->IsGridItem());
diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h
@@ -240,6 +240,18 @@ class nsGridContainerFrame final : public nsContainerFrame,
using nsContainerFrame::IsMasonry;
+ /**
+ * Return true if this frame has masonry layout in aAxis (in this frame's own
+ * writing mode).
+ */
+ bool IsMasonry(mozilla::LogicalAxis aAxis) const;
+ bool IsColMasonry() const {
+ return HasAnyStateBits(NS_STATE_GRID_IS_COL_MASONRY);
+ }
+ bool IsRowMasonry() const {
+ return HasAnyStateBits(NS_STATE_GRID_IS_ROW_MASONRY);
+ }
+
/** Return true if this frame has masonry layout in any axis. */
bool IsMasonry() const {
return HasAnyStateBits(NS_STATE_GRID_IS_ROW_MASONRY |
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
@@ -4720,13 +4720,6 @@ class nsIFrame : public nsQueryFrame {
inline bool IsLegacyWebkitBox() const;
/**
- * Return true if this frame has masonry layout in aAxis (in this frame's own
- * writing mode).
- * @note only valid to call on nsGridContainerFrames
- */
- inline bool IsMasonry(mozilla::LogicalAxis aAxis) const;
-
- /**
* Return true if this frame has masonry layout in aAxis (in the writing
* mode aWM).
* @note only valid to call on nsGridContainerFrames
diff --git a/layout/generic/nsIFrameInlines.h b/layout/generic/nsIFrameInlines.h
@@ -42,13 +42,6 @@ bool nsIFrame::IsLegacyWebkitBox() const {
return HasAnyStateBits(NS_STATE_FLEX_IS_EMULATING_LEGACY_WEBKIT_BOX);
}
-bool nsIFrame::IsMasonry(mozilla::LogicalAxis aAxis) const {
- MOZ_DIAGNOSTIC_ASSERT(IsGridContainerFrame());
- return HasAnyStateBits(aAxis == mozilla::LogicalAxis::Block
- ? NS_STATE_GRID_IS_ROW_MASONRY
- : NS_STATE_GRID_IS_COL_MASONRY);
-}
-
bool nsIFrame::IsMasonry(mozilla::WritingMode aWM,
mozilla::LogicalAxis aAxis) const {
MOZ_DIAGNOSTIC_ASSERT(IsGridContainerFrame());