diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-02-24 08:31:08 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-24 08:31:08 -0500 |
commit | 427003210b3e16a82f958e35ff4212f26ffa35ab (patch) | |
tree | 6ef77f85109aabd13d8764466875f9e51f860b56 | |
parent | f18d64ce582d591abb0fa1808b6c75b33b1d5c33 (diff) | |
parent | 3a1539ccde2b3d30bfea84a620683f988cb9e577 (diff) | |
download | servo-427003210b3e16a82f958e35ff4212f26ffa35ab.tar.gz servo-427003210b3e16a82f958e35ff4212f26ffa35ab.zip |
Auto merge of #22930 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central.
See individual commits for details.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22930)
<!-- Reviewable:end -->
72 files changed, 845 insertions, 1174 deletions
diff --git a/components/layout/display_list/background.rs b/components/layout/display_list/background.rs index 368818471d5..c6fa1691e46 100644 --- a/components/layout/display_list/background.rs +++ b/components/layout/display_list/background.rs @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -// FIXME(rust-lang/rust#26264): Remove GenericBackgroundSize. - use crate::display_list::border; use app_units::Au; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; @@ -12,7 +10,6 @@ use style::computed_values::background_clip::single_value::T as BackgroundClip; use style::computed_values::background_origin::single_value::T as BackgroundOrigin; use style::properties::style_structs::Background; use style::values::computed::{BackgroundSize, NonNegativeLengthPercentageOrAuto}; -use style::values::generics::background::BackgroundSize as GenericBackgroundSize; use style::values::specified::background::BackgroundRepeatKeyword; use webrender_api::BorderRadius; @@ -56,8 +53,8 @@ fn compute_background_image_size( ) -> Size2D<Au> { match intrinsic_size { None => match bg_size { - GenericBackgroundSize::Cover | GenericBackgroundSize::Contain => bounds_size, - GenericBackgroundSize::Explicit { width, height } => Size2D::new( + BackgroundSize::Cover | BackgroundSize::Contain => bounds_size, + BackgroundSize::ExplicitSize { width, height } => Size2D::new( width .to_used_value(bounds_size.width) .unwrap_or(bounds_size.width), @@ -73,20 +70,16 @@ fn compute_background_image_size( let bounds_aspect_ratio = bounds_size.width.to_f32_px() / bounds_size.height.to_f32_px(); match (bg_size, image_aspect_ratio < bounds_aspect_ratio) { - (GenericBackgroundSize::Contain, false) | (GenericBackgroundSize::Cover, true) => { - Size2D::new( - bounds_size.width, - bounds_size.width.scale_by(image_aspect_ratio.recip()), - ) - }, - (GenericBackgroundSize::Contain, true) | (GenericBackgroundSize::Cover, false) => { - Size2D::new( - bounds_size.height.scale_by(image_aspect_ratio), - bounds_size.height, - ) - }, + (BackgroundSize::Contain, false) | (BackgroundSize::Cover, true) => Size2D::new( + bounds_size.width, + bounds_size.width.scale_by(image_aspect_ratio.recip()), + ), + (BackgroundSize::Contain, true) | (BackgroundSize::Cover, false) => Size2D::new( + bounds_size.height.scale_by(image_aspect_ratio), + bounds_size.height, + ), ( - GenericBackgroundSize::Explicit { + BackgroundSize::ExplicitSize { width, height: NonNegativeLengthPercentageOrAuto::Auto, }, @@ -98,7 +91,7 @@ fn compute_background_image_size( Size2D::new(width, width.scale_by(image_aspect_ratio.recip())) }, ( - GenericBackgroundSize::Explicit { + BackgroundSize::ExplicitSize { width: NonNegativeLengthPercentageOrAuto::Auto, height, }, @@ -109,7 +102,7 @@ fn compute_background_image_size( .unwrap_or(own_size.height); Size2D::new(height.scale_by(image_aspect_ratio), height) }, - (GenericBackgroundSize::Explicit { width, height }, _) => Size2D::new( + (BackgroundSize::ExplicitSize { width, height }, _) => Size2D::new( width .to_used_value(bounds_size.width) .unwrap_or(own_size.width), diff --git a/components/layout/display_list/border.rs b/components/layout/display_list/border.rs index d5909abee84..dcbef4473fe 100644 --- a/components/layout/display_list/border.rs +++ b/components/layout/display_list/border.rs @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -// FIXME(rust-lang/rust#26264): Remove GenericBorderImageSideWidth. - use crate::display_list::ToLayout; use app_units::Au; use euclid::{Rect, SideOffsets2D, Size2D}; @@ -11,11 +9,9 @@ use style::computed_values::border_image_outset::T as BorderImageOutset; use style::properties::style_structs::Border; use style::values::computed::NumberOrPercentage; use style::values::computed::{BorderCornerRadius, BorderImageWidth}; -use style::values::computed::{BorderImageSideWidth, LengthOrNumber}; -use style::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; +use style::values::computed::{BorderImageSideWidth, NonNegativeLengthOrNumber}; use style::values::generics::rect::Rect as StyleRect; use style::values::generics::NonNegative; -use style::values::Either; use webrender_api::{BorderRadius, BorderSide, BorderStyle, ColorF}; use webrender_api::{LayoutSideOffsets, LayoutSize, NormalBorder}; @@ -140,10 +136,10 @@ pub fn simple(color: ColorF, style: BorderStyle) -> NormalBorder { } } -fn side_image_outset(outset: LengthOrNumber, border_width: Au) -> Au { +fn side_image_outset(outset: NonNegativeLengthOrNumber, border_width: Au) -> Au { match outset { - Either::First(length) => length.into(), - Either::Second(factor) => border_width.scale_by(factor), + NonNegativeLengthOrNumber::Length(length) => length.into(), + NonNegativeLengthOrNumber::Number(factor) => border_width.scale_by(factor.0), } } @@ -163,9 +159,9 @@ fn side_image_width( total_length: Au, ) -> f32 { match border_image_width { - GenericBorderImageSideWidth::Length(v) => v.to_used_value(total_length).to_f32_px(), - GenericBorderImageSideWidth::Number(x) => border_width * x.0, - GenericBorderImageSideWidth::Auto => border_width, + BorderImageSideWidth::Length(v) => v.to_used_value(total_length).to_f32_px(), + BorderImageSideWidth::Number(x) => border_width * x.0, + BorderImageSideWidth::Auto => border_width, } } diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 6de5ac8498c..d26cd6b9c32 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -763,7 +763,7 @@ impl Fragment { let background_size = get_cyclic(&style.get_background().background_size.0, i).clone(); let size = match background_size { - BackgroundSize::Explicit { width, height } => Size2D::new( + BackgroundSize::ExplicitSize { width, height } => Size2D::new( width .to_used_value(bounding_box_size.width) .unwrap_or(bounding_box_size.width), diff --git a/components/layout/flex.rs b/components/layout/flex.rs index f761bc95dff..82dd9533175 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -30,7 +30,6 @@ use style::properties::ComputedValues; use style::servo::restyle_damage::ServoRestyleDamage; use style::values::computed::flex::FlexBasis; use style::values::computed::{MaxSize, Size}; -use style::values::generics::flex::FlexBasis as GenericFlexBasis; /// The size of an axis. May be a specified size, a min/max /// constraint, or an unlimited size @@ -61,8 +60,8 @@ impl AxisSize { /// is definite after flex size resolving. fn from_flex_basis(flex_basis: FlexBasis, main_length: Size, containing_length: Au) -> MaybeAuto { let width = match flex_basis { - GenericFlexBasis::Content => return MaybeAuto::Auto, - GenericFlexBasis::Width(width) => width, + FlexBasis::Content => return MaybeAuto::Auto, + FlexBasis::Size(width) => width, }; let width = match width { diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 4c0b631d31d..0b8719c4dbf 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -57,6 +57,7 @@ include = [ "CursorKind", "Display", "DisplayMode", + "PrefersColorScheme", "ExtremumLength", "FillRule", "FontDisplay", @@ -69,6 +70,7 @@ include = [ "UserSelect", "Float", "OverscrollBehavior", + "ScrollSnapAlign", "ScrollSnapType", "OverflowAnchor", "OverflowClipBox", @@ -77,32 +79,97 @@ include = [ "LengthPercentage", "NonNegativeLengthPercentage", "LengthPercentageOrAuto", + "NonNegativeLengthPercentageOrAuto", "Rect", "IntersectionObserverRootMargin", + "Size", + "MaxSize", + "FlexBasis", + "Position", + "BackgroundSize", + "BorderImageSlice", + "NonNegativeLengthOrNumberRect", + "Perspective", + "ZIndex", + "TransformOrigin", ] item_types = ["enums", "structs", "typedefs"] [export.body] +"CSSPixelLength" = """ + inline nscoord ToAppUnits() const; +""" + "LengthPercentage" = """ // Defined in nsStyleCoord.h static constexpr inline StyleLengthPercentage Zero(); + static inline StyleLengthPercentage FromAppUnits(nscoord); + static inline StyleLengthPercentage FromPixels(CSSCoord); + static inline StyleLengthPercentage FromPercentage(float); + inline CSSCoord LengthInCSSPixels() const; + inline float Percentage() const; inline bool HasPercent() const; inline bool ConvertsToLength() const; inline nscoord ToLength() const; inline bool ConvertsToPercentage() const; + inline bool HasLengthAndPercentage() const; inline float ToPercentage() const; - inline CSSCoord LengthInCSSPixels() const; - inline float Percentage() const; inline CSSCoord ResolveToCSSPixels(CSSCoord aPercentageBasisInCSSPixels) const; template<typename T> inline CSSCoord ResolveToCSSPixelsWith(T aPercentageGetter) const; + template<typename T, typename U> + inline nscoord Resolve(T aPercentageGetter, U aPercentRoundingFunction) const; + template<typename T> + inline nscoord Resolve(nscoord aPercentageBasis, T aPercentRoundingFunction) const; + template<typename T> inline nscoord Resolve(T aPercentageGetter) const; inline nscoord Resolve(nscoord aPercentageBasis) const; - template<typename T> inline nscoord ResolveWith(T aPercentageGetter) const; """ "GenericLengthPercentageOrAuto" = """ inline const StyleLengthPercentage& AsLengthPercentage() const; + inline bool ConvertsToLength() const; + inline nscoord ToLength() const; + inline bool ConvertsToPercentage() const; + inline float ToPercentage() const; inline bool HasPercent() const; + inline bool HasLengthAndPercentage() const; +""" + +"GenericSize" = """ + inline const StyleLengthPercentage& AsLengthPercentage() const; + inline StyleExtremumLength AsExtremumLength() const; inline bool ConvertsToLength() const; + inline nscoord ToLength() const; + inline bool ConvertsToPercentage() const; + inline float ToPercentage() const; + inline bool HasPercent() const; + inline bool HasLengthAndPercentage() const; + inline bool BehavesLikeInitialValueOnBlockAxis() const; +""" + +"GenericFlexBasis" = """ + inline bool IsAuto() const; + inline const StyleSize& AsSize() const; +""" + +"GenericMaxSize" = """ + inline const StyleLengthPercentage& AsLengthPercentage() const; + inline StyleExtremumLength AsExtremumLength() const; + inline bool ConvertsToLength() const; + inline nscoord ToLength() const; + inline bool ConvertsToPercentage() const; + inline float ToPercentage() const; + inline bool HasPercent() const; + inline bool HasLengthAndPercentage() const; + inline bool BehavesLikeInitialValueOnBlockAxis() const; +""" + +"GenericPosition" = """ + inline bool DependsOnPositioningAreaSize() const; + static inline StyleGenericPosition FromPercentage(float); +""" + +"GenericBackgroundSize" = """ + bool IsInitialValue() const; """ "Rect" = """ diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index ccaa16c844c..2a2ae268395 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -23,13 +23,10 @@ use crate::values::computed::url::ComputedImageUrl; use crate::values::computed::{Angle, Gradient, Image}; use crate::values::computed::{Integer, LengthPercentage}; use crate::values::computed::{Length, Percentage, TextAlign}; -use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentageOrAuto}; use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; -use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto; use crate::values::generics::rect::Rect; -use crate::values::generics::NonNegative; use app_units::Au; use std::f32::consts::PI; use style_traits::values::specified::AllowedNumericType; @@ -62,42 +59,6 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage { ) } } - -impl NonNegativeLengthPercentageOrAuto { - /// Convert this value in an appropriate `nsStyleCoord::CalcValue`. - pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> { - match *self { - GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)), - GenericLengthPercentageOrAuto::Auto => None, - } - } -} - -impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto { - fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto { - GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other)) - } -} - -// FIXME(emilio): A lot of these impl From should probably become explicit or -// disappear as we move more stuff to cbindgen. -impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto { - fn from(other: nsStyleCoord_CalcValue) -> Self { - GenericLengthPercentageOrAuto::LengthPercentage(NonNegative( - LengthPercentage::with_clamping_mode( - Au(other.mLength).into(), - if other.mHasPercent { - Some(Percentage(other.mPercent)) - } else { - None - }, - AllowedNumericType::NonNegative, - /* was_calc = */ true, - ), - )) - } -} - impl From<Angle> for CoordDataValue { fn from(reference: Angle) -> Self { CoordDataValue::Degree(reference.degrees()) @@ -614,7 +575,6 @@ pub mod basic_shape { //! Conversions from and to CSS shape representations. use crate::gecko::values::GeckoStyleCoordConvertible; - use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCorners}; use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType}; use crate::gecko_bindings::structs::{ @@ -628,7 +588,6 @@ pub mod basic_shape { use crate::values::computed::border::{BorderCornerRadius, BorderRadius}; use crate::values::computed::length::LengthPercentage; use crate::values::computed::motion::OffsetPath; - use crate::values::computed::position; use crate::values::computed::url::ComputedUrl; use crate::values::generics::basic_shape::{ BasicShape as GenericBasicShape, InsetRect, Polygon, @@ -759,12 +718,12 @@ pub mod basic_shape { }, StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle { radius: (&other.mCoordinates[0]).into(), - position: (&other.mPosition).into(), + position: other.mPosition, }), StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse { semiaxis_x: (&other.mCoordinates[0]).into(), semiaxis_y: (&other.mCoordinates[1]).into(), - position: (&other.mPosition).into(), + position: other.mPosition, }), StyleBasicShapeType::Polygon => { let mut coords = Vec::with_capacity(other.mCoordinates.len() / 2); @@ -852,17 +811,6 @@ pub mod basic_shape { } } - // Can't be a From impl since we need to set an existing - // Position, not create a new one - impl From<position::Position> for structs::Position { - fn from(other: position::Position) -> Self { - structs::Position { - mXPosition: other.horizontal.into(), - mYPosition: other.vertical.into(), - } - } - } - impl<'a> From<&'a nsStyleCoord> for ShapeRadius { fn from(other: &'a nsStyleCoord) -> Self { let other = other.borrow(); @@ -871,15 +819,6 @@ pub mod basic_shape { } } - impl<'a> From<&'a structs::Position> for position::Position { - fn from(other: &'a structs::Position) -> Self { - position::Position { - horizontal: other.mXPosition.into(), - vertical: other.mYPosition.into(), - } - } - } - impl From<ShapeBox> for StyleGeometryBox { fn from(reference: ShapeBox) -> Self { use crate::gecko_bindings::structs::StyleGeometryBox::*; diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index b6596c75de8..2547f2a45d4 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -280,6 +280,16 @@ enum PrefersReducedMotion { Reduce, } +/// Values for the prefers-color-scheme media feature. +#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)] +#[repr(u8)] +#[allow(missing_docs)] +pub enum PrefersColorScheme { + Light, + Dark, + NoPreference, +} + /// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReducedMotion>) -> bool { let prefers_reduced = @@ -348,6 +358,16 @@ fn eval_overflow_inline(device: &Device, query_value: Option<OverflowInline>) -> } } +/// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme +fn eval_prefers_color_scheme(device: &Device, query_value: Option<PrefersColorScheme>) -> bool { + let prefers_color_scheme = + unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(device.document()) }; + match query_value { + Some(v) => prefers_color_scheme == v, + None => prefers_color_scheme != PrefersColorScheme::NoPreference, + } +} + /// https://drafts.csswg.org/mediaqueries-4/#mf-interaction bitflags! { struct PointerCapabilities: u8 { @@ -441,7 +461,7 @@ fn eval_moz_is_glyph( query_value: Option<bool>, _: Option<RangeOrOperator>, ) -> bool { - let is_glyph = unsafe { (*device.document()).mIsSVGGlyphsDocument() }; + let is_glyph = device.document().mIsSVGGlyphsDocument(); query_value.map_or(is_glyph, |v| v == is_glyph) } @@ -526,7 +546,7 @@ lazy_static! { /// to support new types in these entries and (2) ensuring that either /// nsPresContext::MediaFeatureValuesChanged is called when the value that /// would be returned by the evaluator function could change. - pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 52] = [ + pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 53] = [ feature!( atom!("width"), AllowsRanges::Yes, @@ -658,6 +678,12 @@ lazy_static! { ParsingRequirements::empty(), ), feature!( + atom!("prefers-color-scheme"), + AllowsRanges::No, + keyword_evaluator!(eval_prefers_color_scheme, PrefersColorScheme), + ParsingRequirements::empty(), + ), + feature!( atom!("pointer"), AllowsRanges::No, keyword_evaluator!(eval_pointer, Pointer), diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 851422467ce..8fa2258eaaf 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -85,7 +85,9 @@ impl Device { assert!(!pres_context.is_null()); Device { pres_context, - default_values: ComputedValues::default_values(unsafe { &*pres_context }), + default_values: ComputedValues::default_values(unsafe { + &*(*pres_context).mDocument.mRawPtr + }), // FIXME(bz): Seems dubious? root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize), body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize), @@ -162,13 +164,13 @@ impl Device { /// Gets the document pointer. #[inline] - pub fn document(&self) -> *mut structs::Document { - self.pres_context().mDocument.mRawPtr + pub fn document(&self) -> &structs::Document { + unsafe { &*self.pres_context().mDocument.mRawPtr } } /// Recreates the default computed values. pub fn reset_computed_values(&mut self) { - self.default_values = ComputedValues::default_values(self.pres_context()); + self.default_values = ComputedValues::default_values(self.document()); } /// Rebuild all the cached data. diff --git a/components/style/gecko/pseudo_element.rs b/components/style/gecko/pseudo_element.rs index ae314ee3d6d..8160ea2c9b8 100644 --- a/components/style/gecko/pseudo_element.rs +++ b/components/style/gecko/pseudo_element.rs @@ -8,7 +8,7 @@ //! `pseudo_element_definition.mako.rs`. If you touch that file, you probably //! need to update the checked-in files for Servo. -use crate::gecko_bindings::structs::{self, CSSPseudoElementType}; +use crate::gecko_bindings::structs::{self, PseudoStyleType}; use crate::properties::longhands::display::computed_value::T as Display; use crate::properties::{ComputedValues, PropertyFlags}; use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl}; diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index 613bbd281ee..be156b54a14 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -48,17 +48,6 @@ PseudoElement::${pseudo.capitalized_pseudo()}${"({})".format(tree_arg) if pseudo </%def> impl PseudoElement { - /// Get the pseudo-element as an atom. - #[inline] - fn atom(&self) -> Atom { - match *self { - % for pseudo in PSEUDOS: - ${pseudo_element_variant(pseudo)} => atom!("${pseudo.value}"), - % endfor - PseudoElement::UnknownWebkit(..) => unreachable!(), - } - } - /// Returns an index of the pseudo-element. #[inline] pub fn index(&self) -> usize { @@ -138,45 +127,36 @@ impl PseudoElement { } } - /// Construct a pseudo-element from a `CSSPseudoElementType`. + /// Construct a pseudo-element from a `PseudoStyleType`. #[inline] - pub fn from_pseudo_type(type_: CSSPseudoElementType) -> Option<Self> { + pub fn from_pseudo_type(type_: PseudoStyleType) -> Option<Self> { match type_ { % for pseudo in PSEUDOS: - % if not pseudo.is_anon_box(): - CSSPseudoElementType::${pseudo.pseudo_ident} => { - Some(${pseudo_element_variant(pseudo)}) - }, - % endif + % if not pseudo.is_tree_pseudo_element(): + PseudoStyleType::${pseudo.pseudo_ident} => { + Some(${pseudo_element_variant(pseudo)}) + }, + % endif % endfor _ => None, } } - /// Construct a `CSSPseudoElementType` from a pseudo-element + /// Construct a `PseudoStyleType` from a pseudo-element #[inline] - fn pseudo_type(&self) -> CSSPseudoElementType { + pub fn pseudo_type(&self) -> PseudoStyleType { match *self { % for pseudo in PSEUDOS: - % if not pseudo.is_anon_box(): - PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::${pseudo.pseudo_ident}, - % elif pseudo.is_tree_pseudo_element(): - PseudoElement::${pseudo.capitalized_pseudo()}(..) => CSSPseudoElementType::XULTree, - % elif pseudo.is_inheriting_anon_box(): - PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::InheritingAnonBox, - % else: - PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox, - % endif + % if pseudo.is_tree_pseudo_element(): + PseudoElement::${pseudo.capitalized_pseudo()}(..) => PseudoStyleType::XULTree, + % else: + PseudoElement::${pseudo.capitalized_pseudo()} => PseudoStyleType::${pseudo.pseudo_ident}, + % endif % endfor PseudoElement::UnknownWebkit(..) => unreachable!(), } } - /// Get a PseudoInfo for a pseudo - pub fn pseudo_info(&self) -> (*mut structs::nsAtom, CSSPseudoElementType) { - (self.atom().as_ptr(), self.pseudo_type()) - } - /// Get the argument list of a tree pseudo-element. #[inline] pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> { @@ -188,45 +168,15 @@ impl PseudoElement { } } - /// Construct a pseudo-element from an `Atom`. - #[inline] - pub fn from_atom(atom: &Atom) -> Option<Self> { - % for pseudo in PSEUDOS: - % if pseudo.is_tree_pseudo_element(): - // We cannot generate ${pseudo_element_variant(pseudo)} from just an atom. - % else: - if atom == &atom!("${pseudo.value}") { - return Some(${pseudo_element_variant(pseudo)}); - } - % endif - % endfor - None - } - - /// Construct a pseudo-element from an anonymous box `Atom`. - #[inline] - pub fn from_anon_box_atom(atom: &Atom) -> Option<Self> { - % for pseudo in PSEUDOS: - % if pseudo.is_tree_pseudo_element(): - // We cannot generate ${pseudo_element_variant(pseudo)} from just an atom. - % elif pseudo.is_anon_box(): - if atom == &atom!("${pseudo.value}") { - return Some(${pseudo_element_variant(pseudo)}); - } - % endif - % endfor - None - } - /// Construct a tree pseudo-element from atom and args. #[inline] pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> { % for pseudo in PSEUDOS: - % if pseudo.is_tree_pseudo_element(): - if atom == &atom!("${pseudo.value}") { - return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into())); - } - % endif + % if pseudo.is_tree_pseudo_element(): + if atom == &atom!("${pseudo.value}") { + return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into())); + } + % endif % endfor None } diff --git a/components/style/gecko/regen_atoms.py b/components/style/gecko/regen_atoms.py index b6f68fceb7d..0066d06d054 100755 --- a/components/style/gecko/regen_atoms.py +++ b/components/style/gecko/regen_atoms.py @@ -41,8 +41,10 @@ class Atom: # The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox", # or "InheritingAnonBox". self.atom_type = atom_type - if self.is_pseudo() or self.is_anon_box(): + + if self.is_pseudo_element() or self.is_anon_box() or self.is_tree_pseudo_element(): self.pseudo_ident = (ident.split("_", 1))[1] + if self.is_anon_box(): assert self.is_inheriting_anon_box() or self.is_non_inheriting_anon_box() @@ -52,16 +54,21 @@ class Atom: def capitalized_pseudo(self): return self.pseudo_ident[0].upper() + self.pseudo_ident[1:] - def is_pseudo(self): + def is_pseudo_element(self): return self.atom_type == "PseudoElementAtom" def is_anon_box(self): + if self.is_tree_pseudo_element(): + return False return self.is_non_inheriting_anon_box() or self.is_inheriting_anon_box() def is_non_inheriting_anon_box(self): + assert not self.is_tree_pseudo_element() return self.atom_type == "NonInheritingAnonBoxAtom" def is_inheriting_anon_box(self): + if self.is_tree_pseudo_element(): + return False return self.atom_type == "InheritingAnonBoxAtom" def is_tree_pseudo_element(self): diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 33706f70537..fa1c7d1f6d3 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -7,22 +7,16 @@ //! Different kind of helpers to interact with Gecko values. use crate::counter_style::{Symbol, Symbols}; -use crate::gecko_bindings::structs::{self, nsStyleCoord, CounterStylePtr}; +use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr}; use crate::gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius}; use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; -use crate::media_queries::Device; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; -use crate::values::computed::FlexBasis as ComputedFlexBasis; -use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage}; -use crate::values::computed::{MaxSize as ComputedMaxSize, Size as ComputedSize}; -use crate::values::computed::{NonNegativeLengthPercentage, Percentage}; -use crate::values::computed::{Number, NumberOrPercentage}; +use crate::values::computed::{Angle, Length, LengthPercentage}; +use crate::values::computed::{Number, NumberOrPercentage, Percentage}; use crate::values::generics::basic_shape::ShapeRadius; -use crate::values::generics::box_::Perspective; -use crate::values::generics::flex::FlexBasis; use crate::values::generics::gecko::ScrollSnapPoint; use crate::values::generics::grid::{TrackBreadth, TrackKeyword}; -use crate::values::generics::length::{LengthPercentageOrAuto, MaxSize, Size}; +use crate::values::generics::length::LengthPercentageOrAuto; use crate::values::generics::{CounterStyleOrNone, NonNegative}; use crate::values::{Auto, Either, None_, Normal}; use crate::Atom; @@ -80,29 +74,6 @@ where } } -impl GeckoStyleCoordConvertible for ComputedFlexBasis { - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - match *self { - FlexBasis::Content => coord.set_value(CoordDataValue::Enumerated( - structs::NS_STYLE_FLEX_BASIS_CONTENT, - )), - FlexBasis::Width(ref w) => w.to_gecko_style_coord(coord), - } - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - if let Some(width) = ComputedSize::from_gecko_style_coord(coord) { - return Some(FlexBasis::Width(width)); - } - - if let CoordDataValue::Enumerated(structs::NS_STYLE_FLEX_BASIS_CONTENT) = coord.as_value() { - return Some(FlexBasis::Content); - } - - None - } -} - impl GeckoStyleCoordConvertible for Number { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { coord.set_value(CoordDataValue::Factor(*self)); @@ -336,60 +307,6 @@ impl GeckoStyleCoordConvertible for Normal { } } -impl GeckoStyleCoordConvertible for ExtremumLength { - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - coord.set_value(CoordDataValue::Enumerated(*self as u32)); - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - use num_traits::FromPrimitive; - match coord.as_value() { - CoordDataValue::Enumerated(v) => ExtremumLength::from_u32(v), - _ => None, - } - } -} - -impl GeckoStyleCoordConvertible for ComputedSize { - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - match *self { - Size::LengthPercentage(ref lpoa) => lpoa.to_gecko_style_coord(coord), - Size::Auto => coord.set_value(CoordDataValue::Auto), - Size::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), - } - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - if let CoordDataValue::Auto = coord.as_value() { - return Some(Size::Auto); - } - if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { - return Some(Size::LengthPercentage(lp)); - } - ExtremumLength::from_gecko_style_coord(coord).map(Size::ExtremumLength) - } -} - -impl GeckoStyleCoordConvertible for ComputedMaxSize { - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - match *self { - MaxSize::LengthPercentage(ref lpon) => lpon.to_gecko_style_coord(coord), - MaxSize::None => coord.set_value(CoordDataValue::None), - MaxSize::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), - } - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - if let CoordDataValue::None = coord.as_value() { - return Some(MaxSize::None); - } - if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { - return Some(MaxSize::LengthPercentage(lp)); - } - ExtremumLength::from_gecko_style_coord(coord).map(MaxSize::ExtremumLength) - } -} - impl GeckoStyleCoordConvertible for ScrollSnapPoint<LengthPercentage> { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match self.repeated() { @@ -412,27 +329,6 @@ impl GeckoStyleCoordConvertible for ScrollSnapPoint<LengthPercentage> { } } -impl<L> GeckoStyleCoordConvertible for Perspective<L> -where - L: GeckoStyleCoordConvertible, -{ - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - match *self { - Perspective::None => coord.set_value(CoordDataValue::None), - Perspective::Length(ref l) => l.to_gecko_style_coord(coord), - }; - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - use crate::gecko_bindings::structs::root::nsStyleUnit; - - if coord.unit() == nsStyleUnit::eStyleUnit_None { - return Some(Perspective::None); - } - Some(Perspective::Length(L::from_gecko_style_coord(coord)?)) - } -} - /// Convert a given RGBA value to `nscolor`. pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 { ((rgba.alpha as u32) << 24) | @@ -468,16 +364,15 @@ pub fn round_border_to_device_pixels(width: Au, au_per_device_px: Au) -> Au { impl CounterStyleOrNone { /// Convert this counter style to a Gecko CounterStylePtr. - pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr, device: &Device) { + pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr) { use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name; use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols; - let pres_context = device.pres_context(); match self { CounterStyleOrNone::None => unsafe { - set_name(gecko_value, atom!("none").into_addrefed(), pres_context); + set_name(gecko_value, atom!("none").into_addrefed()); }, CounterStyleOrNone::Name(name) => unsafe { - set_name(gecko_value, name.0.into_addrefed(), pres_context); + set_name(gecko_value, name.0.into_addrefed()); }, CounterStyleOrNone::Symbols(symbols_type, symbols) => { let symbols: Vec<_> = symbols diff --git a/components/style/gecko_bindings/sugar/style_complex_color.rs b/components/style/gecko_bindings/sugar/style_complex_color.rs index 4d31459a628..aec334969d4 100644 --- a/components/style/gecko_bindings/sugar/style_complex_color.rs +++ b/components/style/gecko_bindings/sugar/style_complex_color.rs @@ -7,10 +7,10 @@ use crate::gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor}; use crate::gecko_bindings::structs::StyleComplexColor; use crate::gecko_bindings::structs::StyleComplexColor_Tag as Tag; -use crate::values::computed::ui::ColorOrAuto; -use crate::values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA}; -use crate::values::generics::color::{Color as GenericColor, ComplexColorRatios}; -use crate::values::{Auto, Either}; +use crate::values::computed::{Color as ComputedColor, ColorOrAuto, RGBAColor as ComputedRGBA}; +use crate::values::generics::color::{ + Color as GenericColor, ColorOrAuto as GenericColorOrAuto, ComplexColorRatios, +}; impl StyleComplexColor { /// Create a `StyleComplexColor` value that represents `currentColor`. @@ -94,8 +94,8 @@ impl From<StyleComplexColor> for ComputedColor { impl From<ColorOrAuto> for StyleComplexColor { fn from(other: ColorOrAuto) -> Self { match other { - Either::First(color) => color.into(), - Either::Second(_) => StyleComplexColor::auto(), + GenericColorOrAuto::Color(color) => color.into(), + GenericColorOrAuto::Auto => StyleComplexColor::auto(), } } } @@ -103,9 +103,9 @@ impl From<ColorOrAuto> for StyleComplexColor { impl From<StyleComplexColor> for ColorOrAuto { fn from(other: StyleComplexColor) -> Self { if other.mTag != Tag::eAuto { - Either::First(other.into()) + GenericColorOrAuto::Color(other.into()) } else { - Either::Second(Auto) + GenericColorOrAuto::Auto } } } diff --git a/components/style/properties/cascade.rs b/components/style/properties/cascade.rs index d881524deb5..4a0e07fdcac 100644 --- a/components/style/properties/cascade.rs +++ b/components/style/properties/cascade.rs @@ -236,7 +236,7 @@ where parent_style.unwrap(), parent_style_ignoring_first_line.unwrap() ) || - parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine) + parent_style.unwrap().is_first_line_style() ); let inherited_style = parent_style.unwrap_or(device.default_computed_values()); @@ -745,13 +745,13 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> { // FIXME(emilio): Why both setting the generic and passing it // down? - let pres_context = self.context.builder.device.pres_context(); + let doc = self.context.builder.device.document(); let gecko_font = self.context.builder.mutate_font().gecko_mut(); gecko_font.mGenericID = generic; unsafe { crate::gecko_bindings::bindings::Gecko_nsStyleFont_PrefillDefaultForGeneric( gecko_font, - pres_context, + doc, generic, ); } diff --git a/components/style/properties/data.py b/components/style/properties/data.py index b897cc140d2..f3b4e43c225 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -339,6 +339,7 @@ class Longhand(object): "Resize", "SVGOpacity", "SVGPaintOrder", + "ScrollSnapAlign", "ScrollSnapType", "TextAlign", "TextDecorationLine", diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 6baae1d9063..b1be315e7a0 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -35,10 +35,9 @@ use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone; use crate::gecko_bindings::bindings::Gecko_SetListStyleImageImageValue; use crate::gecko_bindings::bindings::Gecko_SetNullImageValue; use crate::gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom}; -use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsCSSPropertyID; -use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType; +use crate::gecko_bindings::structs::mozilla::PseudoStyleType; use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use crate::gecko_bindings::sugar::refptr::RefPtr; use crate::gecko::values::convert_nscolor_to_rgba; @@ -61,8 +60,6 @@ use crate::values::computed::BorderStyle; use crate::values::computed::font::FontSize; use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow}; use crate::values::generics::column::ColumnCount; -use crate::values::generics::position::ZIndex; -use crate::values::generics::text::MozTabSize; use crate::values::generics::transform::TransformStyle; use crate::values::generics::url::UrlOrNone; @@ -102,7 +99,7 @@ impl ComputedValues { ).to_outer(pseudo) } - pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> { + pub fn default_values(doc: &structs::Document) -> Arc<Self> { ComputedValuesInner::new( /* custom_properties = */ None, /* writing_mode = */ WritingMode::empty(), // FIXME(bz): This seems dubious @@ -110,31 +107,22 @@ impl ComputedValues { /* rules = */ None, /* visited_style = */ None, % for style_struct in data.style_structs: - style_structs::${style_struct.name}::default(pres_context), + style_structs::${style_struct.name}::default(doc), % endfor ).to_outer(None) } + #[inline] pub fn pseudo(&self) -> Option<PseudoElement> { - let atom = (self.0).mPseudoTag.mRawPtr; - if atom.is_null() { + if self.0.mPseudoType == PseudoStyleType::NotPseudo { return None; } - - let atom = unsafe { Atom::from_raw(atom) }; - PseudoElement::from_atom(&atom) + PseudoElement::from_pseudo_type(self.0.mPseudoType) } #[inline] - fn get_pseudo_type(&self) -> CSSPseudoElementType { - self.0.mPseudoType - } - - #[inline] - pub fn is_anon_box(&self) -> bool { - let our_type = self.get_pseudo_type(); - return our_type == CSSPseudoElementType::InheritingAnonBox || - our_type == CSSPseudoElementType::NonInheritingAnonBox; + pub fn is_first_line_style(&self) -> bool { + self.pseudo() == Some(PseudoElement::FirstLine) } /// Returns true if the display property is changed from 'none' to others. @@ -213,9 +201,9 @@ impl ComputedValuesInner { self, pseudo: Option<<&PseudoElement>, ) -> Arc<ComputedValues> { - let (pseudo_tag, pseudo_ty) = match pseudo { - Some(p) => p.pseudo_info(), - None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo), + let pseudo_ty = match pseudo { + Some(p) => p.pseudo_type(), + None => structs::PseudoStyleType::NotPseudo, }; let arc = unsafe { let arc: Arc<ComputedValues> = Arc::new(uninitialized()); @@ -223,7 +211,6 @@ impl ComputedValuesInner { &arc.0 as *const _ as *mut _, &self, pseudo_ty, - pseudo_tag ); // We're simulating a move by having C++ do a memcpy and then forgetting // it on this end. @@ -453,22 +440,6 @@ def set_gecko_property(ffi_name, expr): } </%def> -<%def name="impl_position(ident, gecko_ffi_name)"> - #[allow(non_snake_case)] - pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - ${set_gecko_property("%s.mXPosition" % gecko_ffi_name, "v.horizontal.into()")} - ${set_gecko_property("%s.mYPosition" % gecko_ffi_name, "v.vertical.into()")} - } - <%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call> - #[allow(non_snake_case)] - pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - longhands::${ident}::computed_value::T { - horizontal: self.gecko.${gecko_ffi_name}.mXPosition.into(), - vertical: self.gecko.${gecko_ffi_name}.mYPosition.into(), - } - } -</%def> - <%def name="impl_color(ident, gecko_ffi_name)"> <%call expr="impl_color_setter(ident, gecko_ffi_name)"></%call> <%call expr="impl_color_copy(ident, gecko_ffi_name)"></%call> @@ -1217,55 +1188,6 @@ pub fn clone_transform_from_list( } </%def> -<%def name="impl_transform_origin(ident, gecko_ffi_name)"> - #[allow(non_snake_case)] - pub fn set_${ident}(&mut self, v: values::computed::TransformOrigin) { - self.gecko.${gecko_ffi_name}[0].set(v.horizontal); - self.gecko.${gecko_ffi_name}[1].set(v.vertical); - // transform-origin supports the third value for depth, while - // -moz-window-transform-origin doesn't. The following code is - // for handling this difference. If we can have more knowledge - // about the type here, we may want to check that the length is - // exactly either 2 or 3 in compile time. - if let Some(third) = self.gecko.${gecko_ffi_name}.get_mut(2) { - third.set(v.depth); - } - } - - #[allow(non_snake_case)] - pub fn copy_${ident}_from(&mut self, other: &Self) { - self.gecko.${gecko_ffi_name}[0].copy_from(&other.gecko.${gecko_ffi_name}[0]); - self.gecko.${gecko_ffi_name}[1].copy_from(&other.gecko.${gecko_ffi_name}[1]); - if let (Some(self_third), Some(other_third)) = - (self.gecko.${gecko_ffi_name}.get_mut(2), other.gecko.${gecko_ffi_name}.get(2)) - { - self_third.copy_from(other_third) - } - } - - #[allow(non_snake_case)] - pub fn reset_${ident}(&mut self, other: &Self) { - self.copy_${ident}_from(other) - } - - #[allow(non_snake_case)] - pub fn clone_${ident}(&self) -> values::computed::TransformOrigin { - use crate::values::computed::{Length, LengthPercentage, TransformOrigin}; - TransformOrigin { - horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[0]) - .expect("clone for LengthPercentage failed"), - vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[1]) - .expect("clone for LengthPercentage failed"), - depth: if let Some(third) = self.gecko.${gecko_ffi_name}.get(2) { - Length::from_gecko_style_coord(third) - .expect("clone for Length failed") - } else { - Length::new(0.) - }, - } - } -</%def> - <%def name="impl_logical(name, **kwargs)"> ${helpers.logical_setter(name)} </%def> @@ -1273,11 +1195,13 @@ pub fn clone_transform_from_list( <%def name="impl_style_struct(style_struct)"> impl ${style_struct.gecko_struct_name} { #[allow(dead_code, unused_variables)] - pub fn default(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> { + pub fn default(document: &structs::Document) -> Arc<Self> { let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } }); unsafe { - Gecko_Construct_Default_${style_struct.gecko_ffi_name}(&mut Arc::get_mut(&mut result).unwrap().gecko, - pres_context); + Gecko_Construct_Default_${style_struct.gecko_ffi_name}( + &mut Arc::get_mut(&mut result).unwrap().gecko, + document, + ); } result } @@ -1370,6 +1294,7 @@ impl Clone for ${style_struct.gecko_struct_name} { "Appearance": impl_simple, "OverscrollBehavior": impl_simple, "OverflowClipBox": impl_simple, + "ScrollSnapAlign": impl_simple, "ScrollSnapType": impl_simple, "Float": impl_simple, "Overflow": impl_simple, @@ -1385,32 +1310,36 @@ impl Clone for ${style_struct.gecko_struct_name} { "length::NonNegativeLengthOrAuto": impl_style_coord, "length::NonNegativeLengthPercentageOrNormal": impl_style_coord, "FillRule": impl_simple, - "FlexBasis": impl_style_coord, + "FlexBasis": impl_simple, "Length": impl_absolute_length, "LengthOrNormal": impl_style_coord, "LengthPercentage": impl_simple, "LengthPercentageOrAuto": impl_style_coord, - "MaxSize": impl_style_coord, - "Size": impl_style_coord, + "MaxSize": impl_simple, + "Size": impl_simple, "MozScriptMinSize": impl_absolute_length, "MozScriptSizeMultiplier": impl_simple, "NonNegativeLengthPercentage": impl_simple, + "NonNegativeLengthOrNumber": impl_simple, + "NonNegativeLengthOrNumberRect": impl_simple, + "BorderImageSlice": impl_simple, "NonNegativeNumber": impl_simple, "Number": impl_simple, "Opacity": impl_simple, "OverflowWrap": impl_simple, "OverflowAnchor": impl_simple, - "Perspective": impl_style_coord, - "Position": impl_position, + "Perspective": impl_simple, + "Position": impl_simple, "RGBAColor": impl_rgba_color, "SVGLength": impl_svg_length, "SVGOpacity": impl_svg_opacity, "SVGPaint": impl_svg_paint, "SVGWidth": impl_svg_length, "Transform": impl_transform, - "TransformOrigin": impl_transform_origin, + "TransformOrigin": impl_simple, "UserSelect": impl_simple, "url::UrlOrNone": impl_css_url, + "ZIndex": impl_simple, } def longhand_method(longhand): @@ -1500,8 +1429,8 @@ fn static_assert() { for x in CORNERS]) %> <%self:impl_trait style_struct_name="Border" - skip_longhands="${skip_border_longhands} border-image-source border-image-outset - border-image-repeat border-image-width border-image-slice"> + skip_longhands="${skip_border_longhands} border-image-source + border-image-repeat border-image-width"> % for side in SIDES: pub fn set_border_${side.ident}_style(&mut self, v: BorderStyle) { self.gecko.mBorderStyle[${side.index}] = v; @@ -1602,8 +1531,6 @@ fn static_assert() { } } - <% impl_style_sides("border_image_outset") %> - <% border_image_repeat_keywords = ["Stretch", "Repeat", "Round", "Space"] %> @@ -1645,63 +1572,41 @@ fn static_assert() { } <% impl_style_sides("border_image_width") %> - - pub fn set_border_image_slice(&mut self, v: longhands::border_image_slice::computed_value::T) { - use crate::gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_SLICE_NOFILL, NS_STYLE_BORDER_IMAGE_SLICE_FILL}; - - v.offsets.to_gecko_rect(&mut self.gecko.mBorderImageSlice); - - let fill = if v.fill { - NS_STYLE_BORDER_IMAGE_SLICE_FILL - } else { - NS_STYLE_BORDER_IMAGE_SLICE_NOFILL - }; - self.gecko.mBorderImageFill = fill as u8; - } - - <%self:copy_sides_style_coord ident="border_image_slice"> - self.gecko.mBorderImageFill = other.gecko.mBorderImageFill; - </%self:copy_sides_style_coord> - - pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T { - use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL; - use crate::values::computed::{BorderImageSlice, NonNegativeNumberOrPercentage}; - type NumberOrPercentageRect = crate::values::generics::rect::Rect<NonNegativeNumberOrPercentage>; - - BorderImageSlice { - offsets: - NumberOrPercentageRect::from_gecko_rect(&self.gecko.mBorderImageSlice) - .expect("mBorderImageSlice[${side}] could not convert to NumberOrPercentageRect"), - fill: self.gecko.mBorderImageFill as u32 == NS_STYLE_BORDER_IMAGE_SLICE_FILL - } - } </%self:impl_trait> +<% skip_scroll_margin_longhands = " ".join(["scroll-margin-%s" % x.ident for x in SIDES]) %> <% skip_margin_longhands = " ".join(["margin-%s" % x.ident for x in SIDES]) %> <%self:impl_trait style_struct_name="Margin" - skip_longhands="${skip_margin_longhands}"> + skip_longhands="${skip_margin_longhands} + ${skip_scroll_margin_longhands}"> % for side in SIDES: <% impl_split_style_coord("margin_%s" % side.ident, "mMargin", side.index) %> + <% impl_split_style_coord("scroll_margin_%s" % side.ident, + "mScrollMargin", + side.index) %> % endfor </%self:impl_trait> +<% skip_scroll_padding_longhands = " ".join(["scroll-padding-%s" % x.ident for x in SIDES]) %> <% skip_padding_longhands = " ".join(["padding-%s" % x.ident for x in SIDES]) %> <%self:impl_trait style_struct_name="Padding" - skip_longhands="${skip_padding_longhands}"> + skip_longhands="${skip_padding_longhands} + ${skip_scroll_padding_longhands}"> % for side in SIDES: <% impl_split_style_coord("padding_%s" % side.ident, "mPadding", side.index) %> + <% impl_split_style_coord("scroll_padding_%s" % side.ident, "mScrollPadding", side.index) %> % endfor </%self:impl_trait> <% skip_position_longhands = " ".join(x.ident for x in SIDES + GRID_LINES) %> <%self:impl_trait style_struct_name="Position" - skip_longhands="${skip_position_longhands} z-index order + skip_longhands="${skip_position_longhands} order align-content justify-content align-self justify-self align-items justify-items grid-auto-rows grid-auto-columns @@ -1711,38 +1616,6 @@ fn static_assert() { <% impl_split_style_coord(side.ident, "mOffset", side.index) %> % endfor - pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) { - match v { - ZIndex::Integer(n) => self.gecko.mZIndex.set_value(CoordDataValue::Integer(n)), - ZIndex::Auto => self.gecko.mZIndex.set_value(CoordDataValue::Auto), - } - } - - pub fn copy_z_index_from(&mut self, other: &Self) { - use crate::gecko_bindings::structs::nsStyleUnit; - // z-index is never a calc(). If it were, we'd be leaking here, so - // assert that it isn't. - debug_assert_ne!(self.gecko.mZIndex.unit(), nsStyleUnit::eStyleUnit_Calc); - unsafe { - self.gecko.mZIndex.copy_from_unchecked(&other.gecko.mZIndex); - } - } - - pub fn reset_z_index(&mut self, other: &Self) { - self.copy_z_index_from(other) - } - - pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T { - return match self.gecko.mZIndex.as_value() { - CoordDataValue::Integer(n) => ZIndex::Integer(n), - CoordDataValue::Auto => ZIndex::Auto, - _ => { - debug_assert!(false); - ZIndex::Integer(0) - } - } - } - % for kind in ["align", "justify"]: ${impl_simple_type_with_conversion(kind + "_content")} ${impl_simple_type_with_conversion(kind + "_self")} @@ -2216,7 +2089,7 @@ fn static_assert() { pub fn fixup_none_generic(&mut self, device: &Device) { self.gecko.mFont.systemFont = false; unsafe { - bindings::Gecko_nsStyleFont_FixupNoneGeneric(&mut self.gecko, device.pres_context()) + bindings::Gecko_nsStyleFont_FixupNoneGeneric(&mut self.gecko, device.document()) } } @@ -2332,7 +2205,7 @@ fn static_assert() { } pub fn fixup_font_min_size(&mut self, device: &Device) { - unsafe { bindings::Gecko_nsStyleFont_FixupMinFontSize(&mut self.gecko, device.pres_context()) } + unsafe { bindings::Gecko_nsStyleFont_FixupMinFontSize(&mut self.gecko, device.document()) } } pub fn apply_unconstrained_font_size(&mut self, v: NonNegativeLength) { @@ -2654,12 +2527,11 @@ fn static_assert() { ${impl_simple("_moz_script_level", "mScriptLevel")} <% impl_simple_type_with_conversion("font_language_override", "mFont.languageOverride") %> - pub fn set_font_variant_alternates(&mut self, - v: values::computed::font::FontVariantAlternates, - device: &Device) { + pub fn set_font_variant_alternates( + &mut self, + v: values::computed::font::FontVariantAlternates, + ) { use crate::gecko_bindings::bindings::{Gecko_ClearAlternateValues, Gecko_AppendAlternateValues}; - use crate::gecko_bindings::bindings::Gecko_nsFont_ResetFontFeatureValuesLookup; - use crate::gecko_bindings::bindings::Gecko_nsFont_SetFontFeatureValuesLookup; % for value in "normal swash stylistic ornaments annotation styleset character_variant historical".split(): use crate::gecko_bindings::structs::NS_FONT_VARIANT_ALTERNATES_${value.upper()}; % endfor @@ -2671,7 +2543,6 @@ fn static_assert() { if v.0.is_empty() { self.gecko.mFont.variantAlternates = NS_FONT_VARIANT_ALTERNATES_NORMAL as u16; - unsafe { Gecko_nsFont_ResetFontFeatureValuesLookup(&mut self.gecko.mFont); } return; } @@ -2704,10 +2575,6 @@ fn static_assert() { } } } - - unsafe { - Gecko_nsFont_SetFontFeatureValuesLookup(&mut self.gecko.mFont, device.pres_context()); - } } #[allow(non_snake_case)] @@ -2997,10 +2864,8 @@ fn static_assert() { clear transition-duration transition-delay transition-timing-function transition-property rotate scroll-snap-points-x scroll-snap-points-y - scroll-snap-coordinate - perspective-origin -moz-binding will-change - offset-path perspective-origin -moz-binding - will-change shape-outside contain touch-action + scroll-snap-coordinate -moz-binding will-change + offset-path shape-outside contain touch-action translate scale""" %> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> #[inline] @@ -3095,11 +2960,7 @@ fn static_assert() { where I: IntoIterator<Item = longhands::scroll_snap_coordinate::computed_value::single_value::T>, I::IntoIter: ExactSizeIterator { - let iter = v.into_iter().map(|c| structs::mozilla::Position { - mXPosition: c.horizontal.into(), - mYPosition: c.vertical.into(), - }); - self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(iter); + self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(v.into_iter()); } pub fn copy_scroll_snap_coordinate_from(&mut self, other: &Self) { @@ -3112,7 +2973,7 @@ fn static_assert() { } pub fn clone_scroll_snap_coordinate(&self) -> longhands::scroll_snap_coordinate::computed_value::T { - let vec = self.gecko.mScrollSnapCoordinate.iter().map(|f| f.into()).collect(); + let vec = self.gecko.mScrollSnapCoordinate.iter().cloned().collect(); longhands::scroll_snap_coordinate::computed_value::List(vec) } @@ -3356,31 +3217,6 @@ fn static_assert() { ${impl_animation_timing_function()} - pub fn set_perspective_origin(&mut self, v: longhands::perspective_origin::computed_value::T) { - self.gecko.mPerspectiveOrigin[0].set(v.horizontal); - self.gecko.mPerspectiveOrigin[1].set(v.vertical); - } - - pub fn copy_perspective_origin_from(&mut self, other: &Self) { - self.gecko.mPerspectiveOrigin[0].copy_from(&other.gecko.mPerspectiveOrigin[0]); - self.gecko.mPerspectiveOrigin[1].copy_from(&other.gecko.mPerspectiveOrigin[1]); - } - - pub fn reset_perspective_origin(&mut self, other: &Self) { - self.copy_perspective_origin_from(other) - } - - pub fn clone_perspective_origin(&self) -> longhands::perspective_origin::computed_value::T { - use crate::properties::longhands::perspective_origin::computed_value::T; - use crate::values::computed::LengthPercentage; - T { - horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[0]) - .expect("Expected length or percentage for horizontal value of perspective-origin"), - vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[1]) - .expect("Expected length or percentage for vertical value of perspective-origin"), - } - } - ${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')} ${impl_individual_transform('translate', 'Translate', 'mSpecifiedTranslate')} ${impl_individual_transform('scale', 'Scale', 'mSpecifiedScale')} @@ -3759,7 +3595,7 @@ fn static_assert() { <% impl_simple_image_array_property("clip", shorthand, image_layers_field, "mClip", struct_name) %> <% impl_simple_image_array_property("origin", shorthand, image_layers_field, "mOrigin", struct_name) %> - % for orientation in ["x", "y"]: + % for (orientation, keyword) in [("x", "horizontal"), ("y", "vertical")]: pub fn copy_${shorthand}_position_${orientation}_from(&mut self, other: &Self) { use crate::gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; @@ -3774,8 +3610,7 @@ fn static_assert() { for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut() .zip(other.gecko.${image_layers_field}.mLayers.iter()) .take(count as usize) { - layer.mPosition.m${orientation.upper()}Position - = other.mPosition.m${orientation.upper()}Position; + layer.mPosition.${keyword} = other.mPosition.${keyword}; } self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count = count; } @@ -3789,7 +3624,7 @@ fn static_assert() { longhands::${shorthand}_position_${orientation}::computed_value::List( self.gecko.${image_layers_field}.mLayers.iter() .take(self.gecko.${image_layers_field}.mPosition${orientation.upper()}Count as usize) - .map(|position| position.mPosition.m${orientation.upper()}Position.into()) + .map(|position| position.mPosition.${keyword}) .collect() ) } @@ -3812,86 +3647,18 @@ fn static_assert() { self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count = v.len() as u32; for (servo, geckolayer) in v.zip(self.gecko.${image_layers_field} .mLayers.iter_mut()) { - geckolayer.mPosition.m${orientation[0].upper()}Position = servo.into(); + geckolayer.mPosition.${keyword} = servo; } } % endfor <%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize"> - use crate::gecko_bindings::structs::nsStyleImageLayers_Size_Dimension; - use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType; - use crate::gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImageLayers_Size}; - use crate::values::generics::background::BackgroundSize; - - let mut width = nsStyleCoord_CalcValue::new(); - let mut height = nsStyleCoord_CalcValue::new(); - - let (w_type, h_type) = match servo { - BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => { - let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto; - let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto; - if let Some(w) = explicit_width.to_calc_value() { - width = w; - w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; - } - if let Some(h) = explicit_height.to_calc_value() { - height = h; - h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; - } - (w_type, h_type) - } - BackgroundSize::Cover => { - ( - nsStyleImageLayers_Size_DimensionType::eCover, - nsStyleImageLayers_Size_DimensionType::eCover, - ) - }, - BackgroundSize::Contain => { - ( - nsStyleImageLayers_Size_DimensionType::eContain, - nsStyleImageLayers_Size_DimensionType::eContain, - ) - }, - }; - - nsStyleImageLayers_Size { - mWidth: nsStyleImageLayers_Size_Dimension { _base: width }, - mHeight: nsStyleImageLayers_Size_Dimension { _base: height }, - mWidthType: w_type as u8, - mHeightType: h_type as u8, - } + servo </%self:simple_image_array_property> pub fn clone_${shorthand}_size(&self) -> longhands::${shorthand}_size::computed_value::T { - use crate::gecko_bindings::structs::nsStyleCoord_CalcValue as CalcValue; - use crate::gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType as DimensionType; - use crate::values::computed::NonNegativeLengthPercentageOrAuto; - use crate::values::generics::background::BackgroundSize; - - fn to_servo(value: CalcValue, ty: u8) -> NonNegativeLengthPercentageOrAuto { - if ty == DimensionType::eAuto as u8 { - NonNegativeLengthPercentageOrAuto::auto() - } else { - debug_assert_eq!(ty, DimensionType::eLengthPercentage as u8); - value.into() - } - } - longhands::${shorthand}_size::computed_value::List( - self.gecko.${image_layers_field}.mLayers.iter().map(|ref layer| { - if DimensionType::eCover as u8 == layer.mSize.mWidthType { - debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eCover as u8); - return BackgroundSize::Cover - } - if DimensionType::eContain as u8 == layer.mSize.mWidthType { - debug_assert_eq!(layer.mSize.mHeightType, DimensionType::eContain as u8); - return BackgroundSize::Contain - } - BackgroundSize::Explicit { - width: to_servo(layer.mSize.mWidth._base, layer.mSize.mWidthType), - height: to_servo(layer.mSize.mHeight._base, layer.mSize.mHeightType), - } - }).collect() + self.gecko.${image_layers_field}.mLayers.iter().map(|layer| layer.mSize).collect() ) } @@ -4043,12 +3810,12 @@ fn static_assert() { } } - pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T, device: &Device) { + pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) { use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToString; use nsstring::{nsACString, nsCStr}; use self::longhands::list_style_type::computed_value::T; match v { - T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle, device), + T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle), T::String(s) => unsafe { Gecko_SetCounterStyleToString(&mut self.gecko.mCounterStyle, &nsCStr::from(&s) as &nsACString) @@ -4472,7 +4239,7 @@ fn static_assert() { <%self:impl_trait style_struct_name="InheritedText" skip_longhands="text-align text-emphasis-style text-shadow line-height letter-spacing word-spacing - -webkit-text-stroke-width text-emphasis-position -moz-tab-size"> + -webkit-text-stroke-width text-emphasis-position"> <% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left -moz-right char", @@ -4661,28 +4428,6 @@ fn static_assert() { ${impl_non_negative_length('_webkit_text_stroke_width', 'mWebkitTextStrokeWidth')} - #[allow(non_snake_case)] - pub fn set__moz_tab_size(&mut self, v: longhands::_moz_tab_size::computed_value::T) { - match v { - MozTabSize::Number(non_negative_number) => { - self.gecko.mTabSize.set_value(CoordDataValue::Factor(non_negative_number.0)); - } - MozTabSize::Length(non_negative_length) => { - self.gecko.mTabSize.set(non_negative_length); - } - } - } - - #[allow(non_snake_case)] - pub fn clone__moz_tab_size(&self) -> longhands::_moz_tab_size::computed_value::T { - match self.gecko.mTabSize.as_value() { - CoordDataValue::Coord(coord) => MozTabSize::Length(Au(coord).into()), - CoordDataValue::Factor(number) => MozTabSize::Number(From::from(number)), - _ => unreachable!(), - } - } - - <%call expr="impl_coord_copy('_moz_tab_size', 'mTabSize')"></%call> </%self:impl_trait> <%self:impl_trait style_struct_name="Text" @@ -5290,7 +5035,7 @@ clip-path self.gecko.mContents.is_empty() } - pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) { + pub fn set_content(&mut self, v: longhands::content::computed_value::T) { use crate::values::CustomIdent; use crate::values::generics::counters::{Content, ContentItem}; use crate::values::generics::CounterStyleOrNone; @@ -5315,7 +5060,6 @@ clip-path name: &CustomIdent, sep: &str, style: CounterStyleOrNone, - device: &Device, ) { debug_assert!(content_type == StyleContentType::Counter || content_type == StyleContentType::Counters); @@ -5326,7 +5070,7 @@ clip-path if content_type == StyleContentType::Counters { counter_func.mSeparator.assign_str(sep); } - style.to_gecko_value(&mut counter_func.mCounterStyle, device); + style.to_gecko_value(&mut counter_func.mCounterStyle); } match v { @@ -5401,7 +5145,6 @@ clip-path &name, "", style.clone(), - device, ); } ContentItem::Counters(ref name, ref sep, ref style) => { @@ -5411,7 +5154,6 @@ clip-path &name, &sep, style.clone(), - device, ); } ContentItem::Url(ref url) => { diff --git a/components/style/properties/longhands/border.mako.rs b/components/style/properties/longhands/border.mako.rs index c9d6b7f5e19..13a7f237350 100644 --- a/components/style/properties/longhands/border.mako.rs +++ b/components/style/properties/longhands/border.mako.rs @@ -119,10 +119,9 @@ ${helpers.predefined_type( ${helpers.predefined_type( "border-image-outset", - "LengthOrNumberRect", - parse_method="parse_non_negative", - initial_value="computed::LengthOrNumberRect::all(computed::LengthOrNumber::zero())", - initial_specified_value="specified::LengthOrNumberRect::all(specified::LengthOrNumber::zero())", + "NonNegativeLengthOrNumberRect", + initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())", + initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())", spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset", animation_value_type="discrete", flags="APPLIES_TO_FIRST_LETTER", diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 223db1d6e7c..1a8abfb3611 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -417,6 +417,16 @@ ${helpers.single_keyword( animation_value_type="discrete", )} +${helpers.predefined_type( + "scroll-snap-align", + "ScrollSnapAlign", + "computed::ScrollSnapAlign::none()", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align", + animation_value_type="discrete", +)} + % for axis in ["x", "y"]: ${helpers.predefined_type( "scroll-snap-type-" + axis, diff --git a/components/style/properties/longhands/color.mako.rs b/components/style/properties/longhands/color.mako.rs index 13b1fda545c..487814935aa 100644 --- a/components/style/properties/longhands/color.mako.rs +++ b/components/style/properties/longhands/color.mako.rs @@ -98,7 +98,7 @@ pub mod system_colors { unsafe { Gecko_GetLookAndFeelSystemColor( *self as i32, - cx.device().pres_context(), + cx.device().document(), ) } } diff --git a/components/style/properties/longhands/font.mako.rs b/components/style/properties/longhands/font.mako.rs index 755797711e1..047ec90c480 100644 --- a/components/style/properties/longhands/font.mako.rs +++ b/components/style/properties/longhands/font.mako.rs @@ -396,7 +396,7 @@ ${helpers.predefined_type( &mut system, id as i32, cx.style().get_font().gecko(), - cx.device().pres_context() + cx.device().document() ) } let font_weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight); diff --git a/components/style/properties/longhands/inherited_text.mako.rs b/components/style/properties/longhands/inherited_text.mako.rs index b1ed79379ca..97d551120a4 100644 --- a/components/style/properties/longhands/inherited_text.mako.rs +++ b/components/style/properties/longhands/inherited_text.mako.rs @@ -257,10 +257,10 @@ ${helpers.predefined_type( ${helpers.predefined_type( "-moz-tab-size", - "MozTabSize", - "generics::text::MozTabSize::Number(From::from(8.0))", + "NonNegativeLengthOrNumber", + "generics::length::LengthOrNumber::Number(From::from(8.0))", products="gecko", - animation_value_type="AnimatedMozTabSize", + animation_value_type="LengthOrNumber", spec="https://drafts.csswg.org/css-text-3/#tab-size-property", )} @@ -349,8 +349,8 @@ ${helpers.single_keyword( "-moz-control-character-visibility", "hidden visible", gecko_constant_prefix="NS_STYLE_CONTROL_CHARACTER_VISIBILITY", - gecko_ffi_name="mControlCharacterVisibility", animation_value_type="none", + gecko_ffi_name="mControlCharacterVisibility", products="gecko", spec="Nonstandard", )} diff --git a/components/style/properties/longhands/inherited_ui.mako.rs b/components/style/properties/longhands/inherited_ui.mako.rs index 87c7cd9ac4b..94709e1a681 100644 --- a/components/style/properties/longhands/inherited_ui.mako.rs +++ b/components/style/properties/longhands/inherited_ui.mako.rs @@ -60,7 +60,7 @@ ${helpers.single_keyword( ${helpers.predefined_type( "caret-color", "ColorOrAuto", - "Either::Second(Auto)", + "generics::color::ColorOrAuto::Auto", spec="https://drafts.csswg.org/css-ui/#caret-color", animation_value_type="AnimatedCaretColor", ignored_when_colors_disabled=True, diff --git a/components/style/properties/longhands/margin.mako.rs b/components/style/properties/longhands/margin.mako.rs index e5eac633c96..d2a3be11d1d 100644 --- a/components/style/properties/longhands/margin.mako.rs +++ b/components/style/properties/longhands/margin.mako.rs @@ -27,3 +27,18 @@ servo_restyle_damage="reflow" )} % endfor + +% for side in ALL_SIDES: + ${helpers.predefined_type( + "scroll-margin-%s" % side[0], + "Length", + "computed::Length::zero()", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + logical=side[1], + logical_group="scroll-margin", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0], + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE", + animation_value_type="ComputedValue", + )} +% endfor diff --git a/components/style/properties/longhands/padding.mako.rs b/components/style/properties/longhands/padding.mako.rs index 5fa51863629..6c4e2b32cf9 100644 --- a/components/style/properties/longhands/padding.mako.rs +++ b/components/style/properties/longhands/padding.mako.rs @@ -28,3 +28,17 @@ servo_restyle_damage="reflow rebuild_and_reflow_inline" )} % endfor + +% for side in ALL_SIDES: + ${helpers.predefined_type( + "scroll-padding-%s" % side[0], + "NonNegativeLengthPercentageOrAuto", + "computed::NonNegativeLengthPercentageOrAuto::auto()", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + logical=side[1], + logical_group="scroll-padding", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0], + animation_value_type="ComputedValue", + )} +% endfor diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index 714de149b56..725f0862a99 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -75,6 +75,7 @@ ${helpers.single_keyword( extra_prefixes="webkit", animation_value_type="discrete", servo_restyle_damage = "reflow", + gecko_enum_prefix = "StyleFlexDirection", )} ${helpers.single_keyword( @@ -225,7 +226,7 @@ ${helpers.predefined_type( extra_prefixes="webkit", animation_value_type="ComputedValue", spec="https://drafts.csswg.org/css-flexbox/#order-property", - servo_restyle_damage = "reflow", + servo_restyle_damage="reflow", )} ${helpers.predefined_type( @@ -235,7 +236,8 @@ ${helpers.predefined_type( spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property", extra_prefixes="webkit", animation_value_type="FlexBasis", - servo_restyle_damage = "reflow", + servo_restyle_damage="reflow", + boxed=True, )} % for (size, logical) in ALL_SIZES: diff --git a/components/style/properties/longhands/svg.mako.rs b/components/style/properties/longhands/svg.mako.rs index f003fa5222e..1a84c1d669f 100644 --- a/components/style/properties/longhands/svg.mako.rs +++ b/components/style/properties/longhands/svg.mako.rs @@ -96,6 +96,7 @@ ${helpers.predefined_type( ${helpers.single_keyword( "mask-mode", "match-source alpha luminance", + gecko_enum_prefix="StyleMaskMode", vector=True, products="gecko", animation_value_type="discrete", diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index d818306e96c..7e35d318c30 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -3358,7 +3358,7 @@ impl<'a> StyleBuilder<'a> { debug_assert!(parent_style.is_none() || std::ptr::eq(parent_style.unwrap(), parent_style_ignoring_first_line.unwrap()) || - parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine)); + parent_style.unwrap().is_first_line_style()); let reset_style = device.default_computed_values(); let inherited_style = parent_style.unwrap_or(reset_style); let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style); @@ -3402,7 +3402,7 @@ impl<'a> StyleBuilder<'a> { let inherited_style = parent_style.unwrap_or(reset_style); #[cfg(feature = "gecko")] debug_assert!(parent_style.is_none() || - parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine)); + !parent_style.unwrap().is_first_line_style()); StyleBuilder { device, inherited_style, @@ -3507,14 +3507,11 @@ impl<'a> StyleBuilder<'a> { self.modified_reset = true; % endif - <% props_need_device = ["content", "list_style_type", "font_variant_alternates"] %> self.${property.style_struct.ident}.mutate() .set_${property.ident}( value, % if property.logical: self.writing_mode, - % elif product == "gecko" and property.ident in props_need_device: - self.device, % endif ); } diff --git a/components/style/properties/shorthands/margin.mako.rs b/components/style/properties/shorthands/margin.mako.rs index 8ccd33ebf3b..fd3124a6ae1 100644 --- a/components/style/properties/shorthands/margin.mako.rs +++ b/components/style/properties/shorthands/margin.mako.rs @@ -28,3 +28,32 @@ ${helpers.two_properties_shorthand( "specified::LengthPercentageOrAuto::parse", spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline" )} + +${helpers.four_sides_shorthand( + "scroll-margin", + "scroll-margin-%s", + "specified::Length::parse", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", +)} + +${helpers.two_properties_shorthand( + "scroll-margin-block", + "scroll-margin-block-start", + "scroll-margin-block-end", + "specified::Length::parse", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", +)} + +${helpers.two_properties_shorthand( + "scroll-margin-inline", + "scroll-margin-inline-start", + "scroll-margin-inline-end", + "specified::Length::parse", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", +)} diff --git a/components/style/properties/shorthands/padding.mako.rs b/components/style/properties/shorthands/padding.mako.rs index 3efc0b4a153..a4e013caabc 100644 --- a/components/style/properties/shorthands/padding.mako.rs +++ b/components/style/properties/shorthands/padding.mako.rs @@ -27,3 +27,33 @@ ${helpers.two_properties_shorthand( "specified::NonNegativeLengthPercentage::parse", spec="https://drafts.csswg.org/css-logical/#propdef-padding-inline" )} + +${helpers.four_sides_shorthand( + "scroll-padding", + "scroll-padding-%s", + "specified::NonNegativeLengthPercentageOrAuto::parse", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding" +)} + +${helpers.two_properties_shorthand( + "scroll-padding-block", + "scroll-padding-block-start", + "scroll-padding-block-end", + "specified::NonNegativeLengthPercentageOrAuto::parse", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block" +)} + +${helpers.two_properties_shorthand( + "scroll-padding-inline", + "scroll-padding-inline-start", + "scroll-padding-inline-end", + "specified::NonNegativeLengthPercentageOrAuto::parse", + products="gecko", + gecko_pref="layout.css.scroll-snap-v1.enabled", + spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline" +)} + diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs index c7be23572c6..0675359ed77 100644 --- a/components/style/sharing/mod.rs +++ b/components/style/sharing/mod.rs @@ -766,6 +766,11 @@ impl<E: TElement> StyleSharingCache<E> { return None; } + if target.element.has_animations() { + trace!("Miss: Has Animations"); + return None; + } + if target.matches_user_and_author_rules() != candidate.element.matches_user_and_author_rules() { diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index 4813a0e9150..c73b96bcd9d 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -198,7 +198,7 @@ impl DocumentMatchingFunction { MediaDocumentKind::Video => "video", }, }); - unsafe { Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func) } + unsafe { Gecko_DocumentRule_UseForPresentation(device.document(), &*pattern, func) } } #[cfg(not(feature = "gecko"))] diff --git a/components/style/values/computed/background.rs b/components/style/values/computed/background.rs index dc23915a74b..e2a58f8b74e 100644 --- a/components/style/values/computed/background.rs +++ b/components/style/values/computed/background.rs @@ -6,19 +6,8 @@ use crate::values::computed::length::NonNegativeLengthPercentage; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; -use crate::values::generics::length::LengthPercentageOrAuto; pub use crate::values::specified::background::BackgroundRepeat; /// A computed value for the `background-size` property. pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; - -impl BackgroundSize { - /// Returns `auto auto`. - pub fn auto() -> Self { - GenericBackgroundSize::Explicit { - width: LengthPercentageOrAuto::auto(), - height: LengthPercentageOrAuto::auto(), - } - } -} diff --git a/components/style/values/computed/box.rs b/components/style/values/computed/box.rs index 46d3f93854e..decba9f342f 100644 --- a/components/style/values/computed/box.rs +++ b/components/style/values/computed/box.rs @@ -15,7 +15,7 @@ pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween pub use crate::values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat}; pub use crate::values::specified::box_::{Contain, Display, Overflow}; pub use crate::values::specified::box_::{OverflowAnchor, OverflowClipBox}; -pub use crate::values::specified::box_::{OverscrollBehavior, ScrollSnapType}; +pub use crate::values::specified::box_::{OverscrollBehavior, ScrollSnapAlign, ScrollSnapType}; pub use crate::values::specified::box_::{TouchAction, TransitionProperty, WillChange}; /// A computed value for the `vertical-align` property. diff --git a/components/style/values/computed/color.rs b/components/style/values/computed/color.rs index 758d86be1b8..6795b399888 100644 --- a/components/style/values/computed/color.rs +++ b/components/style/values/computed/color.rs @@ -6,7 +6,7 @@ use crate::values::animated::color::RGBA as AnimatedRGBA; use crate::values::animated::ToAnimatedValue; -use crate::values::generics::color::Color as GenericColor; +use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto}; use cssparser::{Color as CSSParserColor, RGBA}; use std::fmt; use style_traits::{CssWriter, ToCss}; @@ -101,3 +101,6 @@ impl ToAnimatedValue for RGBA { RGBA::from_floats(animated.red, animated.green, animated.blue, animated.alpha) } } + +/// auto | <color> +pub type ColorOrAuto = GenericColorOrAuto<Color>; diff --git a/components/style/values/computed/flex.rs b/components/style/values/computed/flex.rs index c0c2703732f..95c497ecf63 100644 --- a/components/style/values/computed/flex.rs +++ b/components/style/values/computed/flex.rs @@ -14,6 +14,6 @@ impl FlexBasis { /// `auto` #[inline] pub fn auto() -> Self { - GenericFlexBasis::Width(Size::auto()) + GenericFlexBasis::Size(Size::auto()) } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 6cdf359d16a..f578bbbd5ce 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -6,9 +6,12 @@ use super::{Context, Number, Percentage, ToComputedValue}; use crate::values::animated::ToAnimatedValue; +use crate::values::computed::NonNegativeNumber; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; use crate::values::generics::length as generics; -use crate::values::generics::length::{MaxSize as GenericMaxSize, Size as GenericSize}; +use crate::values::generics::length::{ + GenericLengthOrNumber, MaxSize as GenericMaxSize, Size as GenericSize, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::length::ViewportPercentageLength; @@ -503,7 +506,7 @@ impl LengthPercentageOrAuto { /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. pub type NonNegativeLengthPercentageOrAuto = - generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>; + generics::GenericLengthPercentageOrAuto<NonNegativeLengthPercentage>; impl NonNegativeLengthPercentageOrAuto { computed_length_percentage_or_auto!(NonNegativeLengthPercentage); @@ -678,6 +681,15 @@ impl ToCss for CSSPixelLength { } } +impl Add for CSSPixelLength { + type Output = Self; + + #[inline] + fn add(self, other: Self) -> Self { + Self::new(self.px() + other.px()) + } +} + impl Neg for CSSPixelLength { type Output = Self; @@ -708,15 +720,7 @@ pub type Length = CSSPixelLength; pub type LengthOrAuto = Either<Length, Auto>; /// Either a computed `<length>` or a `<number>` value. -pub type LengthOrNumber = Either<Length, Number>; - -impl LengthOrNumber { - /// Returns `0`. - #[inline] - pub fn zero() -> Self { - Either::Second(0.) - } -} +pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>; /// Either a computed `<length>` or the `normal` keyword. pub type LengthOrNormal = Either<Length, Normal>; @@ -776,13 +780,6 @@ impl NonNegativeLength { } } -impl Add<NonNegativeLength> for NonNegativeLength { - type Output = Self; - fn add(self, other: Self) -> Self { - NonNegativeLength::new(self.px() + other.px()) - } -} - impl From<Length> for NonNegativeLength { #[inline] fn from(len: Length) -> Self { @@ -813,6 +810,9 @@ pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>; /// Either a computed NonNegativeLengthPercentage or the `normal` keyword. pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentage, Normal>; +/// Either a non-negative `<length>` or a `<number>`. +pub type NonNegativeLengthOrNumber = GenericLengthOrNumber<NonNegativeLength, NonNegativeNumber>; + /// A type for possible values for min- and max- flavors of width, height, /// block-size, and inline-size. #[allow(missing_docs)] diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 8158e1a16d7..6fe36d684f2 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -44,8 +44,8 @@ pub use self::box_::{AnimationIterationCount, AnimationName, Contain}; pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float}; pub use self::box_::{Display, Overflow, OverflowAnchor, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize}; -pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorPropertyValue, RGBAColor}; +pub use self::box_::{ScrollSnapAlign, ScrollSnapType, TouchAction, VerticalAlign, WillChange}; +pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, RGBAColor}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::easing::TimingFunction; @@ -61,7 +61,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, pub use self::gecko::ScrollSnapPoint; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; -pub use self::length::{Length, LengthOrNumber, LengthPercentage}; +pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber}; pub use self::length::{LengthPercentageOrAuto, MaxSize, Size}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; #[cfg(feature = "gecko")] @@ -71,13 +71,13 @@ pub use self::motion::OffsetPath; pub use self::outline::OutlineStyle; pub use self::percentage::{NonNegativePercentage, Percentage}; pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex}; -pub use self::rect::LengthOrNumberRect; +pub use self::rect::NonNegativeLengthOrNumberRect; pub use self::resolution::Resolution; pub use self::svg::MozContextProperties; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; pub use self::table::XSpan; -pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize}; +pub use self::text::{InitialLetter, LetterSpacing, LineHeight}; pub use self::text::{OverflowWrap, TextOverflow, WordSpacing}; pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle}; pub use self::time::Time; @@ -85,7 +85,7 @@ pub use self::transform::{Rotate, Scale, Transform, TransformOperation}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon, UserSelect}; +pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect}; pub use super::specified::{BorderStyle, TextDecorationLine}; pub use super::{Auto, Either, None_}; pub use app_units::Au; @@ -536,6 +536,7 @@ impl From<GreaterThanOrEqualToOneNumber> for CSSFloat { #[allow(missing_docs)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +#[repr(C, u8)] pub enum NumberOrPercentage { Percentage(Percentage), Number(Number), diff --git a/components/style/values/computed/rect.rs b/components/style/values/computed/rect.rs index 40b722ade21..ec44360fc81 100644 --- a/components/style/values/computed/rect.rs +++ b/components/style/values/computed/rect.rs @@ -4,8 +4,8 @@ //! Computed types for CSS borders. -use crate::values::computed::length::LengthOrNumber; +use crate::values::computed::length::NonNegativeLengthOrNumber; use crate::values::generics::rect::Rect; /// A specified rectangle made of four `<length-or-number>` values. -pub type LengthOrNumberRect = Rect<LengthOrNumber>; +pub type NonNegativeLengthOrNumberRect = Rect<NonNegativeLengthOrNumber>; diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs index 030a6df6cff..2c9a9593ecc 100644 --- a/components/style/values/computed/text.rs +++ b/components/style/values/computed/text.rs @@ -10,7 +10,6 @@ use crate::values::computed::length::{Length, LengthPercentage}; use crate::values::computed::{NonNegativeLength, NonNegativeNumber}; use crate::values::generics::text::InitialLetter as GenericInitialLetter; use crate::values::generics::text::LineHeight as GenericLineHeight; -use crate::values::generics::text::MozTabSize as GenericMozTabSize; use crate::values::generics::text::Spacing; use crate::values::specified::text::TextOverflowSide; use crate::values::specified::text::{TextEmphasisFillMode, TextEmphasisShapeKeyword}; @@ -124,9 +123,6 @@ impl TextDecorationsInEffect { } } -/// A specified value for the `-moz-tab-size` property. -pub type MozTabSize = GenericMozTabSize<NonNegativeNumber, NonNegativeLength>; - /// computed value for the text-emphasis-style property #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum TextEmphasisStyle { diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs index 979886aa996..dd3fe20754c 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -21,7 +21,8 @@ pub type TransformOperation = pub type Transform = generic::Transform<TransformOperation>; /// The computed value of a CSS `<transform-origin>` -pub type TransformOrigin = generic::TransformOrigin<LengthPercentage, LengthPercentage, Length>; +pub type TransformOrigin = + generic::GenericTransformOrigin<LengthPercentage, LengthPercentage, Length>; /// A vector to represent the direction vector (rotate axis) for Rotate3D. pub type DirectionVector = Vector3D<CSSFloat>; diff --git a/components/style/values/computed/ui.rs b/components/style/values/computed/ui.rs index ef19b975494..0c37ea4f518 100644 --- a/components/style/values/computed/ui.rs +++ b/components/style/values/computed/ui.rs @@ -8,14 +8,10 @@ use crate::values::computed::color::Color; use crate::values::computed::url::ComputedImageUrl; use crate::values::computed::Number; use crate::values::generics::ui as generics; -use crate::values::{Auto, Either}; pub use crate::values::specified::ui::CursorKind; pub use crate::values::specified::ui::{MozForceBrokenImageIcon, UserSelect}; -/// auto | <color> -pub type ColorOrAuto = Either<Color, Auto>; - /// A computed value for the `cursor` property. pub type Cursor = generics::Cursor<CursorImage>; diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs index d739329e4fc..14ac9744b14 100644 --- a/components/style/values/generics/background.rs +++ b/components/style/values/generics/background.rs @@ -4,7 +4,7 @@ //! Generic types for CSS values related to backgrounds. -use crate::values::generics::length::LengthPercentageOrAuto; +use crate::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto}; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -22,13 +22,14 @@ use style_traits::{CssWriter, ToCss}; ToAnimatedZero, ToComputedValue, )] -pub enum BackgroundSize<LengthPercentage> { +#[repr(C, u8)] +pub enum GenericBackgroundSize<LengthPercent> { /// `<width> <height>` - Explicit { + ExplicitSize { /// Explicit width. - width: LengthPercentageOrAuto<LengthPercentage>, + width: GenericLengthPercentageOrAuto<LengthPercent>, /// Explicit height. - height: LengthPercentageOrAuto<LengthPercentage>, + height: GenericLengthPercentageOrAuto<LengthPercent>, }, /// `cover` #[animation(error)] @@ -38,6 +39,8 @@ pub enum BackgroundSize<LengthPercentage> { Contain, } +pub use self::GenericBackgroundSize as BackgroundSize; + impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage> where LengthPercentage: ToCss, @@ -47,7 +50,7 @@ where W: Write, { match self { - BackgroundSize::Explicit { width, height } => { + BackgroundSize::ExplicitSize { width, height } => { width.to_css(dest)?; // NOTE(emilio): We should probably simplify all these in case // `width == `height`, but all other browsers agree on only @@ -63,3 +66,13 @@ where } } } + +impl<LengthPercentage> BackgroundSize<LengthPercentage> { + /// Returns `auto auto`. + pub fn auto() -> Self { + GenericBackgroundSize::ExplicitSize { + width: LengthPercentageOrAuto::Auto, + height: LengthPercentageOrAuto::Auto, + } + } +} diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs index 0a1cef3b4bb..ffd30e98678 100644 --- a/components/style/values/generics/border.rs +++ b/components/style/values/generics/border.rs @@ -26,7 +26,8 @@ pub enum BorderImageSideWidth<LengthPercentage, Number> { #[derive( Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, )] -pub struct BorderImageSlice<NumberOrPercentage> { +#[repr(C)] +pub struct GenericBorderImageSlice<NumberOrPercentage> { /// The offsets. #[css(field_bound)] pub offsets: Rect<NumberOrPercentage>, @@ -35,6 +36,8 @@ pub struct BorderImageSlice<NumberOrPercentage> { pub fill: bool, } +pub use self::GenericBorderImageSlice as BorderImageSlice; + /// A generic value for the `border-*-radius` longhand properties. #[derive( Animate, diff --git a/components/style/values/generics/box.rs b/components/style/values/generics/box.rs index 8a8dc58fd92..f49cba4c2e1 100644 --- a/components/style/values/generics/box.rs +++ b/components/style/values/generics/box.rs @@ -74,6 +74,7 @@ pub enum AnimationIterationCount<Number> { Copy, Debug, MallocSizeOf, + Parse, PartialEq, SpecifiedValueInfo, ToAnimatedValue, @@ -81,13 +82,16 @@ pub enum AnimationIterationCount<Number> { ToComputedValue, ToCss, )] -pub enum Perspective<NonNegativeLength> { +#[repr(C, u8)] +pub enum GenericPerspective<NonNegativeLength> { /// A non-negative length. Length(NonNegativeLength), /// The keyword `none`. None, } +pub use self::GenericPerspective as Perspective; + impl<L> Perspective<L> { /// Returns `none`. #[inline] diff --git a/components/style/values/generics/color.rs b/components/style/values/generics/color.rs index 594df927ca9..58e4e9fa97c 100644 --- a/components/style/values/generics/color.rs +++ b/components/style/values/generics/color.rs @@ -74,3 +74,26 @@ impl<RGBA> From<RGBA> for Color<RGBA> { Self::rgba(color) } } + +/// Either `<color>` or `auto`. +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + Parse, + SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, + ToComputedValue, + ToCss, +)] +pub enum ColorOrAuto<C> { + /// A `<color> + Color(C), + /// `auto` + Auto, +} diff --git a/components/style/values/generics/column.rs b/components/style/values/generics/column.rs index d27e47ed4c7..6f8c9daef5b 100644 --- a/components/style/values/generics/column.rs +++ b/components/style/values/generics/column.rs @@ -12,6 +12,7 @@ Copy, Debug, MallocSizeOf, + Parse, PartialEq, SpecifiedValueInfo, ToAnimatedValue, diff --git a/components/style/values/generics/flex.rs b/components/style/values/generics/flex.rs index 31e32a91f81..de67b56e35b 100644 --- a/components/style/values/generics/flex.rs +++ b/components/style/values/generics/flex.rs @@ -12,6 +12,7 @@ ComputeSquaredDistance, Copy, Debug, + Parse, PartialEq, SpecifiedValueInfo, ToAnimatedValue, @@ -19,9 +20,12 @@ ToComputedValue, ToCss, )] -pub enum FlexBasis<Width> { +#[repr(C)] +pub enum GenericFlexBasis<S> { /// `content` Content, /// `<width>` - Width(Width), + Size(S), } + +pub use self::GenericFlexBasis as FlexBasis; diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index 7dbee9b8dbe..6650996c794 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -192,10 +192,7 @@ impl<L> TrackBreadth<L> { /// <https://drafts.csswg.org/css-grid/#typedef-fixed-breadth> #[inline] pub fn is_fixed(&self) -> bool { - match *self { - TrackBreadth::Breadth(ref _lp) => true, - _ => false, - } + matches!(*self, TrackBreadth::Breadth(..)) } } diff --git a/components/style/values/generics/length.rs b/components/style/values/generics/length.rs index f55db4f52c5..1a83f58054c 100644 --- a/components/style/values/generics/length.rs +++ b/components/style/values/generics/length.rs @@ -8,6 +8,7 @@ use crate::parser::{Parse, ParserContext}; #[cfg(feature = "gecko")] use crate::values::computed::ExtremumLength; use cssparser::Parser; +use num_traits::Zero; use style_traits::ParseError; /// A `<length-percentage> | auto` value. @@ -96,14 +97,17 @@ impl<LengthPercentage: Parse> Parse for LengthPercentageOrAuto<LengthPercentage> ToComputedValue, ToCss, )] -pub enum Size<LengthPercentage> { - LengthPercentage(LengthPercentage), +#[repr(C, u8)] +pub enum GenericSize<LengthPercent> { + LengthPercentage(LengthPercent), Auto, #[cfg(feature = "gecko")] #[animation(error)] ExtremumLength(ExtremumLength), } +pub use self::GenericSize as Size; + impl<LengthPercentage> Size<LengthPercentage> { /// `auto` value. #[inline] @@ -134,14 +138,17 @@ impl<LengthPercentage> Size<LengthPercentage> { ToComputedValue, ToCss, )] -pub enum MaxSize<LengthPercentage> { - LengthPercentage(LengthPercentage), +#[repr(C, u8)] +pub enum GenericMaxSize<LengthPercent> { + LengthPercentage(LengthPercent), None, #[cfg(feature = "gecko")] #[animation(error)] ExtremumLength(ExtremumLength), } +pub use self::GenericMaxSize as MaxSize; + impl<LengthPercentage> MaxSize<LengthPercentage> { /// `none` value. #[inline] @@ -149,3 +156,42 @@ impl<LengthPercentage> MaxSize<LengthPercentage> { MaxSize::None } } + +/// A generic `<length>` | `<number>` value for the `-moz-tab-size` property. +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, + ToComputedValue, + ToCss, +)] +#[repr(C, u8)] +pub enum GenericLengthOrNumber<L, N> { + /// A number. + /// + /// NOTE: Numbers need to be before lengths, in order to parse them + /// first, since `0` should be a number, not the `0px` length. + Number(N), + /// A length. + Length(L), +} + +pub use self::GenericLengthOrNumber as LengthOrNumber; + +impl<L, N> LengthOrNumber<L, N> { + /// Returns `0`. + pub fn zero() -> Self + where + N: Zero, + { + LengthOrNumber::Number(num_traits::Zero::zero()) + } +} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index a5c8c957073..737c88e7ba7 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -9,6 +9,8 @@ use super::CustomIdent; use crate::counter_style::{parse_counter_style_name, Symbols}; use crate::parser::{Parse, ParserContext}; use cssparser::Parser; +use num_traits::Zero; +use std::ops::Add; use style_traits::{KeywordsCollectFn, ParseError}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind}; @@ -117,27 +119,25 @@ impl Parse for CounterStyleOrNone { if input.try(|i| i.expect_ident_matching("none")).is_ok() { return Ok(CounterStyleOrNone::None); } - if input.try(|i| i.expect_function_matching("symbols")).is_ok() { - return input.parse_nested_block(|input| { - let symbols_type = input - .try(|i| SymbolsType::parse(i)) - .unwrap_or(SymbolsType::Symbolic); - let symbols = Symbols::parse(context, input)?; - // There must be at least two symbols for alphabetic or - // numeric system. - if (symbols_type == SymbolsType::Alphabetic || - symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 - { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - // Identifier is not allowed in symbols() function. - if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) - }); - } - Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + input.expect_function_matching("symbols")?; + input.parse_nested_block(|input| { + let symbols_type = input + .try(SymbolsType::parse) + .unwrap_or(SymbolsType::Symbolic); + let symbols = Symbols::parse(context, input)?; + // There must be at least two symbols for alphabetic or + // numeric system. + if (symbols_type == SymbolsType::Alphabetic || symbols_type == SymbolsType::Numeric) && + symbols.0.len() < 2 + { + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); + } + // Identifier is not allowed in symbols() function. + if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); + } + Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) + }) } } @@ -177,6 +177,24 @@ impl SpecifiedValueInfo for CounterStyleOrNone { #[repr(transparent)] pub struct NonNegative<T>(pub T); +impl<T: Add<Output = T>> Add<NonNegative<T>> for NonNegative<T> { + type Output = Self; + + fn add(self, other: Self) -> Self { + NonNegative(self.0 + other.0) + } +} + +impl<T: Zero> Zero for NonNegative<T> { + fn is_zero(&self) -> bool { + self.0.is_zero() + } + + fn zero() -> Self { + NonNegative(T::zero()) + } +} + /// A wrapper of greater-than-or-equal-to-one values. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 07612913c0a..34034b7d5b7 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -19,19 +19,22 @@ ToAnimatedZero, ToComputedValue, )] -pub struct Position<H, V> { +#[repr(C)] +pub struct GenericPosition<H, V> { /// The horizontal component of position. pub horizontal: H, /// The vertical component of position. pub vertical: V, } +pub use self::GenericPosition as Position; + impl<H, V> Position<H, V> { /// Returns a new position. pub fn new(horizontal: H, vertical: V) -> Self { Self { - horizontal: horizontal, - vertical: vertical, + horizontal, + vertical, } } } @@ -45,18 +48,22 @@ impl<H, V> Position<H, V> { Debug, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss, )] -pub enum ZIndex<Integer> { +#[repr(C, u8)] +pub enum GenericZIndex<I> { /// An integer value. - Integer(Integer), + Integer(I), /// The keyword `auto`. Auto, } +pub use self::GenericZIndex as ZIndex; + impl<Integer> ZIndex<Integer> { /// Returns `auto` #[inline] diff --git a/components/style/values/generics/svg.rs b/components/style/values/generics/svg.rs index 914de88999c..7f52126a748 100644 --- a/components/style/values/generics/svg.rs +++ b/components/style/values/generics/svg.rs @@ -136,6 +136,7 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP Debug, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, @@ -143,28 +144,26 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP ToCss, )] pub enum SvgLengthPercentageOrNumber<LengthPercentage, Number> { - /// <length> | <percentage> - LengthPercentage(LengthPercentage), /// <number> + /// + /// Note that this needs to be before, so it gets parsed before the length, + /// to handle `0` correctly as a number instead of a `<length>`. Number(Number), + /// <length> | <percentage> + LengthPercentage(LengthPercentage), } -/// Parsing the SvgLengthPercentageOrNumber. At first, we need to parse number -/// since prevent converting to the length. -impl<LengthPercentageType: Parse, NumberType: Parse> Parse - for SvgLengthPercentageOrNumber<LengthPercentageType, NumberType> -{ - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if let Ok(num) = input.try(|i| NumberType::parse(context, i)) { - return Ok(SvgLengthPercentageOrNumber::Number(num)); - } +/// Whether the `context-value` value is enabled. +#[cfg(feature = "gecko")] +pub fn is_context_value_enabled(_: &ParserContext) -> bool { + use crate::gecko_bindings::structs::mozilla; + unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled } +} - let lp = LengthPercentageType::parse(context, input)?; - Ok(SvgLengthPercentageOrNumber::LengthPercentage(lp)) - } +/// Whether the `context-value` value is enabled. +#[cfg(not(feature = "gecko"))] +pub fn is_context_value_enabled(_: &ParserContext) -> bool { + false } /// An SVG length value supports `context-value` in addition to length. @@ -175,6 +174,7 @@ impl<LengthPercentageType: Parse, NumberType: Parse> Parse Debug, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, @@ -185,6 +185,7 @@ pub enum SVGLength<LengthType> { /// `<length> | <percentage> | <number>` Length(LengthType), /// `context-value` + #[parse(condition = "is_context_value_enabled")] ContextValue, } @@ -216,6 +217,7 @@ pub enum SVGStrokeDashArray<LengthType> { Debug, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, diff --git a/components/style/values/generics/text.rs b/components/style/values/generics/text.rs index 5a4f9213908..029c5681318 100644 --- a/components/style/values/generics/text.rs +++ b/components/style/values/generics/text.rs @@ -149,25 +149,3 @@ impl<N, L> LineHeight<N, L> { LineHeight::Normal } } - -/// A generic value for the `-moz-tab-size` property. -#[derive( - Animate, - Clone, - ComputeSquaredDistance, - Copy, - Debug, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToAnimatedValue, - ToAnimatedZero, - ToComputedValue, - ToCss, -)] -pub enum MozTabSize<Number, Length> { - /// A number. - Number(Number), - /// A length. - Length(Length), -} diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index 4591f3addd2..6c60e76cbf6 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -83,7 +83,8 @@ impl<T: Into<f64>> From<Matrix3D<T>> for Transform3D<f64> { ToComputedValue, ToCss, )] -pub struct TransformOrigin<H, V, Depth> { +#[repr(C)] +pub struct GenericTransformOrigin<H, V, Depth> { /// The horizontal origin. pub horizontal: H, /// The vertical origin. @@ -92,13 +93,15 @@ pub struct TransformOrigin<H, V, Depth> { pub depth: Depth, } +pub use self::GenericTransformOrigin as TransformOrigin; + impl<H, V, D> TransformOrigin<H, V, D> { /// Returns a new transform origin. pub fn new(horizontal: H, vertical: V, depth: D) -> Self { Self { - horizontal: horizontal, - vertical: vertical, - depth: depth, + horizontal, + vertical, + depth, } } } diff --git a/components/style/values/generics/url.rs b/components/style/values/generics/url.rs index a1f1aeb1884..80fa48ba882 100644 --- a/components/style/values/generics/url.rs +++ b/components/style/values/generics/url.rs @@ -4,10 +4,6 @@ //! Generic types for url properties. -use crate::parser::{Parse, ParserContext}; -use cssparser::Parser; -use style_traits::ParseError; - /// An image url or none, used for example in list-style-image #[derive( Animate, @@ -16,6 +12,7 @@ use style_traits::ParseError; Debug, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, @@ -35,19 +32,3 @@ impl<Url> UrlOrNone<Url> { UrlOrNone::None } } - -impl<Url> Parse for UrlOrNone<Url> -where - Url: Parse, -{ - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<UrlOrNone<Url>, ParseError<'i>> { - if let Ok(url) = input.try(|input| Url::parse(context, input)) { - return Ok(UrlOrNone::Url(url)); - } - input.expect_ident_matching("none")?; - Ok(UrlOrNone::None) - } -} diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 659ff95b1a7..ccda0f290c1 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -125,6 +125,7 @@ impl Parse for Impossible { Copy, MallocSizeOf, PartialEq, + Parse, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, @@ -147,19 +148,6 @@ impl<A: Debug, B: Debug> Debug for Either<A, B> { } } -impl<A: Parse, B: Parse> Parse for Either<A, B> { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Either<A, B>, ParseError<'i>> { - if let Ok(v) = input.try(|i| A::parse(context, i)) { - Ok(Either::First(v)) - } else { - B::parse(context, input).map(Either::Second) - } - } -} - /// <https://drafts.csswg.org/css-values-4/#custom-idents> #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] pub struct CustomIdent(pub Atom); diff --git a/components/style/values/specified/background.rs b/components/style/values/specified/background.rs index b53669abfa8..a1605e977eb 100644 --- a/components/style/values/specified/background.rs +++ b/components/style/values/specified/background.rs @@ -26,7 +26,7 @@ impl Parse for BackgroundSize { let height = input .try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i)) .unwrap_or(NonNegativeLengthPercentageOrAuto::auto()); - return Ok(GenericBackgroundSize::Explicit { width, height }); + return Ok(GenericBackgroundSize::ExplicitSize { width, height }); } Ok(try_match_ident_ignore_ascii_case! { input, "cover" => GenericBackgroundSize::Cover, @@ -35,16 +35,6 @@ impl Parse for BackgroundSize { } } -impl BackgroundSize { - /// Returns `auto auto`. - pub fn auto() -> Self { - GenericBackgroundSize::Explicit { - width: NonNegativeLengthPercentageOrAuto::auto(), - height: NonNegativeLengthPercentageOrAuto::auto(), - } - } -} - /// One of the keywords for `background-repeat`. #[derive( Clone, diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index b94ec8a0f26..2495cca3d6c 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -392,6 +392,76 @@ pub enum ScrollSnapType { Proximity, } +/// Specified value of scroll-snap-align keyword value. +#[allow(missing_docs)] +#[derive( + Clone, + Copy, + Debug, + Eq, + FromPrimitive, + Hash, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, +)] +#[repr(u8)] +pub enum ScrollSnapAlignKeyword { + None, + Start, + End, + Center, +} + +/// https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] +#[repr(C)] +pub struct ScrollSnapAlign { + block: ScrollSnapAlignKeyword, + inline: ScrollSnapAlignKeyword, +} + +impl ScrollSnapAlign { + /// Returns `none`. + #[inline] + pub fn none() -> Self { + ScrollSnapAlign { + block: ScrollSnapAlignKeyword::None, + inline: ScrollSnapAlignKeyword::None, + } + } +} + +impl Parse for ScrollSnapAlign { + /// [ none | start | end | center ]{1,2} + fn parse<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<ScrollSnapAlign, ParseError<'i>> { + let block = ScrollSnapAlignKeyword::parse(input)?; + let inline = input.try(ScrollSnapAlignKeyword::parse).unwrap_or(block); + Ok(ScrollSnapAlign { block, inline }) + } +} + +impl ToCss for ScrollSnapAlign { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: Write, + { + self.block.to_css(dest)?; + if self.block != self.inline { + dest.write_str(" ")?; + self.inline.to_css(dest)?; + } + Ok(()) + } +} + #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( @@ -782,20 +852,6 @@ impl Parse for Contain { /// A specified value for the `perspective` property. pub type Perspective = GenericPerspective<NonNegativeLength>; -impl Parse for Perspective { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("none")).is_ok() { - return Ok(GenericPerspective::None); - } - Ok(GenericPerspective::Length(NonNegativeLength::parse( - context, input, - )?)) - } -} - /// A given transition property, that is either `All`, a longhand or shorthand /// property, or an unsupported or custom property. #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 97b450362b3..2ee159987f8 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -11,7 +11,7 @@ use crate::parser::{Parse, ParserContext}; #[cfg(feature = "gecko")] use crate::properties::longhands::system_colors::SystemColor; use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue}; -use crate::values::generics::color::Color as GenericColor; +use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto}; use crate::values::specified::calc::CalcNode; use cssparser::{AngleOrNumber, Color as CSSParserColor, Parser, Token, RGBA}; use cssparser::{BasicParseErrorKind, NumberOrPercentage, ParseErrorKind}; @@ -469,3 +469,6 @@ impl Parse for ColorPropertyValue { Color::parse_quirky(context, input, AllowQuirks::Yes).map(ColorPropertyValue) } } + +/// auto | <color> +pub type ColorOrAuto = GenericColorOrAuto<Color>; diff --git a/components/style/values/specified/column.rs b/components/style/values/specified/column.rs index 5d612de437a..2dd7bb0144d 100644 --- a/components/style/values/specified/column.rs +++ b/components/style/values/specified/column.rs @@ -4,25 +4,8 @@ //! Specified types for the column properties. -use crate::parser::{Parse, ParserContext}; use crate::values::generics::column::ColumnCount as GenericColumnCount; use crate::values::specified::PositiveInteger; -use cssparser::Parser; -use style_traits::ParseError; /// A specified type for `column-count` values. pub type ColumnCount = GenericColumnCount<PositiveInteger>; - -impl Parse for ColumnCount { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("auto")).is_ok() { - return Ok(GenericColumnCount::Auto); - } - Ok(GenericColumnCount::Integer(PositiveInteger::parse( - context, input, - )?)) - } -} diff --git a/components/style/values/specified/flex.rs b/components/style/values/specified/flex.rs index a1131dbff5f..7c767cdf34b 100644 --- a/components/style/values/specified/flex.rs +++ b/components/style/values/specified/flex.rs @@ -4,39 +4,22 @@ //! Specified types for CSS values related to flexbox. -use crate::parser::{Parse, ParserContext}; use crate::values::generics::flex::FlexBasis as GenericFlexBasis; use crate::values::specified::Size; -use cssparser::Parser; -use style_traits::ParseError; /// A specified value for the `flex-basis` property. pub type FlexBasis = GenericFlexBasis<Size>; -impl Parse for FlexBasis { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if let Ok(width) = input.try(|i| Size::parse(context, i)) { - return Ok(GenericFlexBasis::Width(width)); - } - try_match_ident_ignore_ascii_case! { input, - "content" => Ok(GenericFlexBasis::Content), - } - } -} - impl FlexBasis { /// `auto` #[inline] pub fn auto() -> Self { - GenericFlexBasis::Width(Size::auto()) + GenericFlexBasis::Size(Size::auto()) } /// `0%` #[inline] pub fn zero_percent() -> Self { - GenericFlexBasis::Width(Size::zero_percent()) + GenericFlexBasis::Size(Size::zero_percent()) } } diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index 5d428656d40..0344af275ce 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -17,7 +17,7 @@ use crate::values::generics::font::{KeywordSize, VariationValue}; use crate::values::generics::NonNegative; use crate::values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX}; use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage}; -use crate::values::specified::{NoCalcLength, Number, Percentage}; +use crate::values::specified::{NoCalcLength, NonNegativeNumber, Number, Percentage}; use crate::values::CustomIdent; use crate::Atom; use app_units::Au; @@ -81,7 +81,7 @@ pub const MAX_FONT_WEIGHT: f32 = 1000.; /// A specified font-weight value. /// /// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] +#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] pub enum FontWeight { /// `<font-weight-absolute>` Absolute(AbsoluteFontWeight), @@ -111,22 +111,6 @@ impl FontWeight { } } -impl Parse for FontWeight { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<FontWeight, ParseError<'i>> { - if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) { - return Ok(FontWeight::Absolute(absolute)); - } - - Ok(try_match_ident_ignore_ascii_case! { input, - "bolder" => FontWeight::Bolder, - "lighter" => FontWeight::Lighter, - }) - } -} - impl ToComputedValue for FontWeight { type ComputedValue = computed::FontWeight; @@ -335,7 +319,7 @@ impl SpecifiedFontStyle { } /// The specified value of the `font-style` property. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] +#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] #[allow(missing_docs)] pub enum FontStyle { Specified(SpecifiedFontStyle), @@ -368,20 +352,11 @@ impl ToComputedValue for FontStyle { } } -impl Parse for FontStyle { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Ok(FontStyle::Specified(SpecifiedFontStyle::parse( - context, input, - )?)) - } -} - /// A value for the `font-stretch` property. /// /// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop +/// +/// TODO(emilio): We could derive Parse if we had NonNegativePercentage. #[allow(missing_docs)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] #[repr(u8)] @@ -628,13 +603,13 @@ impl Parse for FamilyName { } } -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] +#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] /// Preserve the readability of text when font fallback occurs pub enum FontSizeAdjust { /// None variant None, /// Number variant - Number(Number), + Number(NonNegativeNumber), /// system font #[css(skip)] System(SystemFont), @@ -657,7 +632,9 @@ impl ToComputedValue for FontSizeAdjust { match *self { FontSizeAdjust::None => computed::FontSizeAdjust::None, FontSizeAdjust::Number(ref n) => { - computed::FontSizeAdjust::Number(n.to_computed_value(context)) + // The computed version handles clamping of animated values + // itself. + computed::FontSizeAdjust::Number(n.to_computed_value(context).0) }, FontSizeAdjust::System(_) => self.compute_system(context), } @@ -666,32 +643,13 @@ impl ToComputedValue for FontSizeAdjust { fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self { match *computed { computed::FontSizeAdjust::None => FontSizeAdjust::None, - computed::FontSizeAdjust::Number(ref v) => { - FontSizeAdjust::Number(Number::from_computed_value(v)) + computed::FontSizeAdjust::Number(v) => { + FontSizeAdjust::Number(NonNegativeNumber::from_computed_value(&v.into())) }, } } } -impl Parse for FontSizeAdjust { - /// none | <number> - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<FontSizeAdjust, ParseError<'i>> { - if input - .try(|input| input.expect_ident_matching("none")) - .is_ok() - { - return Ok(FontSizeAdjust::None); - } - - Ok(FontSizeAdjust::Number(Number::parse_non_negative( - context, input, - )?)) - } -} - /// Additional information for specified keyword-derived font sizes. pub type KeywordInfo = generics::KeywordInfo<NonNegativeLength>; diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 2dc56f8ad3f..c9d0f10215d 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -305,7 +305,7 @@ impl Gradient { ) -> Result<Self, ParseError<'i>> { type Point = GenericPosition<Component<X>, Component<Y>>; - #[derive(Clone, Copy)] + #[derive(Clone, Copy, Parse)] enum Component<S> { Center, Number(NumberOrPercentage), @@ -408,22 +408,6 @@ impl Gradient { } } - impl<S: Parse> Parse for Component<S> { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if let Ok(side) = input.try(|i| S::parse(context, i)) { - return Ok(Component::Side(side)); - } - if let Ok(number) = input.try(|i| NumberOrPercentage::parse(context, i)) { - return Ok(Component::Number(number)); - } - input.try(|i| i.expect_ident_matching("center"))?; - Ok(Component::Center) - } - } - let ident = input.expect_ident_cloned()?; input.expect_comma()?; diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 597aa990f0c..a8cae981993 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -11,10 +11,13 @@ use crate::font_metrics::FontMetricsQueryResult; use crate::parser::{Parse, ParserContext}; use crate::values::computed::{self, CSSPixelLength, Context}; use crate::values::generics::length as generics; -use crate::values::generics::length::{MaxSize as GenericMaxSize, Size as GenericSize}; +use crate::values::generics::length::{ + GenericLengthOrNumber, MaxSize as GenericMaxSize, Size as GenericSize, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::calc::CalcNode; +use crate::values::specified::NonNegativeNumber; use crate::values::{Auto, CSSFloat, Either, Normal}; use app_units::Au; use cssparser::{Parser, Token}; @@ -1023,30 +1026,7 @@ pub type LengthOrNormal = Either<Length, Normal>; pub type LengthOrAuto = Either<Length, Auto>; /// Either a `<length>` or a `<number>`. -pub type LengthOrNumber = Either<Length, Number>; - -impl LengthOrNumber { - /// Parse a non-negative LengthOrNumber. - pub fn parse_non_negative<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - // We try to parse as a Number first because, for cases like - // LengthOrNumber, we want "0" to be parsed as a plain Number rather - // than a Length (0px); this matches the behaviour of all major browsers - if let Ok(v) = input.try(|i| Number::parse_non_negative(context, i)) { - return Ok(Either::Second(v)); - } - - Length::parse_non_negative(context, input).map(Either::First) - } - - /// Returns `0`. - #[inline] - pub fn zero() -> Self { - Either::Second(Number::new(0.)) - } -} +pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>; /// A specified value for `min-width`, `min-height`, `width` or `height` property. pub type Size = GenericSize<NonNegativeLengthPercentage>; @@ -1123,3 +1103,6 @@ impl MaxSize { Ok(GenericMaxSize::LengthPercentage(length)) } } + +/// A specified non-negative `<length>` | `<number>`. +pub type NonNegativeLengthOrNumber = GenericLengthOrNumber<NonNegativeLength, NonNegativeNumber>; diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index a9582e90307..4956d53f177 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -19,9 +19,10 @@ use crate::values::serialize_atom_identifier; use crate::values::specified::calc::CalcNode; use crate::{Atom, Namespace, Prefix}; use cssparser::{Parser, Token}; -use num_traits::One; +use num_traits::{One, Zero}; use std::f32; use std::fmt::{self, Write}; +use std::ops::Add; use style_traits::values::specified::AllowedNumericType; use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; @@ -39,8 +40,9 @@ pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; pub use self::box_::{Appearance, BreakBetween, BreakWithin}; pub use self::box_::{Clear, Float, Overflow, OverflowAnchor}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize}; -pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorPropertyValue, RGBAColor}; +pub use self::box_::{ScrollSnapAlign, ScrollSnapType}; +pub use self::box_::{TouchAction, TransitionProperty, VerticalAlign, WillChange}; +pub use self::color::{Color, ColorOrAuto, ColorPropertyValue, RGBAColor}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::easing::TimingFunction; @@ -57,7 +59,7 @@ pub use self::gecko::ScrollSnapPoint; pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect}; pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth}; -pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; +pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber}; pub use self::length::{LengthPercentage, LengthPercentageOrAuto}; pub use self::length::{MaxSize, Size}; pub use self::length::{NoCalcLength, ViewportPercentageLength}; @@ -70,14 +72,14 @@ pub use self::outline::OutlineStyle; pub use self::percentage::Percentage; pub use self::position::{GridAutoFlow, GridTemplateAreas, Position}; pub use self::position::{PositionComponent, ZIndex}; -pub use self::rect::LengthOrNumberRect; +pub use self::rect::NonNegativeLengthOrNumberRect; pub use self::resolution::Resolution; pub use self::svg::MozContextProperties; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; pub use self::svg_path::SVGPathData; pub use self::table::XSpan; -pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize, TextAlign}; +pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextAlign}; pub use self::text::{OverflowWrap, TextEmphasisPosition, TextEmphasisStyle}; pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing}; pub use self::time::Time; @@ -85,7 +87,7 @@ pub use self::transform::{Rotate, Scale, Transform}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon, UserSelect}; +pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect}; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; #[cfg(feature = "gecko")] @@ -270,6 +272,26 @@ impl IsParallelTo for (Number, Number, Number) { impl SpecifiedValueInfo for Number {} +impl Add for Number { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self::new(self.get() + other.get()) + } +} + +impl Zero for Number { + #[inline] + fn zero() -> Self { + Self::new(0.) + } + + #[inline] + fn is_zero(&self) -> bool { + self.get() == 0. + } +} + impl From<Number> for f32 { #[inline] fn from(n: Number) -> Self { @@ -563,7 +585,7 @@ impl Parse for PositiveInteger { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - Integer::parse_positive(context, input).map(GreaterThanOrEqualToOne::<Integer>) + Integer::parse_positive(context, input).map(GreaterThanOrEqualToOne) } } diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index b9006ee799b..0212763ec6d 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -731,15 +731,3 @@ impl GridTemplateAreas { /// A specified value for the `z-index` property. pub type ZIndex = GenericZIndex<Integer>; - -impl Parse for ZIndex { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("auto")).is_ok() { - return Ok(GenericZIndex::Auto); - } - Ok(GenericZIndex::Integer(Integer::parse(context, input)?)) - } -} diff --git a/components/style/values/specified/rect.rs b/components/style/values/specified/rect.rs index d86a382c7e9..7955ecaa48d 100644 --- a/components/style/values/specified/rect.rs +++ b/components/style/values/specified/rect.rs @@ -4,22 +4,8 @@ //! Specified types for CSS borders. -use crate::parser::ParserContext; use crate::values::generics::rect::Rect; -use crate::values::specified::length::LengthOrNumber; -use cssparser::Parser; -use style_traits::ParseError; +use crate::values::specified::length::NonNegativeLengthOrNumber; /// A specified rectangle made of four `<length-or-number>` values. -pub type LengthOrNumberRect = Rect<LengthOrNumber>; - -impl LengthOrNumberRect { - /// Parses a `LengthOrNumberRect`, rejecting negative values. - #[inline] - pub fn parse_non_negative<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Rect::parse_with(context, input, LengthOrNumber::parse_non_negative) - } -} +pub type NonNegativeLengthOrNumberRect = Rect<NonNegativeLengthOrNumber>; diff --git a/components/style/values/specified/svg.rs b/components/style/values/specified/svg.rs index 9e9c435ab9d..98db273e61c 100644 --- a/components/style/values/specified/svg.rs +++ b/components/style/values/specified/svg.rs @@ -23,31 +23,6 @@ pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>; /// Specified SVG Paint Kind value pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>; -#[cfg(feature = "gecko")] -fn is_context_value_enabled() -> bool { - // The prefs can only be mutated on the main thread, so it is safe - // to read whenever we are on the main thread or the main thread is - // blocked. - use crate::gecko_bindings::structs::mozilla; - unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled } -} -#[cfg(not(feature = "gecko"))] -fn is_context_value_enabled() -> bool { - false -} - -fn parse_context_value<'i, 't, T>( - input: &mut Parser<'i, 't>, - value: T, -) -> Result<T, ParseError<'i>> { - if !is_context_value_enabled() { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - - input.expect_ident_matching("context-value")?; - Ok(value) -} - /// A value of <length> | <percentage> | <number> for stroke-dashoffset. /// <https://www.w3.org/TR/SVG11/painting.html#StrokeProperties> pub type SvgLengthPercentageOrNumber = @@ -56,18 +31,6 @@ pub type SvgLengthPercentageOrNumber = /// <length> | <percentage> | <number> | context-value pub type SVGLength = generic::SVGLength<SvgLengthPercentageOrNumber>; -impl Parse for SVGLength { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - input - .try(|i| SvgLengthPercentageOrNumber::parse(context, i)) - .map(Into::into) - .or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue)) - } -} - impl From<SvgLengthPercentageOrNumber> for SVGLength { fn from(length: SvgLengthPercentageOrNumber) -> Self { generic::SVGLength::Length(length) @@ -82,18 +45,6 @@ pub type NonNegativeSvgLengthPercentageOrNumber = /// A non-negative version of SVGLength. pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthPercentageOrNumber>; -impl Parse for SVGWidth { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - input - .try(|i| NonNegativeSvgLengthPercentageOrNumber::parse(context, i)) - .map(Into::into) - .or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue)) - } -} - impl From<NonNegativeSvgLengthPercentageOrNumber> for SVGWidth { fn from(length: NonNegativeSvgLengthPercentageOrNumber) -> Self { generic::SVGLength::Length(length) @@ -113,34 +64,21 @@ impl Parse for SVGStrokeDashArray { NonNegativeSvgLengthPercentageOrNumber::parse(context, i) }) }) { - Ok(generic::SVGStrokeDashArray::Values(values)) - } else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) { - Ok(generic::SVGStrokeDashArray::Values(vec![])) - } else { - parse_context_value(input, generic::SVGStrokeDashArray::ContextValue) - } - } -} - -/// <opacity-value> | context-fill-opacity | context-stroke-opacity -pub type SVGOpacity = generic::SVGOpacity<Opacity>; - -impl Parse for SVGOpacity { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if let Ok(opacity) = input.try(|i| Opacity::parse(context, i)) { - return Ok(generic::SVGOpacity::Opacity(opacity)); + return Ok(generic::SVGStrokeDashArray::Values(values)); } try_match_ident_ignore_ascii_case! { input, - "context-fill-opacity" => Ok(generic::SVGOpacity::ContextFillOpacity), - "context-stroke-opacity" => Ok(generic::SVGOpacity::ContextStrokeOpacity), + "context-value" if generic::is_context_value_enabled(context) => { + Ok(generic::SVGStrokeDashArray::ContextValue) + }, + "none" => Ok(generic::SVGStrokeDashArray::Values(vec![])), } } } +/// <opacity-value> | context-fill-opacity | context-stroke-opacity +pub type SVGOpacity = generic::SVGOpacity<Opacity>; + /// The specified value for a single CSS paint-order property. #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ToCss)] diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs index d395132f5b1..1879dc4159a 100644 --- a/components/style/values/specified/text.rs +++ b/components/style/values/specified/text.rs @@ -13,11 +13,10 @@ use crate::values::computed::text::TextOverflow as ComputedTextOverflow; use crate::values::computed::{Context, ToComputedValue}; use crate::values::generics::text::InitialLetter as GenericInitialLetter; use crate::values::generics::text::LineHeight as GenericLineHeight; -use crate::values::generics::text::MozTabSize as GenericMozTabSize; use crate::values::generics::text::Spacing; +use crate::values::specified::length::NonNegativeLengthPercentage; use crate::values::specified::length::{FontRelativeLength, Length}; use crate::values::specified::length::{LengthPercentage, NoCalcLength}; -use crate::values::specified::length::{NonNegativeLength, NonNegativeLengthPercentage}; use crate::values::specified::{AllowQuirks, Integer, NonNegativeNumber, Number}; use cssparser::{Parser, Token}; use selectors::parser::SelectorParseErrorKind; @@ -420,7 +419,7 @@ pub enum TextAlignKeyword { /// Specified value of text-align property. #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, SpecifiedValueInfo, ToCss)] +#[derive(Clone, Copy, Debug, Eq, Hash, Parse, PartialEq, SpecifiedValueInfo, ToCss)] pub enum TextAlign { /// Keyword value of text-align property. Keyword(TextAlignKeyword), @@ -436,27 +435,6 @@ pub enum TextAlign { MozCenterOrInherit, } -impl Parse for TextAlign { - fn parse<'i, 't>( - _context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - // MozCenterOrInherit cannot be parsed, only set directly on the elements - if let Ok(key) = input.try(TextAlignKeyword::parse) { - return Ok(TextAlign::Keyword(key)); - } - #[cfg(feature = "gecko")] - { - input.expect_ident_matching("match-parent")?; - return Ok(TextAlign::MatchParent); - } - #[cfg(feature = "servo")] - { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - } -} - impl TextAlign { /// Convert an enumerated value coming from Gecko to a `TextAlign`. #[cfg(feature = "gecko")] @@ -835,25 +813,6 @@ impl From<TextEmphasisPosition> for u8 { } } -/// A specified value for the `-moz-tab-size` property. -pub type MozTabSize = GenericMozTabSize<NonNegativeNumber, NonNegativeLength>; - -impl Parse for MozTabSize { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if let Ok(number) = input.try(|i| NonNegativeNumber::parse(context, i)) { - // Numbers need to be parsed first because `0` must be recognised - // as the number `0` and not the length `0px`. - return Ok(GenericMozTabSize::Number(number)); - } - Ok(GenericMozTabSize::Length(NonNegativeLength::parse( - context, input, - )?)) - } -} - /// Values for the `overflow-wrap` property. #[repr(u8)] #[derive( diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs index 859cbd80e2a..c4f43735498 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -231,7 +231,7 @@ impl Parse for Transform { } /// The specified value of a component of a CSS `<transform-origin>`. -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] +#[derive(Clone, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] pub enum OriginComponent<S> { /// `center` Center, @@ -295,25 +295,6 @@ impl Parse for TransformOrigin { } } -impl<S> Parse for OriginComponent<S> -where - S: Parse, -{ - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("center")).is_ok() { - return Ok(OriginComponent::Center); - } - if let Ok(lp) = input.try(|i| LengthPercentage::parse(context, i)) { - return Ok(OriginComponent::Length(lp)); - } - let keyword = S::parse(context, input)?; - Ok(OriginComponent::Side(keyword)) - } -} - impl<S> ToComputedValue for OriginComponent<S> where S: Side, diff --git a/components/style/values/specified/ui.rs b/components/style/values/specified/ui.rs index 2290ac06d6d..0ccca5d359e 100644 --- a/components/style/values/specified/ui.rs +++ b/components/style/values/specified/ui.rs @@ -9,14 +9,10 @@ use crate::values::generics::ui as generics; use crate::values::specified::color::Color; use crate::values::specified::url::SpecifiedImageUrl; use crate::values::specified::Number; -use crate::values::{Auto, Either}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; -/// auto | <color> -pub type ColorOrAuto = Either<Color, Auto>; - /// A specified value for the `cursor` property. pub type Cursor = generics::Cursor<CursorImage>; diff --git a/components/style_derive/parse.rs b/components/style_derive/parse.rs index 0f68f1df5ff..b9b7ae37e1c 100644 --- a/components/style_derive/parse.rs +++ b/components/style_derive/parse.rs @@ -5,8 +5,8 @@ use crate::cg; use crate::to_css::CssVariantAttrs; use proc_macro2::TokenStream; -use syn::{DeriveInput, Path}; -use synstructure; +use syn::{self, DeriveInput, Path}; +use synstructure::{Structure, VariantInfo}; #[darling(attributes(parse), default)] #[derive(Default, FromVariant)] @@ -15,22 +15,90 @@ pub struct ParseVariantAttrs { pub condition: Option<Path>, } -pub fn derive(input: DeriveInput) -> TokenStream { +fn parse_non_keyword_variant( + name: &syn::Ident, + variant: &VariantInfo, + variant_attrs: &CssVariantAttrs, + parse_attrs: &ParseVariantAttrs, + skip_try: bool, +) -> TokenStream { + let bindings = variant.bindings(); + assert!(parse_attrs.aliases.is_none()); + assert!(variant_attrs.function.is_none()); + assert!(variant_attrs.keyword.is_none()); + assert_eq!( + bindings.len(), + 1, + "We only support deriving parse for simple variants" + ); + let variant_name = &variant.ast().ident; + let ty = &bindings[0].ast().ty; + let mut parse = if skip_try { + quote! { + let v = <#ty as crate::parser::Parse>::parse(context, input)?; + return Ok(#name::#variant_name(v)); + } + } else { + quote! { + if let Ok(v) = input.try(|i| <#ty as crate::parser::Parse>::parse(context, i)) { + return Ok(#name::#variant_name(v)); + } + } + }; + + if let Some(ref condition) = parse_attrs.condition { + parse = quote! { + if #condition(context) { + #parse + } + }; + + if skip_try { + // We're the last variant and we can fail to parse due to the + // condition clause. If that happens, we need to return an error. + parse = quote! { + #parse + Err(input.new_custom_error(style_traits::StyleParseErrorKind::UnspecifiedError)) + }; + } + } + + parse +} + +pub fn derive(mut input: DeriveInput) -> TokenStream { + { + let mut where_clause = input.generics.where_clause.take(); + for param in input.generics.type_params() { + cg::add_predicate( + &mut where_clause, + parse_quote!(#param: crate::parser::Parse), + ); + } + input.generics.where_clause = where_clause; + } + let name = &input.ident; - let s = synstructure::Structure::new(&input); + let s = Structure::new(&input); let mut saw_condition = false; - let match_body = s.variants().iter().fold(quote!(), |match_body, variant| { - let bindings = variant.bindings(); - assert!( - bindings.is_empty(), - "Parse is only supported for single-variant enums for now" - ); + let mut match_keywords = quote! {}; + let mut non_keywords = vec![]; + let mut effective_variants = 0; + for variant in s.variants().iter() { let css_variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast()); let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast()); if css_variant_attrs.skip { - return match_body; + continue; + } + effective_variants += 1; + + saw_condition |= parse_attrs.condition.is_some(); + + if !variant.bindings().is_empty() { + non_keywords.push((variant, css_variant_attrs, parse_attrs)); + continue; } let identifier = cg::to_css_identifier( @@ -40,55 +108,73 @@ pub fn derive(input: DeriveInput) -> TokenStream { ); let ident = &variant.ast().ident; - saw_condition |= parse_attrs.condition.is_some(); let condition = match parse_attrs.condition { Some(ref p) => quote! { if #p(context) }, None => quote! {}, }; - let mut body = quote! { - #match_body + match_keywords.extend(quote! { #identifier #condition => Ok(#name::#ident), - }; + }); let aliases = match parse_attrs.aliases { Some(aliases) => aliases, - None => return body, + None => continue, }; for alias in aliases.split(',') { - body = quote! { - #body + match_keywords.extend(quote! { #alias #condition => Ok(#name::#ident), - }; + }); } + } - body - }); + let needs_context = saw_condition || !non_keywords.is_empty(); - let context_ident = if saw_condition { + let context_ident = if needs_context { quote! { context } } else { quote! { _ } }; - let parse_body = if saw_condition { - quote! { - let location = input.current_source_location(); - let ident = input.expect_ident()?; - match_ignore_ascii_case! { &ident, - #match_body - _ => Err(location.new_unexpected_token_error( - cssparser::Token::Ident(ident.clone()) - )) + let has_keywords = non_keywords.len() != effective_variants; + + let mut parse_non_keywords = quote! {}; + for (i, (variant, css_attrs, parse_attrs)) in non_keywords.iter().enumerate() { + let skip_try = !has_keywords && i == non_keywords.len() - 1; + let parse_variant = + parse_non_keyword_variant(name, variant, css_attrs, parse_attrs, skip_try); + parse_non_keywords.extend(parse_variant); + } + + let parse_body = if needs_context { + let parse_keywords = if has_keywords { + quote! { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + match_ignore_ascii_case! { &ident, + #match_keywords + _ => Err(location.new_unexpected_token_error( + cssparser::Token::Ident(ident.clone()) + )) + } } + } else { + quote! {} + }; + + quote! { + #parse_non_keywords + #parse_keywords } } else { quote! { Self::parse(input) } }; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let parse_trait_impl = quote! { - impl crate::parser::Parse for #name { + impl #impl_generics crate::parser::Parse for #name #ty_generics #where_clause { #[inline] fn parse<'i, 't>( #context_ident: &crate::parser::ParserContext, @@ -99,10 +185,12 @@ pub fn derive(input: DeriveInput) -> TokenStream { } }; - if saw_condition { + if needs_context { return parse_trait_impl; } + assert!(non_keywords.is_empty()); + // TODO(emilio): It'd be nice to get rid of these, but that makes the // conversion harder... let methods_impl = quote! { @@ -125,7 +213,7 @@ pub fn derive(input: DeriveInput) -> TokenStream { #[inline] pub fn from_ident(ident: &str) -> Result<Self, ()> { match_ignore_ascii_case! { ident, - #match_body + #match_keywords _ => Err(()), } } |