diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index ce6b27543bc..e9205a8a735 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -102,6 +102,18 @@ public: return static_cast*>(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. diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index faab8a93faa..d7a9bda6de5 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2447,6 +2447,8 @@ nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue, already_AddRefed nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList, + const uint32_t aNumLeadingImplicitTracks, + const uint32_t aNumExplicitTracks, const nsTArray* 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 isAutoFill = + aTrackList.HasRepeatAuto() && aTrackList.mIsAutoFill; + DebugOnly 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 is represented as "none" in syntax. if (numSizes == 0) { RefPtr 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 valueList = GetROCSSValueList(false); if (aTrackSizes) { @@ -2508,49 +2512,69 @@ nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrack // repeat(, 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 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& 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& 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& 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& lineNames = aTrackList.mLineNameLists[j]; + AppendGridLineNames(valueList, lineNames); } - } else if (i == endOfRepeat) { - const nsTArray& 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& lineNames = aTrackList.mLineNameLists[j]; + const nsTArray& lineNames = aTrackList.mLineNameLists[i]; AppendGridLineNames(valueList, lineNames); } - } else { - const nsTArray& lineNames = aTrackList.mLineNameLists[i]; - AppendGridLineNames(valueList, lineNames); - } - if (uint32_t(i) == numSizes) { - break; + if (uint32_t(i) == aNumExplicitTracks) { + break; + } + RefPtr 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 val = new nsROCSSPrimitiveValue; val->SetAppUnits((*aTrackSizes)[i]); valueList->AppendCSSValue(val.forget()); @@ -2627,30 +2651,44 @@ already_AddRefed nsComputedDOMStyle::DoGetGridTemplateColumns() { const nsTArray* 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(gridContainerCandidate); trackSizes = gridContainer->GetComputedTemplateColumns(); + numLeadingImplicitTracks = gridContainer->NumImplicitLeadingCols(); + numExplicitTracks = gridContainer->NumExplicitCols(); } } - return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, trackSizes); + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, + numLeadingImplicitTracks, + numExplicitTracks, + trackSizes); } already_AddRefed nsComputedDOMStyle::DoGetGridTemplateRows() { const nsTArray* 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(gridContainerCandidate); trackSizes = gridContainer->GetComputedTemplateRows(); - } + numLeadingImplicitTracks = gridContainer->NumImplicitLeadingRows(); + numExplicitTracks = gridContainer->NumExplicitRows(); + } } - return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, trackSizes); + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, + numLeadingImplicitTracks, + numExplicitTracks, + trackSizes); } already_AddRefed diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index df04293ce6c..eede2613b78 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -190,6 +190,8 @@ private: const nsStyleCoord& aMaxSize); already_AddRefed GetGridTemplateColumnsRows( const nsStyleGridTemplate& aTrackList, + const uint32_t aNumLeadingImplicitTracks, + const uint32_t aNumExplicitTracks, const nsTArray* aTrackSizes); already_AddRefed GetGridLine(const nsStyleGridLine& aGridLine);