summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsGridContainerFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsGridContainerFrame.cpp')
-rw-r--r--layout/generic/nsGridContainerFrame.cpp109
1 files changed, 88 insertions, 21 deletions
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index 71d5bba21..8f117b5ab 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -818,8 +818,11 @@ struct nsGridContainerFrame::GridItemInfo
// Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline.
eContentBaseline = 0x10,
eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline,
+ // Should apply Automatic Minimum Size per:
+ // https://drafts.csswg.org/css-grid/#min-size-auto
+ eApplyAutoMinSize = 0x20,
// Clamp per https://drafts.csswg.org/css-grid/#min-size-auto
- eClampMarginBoxMinSize = 0x20,
+ eClampMarginBoxMinSize = 0x40,
};
explicit GridItemInfo(nsIFrame* aFrame,
@@ -851,11 +854,11 @@ struct nsGridContainerFrame::GridItemInfo
return aAlign;
}
- // Return true if we should we clamp this item's Automatic Minimum Size.
+ // Return true if we should apply Automatic Minimum Size to this item.
// https://drafts.csswg.org/css-grid/#min-size-auto
- bool ShouldClampMinSize(WritingMode aContainerWM,
- LogicalAxis aContainerAxis,
- nscoord aPercentageBasis) const
+ bool ShouldApplyAutoMinSize(WritingMode aContainerWM,
+ LogicalAxis aContainerAxis,
+ nscoord aPercentageBasis) const
{
const auto pos = mFrame->StylePosition();
const auto& size = aContainerAxis == eLogicalAxisInline ?
@@ -2090,6 +2093,18 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput
SizingConstraint aConstraint);
/**
+ * Return the percentage basis for a grid item in its writing-mode.
+ * If aAxis is eLogicalAxisInline then we return NS_UNCONSTRAINEDSIZE in
+ * both axes since we know all track sizes are indefinite at this point
+ * (we calculate column sizes before row sizes). Otherwise, assert that
+ * column sizes are known and calculate the size for aGridItem.mArea.mCols
+ * and use NS_UNCONSTRAINEDSIZE in the other axis.
+ * @param aAxis the axis we're currently calculating track sizes for
+ */
+ LogicalSize PercentageBasisFor(LogicalAxis aAxis,
+ const GridItemInfo& aGridItem) const;
+
+ /**
* Return the containing block for a grid item occupying aArea.
*/
LogicalRect ContainingBlockFor(const GridArea& aArea) const;
@@ -3731,18 +3746,20 @@ MeasuringReflow(nsIFrame* aChild,
* the child's margin-box) in aAxis.
*/
static nscoord
-ContentContribution(const GridItemInfo& aGridItem,
- const GridReflowInput& aState,
- nsRenderingContext* aRC,
- WritingMode aCBWM,
- LogicalAxis aAxis,
- IntrinsicISizeType aConstraint,
- nscoord aMinSizeClamp = NS_MAXSIZE,
- uint32_t aFlags = 0)
+ContentContribution(const GridItemInfo& aGridItem,
+ const GridReflowInput& aState,
+ nsRenderingContext* aRC,
+ WritingMode aCBWM,
+ LogicalAxis aAxis,
+ const Maybe<LogicalSize>& aPercentageBasis,
+ IntrinsicISizeType aConstraint,
+ nscoord aMinSizeClamp = NS_MAXSIZE,
+ uint32_t aFlags = 0)
{
nsIFrame* child = aGridItem.mFrame;
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint,
+ aPercentageBasis,
aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED |
nsLayoutUtils::ADD_PERCENTS,
aMinSizeClamp);
@@ -3812,6 +3829,10 @@ struct CachedIntrinsicSizes
Maybe<nscoord> mMinSize;
Maybe<nscoord> mMinContentContribution;
Maybe<nscoord> mMaxContentContribution;
+
+ // The item's percentage basis for intrinsic sizing purposes.
+ Maybe<LogicalSize> mPercentageBasis;
+
// "if the grid item spans only grid tracks that have a fixed max track
// sizing function, its automatic minimum size in that dimension is
// further clamped to less than or equal to the size necessary to fit its
@@ -3832,7 +3853,11 @@ MinContentContribution(const GridItemInfo& aGridItem,
if (aCache->mMinContentContribution.isSome()) {
return aCache->mMinContentContribution.value();
}
+ if (aCache->mPercentageBasis.isNothing()) {
+ aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem));
+ }
nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis,
+ aCache->mPercentageBasis,
nsLayoutUtils::MIN_ISIZE,
aCache->mMinSizeClamp);
aCache->mMinContentContribution.emplace(s);
@@ -3850,7 +3875,11 @@ MaxContentContribution(const GridItemInfo& aGridItem,
if (aCache->mMaxContentContribution.isSome()) {
return aCache->mMaxContentContribution.value();
}
+ if (aCache->mPercentageBasis.isNothing()) {
+ aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem));
+ }
nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis,
+ aCache->mPercentageBasis,
nsLayoutUtils::PREF_ISIZE,
aCache->mMinSizeClamp);
aCache->mMaxContentContribution.emplace(s);
@@ -3904,7 +3933,11 @@ MinSize(const GridItemInfo& aGridItem,
child->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) {
// Now calculate the "content size" part and return whichever is smaller.
MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE);
+ if (aCache->mPercentageBasis.isNothing()) {
+ aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem));
+ }
sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis,
+ aCache->mPercentageBasis,
nsLayoutUtils::MIN_ISIZE,
aCache->mMinSizeClamp,
nsLayoutUtils::MIN_INTRINSIC_ISIZE));
@@ -3977,9 +4010,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1(
WritingMode wm = aState.mWM;
// Calculate data for "Automatic Minimum Size" clamping, if needed.
bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) ||
- aConstraint == SizingConstraint::eNoConstraint);
- if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState) &&
- aGridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+ aConstraint == SizingConstraint::eNoConstraint) &&
+ (aGridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+ if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState)) {
if (sz.mState & TrackSize::eIntrinsicMinSizing) {
auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart);
cache.mMinSizeClamp =
@@ -4382,6 +4415,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
iter.Reset();
for (; !iter.AtEnd(); iter.Next()) {
auto& gridItem = aGridItems[iter.GridItemIndex()];
+
+ // Check if we need to apply "Automatic Minimum Size" and cache it.
+ MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+ "Why is eApplyAutoMinSize set already?");
+ if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
+ gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
+ }
+
const GridArea& area = gridItem.mArea;
const LineRange& lineRange = area.*aRange;
uint32_t span = lineRange.Extent();
@@ -4407,9 +4448,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
CachedIntrinsicSizes cache;
// Calculate data for "Automatic Minimum Size" clamping, if needed.
bool needed = ((state & TrackSize::eIntrinsicMinSizing) ||
- aConstraint == SizingConstraint::eNoConstraint);
- if (needed && TrackSize::IsDefiniteMaxSizing(state) &&
- gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+ aConstraint == SizingConstraint::eNoConstraint) &&
+ (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+ if (needed && TrackSize::IsDefiniteMaxSizing(state)) {
nscoord minSizeClamp = 0;
for (auto i = lineRange.mStart, end = lineRange.mEnd; i < end; ++i) {
auto maxCoord = aFunctions.MaxSizingFor(i);
@@ -4445,11 +4486,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
gridItem.mState[mAxis] |= ItemState::eIsFlexing;
} else if (aConstraint == SizingConstraint::eNoConstraint &&
TrackSize::IsDefiniteMaxSizing(state) &&
- gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+ (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize)) {
gridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
}
}
}
+ MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eClampMarginBoxMinSize) ||
+ (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+ "clamping only applies to Automatic Minimum Size");
}
// Step 2.
@@ -4707,7 +4751,8 @@ nsGridContainerFrame::Tracks::FindUsedFlexFraction(
const GridItemInfo& item = aGridItems[iter.GridItemIndex()];
if (item.mState[mAxis] & ItemState::eIsFlexing) {
// XXX optimize: bug 1194446
- nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis,
+ auto pb = Some(aState.PercentageBasisFor(mAxis, item));
+ nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, pb,
nsLayoutUtils::PREF_ISIZE);
if (spaceToFill <= 0) {
continue;
@@ -5038,6 +5083,25 @@ nsGridContainerFrame::LineRange::ToPositionAndLengthForAbsPos(
}
}
+LogicalSize
+nsGridContainerFrame::GridReflowInput::PercentageBasisFor(
+ LogicalAxis aAxis,
+ const GridItemInfo& aGridItem) const
+{
+ auto wm = aGridItem.mFrame->GetWritingMode();
+ if (aAxis == eLogicalAxisInline) {
+ return LogicalSize(wm, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ }
+ // Note: for now, we only resolve transferred percentages to row sizing.
+ // We may need to adjust these assertions once we implement bug 1300366.
+ MOZ_ASSERT(mCols.mCanResolveLineRangeSize);
+ MOZ_ASSERT(!mRows.mCanResolveLineRangeSize);
+ nscoord colSize = aGridItem.mArea.mCols.ToLength(mCols.mSizes);
+ nscoord rowSize = NS_UNCONSTRAINEDSIZE;
+ return !wm.IsOrthogonalTo(mWM) ?
+ LogicalSize(wm, colSize, rowSize) : LogicalSize(wm, rowSize, colSize);
+}
+
LogicalRect
nsGridContainerFrame::GridReflowInput::ContainingBlockFor(const GridArea& aArea) const
{
@@ -5231,6 +5295,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
} else {
aChild->Properties().Delete(BClampMarginBoxMinSizeProperty());
}
+ if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) {
+ flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE;
+ }
}
if (!isConstrainedBSize) {