--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1526,23 +1526,21 @@ nsBlockFrame::Reflow(nsPresContext*
(value == NS_STYLE_ALIGN_AUTO));
};
// First check this frame for non-default values of the css-align properties
// that apply to block containers.
// Note: we check here for non-default "justify-items", though technically
// that'd only affect rendering if some child has "justify-self:auto".
// (It's safe to assume that's likely, since it's the default value that
- // a child would have.) We also pass in nullptr for the parent style context
- // because an accurate parameter is slower and only necessary to detect a
- // narrow edge case with the "legacy" keyword.
+ // a child would have.)
const nsStylePosition* stylePosition = reflowInput->mStylePosition;
if (!IsStyleNormalOrAuto(stylePosition->mJustifyContent) ||
!IsStyleNormalOrAuto(stylePosition->mAlignContent) ||
- !IsStyleNormalOrAuto(stylePosition->ComputedJustifyItems(nullptr))) {
+ !IsStyleNormalOrAuto(stylePosition->mJustifyItems)) {
Telemetry::Accumulate(Telemetry::BOX_ALIGN_PROPS_IN_BLOCKS_FLAG, true);
} else {
// If not already flagged by the parent, now check justify-self of the
// block-level child frames.
for (nsBlockFrame::LineIterator line = LinesBegin();
line != LinesEnd(); ++line) {
if (line->IsBlock() &&
!IsStyleNormalOrAuto(line->mFirstChild->StylePosition()->mJustifySelf)) {
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -392,16 +392,17 @@ GeckoStyleContext::GetUniqueStyleData(co
#define UNIQUE_CASE(c_) \
case eStyleStruct_##c_: \
result = new (presContext) nsStyle##c_( \
* static_cast<const nsStyle##c_ *>(current)); \
break;
UNIQUE_CASE(Font)
UNIQUE_CASE(Display)
+ UNIQUE_CASE(Position)
UNIQUE_CASE(Text)
UNIQUE_CASE(TextReset)
UNIQUE_CASE(Visibility)
#undef UNIQUE_CASE
default:
NS_ERROR("Struct type not supported. Please find another way to do this if you can!");
@@ -860,16 +861,33 @@ GeckoStyleContext::ApplyStyleFixups(bool
text->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_CENTER ||
text->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)
{
nsStyleText* uniqueText = GET_UNIQUE_STYLE_DATA(Text);
uniqueText->mTextAlign = NS_STYLE_TEXT_ALIGN_START;
}
}
+ // Fixup the "justify-items: auto" value based on our parent style here if
+ // needed.
+ //
+ // Note that this only pulls a unique struct in the case the parent has the
+ // "legacy" modifier (which is not the default), and the computed value would
+ // change as a result.
+ //
+ // We check the parent first just to avoid unconditionally pulling the
+ // nsStylePosition struct on every style context.
+ if (mParent &&
+ mParent->StylePosition()->mJustifyItems & NS_STYLE_JUSTIFY_LEGACY &&
+ StylePosition()->mSpecifiedJustifyItems == NS_STYLE_JUSTIFY_AUTO &&
+ StylePosition()->mJustifyItems != mParent->StylePosition()->mJustifyItems) {
+ nsStylePosition* uniquePosition = GET_UNIQUE_STYLE_DATA(Position);
+ uniquePosition->mJustifyItems = mParent->StylePosition()->mJustifyItems;
+ }
+
// CSS2.1 section 9.2.4 specifies fixups for the 'display' property of
// the root element. We can't implement them in nsRuleNode because we
// don't want to store all display structs that aren't 'block',
// 'inline', or 'table' in the style context tree on the off chance
// that the root element has its style reresolved later. So do them
// here if needed, by changing the style data, so that other code
// doesn't get confused by looking at the style data.
if (!mParent &&
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4689,18 +4689,17 @@ nsComputedDOMStyle::DoGetJustifyContent(
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetJustifyItems()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
nsAutoString str;
- auto justify =
- StylePosition()->ComputedJustifyItems(mStyleContext->GetParentAllowServo());
+ auto justify = StylePosition()->mJustifyItems;
nsCSSValue::AppendAlignJustifyValueToString(justify, str);
val->SetString(str);
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetJustifySelf()
{
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -8654,31 +8654,38 @@ nsRuleNode::ComputePositionData(void* aS
pos->mJustifyContent, conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
parentPos->mJustifyContent,
NS_STYLE_JUSTIFY_NORMAL);
// justify-items: enum, inherit, initial
const auto& justifyItemsValue = *aRuleData->ValueForJustifyItems();
if (MOZ_UNLIKELY(justifyItemsValue.GetUnit() == eCSSUnit_Inherit)) {
- if (MOZ_LIKELY(parentContext)) {
- pos->mJustifyItems =
- parentPos->ComputedJustifyItems(parentContext->GetParent());
- } else {
- pos->mJustifyItems = NS_STYLE_JUSTIFY_NORMAL;
- }
+ pos->mSpecifiedJustifyItems =
+ MOZ_LIKELY(parentContext)
+ ? parentPos->mJustifyItems
+ : NS_STYLE_JUSTIFY_NORMAL;
conditions.SetUncacheable();
} else {
SetValue(justifyItemsValue,
- pos->mJustifyItems, conditions,
+ pos->mSpecifiedJustifyItems, conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
- parentPos->mJustifyItems, // unused, we handle 'inherit' above
+ parentPos->mSpecifiedJustifyItems, // unused, we handle 'inherit' above
NS_STYLE_JUSTIFY_AUTO);
}
+ // NOTE(emilio): Even though "auto" technically depends on the parent style
+ // context, most of the time it'll resolve to "normal". So, we
+ // optimistically assume here that it does resolve to "normal", and we
+ // handle the other cases in ApplyStyleFixups. This way, position structs
+ // can be cached in the default/common case.
+ pos->mJustifyItems =
+ pos->mSpecifiedJustifyItems == NS_STYLE_JUSTIFY_AUTO
+ ? NS_STYLE_JUSTIFY_NORMAL : pos->mSpecifiedJustifyItems;
+
// justify-self: enum, inherit, initial
SetValue(*aRuleData->ValueForJustifySelf(),
pos->mJustifySelf, conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
parentPos->mJustifySelf,
NS_STYLE_JUSTIFY_AUTO);
// flex-basis: auto, length, percent, enum, calc, inherit, initial
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1439,17 +1439,18 @@ nsStylePosition::nsStylePosition(const n
, mGridAutoRowsMin(eStyleUnit_Auto)
, mGridAutoRowsMax(eStyleUnit_Auto)
, mGridAutoFlow(NS_STYLE_GRID_AUTO_FLOW_ROW)
, mBoxSizing(StyleBoxSizing::Content)
, mAlignContent(NS_STYLE_ALIGN_NORMAL)
, mAlignItems(NS_STYLE_ALIGN_NORMAL)
, mAlignSelf(NS_STYLE_ALIGN_AUTO)
, mJustifyContent(NS_STYLE_JUSTIFY_NORMAL)
- , mJustifyItems(NS_STYLE_JUSTIFY_AUTO)
+ , mSpecifiedJustifyItems(NS_STYLE_JUSTIFY_AUTO)
+ , mJustifyItems(NS_STYLE_JUSTIFY_NORMAL)
, mJustifySelf(NS_STYLE_JUSTIFY_AUTO)
, mFlexDirection(NS_STYLE_FLEX_DIRECTION_ROW)
, mFlexWrap(NS_STYLE_FLEX_WRAP_NOWRAP)
, mObjectFit(NS_STYLE_OBJECT_FIT_FILL)
, mOrder(NS_STYLE_ORDER_INITIAL)
, mFlexGrow(0.0f)
, mFlexShrink(1.0f)
, mZIndex(eStyleUnit_Auto)
@@ -1497,16 +1498,17 @@ nsStylePosition::nsStylePosition(const n
, mGridAutoRowsMin(aSource.mGridAutoRowsMin)
, mGridAutoRowsMax(aSource.mGridAutoRowsMax)
, mGridAutoFlow(aSource.mGridAutoFlow)
, mBoxSizing(aSource.mBoxSizing)
, mAlignContent(aSource.mAlignContent)
, mAlignItems(aSource.mAlignItems)
, mAlignSelf(aSource.mAlignSelf)
, mJustifyContent(aSource.mJustifyContent)
+ , mSpecifiedJustifyItems(aSource.mSpecifiedJustifyItems)
, mJustifyItems(aSource.mJustifyItems)
, mJustifySelf(aSource.mJustifySelf)
, mFlexDirection(aSource.mFlexDirection)
, mFlexWrap(aSource.mFlexWrap)
, mObjectFit(aSource.mObjectFit)
, mOrder(aSource.mOrder)
, mFlexGrow(aSource.mFlexGrow)
, mFlexShrink(aSource.mFlexShrink)
@@ -1628,16 +1630,22 @@ nsStylePosition::CalcDifference(const ns
// Changing 'justify-content/items/self' might affect the positioning,
// but it won't affect any sizing.
if (mJustifyContent != aNewData.mJustifyContent ||
mJustifyItems != aNewData.mJustifyItems ||
mJustifySelf != aNewData.mJustifySelf) {
hint |= nsChangeHint_NeedReflow;
}
+ // No need to do anything if mSpecifiedJustifyItems changes, as long as
+ // mJustifyItems (tested above) is unchanged.
+ if (mSpecifiedJustifyItems != aNewData.mSpecifiedJustifyItems) {
+ hint |= nsChangeHint_NeutralChange;
+ }
+
// 'align-content' doesn't apply to a single-line flexbox but we don't know
// if we're a flex container at this point so we can't optimize for that.
if (mAlignContent != aNewData.mAlignContent) {
hint |= nsChangeHint_NeedReflow;
}
bool widthChanged = mWidth != aNewData.mWidth ||
mMinWidth != aNewData.mMinWidth ||
@@ -1710,42 +1718,23 @@ nsStylePosition::UsedAlignSelf(nsStyleCo
MOZ_ASSERT(!(parentAlignItems & NS_STYLE_ALIGN_LEGACY),
"align-items can't have 'legacy'");
return parentAlignItems;
}
return NS_STYLE_ALIGN_NORMAL;
}
uint8_t
-nsStylePosition::ComputedJustifyItems(nsStyleContext* aParent) const
-{
- if (mJustifyItems != NS_STYLE_JUSTIFY_AUTO) {
- return mJustifyItems;
- }
- if (MOZ_LIKELY(aParent)) {
- auto inheritedJustifyItems = aParent->StylePosition()->ComputedJustifyItems(
- aParent->GetParentAllowServo());
- // "If the inherited value of justify-items includes the 'legacy' keyword,
- // 'auto' computes to the inherited value." Otherwise, 'normal'.
- if (inheritedJustifyItems & NS_STYLE_JUSTIFY_LEGACY) {
- return inheritedJustifyItems;
- }
- }
- return NS_STYLE_JUSTIFY_NORMAL;
-}
-
-uint8_t
nsStylePosition::UsedJustifySelf(nsStyleContext* aParent) const
{
if (mJustifySelf != NS_STYLE_JUSTIFY_AUTO) {
return mJustifySelf;
}
if (MOZ_LIKELY(aParent)) {
- auto inheritedJustifyItems = aParent->StylePosition()->ComputedJustifyItems(
- aParent->GetParentAllowServo());
+ auto inheritedJustifyItems = aParent->StylePosition()->mJustifyItems;
return inheritedJustifyItems & ~NS_STYLE_JUSTIFY_LEGACY;
}
return NS_STYLE_JUSTIFY_NORMAL;
}
// --------------------
// nsStyleTable
//
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1674,22 +1674,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
/**
* Return the used value for 'align-self' given our parent StyleContext
* aParent (or null for the root).
*/
uint8_t UsedAlignSelf(nsStyleContext* aParent) const;
/**
- * Return the computed value for 'justify-items' given our parent StyleContext
- * aParent (or null for the root).
- */
- uint8_t ComputedJustifyItems(nsStyleContext* aParent) const;
-
- /**
* Return the used value for 'justify-self' given our parent StyleContext
* aParent (or null for the root).
*/
uint8_t UsedJustifySelf(nsStyleContext* aParent) const;
mozilla::Position mObjectPosition; // [reset]
nsStyleSides mOffset; // [reset] coord, percent, calc, auto
nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
@@ -1705,24 +1699,27 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex
uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h
mozilla::StyleBoxSizing mBoxSizing; // [reset] see nsStyleConsts.h
uint16_t mAlignContent; // [reset] fallback value in the high byte
uint8_t mAlignItems; // [reset] see nsStyleConsts.h
uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
uint16_t mJustifyContent; // [reset] fallback value in the high byte
-private:
- friend class nsRuleNode;
-
- // mJustifyItems should only be read via ComputedJustifyItems(), which
- // lazily resolves its "auto" value. nsRuleNode needs direct access so
- // it can set mJustifyItems' value when populating this struct.
+ // We cascade mSpecifiedJustifyItems, to handle the auto value, but store the
+ // computed value in mJustifyItems.
+ //
+ // They're effectively only different in this regard: mJustifyItems is set to
+ // mSpecifiedJustifyItems, except when the latter is AUTO -- in that case,
+ // mJustifyItems is set to NORMAL, or to the parent style context's
+ // mJustifyItems if it has the legacy flag.
+ //
+ // This last part happens in nsStyleContext::ApplyStyleFixups.
+ uint8_t mSpecifiedJustifyItems; // [reset] see nsStyleConsts.h
uint8_t mJustifyItems; // [reset] see nsStyleConsts.h
-public:
uint8_t mJustifySelf; // [reset] see nsStyleConsts.h
uint8_t mFlexDirection; // [reset] see nsStyleConsts.h
uint8_t mFlexWrap; // [reset] see nsStyleConsts.h
uint8_t mObjectFit; // [reset] see nsStyleConsts.h
int32_t mOrder; // [reset] integer
float mFlexGrow; // [reset] float
float mFlexShrink; // [reset] float
nsStyleCoord mZIndex; // [reset] integer, auto
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -55,17 +55,17 @@ use properties::animated_properties::Tra
use properties::computed_value_flags::ComputedValueFlags;
use properties::{longhands, FontComputationData, Importance, LonghandId};
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
use rule_tree::StrongRuleNode;
use selector_parser::PseudoElement;
use servo_arc::{Arc, RawOffsetArc};
use std::mem::{forget, uninitialized, transmute, zeroed};
use std::{cmp, ops, ptr};
-use values::{Auto, CustomIdent, Either, KeyframesName};
+use values::{self, Auto, CustomIdent, Either, KeyframesName};
use values::computed::ToComputedValue;
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
use values::computed::length::Percentage;
use computed_values::border_style;
pub mod style_structs {
% for style_struct in data.style_structs:
pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
@@ -1349,18 +1349,45 @@ fn static_assert() {
Either::First(0)
}
}
}
% for kind in ["align", "justify"]:
${impl_simple_type_with_conversion(kind + "_content")}
${impl_simple_type_with_conversion(kind + "_self")}
- ${impl_simple_type_with_conversion(kind + "_items")}
% endfor
+ ${impl_simple_type_with_conversion("align_items")}
+
+ pub fn set_justify_items(&mut self, v: longhands::justify_items::computed_value::T) {
+ self.gecko.mSpecifiedJustifyItems = v.specified.into();
+ self.set_computed_justify_items(v.computed);
+ }
+
+ pub fn set_computed_justify_items(&mut self, v: values::specified::JustifyItems) {
+ debug_assert!(v.0 != ::values::specified::align::ALIGN_AUTO);
+ self.gecko.mJustifyItems = v.into();
+ }
+
+ pub fn reset_justify_items(&mut self, reset_style: &Self) {
+ self.gecko.mJustifyItems = reset_style.gecko.mJustifyItems;
+ self.gecko.mSpecifiedJustifyItems = reset_style.gecko.mSpecifiedJustifyItems;
+ }
+
+ pub fn copy_justify_items_from(&mut self, other: &Self) {
+ self.gecko.mJustifyItems = other.gecko.mJustifyItems;
+ self.gecko.mSpecifiedJustifyItems = other.gecko.mJustifyItems;
+ }
+
+ pub fn clone_justify_items(&self) -> longhands::justify_items::computed_value::T {
+ longhands::justify_items::computed_value::T {
+ computed: self.gecko.mJustifyItems.into(),
+ specified: self.gecko.mSpecifiedJustifyItems.into(),
+ }
+ }
pub fn set_order(&mut self, v: longhands::order::computed_value::T) {
self.gecko.mOrder = v;
}
pub fn clone_order(&self) -> longhands::order::computed_value::T {
self.gecko.mOrder
}
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -103,17 +103,17 @@ macro_rules! impl_align_conversions {
extra_prefixes="webkit",
animation_value_type="discrete")}
#[cfg(feature = "gecko")]
impl_align_conversions!(::values::specified::align::AlignItems);
${helpers.predefined_type(name="justify-items",
type="JustifyItems",
- initial_value="specified::JustifyItems::auto()",
+ initial_value="computed::JustifyItems::auto()",
spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
animation_value_type="discrete")}
#[cfg(feature = "gecko")]
impl_align_conversions!(::values::specified::align::JustifyItems);
% endif
// Flex item properties
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -2600,43 +2600,50 @@ impl<'a> StyleBuilder<'a> {
}
}
% for property in data.longhands:
% if property.ident != "font_size":
/// Inherit `${property.ident}` from our parent style.
#[allow(non_snake_case)]
pub fn inherit_${property.ident}(&mut self) {
+ let inherited_struct =
% if property.style_struct.inherited:
- let inherited_struct =
self.inherited_style.get_${property.style_struct.name_lower}();
% else:
- let inherited_struct =
self.inherited_style_ignoring_first_line.get_${property.style_struct.name_lower}();
% endif
+
self.${property.style_struct.ident}.mutate()
.copy_${property.ident}_from(
inherited_struct,
% if property.logical:
self.writing_mode,
% endif
);
}
/// Reset `${property.ident}` to the initial value.
#[allow(non_snake_case)]
pub fn reset_${property.ident}(&mut self) {
- let reset_struct = self.reset_style.get_${property.style_struct.name_lower}();
- self.${property.style_struct.ident}.mutate()
- .copy_${property.ident}_from(
- reset_struct,
- % if property.logical:
- self.writing_mode,
- % endif
- );
+ let reset_struct =
+ self.reset_style.get_${property.style_struct.name_lower}();
+ % if property.ident == "justify_items":
+ // TODO(emilio): Generalise this!
+ self.${property.style_struct.ident}.mutate()
+ .reset_${property.ident}(reset_struct)
+ % else:
+ self.${property.style_struct.ident}.mutate()
+ .copy_${property.ident}_from(
+ reset_struct,
+ % if property.logical:
+ self.writing_mode,
+ % endif
+ );
+ % endif
}
% if not property.is_vector:
/// Set the `${property.ident}` to the computed value `value`.
#[allow(non_snake_case)]
pub fn set_${property.ident}(
&mut self,
value: longhands::${property.ident}::computed_value::T
--- a/servo/components/style/style_adjuster.rs
+++ b/servo/components/style/style_adjuster.rs
@@ -449,16 +449,46 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
self.style.inherited_flags().contains(IS_RELEVANT_LINK_VISITED)
};
if relevant_link_visited {
self.style.flags.insert(IS_RELEVANT_LINK_VISITED);
}
}
+ /// Resolves "justify-items: auto" based on the inherited style if needed to
+ /// comply with:
+ ///
+ /// https://drafts.csswg.org/css-align/#valdef-justify-items-legacy
+ ///
+ /// (Note that "auto" is being renamed to "legacy")
+ #[cfg(feature = "gecko")]
+ fn adjust_for_justify_items(&mut self) {
+ use values::specified::align;
+ let justify_items = self.style.get_position().clone_justify_items();
+ if justify_items.specified.0 != align::ALIGN_AUTO {
+ return;
+ }
+
+ let parent_justify_items =
+ self.style.get_parent_position().clone_justify_items();
+
+ if !parent_justify_items.computed.0.contains(align::ALIGN_LEGACY) {
+ return;
+ }
+
+ if parent_justify_items.computed == justify_items.computed {
+ return;
+ }
+
+ self.style
+ .mutate_position()
+ .set_computed_justify_items(parent_justify_items.computed);
+ }
+
/// Adjusts the style to account for various fixups that don't fit naturally
/// into the cascade.
///
/// When comparing to Gecko, this is similar to the work done by
/// `nsStyleContext::ApplyStyleFixups`, plus some parts of
/// `nsStyleSet::GetContext`.
pub fn adjust(&mut self,
layout_parent_style: &ComputedValues,
@@ -478,16 +508,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
self.adjust_for_table_text_align();
self.adjust_for_contain();
self.adjust_for_mathvariant();
}
#[cfg(feature = "servo")]
{
self.adjust_for_alignment(layout_parent_style);
}
+ self.adjust_for_justify_items();
self.adjust_for_border_width();
self.adjust_for_outline();
self.adjust_for_writing_mode(layout_parent_style);
self.adjust_for_text_decoration_lines(layout_parent_style);
#[cfg(feature = "gecko")]
{
self.adjust_for_ruby(layout_parent_style, flags);
}
new file mode 100644
--- /dev/null
+++ b/servo/components/style/values/computed/align.rs
@@ -0,0 +1,76 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//! Values for CSS Box Alignment properties
+//!
+//! https://drafts.csswg.org/css-align/
+
+
+use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
+use values::specified;
+use std::fmt;
+use style_traits::ToCss;
+
+pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf};
+
+/// The computed value for the `justify-items` property.
+///
+/// Need to carry around both the specified and computed value to handle the
+/// special legacy keyword. Sigh.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct JustifyItems {
+ /// The specified value for the property. Can contain `auto`.
+ pub specified: specified::JustifyItems,
+ /// The computed value for the property. Cannot contain `auto`.
+ pub computed: specified::JustifyItems,
+}
+
+impl ToCss for JustifyItems {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+ where W: fmt::Write,
+ {
+ self.computed.to_css(dest)
+ }
+}
+
+impl JustifyItems {
+ /// Returns the `auto` value.
+ pub fn auto() -> Self {
+ Self {
+ specified: specified::JustifyItems::auto(),
+ computed: specified::JustifyItems::normal(),
+ }
+ }
+}
+
+impl ToComputedValue for specified::JustifyItems {
+ type ComputedValue = JustifyItems;
+
+ /// https://drafts.csswg.org/css-align/#valdef-justify-items-legacy
+ fn to_computed_value(&self, _context: &Context) -> JustifyItems {
+ use values::specified::align;
+ let specified = *self;
+ let computed =
+ if self.0 != align::ALIGN_AUTO {
+ *self
+ } else {
+ // If the inherited value of `justify-items` includes the
+ // `legacy` keyword, `auto` computes to the inherited value,
+ // but we assume it computes to `normal`, and handle that
+ // special-case in StyleAdjuster.
+ Self::normal()
+ };
+
+ JustifyItems { specified, computed }
+ }
+
+ #[inline]
+ fn from_computed_value(computed: &JustifyItems) -> Self {
+ computed.specified
+ }
+}
+
+impl ComputedValueAsSpecified for AlignItems {}
+impl ComputedValueAsSpecified for AlignJustifyContent {}
+impl ComputedValueAsSpecified for AlignJustifySelf {}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -20,38 +20,40 @@ use style_traits::ToCss;
use super::{CSSFloat, CSSInteger, RGBA};
use super::generics::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize};
use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
use super::generics::grid::TrackList as GenericTrackList;
use super::specified;
pub use app_units::Au;
pub use properties::animated_properties::TransitionProperty;
+#[cfg(feature = "gecko")]
+pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use self::background::BackgroundSize;
pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth};
pub use self::border::{BorderRadius, BorderCornerRadius};
pub use self::color::{Color, RGBAColor};
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
#[cfg(feature = "gecko")]
pub use self::gecko::ScrollSnapPoint;
pub use self::rect::LengthOrNumberRect;
pub use super::{Auto, Either, None_};
-#[cfg(feature = "gecko")]
-pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use super::specified::{BorderStyle, UrlOrNone};
pub use super::generics::grid::GridLine;
pub use super::specified::url::SpecifiedUrl;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage};
pub use self::position::Position;
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
pub use self::transform::{TimingFunction, TransformOrigin};
+#[cfg(feature = "gecko")]
+pub mod align;
pub mod background;
pub mod basic_shape;
pub mod border;
pub mod color;
pub mod effects;
pub mod flex;
pub mod image;
#[cfg(feature = "gecko")]
@@ -391,46 +393,16 @@ impl Time {
impl ToCss for Time {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
write!(dest, "{}s", self.seconds())
}
}
-#[cfg(feature = "gecko")]
-impl ToComputedValue for specified::JustifyItems {
- type ComputedValue = JustifyItems;
-
- // https://drafts.csswg.org/css-align/#valdef-justify-items-auto
- fn to_computed_value(&self, context: &Context) -> JustifyItems {
- use values::specified::align;
- // If the inherited value of `justify-items` includes the `legacy` keyword, `auto` computes
- // to the inherited value.
- if self.0 == align::ALIGN_AUTO {
- let inherited = context.builder.get_parent_position().clone_justify_items();
- if inherited.0.contains(align::ALIGN_LEGACY) {
- return inherited
- }
- }
- return *self
- }
-
- #[inline]
- fn from_computed_value(computed: &JustifyItems) -> Self {
- *computed
- }
-}
-
-#[cfg(feature = "gecko")]
-impl ComputedValueAsSpecified for specified::AlignItems {}
-#[cfg(feature = "gecko")]
-impl ComputedValueAsSpecified for specified::AlignJustifyContent {}
-#[cfg(feature = "gecko")]
-impl ComputedValueAsSpecified for specified::AlignJustifySelf {}
impl ComputedValueAsSpecified for specified::BorderStyle {}
/// A `<number>` value.
pub type Number = CSSFloat;
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
--- a/servo/components/style/values/specified/align.rs
+++ b/servo/components/style/values/specified/align.rs
@@ -287,16 +287,22 @@ pub struct JustifyItems(pub AlignFlags);
impl JustifyItems {
/// The initial value 'auto'
#[inline]
pub fn auto() -> Self {
JustifyItems(ALIGN_AUTO)
}
+ /// The value 'normal'
+ #[inline]
+ pub fn normal() -> Self {
+ JustifyItems(ALIGN_NORMAL)
+ }
+
/// Whether this value has extra flags.
#[inline]
pub fn has_extra_flags(self) -> bool {
self.0.intersects(ALIGN_FLAG_BITS)
}
}
no_viewport_percentage!(JustifyItems);