Bug 1900195. Remove support for the 'align-tracks' and 'justify-tracks' properties. r=emilio

These properties were added as part of the experimental Masonry support added
in bug 1607954. Since then the CSS WG resolved to remove these properties in:
https://github.com/w3c/csswg-drafts/pull/9529

This patch is a fairly brain dead removal of the properties, simply changing
the consumer code to take the code paths that would have been taken previously
if the properties were not set. That leaves some obvious dead code, which has
been removed, but no attempt has been made to redesign the Masonry code to
"make sense" without these properties. That would require a more prolonged
effort to understand Masonry, how the spec has changed in the last four years,
and how we should best change our code.

For now, this removal is simply focused on reducing the amount of memory used
by nsStyleDisplay to unblock the landing of bug 1899949.

Differential Revision: https://phabricator.services.mozilla.com/D212358
This commit is contained in:
Jonathan Watt 2024-06-02 00:16:26 +00:00
parent 09ccc60d8c
commit 8191eda786
14 changed files with 31 additions and 420 deletions

View File

@ -14,7 +14,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
"align-content",
"align-items",
"align-self",
"align-tracks",
"aspect-ratio",
"appearance",
"backface-visibility",
@ -103,7 +102,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
"justify-content",
"justify-items",
"justify-self",
"justify-tracks",
"line-break",
"list-style-image",
"list-style-position",

View File

@ -107,7 +107,7 @@ use.counter:
send_in_pings:
- use-counters
# Total of 2345 use counter metrics (excludes denominators).
# Total of 2341 use counter metrics (excludes denominators).
# Total of 364 'page' use counters.
use.counter.page:
svgsvgelement_getelementbyid:
@ -16085,7 +16085,7 @@ use.counter.deprecated_ops.doc:
send_in_pings:
- use-counters
# Total of 703 'CSS (page)' use counters.
# Total of 701 'CSS (page)' use counters.
use.counter.css.page:
css_align_content:
type: counter
@ -19164,23 +19164,6 @@ use.counter.css.page:
send_in_pings:
- use-counters
css_align_tracks:
type: counter
description: >
Whether a page used the CSS property align-tracks.
Compare against `use.counter.top_level_content_documents_destroyed`
to calculate the rate.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
notification_emails:
- dom-core@mozilla.com
- emilio@mozilla.com
expires: never
send_in_pings:
- use-counters
css_anchor_name:
type: counter
description: >
@ -20031,23 +20014,6 @@ use.counter.css.page:
send_in_pings:
- use-counters
css_justify_tracks:
type: counter
description: >
Whether a page used the CSS property justify-tracks.
Compare against `use.counter.top_level_content_documents_destroyed`
to calculate the rate.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
notification_emails:
- dom-core@mozilla.com
- emilio@mozilla.com
expires: never
send_in_pings:
- use-counters
css_letter_spacing:
type: counter
description: >
@ -28038,7 +28004,7 @@ use.counter.css.page:
send_in_pings:
- use-counters
# Total of 703 'CSS (document)' use counters.
# Total of 701 'CSS (document)' use counters.
use.counter.css.doc:
css_align_content:
type: counter
@ -31117,23 +31083,6 @@ use.counter.css.doc:
send_in_pings:
- use-counters
css_align_tracks:
type: counter
description: >
Whether a document used the CSS property align-tracks.
Compare against `use.counter.content_documents_destroyed`
to calculate the rate.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
notification_emails:
- dom-core@mozilla.com
- emilio@mozilla.com
expires: never
send_in_pings:
- use-counters
css_anchor_name:
type: counter
description: >
@ -31984,23 +31933,6 @@ use.counter.css.doc:
send_in_pings:
- use-counters
css_justify_tracks:
type: counter
description: >
Whether a document used the CSS property justify-tracks.
Compare against `use.counter.content_documents_destroyed`
to calculate the rate.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
notification_emails:
- dom-core@mozilla.com
- emilio@mozilla.com
expires: never
send_in_pings:
- use-counters
css_letter_spacing:
type: counter
description: >

View File

@ -2200,25 +2200,4 @@ inline mozilla::StyleContentDistribution nsStylePosition::UsedContentAlignment(
return aAxis == mozilla::LogicalAxis::Block ? mAlignContent : mJustifyContent;
}
inline mozilla::StyleContentDistribution nsStylePosition::UsedTracksAlignment(
mozilla::LogicalAxis aAxis, uint32_t aIndex) const {
using T = mozilla::StyleAlignFlags;
const auto& tracksAlignment =
aAxis == mozilla::LogicalAxis::Block ? mAlignTracks : mJustifyTracks;
if (MOZ_LIKELY(tracksAlignment.IsEmpty())) {
// An empty array encodes the initial value, 'normal', which behaves as
// 'start' for Grid containers.
return mozilla::StyleContentDistribution{T::START};
}
// If there are fewer values than tracks, then the last value is used for all
// the remaining tracks.
const auto& ta = tracksAlignment.AsSpan();
auto align = ta[std::min<size_t>(aIndex, ta.Length() - 1)];
if (align.primary == T::NORMAL) {
align = mozilla::StyleContentDistribution{T::START};
}
return align;
}
#endif // WritingModes_h_

View File

@ -5435,47 +5435,6 @@ static nscoord MeasuringReflow(nsIFrame* aChild,
return childSize.BSize(wm);
}
/**
* Reflow aChild in the given aAvailableSize, using aNewContentBoxSize as its
* computed size in aChildAxis.
*/
static void PostReflowStretchChild(
nsIFrame* aChild, const ReflowInput& aReflowInput,
const LogicalSize& aAvailableSize, const LogicalSize& aCBSize,
LogicalAxis aChildAxis, const nscoord aNewContentBoxSize,
nscoord aIMinSizeClamp = NS_MAXSIZE, nscoord aBMinSizeClamp = NS_MAXSIZE) {
nsPresContext* pc = aChild->PresContext();
ComputeSizeFlags csFlags;
if (aIMinSizeClamp != NS_MAXSIZE) {
csFlags += ComputeSizeFlag::IClampMarginBoxMinSize;
}
if (aBMinSizeClamp != NS_MAXSIZE) {
csFlags += ComputeSizeFlag::BClampMarginBoxMinSize;
aChild->SetProperty(nsIFrame::BClampMarginBoxMinSizeProperty(),
aBMinSizeClamp);
} else {
aChild->RemoveProperty(nsIFrame::BClampMarginBoxMinSizeProperty());
}
ReflowInput ri(pc, aReflowInput, aChild, aAvailableSize, Some(aCBSize), {},
{}, csFlags);
if (aChildAxis == LogicalAxis::Block) {
ri.SetComputedBSize(ri.ApplyMinMaxBSize(aNewContentBoxSize));
} else {
ri.SetComputedISize(ri.ApplyMinMaxISize(aNewContentBoxSize));
}
ReflowOutput childSize(ri);
nsReflowStatus childStatus;
const nsIFrame::ReflowChildFlags flags =
nsIFrame::ReflowChildFlags::NoMoveFrame |
nsIFrame::ReflowChildFlags::NoDeleteNextInFlowChild;
auto wm = aChild->GetWritingMode();
nsContainerFrame* parent = aChild->GetParent();
parent->ReflowChild(aChild, pc, childSize, ri, wm, LogicalPoint(wm), nsSize(),
flags, childStatus);
nsContainerFrame::FinishReflowChild(aChild, pc, childSize, &ri, wm,
LogicalPoint(wm), nsSize(), flags);
}
/**
* Return the accumulated margin+border+padding in aAxis for aFrame (a subgrid)
* and its ancestor subgrids.
@ -6293,12 +6252,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselinesInMasonryAxis(
continue;
}
}
auto trackAlign =
aState.mGridStyle
->UsedTracksAlignment(
mAxis, area.LineRangeForAxis(GetOrthogonalAxis(mAxis)).mStart)
.primary;
if (!aSet.MatchTrackAlignment(trackAlign)) {
if (!aSet.MatchTrackAlignment(StyleAlignFlags::START)) {
continue;
}
@ -7348,6 +7302,13 @@ void nsGridContainerFrame::GridReflowInput::AlignJustifyContentInMasonryAxis(
}
}
// XXX This function was gutted when the 'align-tracks' and 'justify-tracks'
// properties were removed in
// https://bugzilla.mozilla.org/show_bug.cgi?id=1900195
// Possibly the current design of the Masonry code doesn't make much sense now
// without those properties, or at the very least this function should be
// renamed?
//
// Note: this is called after all items have been positioned/reflowed.
// The masonry-axis tracks have the size of the "masonry box" at this point
// and are positioned according to 'align/justify-content'.
@ -7356,160 +7317,18 @@ void nsGridContainerFrame::GridReflowInput::AlignJustifyTracksInMasonryAxis(
auto& masonryAxisTracks = mRows.mIsMasonry ? mRows : mCols;
MOZ_ASSERT(masonryAxisTracks.mSizes.Length() == 2,
"unexpected masonry axis tracks");
// The offset to the "masonry box" from our content-box start edge.
const nscoord masonryBoxOffset = masonryAxisTracks.mSizes[0].mPosition;
if (masonryBoxOffset == 0) {
return;
}
const auto masonryAxis = masonryAxisTracks.mAxis;
auto gridAxis = GetOrthogonalAxis(masonryAxis);
auto& gridAxisTracks = TracksFor(gridAxis);
AutoTArray<TrackSize, 32> savedSizes;
savedSizes.AppendElements(masonryAxisTracks.mSizes);
auto wm = mWM;
nscoord contentAreaStart = mBorderPadding.Start(masonryAxis, wm);
// The offset to the "masonry box" from our content-box start edge.
nscoord masonryBoxOffset = masonryAxisTracks.mSizes[0].mPosition;
nscoord alignmentContainerSize = masonryAxisTracks.mSizes[0].mBase;
for (auto i : IntegerRange(gridAxisTracks.mSizes.Length())) {
auto tracksAlignment = mGridStyle->UsedTracksAlignment(masonryAxis, i);
if (tracksAlignment.primary != StyleAlignFlags::START) {
masonryAxisTracks.mSizes.ClearAndRetainStorage();
for (const auto& item : mGridItems) {
if (item.mArea.LineRangeForAxis(gridAxis).mStart == i) {
const auto* child = item.mFrame;
LogicalRect rect = child->GetLogicalRect(wm, aContainerSize);
TrackSize sz = {0, 0, 0, {0, 0}, TrackSize::StateBits{0}};
const auto& margin = child->GetLogicalUsedMargin(wm);
sz.mPosition = rect.Start(masonryAxis, wm) -
margin.Start(masonryAxis, wm) - contentAreaStart;
sz.mBase =
rect.Size(masonryAxis, wm) + margin.StartEnd(masonryAxis, wm);
// Account for a align-self baseline offset on the end side.
// XXXmats hmm, it seems it would be a lot simpler to just store
// these baseline adjustments into the UsedMarginProperty instead
auto state = item.mState[masonryAxis];
if ((state & ItemState::eSelfBaseline) &&
(state & ItemState::eEndSideBaseline)) {
sz.mBase += item.mBaselineOffset[masonryAxis];
}
if (tracksAlignment.primary == StyleAlignFlags::STRETCH) {
const auto* pos = child->StylePosition();
auto itemAlignment =
pos->UsedSelfAlignment(masonryAxis, mFrame->Style());
if (child->StyleMargin()->HasAuto(masonryAxis, wm)) {
sz.mState |= TrackSize::eAutoMaxSizing;
sz.mState |= TrackSize::eItemHasAutoMargin;
} else if (pos->Size(masonryAxis, wm).IsAuto() &&
(itemAlignment == StyleAlignFlags::NORMAL ||
itemAlignment == StyleAlignFlags::STRETCH)) {
sz.mState |= TrackSize::eAutoMaxSizing;
sz.mState |= TrackSize::eItemStretchSize;
const auto& max = pos->MaxSize(masonryAxis, wm);
if (max.ConvertsToLength()) { // XXX deal with percentages
// XXX add in baselineOffset ? use actual frame size - content
// size?
nscoord boxSizingAdjust =
child->GetLogicalUsedBorderAndPadding(wm).StartEnd(
masonryAxis, wm);
if (pos->mBoxSizing == StyleBoxSizing::Border) {
boxSizingAdjust = 0;
}
sz.mLimit = nsLayoutUtils::ComputeBSizeValue(
aContentSize.Size(masonryAxis, wm), boxSizingAdjust,
max.AsLengthPercentage());
sz.mLimit += margin.StartEnd(masonryAxis, wm);
sz.mState |= TrackSize::eClampToLimit;
}
}
}
masonryAxisTracks.mSizes.AppendElement(std::move(sz));
}
}
masonryAxisTracks.AlignJustifyContent(mGridStyle, tracksAlignment, wm,
alignmentContainerSize, false);
auto iter = mGridItems.begin();
auto end = mGridItems.end();
// We limit the loop to the number of items we found in the current
// grid-axis axis track (in the outer loop) as an optimization.
for (auto r : IntegerRange(masonryAxisTracks.mSizes.Length())) {
GridItemInfo* item = nullptr;
auto& sz = masonryAxisTracks.mSizes[r];
// Find the next item in the current grid-axis axis track.
for (; iter != end; ++iter) {
if (iter->mArea.LineRangeForAxis(gridAxis).mStart == i) {
item = &*iter;
++iter;
break;
}
}
nsIFrame* child = item->mFrame;
const auto childWM = child->GetWritingMode();
auto masonryChildAxis =
childWM.IsOrthogonalTo(wm) ? gridAxis : masonryAxis;
LogicalMargin margin = child->GetLogicalUsedMargin(childWM);
bool forceReposition = false;
if (sz.mState & TrackSize::eItemStretchSize) {
auto size = child->GetLogicalSize().Size(masonryChildAxis, childWM);
auto newSize = sz.mBase - margin.StartEnd(masonryChildAxis, childWM);
if (size != newSize) {
// XXX need to pass aIMinSizeClamp aBMinSizeClamp ?
LogicalSize cb =
ContainingBlockFor(item->mArea).Size(wm).ConvertTo(childWM, wm);
LogicalSize availableSize = cb;
cb.Size(masonryChildAxis, childWM) = alignmentContainerSize;
availableSize.Size(LogicalAxis::Block, childWM) =
NS_UNCONSTRAINEDSIZE;
const auto& bp = child->GetLogicalUsedBorderAndPadding(childWM);
newSize -= bp.StartEnd(masonryChildAxis, childWM);
::PostReflowStretchChild(child, *mReflowInput, availableSize, cb,
masonryChildAxis, newSize);
if (childWM.IsPhysicalRTL()) {
// The NormalPosition of this child is frame-size dependent so we
// need to reset its stored position below.
forceReposition = true;
}
}
} else if (sz.mState & TrackSize::eItemHasAutoMargin) {
// Re-compute the auto-margin(s) in the masonry axis.
auto size = child->GetLogicalSize().Size(masonryChildAxis, childWM);
auto spaceToFill = sz.mBase - size;
if (spaceToFill > nscoord(0)) {
const auto& marginStyle = child->StyleMargin();
if (marginStyle->mMargin.Start(masonryChildAxis, childWM)
.IsAuto()) {
if (marginStyle->mMargin.End(masonryChildAxis, childWM)
.IsAuto()) {
nscoord half;
nscoord roundingError = NSCoordDivRem(spaceToFill, 2, &half);
margin.Start(masonryChildAxis, childWM) = half;
margin.End(masonryChildAxis, childWM) = half + roundingError;
} else {
margin.Start(masonryChildAxis, childWM) = spaceToFill;
}
} else {
MOZ_ASSERT(
marginStyle->mMargin.End(masonryChildAxis, childWM).IsAuto());
margin.End(masonryChildAxis, childWM) = spaceToFill;
}
nsMargin* propValue =
child->GetProperty(nsIFrame::UsedMarginProperty());
if (propValue) {
*propValue = margin.GetPhysicalMargin(childWM);
} else {
child->AddProperty(
nsIFrame::UsedMarginProperty(),
new nsMargin(margin.GetPhysicalMargin(childWM)));
}
}
}
nscoord newPos = contentAreaStart + masonryBoxOffset + sz.mPosition +
margin.Start(masonryChildAxis, childWM);
LogicalPoint pos = child->GetLogicalNormalPosition(wm, aContainerSize);
auto delta = newPos - pos.Pos(masonryAxis, wm);
if (delta != 0 || forceReposition) {
LogicalPoint logicalDelta(wm);
logicalDelta.Pos(masonryAxis, wm) = delta;
child->MovePositionBy(wm, logicalDelta);
}
}
} else if (masonryBoxOffset != nscoord(0)) {
// TODO move placeholders too
auto delta = masonryBoxOffset;
LogicalPoint logicalDelta(wm);
@ -7522,8 +7341,6 @@ void nsGridContainerFrame::GridReflowInput::AlignJustifyTracksInMasonryAxis(
}
}
}
masonryAxisTracks.mSizes = std::move(savedSizes);
}
/**
* Return a Fragmentainer object if we have a fragmentainer frame in our

View File

@ -574,8 +574,6 @@ cbindgen-types = [
{ gecko = "StyleJustifySelf", servo = "crate::values::computed::JustifySelf" },
{ gecko = "StyleAlignSelf", servo = "crate::values::computed::AlignSelf" },
{ gecko = "StyleAlignContent", servo = "crate::values::computed::align::AlignContent" },
{ gecko = "StyleJustifyTracks", servo = "crate::values::computed::align::JustifyTracks" },
{ gecko = "StyleAlignTracks", servo = "crate::values::computed::align::AlignTracks" },
{ gecko = "StyleJustifyContent", servo = "crate::values::computed::align::JustifyContent" },
{ gecko = "StyleComputedValueFlags", servo = "crate::computed_value_flags::ComputedValueFlags" },
{ gecko = "StyleImage", servo = "crate::values::computed::Image" },

View File

@ -1092,9 +1092,7 @@ nsStylePosition::nsStylePosition()
}
nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
: mAlignTracks(aSource.mAlignTracks),
mJustifyTracks(aSource.mJustifyTracks),
mObjectPosition(aSource.mObjectPosition),
: mObjectPosition(aSource.mObjectPosition),
mOffset(aSource.mOffset),
mWidth(aSource.mWidth),
mMinWidth(aSource.mMinWidth),
@ -1196,9 +1194,7 @@ nsChangeHint nsStylePosition::CalcDifference(
}
if (mAlignItems != aNewData.mAlignItems ||
mAlignSelf != aNewData.mAlignSelf ||
mJustifyTracks != aNewData.mJustifyTracks ||
mAlignTracks != aNewData.mAlignTracks) {
mAlignSelf != aNewData.mAlignSelf) {
return hint | nsChangeHint_AllReflowHints;
}

View File

@ -722,18 +722,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
inline mozilla::StyleContentDistribution UsedContentAlignment(
LogicalAxis aAxis) const;
/**
* Return the used value for 'align-tracks'/'justify-tracks' for a track
* in the given axis.
* (defined in WritingModes.h since we need the full LogicalAxis type)
*/
inline mozilla::StyleContentDistribution UsedTracksAlignment(
LogicalAxis aAxis, uint32_t aIndex) const;
// Each entry has the same encoding as *-content, see below.
mozilla::StyleAlignTracks mAlignTracks;
mozilla::StyleJustifyTracks mJustifyTracks;
Position mObjectPosition;
StyleRect<LengthPercentageOrAuto> mOffset;
StyleSize mWidth;

View File

@ -12383,14 +12383,6 @@ if (isGridTemplateMasonryValueEnabled) {
other_values: ["pack ordered", "ordered next", "next definite-first"],
invalid_values: ["auto", "none", "10px", "row", "dense"],
};
let alignTracks = { ...gCSSProperties["align-content"] };
alignTracks.domProp = "alignTracks";
gCSSProperties["align-tracks"] = alignTracks;
let justifyTracks = { ...gCSSProperties["justify-content"] };
justifyTracks.domProp = "justifyTracks";
gCSSProperties["justify-tracks"] = justifyTracks;
}
gCSSProperties["display"].other_values.push("grid", "inline-grid");

View File

@ -101,18 +101,6 @@ ${helpers.single_keyword(
servo_restyle_damage="reflow",
affects="layout",
)}
${helpers.predefined_type(
"justify-tracks",
"JustifyTracks",
"specified::JustifyTracks::default()",
engines="gecko",
gecko_pref="layout.css.grid-template-masonry-value.enabled",
animation_value_type="discrete",
servo_restyle_damage="reflow",
spec="https://github.com/w3c/csswg-drafts/issues/4650",
affects="layout",
)}
% endif
% if engine == "servo":
@ -154,18 +142,6 @@ ${helpers.single_keyword(
affects="layout",
)}
${helpers.predefined_type(
"align-tracks",
"AlignTracks",
"specified::AlignTracks::default()",
engines="gecko",
gecko_pref="layout.css.grid-template-masonry-value.enabled",
animation_value_type="discrete",
servo_restyle_damage="reflow",
spec="https://github.com/w3c/csswg-drafts/issues/4650",
affects="layout",
)}
${helpers.predefined_type(
"align-items",
"AlignItems",

View File

@ -10,8 +10,7 @@ use crate::values::computed::{Context, ToComputedValue};
use crate::values::specified;
pub use super::specified::{
AlignContent, AlignItems, AlignTracks, ContentDistribution, JustifyContent, JustifyTracks,
SelfAlignment,
AlignContent, AlignItems, ContentDistribution, JustifyContent, SelfAlignment,
};
pub use super::specified::{AlignSelf, JustifySelf};

View File

@ -38,8 +38,7 @@ use std::ops::{Add, Sub};
#[cfg(feature = "gecko")]
pub use self::align::{
AlignContent, AlignItems, AlignTracks, JustifyContent, JustifyItems, JustifyTracks,
SelfAlignment,
AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment,
};
#[cfg(feature = "gecko")]
pub use self::align::{AlignSelf, JustifySelf};

View File

@ -288,36 +288,6 @@ impl SpecifiedValueInfo for AlignContent {
}
}
/// Value for the `align-tracks` property.
///
/// <https://github.com/w3c/csswg-drafts/issues/4650>
#[derive(
Clone,
Debug,
Default,
Eq,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(transparent)]
#[css(comma)]
pub struct AlignTracks(#[css(iterable, if_empty = "normal")] pub crate::OwnedSlice<AlignContent>);
impl Parse for AlignTracks {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let values = input.parse_comma_separated(|input| AlignContent::parse(context, input))?;
Ok(AlignTracks(values.into()))
}
}
/// Value for the `justify-content` property.
///
/// <https://drafts.csswg.org/css-align/#propdef-justify-content>
@ -355,37 +325,6 @@ impl SpecifiedValueInfo for JustifyContent {
ContentDistribution::list_keywords(f, AxisDirection::Inline);
}
}
/// Value for the `justify-tracks` property.
///
/// <https://github.com/w3c/csswg-drafts/issues/4650>
#[derive(
Clone,
Debug,
Default,
Eq,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(transparent)]
#[css(comma)]
pub struct JustifyTracks(
#[css(iterable, if_empty = "normal")] pub crate::OwnedSlice<JustifyContent>,
);
impl Parse for JustifyTracks {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let values = input.parse_comma_separated(|input| JustifyContent::parse(context, input))?;
Ok(JustifyTracks(values.into()))
}
}
/// <https://drafts.csswg.org/css-align/#self-alignment>
#[derive(

View File

@ -26,9 +26,9 @@ use style_traits::values::specified::AllowedNumericType;
use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss};
#[cfg(feature = "gecko")]
pub use self::align::{AlignContent, AlignItems, AlignSelf, AlignTracks, ContentDistribution};
pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution};
#[cfg(feature = "gecko")]
pub use self::align::{JustifyContent, JustifyItems, JustifySelf, JustifyTracks, SelfAlignment};
pub use self::align::{JustifyContent, JustifyItems, JustifySelf, SelfAlignment};
pub use self::angle::{AllowUnitlessZeroAngle, Angle};
pub use self::animation::{
AnimationComposition, AnimationDirection, AnimationFillMode, AnimationIterationCount,

View File

@ -273,8 +273,6 @@ include = [
"ComputedJustifyItems",
"AlignContent",
"JustifyContent",
"AlignTracks",
"JustifyTracks",
"TransformStyle",
"Image",
"ClipPath",