aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/display_list/background.rs33
-rw-r--r--components/layout/display_list/border.rs18
-rw-r--r--components/layout/display_list/builder.rs2
-rw-r--r--components/layout/flex.rs5
-rw-r--r--components/style/cbindgen.toml73
-rw-r--r--components/style/gecko/conversions.rs65
-rw-r--r--components/style/gecko/media_features.rs30
-rw-r--r--components/style/gecko/media_queries.rs10
-rw-r--r--components/style/gecko/pseudo_element.rs2
-rw-r--r--components/style/gecko/pseudo_element_definition.mako.rs88
-rwxr-xr-xcomponents/style/gecko/regen_atoms.py11
-rw-r--r--components/style/gecko/values.rs119
-rw-r--r--components/style/gecko_bindings/sugar/style_complex_color.rs16
-rw-r--r--components/style/properties/cascade.rs6
-rw-r--r--components/style/properties/data.py1
-rw-r--r--components/style/properties/gecko.mako.rs380
-rw-r--r--components/style/properties/longhands/border.mako.rs7
-rw-r--r--components/style/properties/longhands/box.mako.rs10
-rw-r--r--components/style/properties/longhands/color.mako.rs2
-rw-r--r--components/style/properties/longhands/font.mako.rs2
-rw-r--r--components/style/properties/longhands/inherited_text.mako.rs8
-rw-r--r--components/style/properties/longhands/inherited_ui.mako.rs2
-rw-r--r--components/style/properties/longhands/margin.mako.rs15
-rw-r--r--components/style/properties/longhands/padding.mako.rs14
-rw-r--r--components/style/properties/longhands/position.mako.rs6
-rw-r--r--components/style/properties/longhands/svg.mako.rs1
-rw-r--r--components/style/properties/properties.mako.rs7
-rw-r--r--components/style/properties/shorthands/margin.mako.rs29
-rw-r--r--components/style/properties/shorthands/padding.mako.rs30
-rw-r--r--components/style/sharing/mod.rs5
-rw-r--r--components/style/stylesheets/document_rule.rs2
-rw-r--r--components/style/values/computed/background.rs11
-rw-r--r--components/style/values/computed/box.rs2
-rw-r--r--components/style/values/computed/color.rs5
-rw-r--r--components/style/values/computed/flex.rs2
-rw-r--r--components/style/values/computed/length.rs36
-rw-r--r--components/style/values/computed/mod.rs13
-rw-r--r--components/style/values/computed/rect.rs4
-rw-r--r--components/style/values/computed/text.rs4
-rw-r--r--components/style/values/computed/transform.rs3
-rw-r--r--components/style/values/computed/ui.rs4
-rw-r--r--components/style/values/generics/background.rs25
-rw-r--r--components/style/values/generics/border.rs5
-rw-r--r--components/style/values/generics/box.rs6
-rw-r--r--components/style/values/generics/color.rs23
-rw-r--r--components/style/values/generics/column.rs1
-rw-r--r--components/style/values/generics/flex.rs8
-rw-r--r--components/style/values/generics/grid.rs5
-rw-r--r--components/style/values/generics/length.rs54
-rw-r--r--components/style/values/generics/mod.rs60
-rw-r--r--components/style/values/generics/position.rs17
-rw-r--r--components/style/values/generics/svg.rs36
-rw-r--r--components/style/values/generics/text.rs22
-rw-r--r--components/style/values/generics/transform.rs11
-rw-r--r--components/style/values/generics/url.rs21
-rw-r--r--components/style/values/mod.rs14
-rw-r--r--components/style/values/specified/background.rs12
-rw-r--r--components/style/values/specified/box.rs84
-rw-r--r--components/style/values/specified/color.rs5
-rw-r--r--components/style/values/specified/column.rs17
-rw-r--r--components/style/values/specified/flex.rs21
-rw-r--r--components/style/values/specified/font.rs66
-rw-r--r--components/style/values/specified/image.rs18
-rw-r--r--components/style/values/specified/length.rs33
-rw-r--r--components/style/values/specified/mod.rs38
-rw-r--r--components/style/values/specified/position.rs12
-rw-r--r--components/style/values/specified/rect.rs18
-rw-r--r--components/style/values/specified/svg.rs78
-rw-r--r--components/style/values/specified/text.rs45
-rw-r--r--components/style/values/specified/transform.rs21
-rw-r--r--components/style/values/specified/ui.rs4
-rw-r--r--components/style_derive/parse.rs156
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(()),
}
}