diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index 7b22c37f73f..eb6463c2e10 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -9,6 +9,7 @@ use crate::values::computed::{Integer, LengthPercentage, Percentage}; use crate::values::generics::position::Position as GenericPosition; +use crate::values::generics::position::PositionComponent as GenericPositionComponent; use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto; use crate::values::generics::position::ZIndex as GenericZIndex; pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas}; @@ -56,5 +57,14 @@ impl ToCss for Position { } } +impl GenericPositionComponent for LengthPercentage { + fn is_center(&self) -> bool { + match self.to_percentage() { + Some(Percentage(per)) => per == 0.5, + _ => false + } + } +} + /// A computed value for the `z-index` property. pub type ZIndex = GenericZIndex; diff --git a/components/style/values/generics/image.rs b/components/style/values/generics/image.rs index 9e70d68f3c7..28eba90bd4c 100644 --- a/components/style/values/generics/image.rs +++ b/components/style/values/generics/image.rs @@ -13,6 +13,7 @@ use crate::Zero; use servo_arc::Arc; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; +use values::generics::position::PositionComponent; /// An ` | none` value. /// @@ -330,7 +331,7 @@ where LP: ToCss, NL: ToCss, NLP: ToCss, - P: ToCss, + P: PositionComponent + ToCss, A: ToCss, AoP: ToCss, C: ToCss, @@ -379,36 +380,59 @@ where EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true, _ => false, }; + let omit_position = position.is_center(); if compat_mode == GradientCompatMode::Modern { if !omit_shape { shape.to_css(dest)?; - dest.write_str(" ")?; + if !omit_position { + dest.write_str(" ")?; + } + } + if !omit_position { + dest.write_str("at ")?; + position.to_css(dest)?; } - dest.write_str("at ")?; - position.to_css(dest)?; } else { - position.to_css(dest)?; + if !omit_position { + position.to_css(dest)?; + if !omit_shape { + dest.write_str(", ")?; + } + } if !omit_shape { - dest.write_str(", ")?; shape.to_css(dest)?; } } + let mut skip_comma = omit_shape && omit_position; for item in &**items { - dest.write_str(", ")?; + if !skip_comma { + dest.write_str(", ")?; + } + skip_comma = false; item.to_css(dest)?; } }, Gradient::Conic { ref angle, ref position, ref items, .. } => { dest.write_str("conic-gradient(")?; - if !angle.is_zero() { + let omit_angle = angle.is_zero(); + let omit_position = position.is_center(); + if !omit_angle { dest.write_str("from ")?; angle.to_css(dest)?; - dest.write_str(" ")?; + if !omit_position { + dest.write_str(" ")?; + } } - dest.write_str("at ")?; - position.to_css(dest)?; + if !omit_position { + dest.write_str("at ")?; + position.to_css(dest)?; + } + let mut skip_comma = omit_angle && omit_position; for item in &**items { - dest.write_str(", ")?; + if !skip_comma { + dest.write_str(", ")?; + } + skip_comma = false; item.to_css(dest)?; } }, diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index a3552ea3eab..00a9a219df4 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -31,6 +31,17 @@ pub struct GenericPosition { pub vertical: V, } +impl PositionComponent for Position +where + H: PositionComponent, + V: PositionComponent, +{ + #[inline] + fn is_center(&self) -> bool { + self.horizontal.is_center() && self.vertical.is_center() + } +} + pub use self::GenericPosition as Position; impl Position { @@ -43,6 +54,13 @@ impl Position { } } +/// Implements a method that checks if the position is centered. +pub trait PositionComponent { + /// Returns if the position component is 50% or center. + /// For pixel lengths, it always returns false. + fn is_center(&self) -> bool; +} + /// A generic type for representing an `Auto | `. /// This is used by for now. /// https://drafts.fxtf.org/motion-1/#offset-anchor-property diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index ae21e739973..b843de29a41 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -13,6 +13,7 @@ use crate::str::HTML_SPACE_CHARACTERS; use crate::values::computed::LengthPercentage as ComputedLengthPercentage; use crate::values::computed::{Context, Percentage, ToComputedValue}; use crate::values::generics::position::Position as GenericPosition; +use crate::values::generics::position::PositionComponent as GenericPositionComponent; use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto; use crate::values::generics::position::ZIndex as GenericZIndex; use crate::values::specified::{AllowQuirks, Integer, LengthPercentage}; @@ -262,6 +263,18 @@ impl PositionComponent { } } +impl GenericPositionComponent for PositionComponent { + fn is_center(&self) -> bool { + match *self { + PositionComponent::Center => true, + PositionComponent::Length(LengthPercentage::Percentage(ref per)) => per.0 == 0.5, + // 50% from any side is still the center. + PositionComponent::Side(_, Some(LengthPercentage::Percentage(ref per))) => per.0 == 0.5, + _ => false, + } + } +} + impl PositionComponent { /// `0%` pub fn zero() -> Self {