diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 158871e8cca5..7fd6d73f9948 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -2282,6 +2282,21 @@ nsGridContainerFrame::LineRange::ToPositionAndLength( *aLength = length; } +nscoord +nsGridContainerFrame::LineRange::ToLength( + const nsTArray& aTrackSizes) const +{ + MOZ_ASSERT(mStart != kAutoLine && mEnd != kAutoLine, + "expected a definite LineRange"); + nscoord length = 0; + const uint32_t end = mEnd; + MOZ_ASSERT(end <= aTrackSizes.Length(), "aTrackSizes isn't large enough"); + for (uint32_t i = mStart; i < end; ++i) { + length += aTrackSizes[i].mBase; + } + return length; +} + void nsGridContainerFrame::LineRange::ToPositionAndLengthForAbsPos( const nsTArray& aTrackSizes, nscoord aGridOrigin, @@ -2502,6 +2517,56 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); } +nscoord +nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext, + IntrinsicISizeType aConstraint) +{ + // Calculate the sum of column sizes under aConstraint. + // http://dev.w3.org/csswg/css-grid/#intrinsic-sizes + GridReflowState state(this, *aRenderingContext); + InitImplicitNamedAreas(state.mGridStyle); // XXX optimize + PlaceGridItems(state); // XXX optimize + if (mGridColEnd == 0) { + return 0; + } + state.mCols.Initialize(state.mColFunctions, mGridColEnd, + NS_UNCONSTRAINEDSIZE); + state.mIter.Reset(); + state.mCols.CalculateSizes(state, mGridItems, state.mColFunctions, + NS_UNCONSTRAINEDSIZE, &GridArea::mCols, + aConstraint); + TranslatedLineRange allTracks(0, mGridColEnd); + return allTracks.ToLength(state.mCols.mSizes); +} + +nscoord +nsGridContainerFrame::GetMinISize(nsRenderingContext* aRC) +{ + DISPLAY_MIN_WIDTH(this, mCachedMinISize); + if (mCachedMinISize == NS_INTRINSIC_WIDTH_UNKNOWN) { + mCachedMinISize = IntrinsicISize(aRC, nsLayoutUtils::MIN_ISIZE); + } + return mCachedMinISize; +} + +nscoord +nsGridContainerFrame::GetPrefISize(nsRenderingContext* aRC) +{ + DISPLAY_PREF_WIDTH(this, mCachedPrefISize); + if (mCachedPrefISize == NS_INTRINSIC_WIDTH_UNKNOWN) { + mCachedPrefISize = IntrinsicISize(aRC, nsLayoutUtils::PREF_ISIZE); + } + return mCachedPrefISize; +} + +void +nsGridContainerFrame::MarkIntrinsicISizesDirty() +{ + mCachedMinISize = NS_INTRINSIC_WIDTH_UNKNOWN; + mCachedPrefISize = NS_INTRINSIC_WIDTH_UNKNOWN; + nsContainerFrame::MarkIntrinsicISizesDirty(); +} + nsIAtom* nsGridContainerFrame::GetType() const { diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index b1c310e1458d..9c3c403fe2cf 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -33,6 +33,9 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) override; + nscoord GetMinISize(nsRenderingContext* aRenderingContext) override; + nscoord GetPrefISize(nsRenderingContext* aRenderingContext) override; + void MarkIntrinsicISizesDirty() override; virtual nsIAtom* GetType() const override; void BuildDisplayList(nsDisplayListBuilder* aBuilder, @@ -107,7 +110,11 @@ protected: struct GridReflowState; friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - explicit nsGridContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {} + explicit nsGridContainerFrame(nsStyleContext* aContext) + : nsContainerFrame(aContext) + , mCachedMinISize(NS_INTRINSIC_WIDTH_UNKNOWN) + , mCachedPrefISize(NS_INTRINSIC_WIDTH_UNKNOWN) + {} /** * A LineRange can be definite or auto - when it's definite it represents @@ -182,6 +189,11 @@ protected: */ void ToPositionAndLength(const nsTArray& aTrackSizes, nscoord* aPos, nscoord* aLength) const; + /** + * Given an array of track sizes, return the length of the tracks in this + * line range. + */ + nscoord ToLength(const nsTArray& aTrackSizes) const; /** * Given an array of track sizes and a grid origin coordinate, adjust the * abs.pos. containing block along an axis given by aPos and aLength. @@ -523,6 +535,12 @@ protected: nsHTMLReflowMetrics& aDesiredSize, nsReflowStatus& aStatus); + /** + * Helper for GetMinISize / GetPrefISize. + */ + nscoord IntrinsicISize(nsRenderingContext* aRenderingContext, + IntrinsicISizeType aConstraint); + #ifdef DEBUG void SanityCheckAnonymousGridItems() const; #endif // DEBUG @@ -568,6 +586,12 @@ private: uint32_t mExplicitGridOffsetCol; uint32_t mExplicitGridOffsetRow; + /** + * Cached values to optimize GetMinISize/GetPrefISize. + */ + nscoord mCachedMinISize; + nscoord mCachedPrefISize; + /** * True iff the normal flow children are already in CSS 'order' in the * order they occur in the child frame list.