style: Omit center positions in conic/radial gradient serialization.

Differential Revision: https://phabricator.services.mozilla.com/D67461
This commit is contained in:
Tim Nguyen 2020-03-27 22:52:32 +00:00 committed by Emilio Cobos Álvarez
parent 414edb5a4a
commit d17b3cc202
4 changed files with 77 additions and 12 deletions

View file

@ -9,6 +9,7 @@
use crate::values::computed::{Integer, LengthPercentage, Percentage}; use crate::values::computed::{Integer, LengthPercentage, Percentage};
use crate::values::generics::position::Position as GenericPosition; 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::PositionOrAuto as GenericPositionOrAuto;
use crate::values::generics::position::ZIndex as GenericZIndex; use crate::values::generics::position::ZIndex as GenericZIndex;
pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas}; 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. /// A computed value for the `z-index` property.
pub type ZIndex = GenericZIndex<Integer>; pub type ZIndex = GenericZIndex<Integer>;

View file

@ -13,6 +13,7 @@ use crate::Zero;
use servo_arc::Arc; use servo_arc::Arc;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss}; use style_traits::{CssWriter, ToCss};
use values::generics::position::PositionComponent;
/// An `<image> | none` value. /// An `<image> | none` value.
/// ///
@ -330,7 +331,7 @@ where
LP: ToCss, LP: ToCss,
NL: ToCss, NL: ToCss,
NLP: ToCss, NLP: ToCss,
P: ToCss, P: PositionComponent + ToCss,
A: ToCss, A: ToCss,
AoP: ToCss, AoP: ToCss,
C: ToCss, C: ToCss,
@ -379,36 +380,59 @@ where
EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true, EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true,
_ => false, _ => false,
}; };
let omit_position = position.is_center();
if compat_mode == GradientCompatMode::Modern { if compat_mode == GradientCompatMode::Modern {
if !omit_shape { if !omit_shape {
shape.to_css(dest)?; 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 { } else {
position.to_css(dest)?; if !omit_position {
position.to_css(dest)?;
if !omit_shape {
dest.write_str(", ")?;
}
}
if !omit_shape { if !omit_shape {
dest.write_str(", ")?;
shape.to_css(dest)?; shape.to_css(dest)?;
} }
} }
let mut skip_comma = omit_shape && omit_position;
for item in &**items { for item in &**items {
dest.write_str(", ")?; if !skip_comma {
dest.write_str(", ")?;
}
skip_comma = false;
item.to_css(dest)?; item.to_css(dest)?;
} }
}, },
Gradient::Conic { ref angle, ref position, ref items, .. } => { Gradient::Conic { ref angle, ref position, ref items, .. } => {
dest.write_str("conic-gradient(")?; 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 ")?; dest.write_str("from ")?;
angle.to_css(dest)?; angle.to_css(dest)?;
dest.write_str(" ")?; if !omit_position {
dest.write_str(" ")?;
}
} }
dest.write_str("at ")?; if !omit_position {
position.to_css(dest)?; dest.write_str("at ")?;
position.to_css(dest)?;
}
let mut skip_comma = omit_angle && omit_position;
for item in &**items { for item in &**items {
dest.write_str(", ")?; if !skip_comma {
dest.write_str(", ")?;
}
skip_comma = false;
item.to_css(dest)?; item.to_css(dest)?;
} }
}, },

View file

@ -31,6 +31,17 @@ pub struct GenericPosition<H, V> {
pub vertical: V, pub vertical: V,
} }
impl<H, V> PositionComponent for Position<H, V>
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; pub use self::GenericPosition as Position;
impl<H, V> Position<H, V> { impl<H, V> Position<H, V> {
@ -43,6 +54,13 @@ impl<H, V> Position<H, V> {
} }
} }
/// 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 | <position>`. /// A generic type for representing an `Auto | <position>`.
/// This is used by <offset-anchor> for now. /// This is used by <offset-anchor> for now.
/// https://drafts.fxtf.org/motion-1/#offset-anchor-property /// https://drafts.fxtf.org/motion-1/#offset-anchor-property

View file

@ -13,6 +13,7 @@ use crate::str::HTML_SPACE_CHARACTERS;
use crate::values::computed::LengthPercentage as ComputedLengthPercentage; use crate::values::computed::LengthPercentage as ComputedLengthPercentage;
use crate::values::computed::{Context, Percentage, ToComputedValue}; use crate::values::computed::{Context, Percentage, ToComputedValue};
use crate::values::generics::position::Position as GenericPosition; 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::PositionOrAuto as GenericPositionOrAuto;
use crate::values::generics::position::ZIndex as GenericZIndex; use crate::values::generics::position::ZIndex as GenericZIndex;
use crate::values::specified::{AllowQuirks, Integer, LengthPercentage}; use crate::values::specified::{AllowQuirks, Integer, LengthPercentage};
@ -262,6 +263,18 @@ impl<S: Parse> PositionComponent<S> {
} }
} }
impl<S> GenericPositionComponent for PositionComponent<S> {
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<S> PositionComponent<S> { impl<S> PositionComponent<S> {
/// `0%` /// `0%`
pub fn zero() -> Self { pub fn zero() -> Self {