зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1234311 part 1 - [css-grid][css-grid-2] Simplify and improve calculation of 'grid-template-rows/columns' resolved value when the element has no box. r=dholbert
Differential Revision: https://phabricator.services.mozilla.com/D49026 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
cb5a3a5401
Коммит
8be7bfbd5b
|
@ -1547,7 +1547,7 @@ already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::GetGridTrackSize(
|
|||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows(
|
||||
const StyleGridTemplateComponent& aTrackList,
|
||||
const ComputedGridTrackInfo* aTrackInfo) {
|
||||
const ComputedGridTrackInfo& aTrackInfo) {
|
||||
if (aTrackList.IsSubgrid()) {
|
||||
// XXX TODO: add support for repeat(auto-fill) for 'subgrid' (bug 1234311)
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||
|
@ -1575,235 +1575,177 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows(
|
|||
}
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
uint32_t numSizes = aTrackInfo.mSizes.Length();
|
||||
if (!numSizes && !aTrackList.HasRepeatAuto()) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
// We've done layout on the grid and have resolved the sizes of its tracks,
|
||||
// so we'll return those sizes here. The grid spec says we MAY use
|
||||
// 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.
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||
if (aTrackInfo) {
|
||||
uint32_t numSizes = aTrackInfo->mSizes.Length();
|
||||
if (!numSizes && !aTrackList.HasRepeatAuto()) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
return val.forget();
|
||||
const nsTArray<nscoord>& trackSizes = aTrackInfo.mSizes;
|
||||
const uint32_t numExplicitTracks = aTrackInfo.mNumExplicitTracks;
|
||||
const uint32_t numLeadingImplicitTracks =
|
||||
aTrackInfo.mNumLeadingImplicitTracks;
|
||||
MOZ_ASSERT(numSizes >= numLeadingImplicitTracks + numExplicitTracks);
|
||||
|
||||
// Add any leading implicit tracks.
|
||||
for (uint32_t i = 0; i < numLeadingImplicitTracks; ++i) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
}
|
||||
|
||||
// Then add any explicit tracks and removed auto-fit tracks.
|
||||
if (numExplicitTracks || aTrackList.HasRepeatAuto()) {
|
||||
uint32_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 =
|
||||
numExplicitTracks + 1 - aTrackInfo.mResolvedLineNames.Length();
|
||||
endOfRepeat = aTrackInfo.mRepeatFirstTrack + offsetToLastRepeat + 1;
|
||||
}
|
||||
|
||||
// We've done layout on the grid and have resolved the sizes of its tracks,
|
||||
// so we'll return those sizes here. The grid spec says we MAY use
|
||||
// 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.
|
||||
const nsTArray<nscoord>& trackSizes = aTrackInfo->mSizes;
|
||||
const uint32_t numExplicitTracks = aTrackInfo->mNumExplicitTracks;
|
||||
const uint32_t numLeadingImplicitTracks =
|
||||
aTrackInfo->mNumLeadingImplicitTracks;
|
||||
MOZ_ASSERT(numSizes >= numLeadingImplicitTracks + numExplicitTracks);
|
||||
auto* autoRepeatValue = aTrackList.GetRepeatAutoValue();
|
||||
auto beforeAutoRepeat =
|
||||
autoRepeatValue ? autoRepeatValue->line_names.AsSpan()[0].AsSpan()
|
||||
: Span<StyleCustomIdent>();
|
||||
auto afterAutoRepeat =
|
||||
autoRepeatValue ? autoRepeatValue->line_names.AsSpan()[1].AsSpan()
|
||||
: Span<StyleCustomIdent>();
|
||||
uint32_t repeatIndex = 0;
|
||||
uint32_t numRepeatTracks = aTrackInfo.mRemovedRepeatTracks.Length();
|
||||
enum LinePlacement { LinesPrecede, LinesFollow, LinesBetween };
|
||||
auto AppendRemovedAutoFits =
|
||||
[&aTrackInfo, &valueList, aTrackList, beforeAutoRepeat, afterAutoRepeat,
|
||||
&repeatIndex, numRepeatTracks](LinePlacement aPlacement) {
|
||||
// Add in removed auto-fit tracks and lines here, if necessary
|
||||
bool atLeastOneTrackReported = false;
|
||||
while (repeatIndex < numRepeatTracks &&
|
||||
aTrackInfo.mRemovedRepeatTracks[repeatIndex]) {
|
||||
if ((aPlacement == LinesPrecede) ||
|
||||
((aPlacement == LinesBetween) && atLeastOneTrackReported)) {
|
||||
// Precede it with the lines between repeats.
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
}
|
||||
|
||||
// Add any leading implicit tracks.
|
||||
for (uint32_t i = 0; i < numLeadingImplicitTracks; ++i) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
}
|
||||
// Removed 'auto-fit' tracks are reported as 0px.
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(0);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
atLeastOneTrackReported = true;
|
||||
|
||||
// Then add any explicit tracks and removed auto-fit tracks.
|
||||
if (numExplicitTracks || aTrackList.HasRepeatAuto()) {
|
||||
uint32_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 =
|
||||
numExplicitTracks + 1 - aTrackInfo->mResolvedLineNames.Length();
|
||||
endOfRepeat = aTrackInfo->mRepeatFirstTrack + offsetToLastRepeat + 1;
|
||||
}
|
||||
|
||||
auto* autoRepeatValue = aTrackList.GetRepeatAutoValue();
|
||||
auto beforeAutoRepeat =
|
||||
autoRepeatValue ? autoRepeatValue->line_names.AsSpan()[0].AsSpan()
|
||||
: Span<StyleCustomIdent>();
|
||||
auto afterAutoRepeat =
|
||||
autoRepeatValue ? autoRepeatValue->line_names.AsSpan()[1].AsSpan()
|
||||
: Span<StyleCustomIdent>();
|
||||
uint32_t repeatIndex = 0;
|
||||
uint32_t numRepeatTracks = aTrackInfo->mRemovedRepeatTracks.Length();
|
||||
enum LinePlacement { LinesPrecede, LinesFollow, LinesBetween };
|
||||
auto AppendRemovedAutoFits = [aTrackInfo, &valueList, aTrackList,
|
||||
beforeAutoRepeat, afterAutoRepeat,
|
||||
&repeatIndex,
|
||||
numRepeatTracks](LinePlacement aPlacement) {
|
||||
// Add in removed auto-fit tracks and lines here, if necessary
|
||||
bool atLeastOneTrackReported = false;
|
||||
while (repeatIndex < numRepeatTracks &&
|
||||
aTrackInfo->mRemovedRepeatTracks[repeatIndex]) {
|
||||
if ((aPlacement == LinesPrecede) ||
|
||||
((aPlacement == LinesBetween) && atLeastOneTrackReported)) {
|
||||
// Precede it with the lines between repeats.
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
}
|
||||
|
||||
// Removed 'auto-fit' tracks are reported as 0px.
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(0);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
atLeastOneTrackReported = true;
|
||||
|
||||
if (aPlacement == LinesFollow) {
|
||||
// Follow it with the lines between repeats.
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
if (aPlacement == LinesFollow) {
|
||||
// Follow it with the lines between repeats.
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
}
|
||||
repeatIndex++;
|
||||
}
|
||||
repeatIndex++;
|
||||
}
|
||||
repeatIndex++;
|
||||
};
|
||||
};
|
||||
|
||||
for (uint32_t i = 0;; i++) {
|
||||
if (aTrackList.HasRepeatAuto()) {
|
||||
if (i == aTrackInfo->mRepeatFirstTrack) {
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo->mResolvedLineNames[i];
|
||||
if (i == endOfRepeat) {
|
||||
// All auto-fit tracks are empty, but we report them anyway.
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
|
||||
AppendRemovedAutoFits(LinesBetween);
|
||||
|
||||
AppendGridLineNames(valueList,
|
||||
aTrackInfo->mResolvedLineNames[i + 1]);
|
||||
} else {
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
AppendRemovedAutoFits(LinesFollow);
|
||||
}
|
||||
} else if (i == endOfRepeat) {
|
||||
// Before appending the last line, finish off any removed auto-fits.
|
||||
AppendRemovedAutoFits(LinesPrecede);
|
||||
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo
|
||||
->mResolvedLineNames[aTrackInfo->mRepeatFirstTrack + 1];
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
} else if (i > aTrackInfo->mRepeatFirstTrack && i < endOfRepeat) {
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
AppendRemovedAutoFits(LinesFollow);
|
||||
} else {
|
||||
uint32_t j = i > endOfRepeat ? i - offsetToLastRepeat : i;
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo->mResolvedLineNames[j];
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0;; i++) {
|
||||
if (aTrackList.HasRepeatAuto()) {
|
||||
if (i == aTrackInfo.mRepeatFirstTrack) {
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo->mResolvedLineNames[i];
|
||||
aTrackInfo.mResolvedLineNames[i];
|
||||
if (i == endOfRepeat) {
|
||||
// All auto-fit tracks are empty, but we report them anyway.
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
|
||||
AppendRemovedAutoFits(LinesBetween);
|
||||
|
||||
AppendGridLineNames(valueList,
|
||||
aTrackInfo.mResolvedLineNames[i + 1]);
|
||||
} else {
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
AppendRemovedAutoFits(LinesFollow);
|
||||
}
|
||||
} else if (i == endOfRepeat) {
|
||||
// Before appending the last line, finish off any removed auto-fits.
|
||||
AppendRemovedAutoFits(LinesPrecede);
|
||||
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo.mResolvedLineNames[aTrackInfo.mRepeatFirstTrack + 1];
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
} else if (i > aTrackInfo.mRepeatFirstTrack && i < endOfRepeat) {
|
||||
AppendGridLineNames(valueList, afterAutoRepeat, beforeAutoRepeat);
|
||||
AppendRemovedAutoFits(LinesFollow);
|
||||
} else {
|
||||
uint32_t j = i > endOfRepeat ? i - offsetToLastRepeat : i;
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo.mResolvedLineNames[j];
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
}
|
||||
if (i == numExplicitTracks) {
|
||||
break;
|
||||
}
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i + numLeadingImplicitTracks]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
} else {
|
||||
const nsTArray<StyleCustomIdent>& lineNames =
|
||||
aTrackInfo.mResolvedLineNames[i];
|
||||
AppendGridLineNames(valueList, lineNames);
|
||||
}
|
||||
}
|
||||
|
||||
// Add any trailing implicit tracks.
|
||||
for (uint32_t i = numLeadingImplicitTracks + numExplicitTracks;
|
||||
i < numSizes; ++i) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
}
|
||||
} else {
|
||||
if (aTrackList.IsNone()) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
return val.forget();
|
||||
}
|
||||
// We don't have a frame. So, we'll just return a serialization of
|
||||
// the tracks from the style (without resolved sizes).
|
||||
auto& trackList = *aTrackList.AsTrackList();
|
||||
auto nameLists = trackList.line_names.AsSpan();
|
||||
auto values = trackList.values.AsSpan();
|
||||
uint32_t numSizes = values.Length();
|
||||
for (uint32_t i = 0;; i++) {
|
||||
auto names = nameLists[i].AsSpan();
|
||||
if (!names.IsEmpty()) {
|
||||
AppendGridLineNames(valueList, names);
|
||||
}
|
||||
if (i == numSizes) {
|
||||
if (i == numExplicitTracks) {
|
||||
break;
|
||||
}
|
||||
auto& value = values[i];
|
||||
if (value.IsTrackRepeat()) {
|
||||
auto& repeat = value.AsTrackRepeat();
|
||||
nsAutoString string;
|
||||
string.AppendLiteral("repeat(");
|
||||
if (repeat.count.IsNumber()) {
|
||||
nsStyleUtil::AppendCSSNumber(repeat.count.AsNumber(), string);
|
||||
} else if (repeat.count.IsAutoFit()) {
|
||||
string.AppendLiteral("auto-fit");
|
||||
} else {
|
||||
MOZ_ASSERT(repeat.count.IsAutoFill());
|
||||
string.AppendLiteral("auto-fill");
|
||||
}
|
||||
string.AppendLiteral(",");
|
||||
|
||||
auto repeat_names = repeat.line_names.AsSpan();
|
||||
auto repeat_sizes = repeat.track_sizes.AsSpan();
|
||||
MOZ_ASSERT(repeat_names.Length() == repeat_sizes.Length() ||
|
||||
repeat_names.Length() == repeat_sizes.Length() + 1);
|
||||
for (auto i : IntegerRange(repeat_sizes.Length())) {
|
||||
auto names = repeat_names[i];
|
||||
if (!names.IsEmpty()) {
|
||||
string.Append(' ');
|
||||
AppendGridLineNames(string, names.AsSpan(), Brackets::Yes);
|
||||
}
|
||||
string.Append(' ');
|
||||
RefPtr<nsROCSSPrimitiveValue> size =
|
||||
GetGridTrackSize(repeat_sizes[i]);
|
||||
nsAutoString tmp;
|
||||
size->GetCssText(tmp);
|
||||
string.Append(tmp);
|
||||
}
|
||||
if (repeat_names.Length() == repeat_sizes.Length() + 1) {
|
||||
auto lastList = repeat_names[repeat_sizes.Length()].AsSpan();
|
||||
if (!lastList.IsEmpty()) {
|
||||
string.Append(' ');
|
||||
AppendGridLineNames(string, lastList, Brackets::Yes);
|
||||
}
|
||||
}
|
||||
string.Append(')');
|
||||
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
|
||||
value->SetString(string);
|
||||
valueList->AppendCSSValue(value.forget());
|
||||
} else {
|
||||
valueList->AppendCSSValue(GetGridTrackSize(value.AsTrackSize()));
|
||||
}
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i + numLeadingImplicitTracks]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
}
|
||||
}
|
||||
|
||||
// Add any trailing implicit tracks.
|
||||
for (uint32_t i = numLeadingImplicitTracks + numExplicitTracks; i < numSizes;
|
||||
++i) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(trackSizes[i]);
|
||||
valueList->AppendCSSValue(val.forget());
|
||||
}
|
||||
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridTemplateColumns() {
|
||||
const ComputedGridTrackInfo* info = nullptr;
|
||||
|
||||
nsGridContainerFrame* gridFrame =
|
||||
nsGridContainerFrame::GetGridFrameWithComputedInfo(mInnerFrame);
|
||||
|
||||
if (gridFrame) {
|
||||
info = gridFrame->GetComputedTemplateColumns();
|
||||
if (!gridFrame) {
|
||||
// The element doesn't have a box - return the computed value.
|
||||
// https://drafts.csswg.org/css-grid/#resolved-track-list
|
||||
nsAutoString string;
|
||||
Servo_GetPropertyValue(mComputedStyle, eCSSProperty_grid_template_columns,
|
||||
&string);
|
||||
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
|
||||
value->SetString(string);
|
||||
return value.forget();
|
||||
}
|
||||
|
||||
// GetGridFrameWithComputedInfo() above ensures that this returns non-null:
|
||||
const ComputedGridTrackInfo* info = gridFrame->GetComputedTemplateColumns();
|
||||
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns,
|
||||
info);
|
||||
*info);
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridTemplateRows() {
|
||||
const ComputedGridTrackInfo* info = nullptr;
|
||||
|
||||
nsGridContainerFrame* gridFrame =
|
||||
nsGridContainerFrame::GetGridFrameWithComputedInfo(mInnerFrame);
|
||||
|
||||
if (gridFrame) {
|
||||
info = gridFrame->GetComputedTemplateRows();
|
||||
if (!gridFrame) {
|
||||
// The element doesn't have a box - return the computed value.
|
||||
// https://drafts.csswg.org/css-grid/#resolved-track-list
|
||||
nsAutoString string;
|
||||
Servo_GetPropertyValue(mComputedStyle, eCSSProperty_grid_template_rows,
|
||||
&string);
|
||||
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
|
||||
value->SetString(string);
|
||||
return value.forget();
|
||||
}
|
||||
|
||||
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, info);
|
||||
// GetGridFrameWithComputedInfo() above ensures that this returns non-null:
|
||||
const ComputedGridTrackInfo* info = gridFrame->GetComputedTemplateRows();
|
||||
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, *info);
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingTop() {
|
||||
|
|
|
@ -197,7 +197,7 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
|
|||
const mozilla::StyleTrackBreadth&);
|
||||
already_AddRefed<CSSValue> GetGridTemplateColumnsRows(
|
||||
const mozilla::StyleGridTemplateComponent& aTrackList,
|
||||
const mozilla::ComputedGridTrackInfo* aTrackInfo);
|
||||
const mozilla::ComputedGridTrackInfo& aTrackInfo);
|
||||
|
||||
bool GetLineHeightCoord(nscoord& aCoord);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче