зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1118820 part 3a - [css-grid] Modify TrackSizingFunctions to take a dynamic number of 'repeat(auto-fill/auto-fit)' tracks taking into account. r=dholbert
This commit is contained in:
Родитель
6a0b77effc
Коммит
0fa25cd68c
|
@ -365,12 +365,62 @@ private:
|
|||
*/
|
||||
struct MOZ_STACK_CLASS nsGridContainerFrame::TrackSizingFunctions
|
||||
{
|
||||
TrackSizingFunctions(const nsStyleGridTemplate& aGridTemplate,
|
||||
const nsStyleCoord& aAutoMinSizing,
|
||||
const nsStyleCoord& aAutoMaxSizing)
|
||||
: mMinSizingFunctions(aGridTemplate.mMinTrackSizingFunctions)
|
||||
, mMaxSizingFunctions(aGridTemplate.mMaxTrackSizingFunctions)
|
||||
, mAutoMinSizing(aAutoMinSizing)
|
||||
, mAutoMaxSizing(aAutoMaxSizing)
|
||||
, mExplicitGridOffset(0)
|
||||
, mRepeatAutoStart(aGridTemplate.HasRepeatAuto() ?
|
||||
aGridTemplate.mRepeatAutoIndex : 0)
|
||||
, mRepeatAutoEnd(mRepeatAutoStart)
|
||||
, mRepeatEndDelta(0)
|
||||
, mHasRepeatAuto(aGridTemplate.HasRepeatAuto())
|
||||
{
|
||||
MOZ_ASSERT(mMinSizingFunctions.Length() == mMaxSizingFunctions.Length());
|
||||
MOZ_ASSERT(!mHasRepeatAuto ||
|
||||
(mMinSizingFunctions.Length() >= 1 &&
|
||||
mRepeatAutoStart < mMinSizingFunctions.Length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the number of auto-fill/fit tracks to use and return that.
|
||||
* (zero if no auto-fill/fit track was specified)
|
||||
*/
|
||||
uint32_t InitRepeatTracks(nscoord aGridGap, nscoord aMinSize, nscoord aSize,
|
||||
nscoord aMaxSize)
|
||||
{
|
||||
uint32_t repeatTracks = 0; // XXX will be fixed in a later patch
|
||||
SetNumRepeatTracks(repeatTracks);
|
||||
return repeatTracks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the explicit grid end line number (in a zero-based grid).
|
||||
* @param aGridTemplateAreasEnd 'grid-template-areas' end line in this axis
|
||||
*/
|
||||
uint32_t ComputeExplicitGridEnd(uint32_t aGridTemplateAreasEnd)
|
||||
{
|
||||
uint32_t end = NumExplicitTracks() + 1;
|
||||
end = std::max(end, aGridTemplateAreasEnd);
|
||||
end = std::min(end, uint32_t(nsStyleGridLine::kMaxLine));
|
||||
return end;
|
||||
}
|
||||
|
||||
const nsStyleCoord& MinSizingFor(uint32_t aTrackIndex) const
|
||||
{
|
||||
if (MOZ_UNLIKELY(aTrackIndex < mExplicitGridOffset)) {
|
||||
return mAutoMinSizing;
|
||||
}
|
||||
uint32_t index = aTrackIndex - mExplicitGridOffset;
|
||||
if (index >= mRepeatAutoStart) {
|
||||
if (index < mRepeatAutoEnd) {
|
||||
return mMinSizingFunctions[mRepeatAutoStart];
|
||||
}
|
||||
index -= mRepeatEndDelta;
|
||||
}
|
||||
return index < mMinSizingFunctions.Length() ?
|
||||
mMinSizingFunctions[index] : mAutoMinSizing;
|
||||
}
|
||||
|
@ -380,15 +430,47 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::TrackSizingFunctions
|
|||
return mAutoMaxSizing;
|
||||
}
|
||||
uint32_t index = aTrackIndex - mExplicitGridOffset;
|
||||
if (index >= mRepeatAutoStart) {
|
||||
if (index < mRepeatAutoEnd) {
|
||||
return mMaxSizingFunctions[mRepeatAutoStart];
|
||||
}
|
||||
index -= mRepeatEndDelta;
|
||||
}
|
||||
return index < mMaxSizingFunctions.Length() ?
|
||||
mMaxSizingFunctions[index] : mAutoMaxSizing;
|
||||
}
|
||||
uint32_t NumExplicitTracks() const
|
||||
{
|
||||
return mMinSizingFunctions.Length() + mRepeatEndDelta;
|
||||
}
|
||||
uint32_t NumRepeatTracks() const
|
||||
{
|
||||
return mRepeatAutoEnd - mRepeatAutoStart;
|
||||
}
|
||||
void SetNumRepeatTracks(uint32_t aNumRepeatTracks)
|
||||
{
|
||||
MOZ_ASSERT(mHasRepeatAuto || aNumRepeatTracks == 0);
|
||||
mRepeatAutoEnd = mRepeatAutoStart + aNumRepeatTracks;
|
||||
mRepeatEndDelta = mHasRepeatAuto ?
|
||||
int32_t(aNumRepeatTracks) - 1 :
|
||||
0;
|
||||
}
|
||||
|
||||
// Some style data references, for easy access.
|
||||
const nsTArray<nsStyleCoord>& mMinSizingFunctions;
|
||||
const nsTArray<nsStyleCoord>& mMaxSizingFunctions;
|
||||
const nsStyleCoord& mAutoMinSizing;
|
||||
const nsStyleCoord& mAutoMaxSizing;
|
||||
// Offset from the start of the implicit grid to the first explicit track.
|
||||
uint32_t mExplicitGridOffset;
|
||||
// The index of the repeat(auto-fill/fit) track, or zero if there is none.
|
||||
const uint32_t mRepeatAutoStart;
|
||||
// The (hypothetical) index of the last such repeat() track.
|
||||
uint32_t mRepeatAutoEnd;
|
||||
// The difference between mExplicitGridEnd and mMinSizingFunctions.Length().
|
||||
int32_t mRepeatEndDelta;
|
||||
// True if there is a specified repeat(auto-fill/fit) track.
|
||||
const bool mHasRepeatAuto;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -824,18 +906,12 @@ private:
|
|||
, mGridStyle(aGridStyle)
|
||||
, mCols(eLogicalAxisInline)
|
||||
, mRows(eLogicalAxisBlock)
|
||||
, mColFunctions({
|
||||
mGridStyle->mGridTemplateColumns.mMinTrackSizingFunctions,
|
||||
mGridStyle->mGridTemplateColumns.mMaxTrackSizingFunctions,
|
||||
mGridStyle->mGridAutoColumnsMin,
|
||||
mGridStyle->mGridAutoColumnsMax,
|
||||
})
|
||||
, mRowFunctions({
|
||||
mGridStyle->mGridTemplateRows.mMinTrackSizingFunctions,
|
||||
mGridStyle->mGridTemplateRows.mMaxTrackSizingFunctions,
|
||||
mGridStyle->mGridAutoRowsMin,
|
||||
mGridStyle->mGridAutoRowsMax,
|
||||
})
|
||||
, mColFunctions(mGridStyle->mGridTemplateColumns,
|
||||
mGridStyle->mGridAutoColumnsMin,
|
||||
mGridStyle->mGridAutoColumnsMax)
|
||||
, mRowFunctions(mGridStyle->mGridTemplateRows,
|
||||
mGridStyle->mGridAutoRowsMin,
|
||||
mGridStyle->mGridAutoRowsMax)
|
||||
, mReflowState(aReflowState)
|
||||
, mRenderingContext(aRenderingContext)
|
||||
, mWM(aWM)
|
||||
|
@ -1777,36 +1853,38 @@ nsGridContainerFrame::PlaceAutoAutoInColOrder(uint32_t aStartCol,
|
|||
}
|
||||
|
||||
void
|
||||
nsGridContainerFrame::InitializeGridBounds(const nsStylePosition* aStyle)
|
||||
{
|
||||
// http://dev.w3.org/csswg/css-grid/#grid-definition
|
||||
// Note that this is for a grid with a 1,1 origin. We'll change that
|
||||
// to a 0,0 based grid after placing definite lines.
|
||||
uint32_t colEnd = aStyle->mGridTemplateColumns.mLineNameLists.Length();
|
||||
uint32_t rowEnd = aStyle->mGridTemplateRows.mLineNameLists.Length();
|
||||
auto areas = aStyle->mGridTemplateAreas.get();
|
||||
mExplicitGridColEnd = std::max(colEnd, areas ? areas->mNColumns + 1 : 1);
|
||||
mExplicitGridRowEnd = std::max(rowEnd, areas ? areas->NRows() + 1 : 1);
|
||||
mExplicitGridColEnd =
|
||||
std::min(mExplicitGridColEnd, uint32_t(nsStyleGridLine::kMaxLine));
|
||||
mExplicitGridRowEnd =
|
||||
std::min(mExplicitGridRowEnd, uint32_t(nsStyleGridLine::kMaxLine));
|
||||
mGridColEnd = mExplicitGridColEnd;
|
||||
mGridRowEnd = mExplicitGridRowEnd;
|
||||
}
|
||||
|
||||
void
|
||||
nsGridContainerFrame::PlaceGridItems(GridReflowState& aState)
|
||||
nsGridContainerFrame::PlaceGridItems(GridReflowState& aState,
|
||||
const LogicalSize& aComputedMinSize,
|
||||
const LogicalSize& aComputedSize,
|
||||
const LogicalSize& aComputedMaxSize)
|
||||
{
|
||||
const nsStylePosition* const gridStyle = aState.mGridStyle;
|
||||
|
||||
mCellMap.ClearOccupied();
|
||||
InitializeGridBounds(gridStyle);
|
||||
|
||||
uint32_t numRepeatCols = 0; // XXX will be fixed in a later patch
|
||||
// http://dev.w3.org/csswg/css-grid/#grid-definition
|
||||
// Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
|
||||
// This is determined by the larger of the number of rows/columns defined
|
||||
// by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
|
||||
// Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
|
||||
// Note that this is for a grid with a 1,1 origin. We'll change that
|
||||
// to a 0,0 based grid after placing definite lines.
|
||||
auto areas = gridStyle->mGridTemplateAreas.get();
|
||||
uint32_t numRepeatCols = aState.mColFunctions.InitRepeatTracks(
|
||||
gridStyle->mGridColumnGap,
|
||||
aComputedMinSize.ISize(aState.mWM),
|
||||
aComputedSize.ISize(aState.mWM),
|
||||
aComputedMaxSize.ISize(aState.mWM));
|
||||
mGridColEnd = mExplicitGridColEnd =
|
||||
aState.mColFunctions.ComputeExplicitGridEnd(areas ? areas->mNColumns + 1 : 1);
|
||||
LineNameMap colLineNameMap(gridStyle->mGridTemplateColumns, numRepeatCols);
|
||||
|
||||
uint32_t numRepeatRows = 0; // XXX will be fixed in a later patch
|
||||
uint32_t numRepeatRows = aState.mRowFunctions.InitRepeatTracks(
|
||||
gridStyle->mGridRowGap,
|
||||
aComputedMinSize.BSize(aState.mWM),
|
||||
aComputedSize.BSize(aState.mWM),
|
||||
aComputedMaxSize.BSize(aState.mWM));
|
||||
mGridRowEnd = mExplicitGridRowEnd =
|
||||
aState.mRowFunctions.ComputeExplicitGridEnd(areas ? areas->NRows() + 1 : 1);
|
||||
LineNameMap rowLineNameMap(gridStyle->mGridTemplateRows, numRepeatRows);
|
||||
|
||||
// http://dev.w3.org/csswg/css-grid/#line-placement
|
||||
|
@ -2048,42 +2126,19 @@ nsGridContainerFrame::Tracks::Initialize(
|
|||
uint32_t aNumTracks,
|
||||
nscoord aContentBoxSize)
|
||||
{
|
||||
MOZ_ASSERT(aNumTracks >= aFunctions.mExplicitGridOffset +
|
||||
aFunctions.NumExplicitTracks());
|
||||
mSizes.SetLength(aNumTracks);
|
||||
PodZero(mSizes.Elements(), mSizes.Length());
|
||||
nscoord percentageBasis = aContentBoxSize;
|
||||
if (percentageBasis == NS_UNCONSTRAINEDSIZE) {
|
||||
percentageBasis = 0;
|
||||
}
|
||||
|
||||
const uint32_t explicitGridOffset = aFunctions.mExplicitGridOffset;
|
||||
MOZ_ASSERT(mSizes.Length() >=
|
||||
explicitGridOffset + aFunctions.mMinSizingFunctions.Length());
|
||||
MOZ_ASSERT(aFunctions.mMinSizingFunctions.Length() ==
|
||||
aFunctions.mMaxSizingFunctions.Length());
|
||||
// First we initialize the implicit tracks before the explicit grid starts.
|
||||
uint32_t i = 0;
|
||||
uint32_t sentinel = std::min<uint32_t>(explicitGridOffset, mSizes.Length());
|
||||
for (; i < sentinel; ++i) {
|
||||
for (uint32_t i = 0, len = mSizes.Length(); i < len; ++i) {
|
||||
mSizes[i].Initialize(percentageBasis,
|
||||
aFunctions.mAutoMinSizing,
|
||||
aFunctions.mAutoMaxSizing);
|
||||
aFunctions.MinSizingFor(i),
|
||||
aFunctions.MaxSizingFor(i));
|
||||
}
|
||||
// Now initialize the explicit grid tracks.
|
||||
sentinel = std::min<uint32_t>(i + aFunctions.mMinSizingFunctions.Length(),
|
||||
mSizes.Length());
|
||||
for (uint32_t j = 0; i < sentinel; ++i, ++j) {
|
||||
mSizes[i].Initialize(percentageBasis,
|
||||
aFunctions.mMinSizingFunctions[j],
|
||||
aFunctions.mMaxSizingFunctions[j]);
|
||||
}
|
||||
// Finally, initialize the implicit tracks that comes after the explicit grid.
|
||||
sentinel = mSizes.Length();
|
||||
for (; i < sentinel; ++i) {
|
||||
mSizes[i].Initialize(percentageBasis,
|
||||
aFunctions.mAutoMinSizing,
|
||||
aFunctions.mAutoMaxSizing);
|
||||
}
|
||||
|
||||
mGridGap = aGridGap;
|
||||
MOZ_ASSERT(mGridGap >= nscoord(0), "negative grid gap");
|
||||
}
|
||||
|
@ -3105,7 +3160,8 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
InitImplicitNamedAreas(stylePos);
|
||||
GridReflowState gridReflowState(this, aReflowState);
|
||||
mIsNormalFlowInCSSOrder = gridReflowState.mIter.ItemsAreAlreadyInOrder();
|
||||
PlaceGridItems(gridReflowState);
|
||||
LogicalSize indefinite(gridReflowState.mWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
PlaceGridItems(gridReflowState, indefinite, indefinite, indefinite);
|
||||
|
||||
const nscoord computedBSize = aReflowState.ComputedBSize();
|
||||
const nscoord computedISize = aReflowState.ComputedISize();
|
||||
|
@ -3171,7 +3227,8 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext,
|
|||
// http://dev.w3.org/csswg/css-grid/#intrinsic-sizes
|
||||
GridReflowState state(this, *aRenderingContext);
|
||||
InitImplicitNamedAreas(state.mGridStyle); // XXX optimize
|
||||
PlaceGridItems(state); // XXX optimize
|
||||
LogicalSize indefinite(state.mWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
PlaceGridItems(state, indefinite, indefinite, indefinite); // XXX optimize
|
||||
if (mGridColEnd == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -470,17 +470,21 @@ protected:
|
|||
* Place all child frames into the grid and expand the (implicit) grid as
|
||||
* needed. The allocated GridAreas are stored in the GridAreaProperty
|
||||
* frame property on the child frame.
|
||||
* @param aComputedMinSize the container's min-size - used to determine
|
||||
* the number of repeat(auto-fill/fit) tracks.
|
||||
* @param aComputedSize the container's size - used to determine
|
||||
* the number of repeat(auto-fill/fit) tracks.
|
||||
* @param aComputedMaxSize the container's max-size - used to determine
|
||||
* the number of repeat(auto-fill/fit) tracks.
|
||||
*/
|
||||
void PlaceGridItems(GridReflowState& aState);
|
||||
|
||||
/**
|
||||
* Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
|
||||
* This is determined by the larger of the number of rows/columns defined
|
||||
* by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
|
||||
* Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
|
||||
* @param aStyle the StylePosition() for the grid container
|
||||
*/
|
||||
void InitializeGridBounds(const nsStylePosition* aStyle);
|
||||
void PlaceGridItems(GridReflowState& aState,
|
||||
const LogicalSize& aComputedMinSize,
|
||||
const LogicalSize& aComputedSize,
|
||||
const LogicalSize& aComputedMaxSize);
|
||||
// Helper for the above.
|
||||
void PlaceGridItems(GridReflowState& aState,
|
||||
const LineNameMap& aColLineNameMap,
|
||||
const LineNameMap& aRowLineNameMap);
|
||||
|
||||
/**
|
||||
* Inflate the implicit grid to include aArea.
|
||||
|
|
Загрузка…
Ссылка в новой задаче