Bug 1239036 - [css-grid] Deal with implicit tracks when computing grid-template-{columns,rows}. r=dholbert

This commit is contained in:
Mats Palmgren 2016-01-14 23:11:44 +01:00
parent 25be8cb570
commit 3ff7868f9e
3 changed files with 98 additions and 46 deletions

View File

@ -102,6 +102,18 @@ public:
return static_cast<nsTArray<nscoord>*>(Properties().Get(GridRowTrackSizes()));
}
/**
* Return the number of implicit tracks that comes before the explicit grid.
*/
uint32_t NumImplicitLeadingCols() const { return mExplicitGridOffsetCol; }
uint32_t NumImplicitLeadingRows() const { return mExplicitGridOffsetRow; }
/**
* Return the number of explicit tracks.
*/
uint32_t NumExplicitCols() const { return mExplicitGridColEnd - 1; }
uint32_t NumExplicitRows() const { return mExplicitGridRowEnd - 1; }
protected:
static const uint32_t kAutoLine;
// The maximum line number, in the zero-based translated grid.

View File

@ -2447,6 +2447,8 @@ nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue,
already_AddRefed<CSSValue>
nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList,
const uint32_t aNumLeadingImplicitTracks,
const uint32_t aNumExplicitTracks,
const nsTArray<nscoord>* aTrackSizes)
{
if (aTrackList.mIsSubgrid) {
@ -2484,22 +2486,24 @@ nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrack
MOZ_ASSERT(aTrackList.mMaxTrackSizingFunctions.Length() == numSizes,
"Different number of min and max track sizing functions");
if (aTrackSizes) {
DebugOnly<bool> isAutoFill =
aTrackList.HasRepeatAuto() && aTrackList.mIsAutoFill;
DebugOnly<bool> isAutoFit =
aTrackList.HasRepeatAuto() && !aTrackList.mIsAutoFill;
MOZ_ASSERT(aNumExplicitTracks == numSizes ||
(isAutoFill && aNumExplicitTracks >= numSizes) ||
(isAutoFit && aNumExplicitTracks + 1 >= numSizes),
"expected all explicit tracks (or possibly one less, if there's "
"an 'auto-fit' track, since that can collapse away)");
numSizes = aTrackSizes->Length();
MOZ_ASSERT(numSizes > 0 ||
(aTrackList.HasRepeatAuto() && !aTrackList.mIsAutoFill),
"only 'auto-fit' can result in zero tracks");
}
// An empty <track-list> is represented as "none" in syntax.
if (numSizes == 0) {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(eCSSKeyword_none);
return val.forget();
}
// Delimiting N (specified) tracks requires N+1 lines:
// one before each track, plus one at the very end.
MOZ_ASSERT(aTrackList.mLineNameLists.Length() ==
aTrackList.mMinTrackSizingFunctions.Length() + 1,
"Unexpected number of line name lists");
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
if (aTrackSizes) {
@ -2508,49 +2512,69 @@ nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrack
// repeat(<positive-integer>, Npx) here for consecutive tracks with the same
// size, but that doesn't seem worth doing since even for repeat(auto-*)
// the resolved size might differ for the repeated tracks.
int32_t endOfRepeat = 0; // first index after any repeat() tracks
int32_t offsetToLastRepeat = 0;
if (aTrackList.HasRepeatAuto()) {
// offsetToLastRepeat is -1 if all repeat(auto-fit) tracks are empty
offsetToLastRepeat = numSizes + 1 - aTrackList.mLineNameLists.Length();
endOfRepeat = aTrackList.mRepeatAutoIndex + offsetToLastRepeat + 1;
MOZ_ASSERT(numSizes > 0 &&
numSizes >= aNumLeadingImplicitTracks + aNumExplicitTracks);
// Add any leading implicit tracks.
for (uint32_t i = 0; i < aNumLeadingImplicitTracks; ++i) {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetAppUnits((*aTrackSizes)[i]);
valueList->AppendCSSValue(val.forget());
}
MOZ_ASSERT(numSizes > 0);
for (int32_t i = 0;; i++) {
// Then add any explicit tracks.
if (aNumExplicitTracks) {
int32_t endOfRepeat = 0; // first index after any repeat() tracks
int32_t offsetToLastRepeat = 0;
if (aTrackList.HasRepeatAuto()) {
if (i == aTrackList.mRepeatAutoIndex) {
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
if (i == endOfRepeat) {
// all auto-fit tracks are empty, so "[a] repeat(...) [b]"
// becomes "[a b]"
AppendGridLineNames(valueList, lineNames,
aTrackList.mLineNameLists[i + 1]);
} else {
AppendGridLineNames(valueList, lineNames,
// offsetToLastRepeat is -1 if all repeat(auto-fit) tracks are empty
offsetToLastRepeat = aNumExplicitTracks + 1 - aTrackList.mLineNameLists.Length();
endOfRepeat = aTrackList.mRepeatAutoIndex + offsetToLastRepeat + 1;
}
for (int32_t i = 0;; i++) {
if (aTrackList.HasRepeatAuto()) {
if (i == aTrackList.mRepeatAutoIndex) {
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
if (i == endOfRepeat) {
// all auto-fit tracks are empty, so "[a] repeat(...) [b]"
// becomes "[a b]"
AppendGridLineNames(valueList, lineNames,
aTrackList.mLineNameLists[i + 1]);
} else {
AppendGridLineNames(valueList, lineNames,
aTrackList.mRepeatAutoLineNameListBefore);
}
} else if (i == endOfRepeat) {
const nsTArray<nsString>& lineNames =
aTrackList.mLineNameLists[aTrackList.mRepeatAutoIndex + 1];
AppendGridLineNames(valueList,
aTrackList.mRepeatAutoLineNameListAfter,
lineNames);
} else if (i > aTrackList.mRepeatAutoIndex && i < endOfRepeat) {
AppendGridLineNames(valueList,
aTrackList.mRepeatAutoLineNameListAfter,
aTrackList.mRepeatAutoLineNameListBefore);
} else {
uint32_t j = i > endOfRepeat ? i - offsetToLastRepeat : i;
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[j];
AppendGridLineNames(valueList, lineNames);
}
} else if (i == endOfRepeat) {
const nsTArray<nsString>& lineNames =
aTrackList.mLineNameLists[aTrackList.mRepeatAutoIndex + 1];
AppendGridLineNames(valueList,
aTrackList.mRepeatAutoLineNameListAfter,
lineNames);
} else if (i > aTrackList.mRepeatAutoIndex && i < endOfRepeat) {
AppendGridLineNames(valueList,
aTrackList.mRepeatAutoLineNameListAfter,
aTrackList.mRepeatAutoLineNameListBefore);
} else {
uint32_t j = i > endOfRepeat ? i - offsetToLastRepeat : i;
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[j];
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
AppendGridLineNames(valueList, lineNames);
}
} else {
const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
AppendGridLineNames(valueList, lineNames);
}
if (uint32_t(i) == numSizes) {
break;
if (uint32_t(i) == aNumExplicitTracks) {
break;
}
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetAppUnits((*aTrackSizes)[i + aNumLeadingImplicitTracks]);
valueList->AppendCSSValue(val.forget());
}
}
// Add any trailing implicit tracks.
for (uint32_t i = aNumLeadingImplicitTracks + aNumExplicitTracks;
i < numSizes; ++i) {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetAppUnits((*aTrackSizes)[i]);
valueList->AppendCSSValue(val.forget());
@ -2627,30 +2651,44 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetGridTemplateColumns()
{
const nsTArray<nscoord>* trackSizes = nullptr;
uint32_t numLeadingImplicitTracks = 0;
uint32_t numExplicitTracks = 0;
if (mInnerFrame) {
nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame();
if (gridContainerCandidate &&
gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) {
auto gridContainer = static_cast<nsGridContainerFrame*>(gridContainerCandidate);
trackSizes = gridContainer->GetComputedTemplateColumns();
numLeadingImplicitTracks = gridContainer->NumImplicitLeadingCols();
numExplicitTracks = gridContainer->NumExplicitCols();
}
}
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, trackSizes);
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns,
numLeadingImplicitTracks,
numExplicitTracks,
trackSizes);
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetGridTemplateRows()
{
const nsTArray<nscoord>* trackSizes = nullptr;
uint32_t numLeadingImplicitTracks = 0;
uint32_t numExplicitTracks = 0;
if (mInnerFrame) {
nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame();
if (gridContainerCandidate &&
gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) {
auto gridContainer = static_cast<nsGridContainerFrame*>(gridContainerCandidate);
trackSizes = gridContainer->GetComputedTemplateRows();
}
numLeadingImplicitTracks = gridContainer->NumImplicitLeadingRows();
numExplicitTracks = gridContainer->NumExplicitRows();
}
}
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, trackSizes);
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows,
numLeadingImplicitTracks,
numExplicitTracks,
trackSizes);
}
already_AddRefed<CSSValue>

View File

@ -190,6 +190,8 @@ private:
const nsStyleCoord& aMaxSize);
already_AddRefed<CSSValue> GetGridTemplateColumnsRows(
const nsStyleGridTemplate& aTrackList,
const uint32_t aNumLeadingImplicitTracks,
const uint32_t aNumExplicitTracks,
const nsTArray<nscoord>* aTrackSizes);
already_AddRefed<CSSValue> GetGridLine(const nsStyleGridLine& aGridLine);