Bug 1237805 part 1 - [css-grid] Remove all empty 'auto-fit' tracks, not just those at the end. r=dholbert

Change due to CSSWG decision:
https://lists.w3.org/Archives/Public/www-style/2016Jan/0031.html
This commit is contained in:
Mats Palmgren 2016-01-11 19:46:56 +01:00
parent b55cba1139
commit 832af414f9
2 changed files with 63 additions and 48 deletions

View File

@ -2139,45 +2139,73 @@ nsGridContainerFrame::PlaceGridItems(GridReflowState& aState,
}
}
// Count empty 'auto-fit' tracks at the end of the repeat() range.
// Count empty 'auto-fit' tracks in the repeat() range.
// |colAdjust| will have a count for each line in the grid of how many
// tracks were empty between the start of the grid and that line.
Maybe<nsTArray<uint32_t>> colAdjust;
uint32_t numEmptyCols = 0;
if (aState.mColFunctions.mHasRepeatAuto &&
!gridStyle->mGridTemplateColumns.mIsAutoFill &&
aState.mColFunctions.NumRepeatTracks() > 0) {
for (int32_t start = aState.mColFunctions.mRepeatAutoStart,
col = aState.mColFunctions.mRepeatAutoEnd - 1;
col >= start && mCellMap.IsEmptyCol(col);
--col) {
++numEmptyCols;
for (uint32_t col = aState.mColFunctions.mRepeatAutoStart,
endRepeat = aState.mColFunctions.mRepeatAutoEnd,
numColLines = mGridColEnd + 1;
col < numColLines; ++col) {
if (numEmptyCols) {
(*colAdjust)[col] = numEmptyCols;
}
if (col < endRepeat && mCellMap.IsEmptyCol(col)) {
++numEmptyCols;
if (colAdjust.isNothing()) {
colAdjust.emplace(numColLines);
colAdjust->SetLength(numColLines);
PodZero(colAdjust->Elements(), colAdjust->Length());
}
}
}
}
Maybe<nsTArray<uint32_t>> rowAdjust;
uint32_t numEmptyRows = 0;
if (aState.mRowFunctions.mHasRepeatAuto &&
!gridStyle->mGridTemplateRows.mIsAutoFill &&
aState.mRowFunctions.NumRepeatTracks() > 0) {
for (int32_t start = aState.mRowFunctions.mRepeatAutoStart,
row = aState.mRowFunctions.mRepeatAutoEnd - 1;
row >= start && mCellMap.IsEmptyRow(row);
--row) {
++numEmptyRows;
for (uint32_t row = aState.mRowFunctions.mRepeatAutoStart,
endRepeat = aState.mRowFunctions.mRepeatAutoEnd,
numRowLines = mGridRowEnd + 1;
row < numRowLines; ++row) {
if (numEmptyRows) {
(*rowAdjust)[row] = numEmptyRows;
}
if (row < endRepeat && mCellMap.IsEmptyRow(row)) {
++numEmptyRows;
if (rowAdjust.isNothing()) {
rowAdjust.emplace(numRowLines);
rowAdjust->SetLength(numRowLines);
PodZero(rowAdjust->Elements(), rowAdjust->Length());
}
}
}
}
// Remove the empty 'auto-fit' tracks we found above, if any.
if (numEmptyCols || numEmptyRows) {
// Adjust the line numbers in the grid areas.
const uint32_t firstRemovedCol =
aState.mColFunctions.mRepeatAutoEnd - numEmptyCols;
const uint32_t firstRemovedRow =
aState.mRowFunctions.mRepeatAutoEnd - numEmptyRows;
for (auto& item : mGridItems) {
GridArea& area = item.mArea;
area.mCols.AdjustForRemovedTracks(firstRemovedCol, numEmptyCols);
area.mRows.AdjustForRemovedTracks(firstRemovedRow, numEmptyRows);
if (numEmptyCols) {
area.mCols.AdjustForRemovedTracks(*colAdjust);
}
if (numEmptyRows) {
area.mRows.AdjustForRemovedTracks(*rowAdjust);
}
}
for (auto& item : mAbsPosItems) {
GridArea& area = item.mArea;
area.mCols.AdjustAbsPosForRemovedTracks(firstRemovedCol, numEmptyCols);
area.mRows.AdjustAbsPosForRemovedTracks(firstRemovedRow, numEmptyRows);
if (numEmptyCols) {
area.mCols.AdjustAbsPosForRemovedTracks(*colAdjust);
}
if (numEmptyRows) {
area.mRows.AdjustAbsPosForRemovedTracks(*rowAdjust);
}
}
// Adjust the grid size.
mGridColEnd -= numEmptyCols;

View File

@ -192,47 +192,34 @@ protected:
/**
* Translate the lines to account for (empty) removed tracks. This method
* is only for grid items and should only be called after placement.
* aNumRemovedTracks contains a count for each line in the grid how many
* tracks were removed between the start of the grid and that line.
*/
void AdjustForRemovedTracks(uint32_t aFirstRemovedTrack,
uint32_t aNumRemovedTracks)
void AdjustForRemovedTracks(const nsTArray<uint32_t>& aNumRemovedTracks)
{
MOZ_ASSERT(mStart != kAutoLine, "invalid resolved line for a grid item");
MOZ_ASSERT(mEnd != kAutoLine, "invalid resolved line for a grid item");
if (mStart >= aFirstRemovedTrack) {
MOZ_ASSERT(mStart >= aFirstRemovedTrack + aNumRemovedTracks,
"can't start in a removed range of tracks - those tracks "
"are supposed to be empty");
mStart -= aNumRemovedTracks;
mEnd -= aNumRemovedTracks;
} else {
MOZ_ASSERT(mEnd <= aFirstRemovedTrack, "can't span into a removed "
"range of tracks - those tracks are supposed to be empty");
}
uint32_t numRemovedTracks = aNumRemovedTracks[mStart];
MOZ_ASSERT(numRemovedTracks == aNumRemovedTracks[mEnd],
"tracks that a grid item spans can't be removed");
mStart -= numRemovedTracks;
mEnd -= numRemovedTracks;
}
/**
* Translate the lines to account for (empty) removed tracks. This method
* is only for abs.pos. children and should only be called after placement.
* Same as for in-flow items, but we don't touch 'auto' lines here and we
* also need to adjust areas that span into the removed range.
* also need to adjust areas that span into the removed tracks.
*/
void AdjustAbsPosForRemovedTracks(uint32_t aFirstRemovedTrack,
uint32_t aNumRemovedTracks)
void AdjustAbsPosForRemovedTracks(const nsTArray<uint32_t>& aNumRemovedTracks)
{
if (mStart != nsGridContainerFrame::kAutoLine &&
mStart > aFirstRemovedTrack) {
if (mStart < aFirstRemovedTrack + aNumRemovedTracks) {
mStart = aFirstRemovedTrack;
} else {
mStart -= aNumRemovedTracks;
}
if (mStart != nsGridContainerFrame::kAutoLine) {
mStart -= aNumRemovedTracks[mStart];
}
if (mEnd != nsGridContainerFrame::kAutoLine &&
mEnd > aFirstRemovedTrack) {
if (mEnd < aFirstRemovedTrack + aNumRemovedTracks) {
mEnd = aFirstRemovedTrack;
} else {
mEnd -= aNumRemovedTracks;
}
if (mEnd != nsGridContainerFrame::kAutoLine) {
MOZ_ASSERT(mStart == nsGridContainerFrame::kAutoLine ||
mEnd > mStart, "invalid line range");
mEnd -= aNumRemovedTracks[mEnd];
}
if (mStart == mEnd) {
mEnd = nsGridContainerFrame::kAutoLine;