mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Cleanup gradient parsing by removing the simple-moz-gradient parsing pref.
It looks like bug 1547939 will stick, given how fast the other regressions came in for bug 1337655. We haven't seen any regression from this, and it seems unlikely that we'd want this code back. This blocks further improvements to the style system. Simplifying this code allows me to remove all the conversion code for gradients. Let me know if you think it's premature and I'm happy to wait, but I really want to see this code gone :) Differential Revision: https://phabricator.services.mozilla.com/D33820
This commit is contained in:
parent
e9b0d54a95
commit
3980dc31cd
5 changed files with 50 additions and 443 deletions
|
@ -65,7 +65,6 @@ impl From<Angle> for CoordDataValue {
|
|||
}
|
||||
|
||||
fn line_direction(horizontal: LengthPercentage, vertical: LengthPercentage) -> LineDirection {
|
||||
use crate::values::computed::position::Position;
|
||||
use crate::values::specified::position::{X, Y};
|
||||
|
||||
let horizontal_percentage = horizontal.as_percentage();
|
||||
|
@ -107,13 +106,7 @@ fn line_direction(horizontal: LengthPercentage, vertical: LengthPercentage) -> L
|
|||
}
|
||||
}
|
||||
|
||||
LineDirection::MozPosition(
|
||||
Some(Position {
|
||||
horizontal,
|
||||
vertical,
|
||||
}),
|
||||
None,
|
||||
)
|
||||
unreachable!("Unexpected line direction");
|
||||
}
|
||||
|
||||
impl nsStyleImage {
|
||||
|
@ -241,20 +234,10 @@ impl nsStyleImage {
|
|||
.set_value(CoordDataValue::Percent(percent_y));
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(position, angle) => unsafe {
|
||||
if let Some(position) = position {
|
||||
(*gecko_gradient).mBgPosX.set(position.horizontal);
|
||||
(*gecko_gradient).mBgPosY.set(position.vertical);
|
||||
}
|
||||
if let Some(angle) = angle {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
}
|
||||
},
|
||||
}
|
||||
gecko_gradient
|
||||
},
|
||||
GradientKind::Radial(shape, position, angle) => {
|
||||
GradientKind::Radial(shape, position) => {
|
||||
let keyword_to_gecko_size = |keyword| match keyword {
|
||||
ShapeExtent::ClosestSide => CLOSEST_SIDE,
|
||||
ShapeExtent::FarthestSide => FARTHEST_SIDE,
|
||||
|
@ -294,13 +277,6 @@ impl nsStyleImage {
|
|||
)
|
||||
};
|
||||
|
||||
// Clear mBgPos field and set mAngle if angle is set. Otherwise clear it.
|
||||
unsafe {
|
||||
if let Some(angle) = angle {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
}
|
||||
}
|
||||
|
||||
// Setting radius values depending shape
|
||||
match shape {
|
||||
EndingShape::Circle(Circle::Radius(length)) => unsafe {
|
||||
|
@ -405,30 +381,19 @@ impl nsStyleImage {
|
|||
let gecko_gradient = bindings::Gecko_GetGradientImageValue(self)
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let angle = Angle::from_gecko_style_coord(&gecko_gradient.mAngle);
|
||||
let horizontal_style = LengthPercentage::from_gecko_style_coord(&gecko_gradient.mBgPosX);
|
||||
let vertical_style = LengthPercentage::from_gecko_style_coord(&gecko_gradient.mBgPosY);
|
||||
|
||||
let kind = match gecko_gradient.mShape as u32 {
|
||||
structs::NS_STYLE_GRADIENT_SHAPE_LINEAR => {
|
||||
let angle = Angle::from_gecko_style_coord(&gecko_gradient.mAngle);
|
||||
let line_direction = match (angle, horizontal_style, vertical_style) {
|
||||
(Some(a), None, None) => LineDirection::Angle(a),
|
||||
(None, Some(horizontal), Some(vertical)) => {
|
||||
line_direction(horizontal, vertical)
|
||||
},
|
||||
(Some(_), Some(horizontal), Some(vertical)) => LineDirection::MozPosition(
|
||||
Some(Position {
|
||||
horizontal,
|
||||
vertical,
|
||||
}),
|
||||
angle,
|
||||
),
|
||||
_ => {
|
||||
debug_assert!(
|
||||
horizontal_style.is_none() && vertical_style.is_none(),
|
||||
"Unexpected linear gradient direction"
|
||||
);
|
||||
LineDirection::MozPosition(None, None)
|
||||
unreachable!("unexpected line direction for linear gradient direction");
|
||||
},
|
||||
};
|
||||
GradientKind::Linear(line_direction)
|
||||
|
@ -507,7 +472,7 @@ impl nsStyleImage {
|
|||
},
|
||||
};
|
||||
|
||||
GradientKind::Radial(shape, position, angle)
|
||||
GradientKind::Radial(shape, position)
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -29,11 +29,11 @@ pub type Image = generic::Image<Gradient, MozImageRect, ComputedImageUrl>;
|
|||
/// Computed values for a CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
pub type Gradient =
|
||||
generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color, Angle>;
|
||||
generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color>;
|
||||
|
||||
/// A computed gradient kind.
|
||||
pub type GradientKind =
|
||||
generic::GradientKind<LineDirection, Length, LengthPercentage, Position, Angle>;
|
||||
generic::GradientKind<LineDirection, Length, LengthPercentage, Position>;
|
||||
|
||||
/// A computed gradient line direction.
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
|
||||
|
@ -46,9 +46,6 @@ pub enum LineDirection {
|
|||
Vertical(Y),
|
||||
/// A corner.
|
||||
Corner(X, Y),
|
||||
/// A Position and an Angle for legacy `-moz-` prefixed gradient.
|
||||
#[cfg(feature = "gecko")]
|
||||
MozPosition(Option<Position>, Option<Angle>),
|
||||
}
|
||||
|
||||
/// A computed radial gradient ending shape.
|
||||
|
@ -69,19 +66,6 @@ impl generic::LineDirection for LineDirection {
|
|||
LineDirection::Angle(angle) => angle.radians() == PI,
|
||||
LineDirection::Vertical(Y::Bottom) if compat_mode == CompatMode::Modern => true,
|
||||
LineDirection::Vertical(Y::Top) if compat_mode != CompatMode::Modern => true,
|
||||
LineDirection::Corner(..) => false,
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(
|
||||
Some(Position {
|
||||
ref vertical,
|
||||
ref horizontal,
|
||||
}),
|
||||
None,
|
||||
) => {
|
||||
// `50% 0%` is the default value for line direction.
|
||||
horizontal.as_percentage().map_or(false, |p| p.0 == 0.5) &&
|
||||
vertical.as_percentage().map_or(false, |p| p.0 == 0.0)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -112,21 +96,6 @@ impl generic::LineDirection for LineDirection {
|
|||
dest.write_str(" ")?;
|
||||
y.to_css(dest)
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(position, angle) => {
|
||||
let mut need_space = false;
|
||||
if let Some(position) = position {
|
||||
position.to_css(dest)?;
|
||||
need_space = true;
|
||||
}
|
||||
if let Some(angle) = angle {
|
||||
if need_space {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
angle.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,13 +111,6 @@ impl ToComputedValue for SpecifiedLineDirection {
|
|||
SpecifiedLineDirection::Horizontal(x) => LineDirection::Horizontal(x),
|
||||
SpecifiedLineDirection::Vertical(y) => LineDirection::Vertical(y),
|
||||
SpecifiedLineDirection::Corner(x, y) => LineDirection::Corner(x, y),
|
||||
#[cfg(feature = "gecko")]
|
||||
SpecifiedLineDirection::MozPosition(ref position, ref angle) => {
|
||||
LineDirection::MozPosition(
|
||||
position.to_computed_value(context),
|
||||
angle.to_computed_value(context),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,13 +122,6 @@ impl ToComputedValue for SpecifiedLineDirection {
|
|||
LineDirection::Horizontal(x) => SpecifiedLineDirection::Horizontal(x),
|
||||
LineDirection::Vertical(y) => SpecifiedLineDirection::Vertical(y),
|
||||
LineDirection::Corner(x, y) => SpecifiedLineDirection::Corner(x, y),
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(ref position, ref angle) => {
|
||||
SpecifiedLineDirection::MozPosition(
|
||||
ToComputedValue::from_computed_value(position),
|
||||
ToComputedValue::from_computed_value(angle),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ pub enum Image<Gradient, MozImageRect, ImageUrl> {
|
|||
/// A CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
pub struct Gradient<LineDirection, Length, LengthPercentage, Position, Color, Angle> {
|
||||
pub struct Gradient<LineDirection, Length, LengthPercentage, Position, Color> {
|
||||
/// Gradients can be linear or radial.
|
||||
pub kind: GradientKind<LineDirection, Length, LengthPercentage, Position, Angle>,
|
||||
pub kind: GradientKind<LineDirection, Length, LengthPercentage, Position>,
|
||||
/// The color stops and interpolation hints.
|
||||
pub items: Vec<GradientItem<Color, LengthPercentage>>,
|
||||
/// True if this is a repeating gradient.
|
||||
|
@ -63,15 +63,11 @@ pub enum CompatMode {
|
|||
|
||||
/// A gradient kind.
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
pub enum GradientKind<LineDirection, Length, LengthPercentage, Position, Angle> {
|
||||
pub enum GradientKind<LineDirection, Length, LengthPercentage, Position> {
|
||||
/// A linear gradient.
|
||||
Linear(LineDirection),
|
||||
/// A radial gradient.
|
||||
Radial(
|
||||
EndingShape<Length, LengthPercentage>,
|
||||
Position,
|
||||
Option<Angle>,
|
||||
),
|
||||
Radial(EndingShape<Length, LengthPercentage>, Position),
|
||||
}
|
||||
|
||||
/// A radial gradient's ending shape.
|
||||
|
@ -268,14 +264,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<D, L, LoP, P, C, A> ToCss for Gradient<D, L, LoP, P, C, A>
|
||||
impl<D, L, LoP, P, C> ToCss for Gradient<D, L, LoP, P, C>
|
||||
where
|
||||
D: LineDirection,
|
||||
L: ToCss,
|
||||
LoP: ToCss,
|
||||
P: ToCss,
|
||||
C: ToCss,
|
||||
A: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
|
@ -300,7 +295,7 @@ where
|
|||
direction.to_css(dest, self.compat_mode)?;
|
||||
false
|
||||
},
|
||||
GradientKind::Radial(ref shape, ref position, ref angle) => {
|
||||
GradientKind::Radial(ref shape, ref position) => {
|
||||
let omit_shape = match *shape {
|
||||
EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::Cover)) |
|
||||
EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true,
|
||||
|
@ -315,10 +310,6 @@ where
|
|||
position.to_css(dest)?;
|
||||
} else {
|
||||
position.to_css(dest)?;
|
||||
if let Some(ref a) = *angle {
|
||||
dest.write_str(" ")?;
|
||||
a.to_css(dest)?;
|
||||
}
|
||||
if !omit_shape {
|
||||
dest.write_str(", ")?;
|
||||
shape.to_css(dest)?;
|
||||
|
@ -338,7 +329,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<D, L, LoP, P, A> GradientKind<D, L, LoP, P, A> {
|
||||
impl<D, L, LoP, P> GradientKind<D, L, LoP, P> {
|
||||
fn label(&self) -> &str {
|
||||
match *self {
|
||||
GradientKind::Linear(..) => "linear",
|
||||
|
|
|
@ -8,16 +8,12 @@
|
|||
//! [image]: https://drafts.csswg.org/css-images/#image-values
|
||||
|
||||
use crate::custom_properties::SpecifiedValue;
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::gecko_bindings::structs;
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::stylesheets::CorsMode;
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::values::computed::{Context, Position as ComputedPosition, ToComputedValue};
|
||||
use crate::values::generics::image::PaintWorklet;
|
||||
use crate::values::generics::image::{self as generic, Circle, CompatMode, Ellipse, ShapeExtent};
|
||||
use crate::values::generics::position::Position as GenericPosition;
|
||||
use crate::values::specified::position::{LegacyPosition, Position, PositionComponent, Side, X, Y};
|
||||
use crate::values::specified::position::{Position, PositionComponent, Side, X, Y};
|
||||
use crate::values::specified::url::SpecifiedImageUrl;
|
||||
use crate::values::specified::{Angle, Color, Length, LengthPercentage};
|
||||
use crate::values::specified::{Number, NumberOrPercentage, Percentage};
|
||||
|
@ -55,15 +51,7 @@ pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
|
|||
|
||||
/// Specified values for a CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type Gradient =
|
||||
generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color, Angle>;
|
||||
|
||||
/// Specified values for a CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type Gradient =
|
||||
generic::Gradient<LineDirection, Length, LengthPercentage, GradientPosition, Color, Angle>;
|
||||
pub type Gradient = generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color>;
|
||||
|
||||
impl SpecifiedValueInfo for Gradient {
|
||||
const SUPPORTED_TYPES: u8 = CssType::GRADIENT;
|
||||
|
@ -89,16 +77,11 @@ impl SpecifiedValueInfo for Gradient {
|
|||
}
|
||||
|
||||
/// A specified gradient kind.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type GradientKind =
|
||||
generic::GradientKind<LineDirection, Length, LengthPercentage, Position, Angle>;
|
||||
|
||||
/// A specified gradient kind.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type GradientKind =
|
||||
generic::GradientKind<LineDirection, Length, LengthPercentage, GradientPosition, Angle>;
|
||||
pub type GradientKind = generic::GradientKind<LineDirection, Length, LengthPercentage, Position>;
|
||||
|
||||
/// A specified gradient line direction.
|
||||
///
|
||||
/// FIXME(emilio): This should be generic over Angle.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
|
||||
pub enum LineDirection {
|
||||
/// An angular direction.
|
||||
|
@ -109,22 +92,6 @@ pub enum LineDirection {
|
|||
Vertical(Y),
|
||||
/// A direction towards a corner of a box.
|
||||
Corner(X, Y),
|
||||
/// A Position and an Angle for legacy `-moz-` prefixed gradient.
|
||||
/// `-moz-` prefixed linear gradient can contain both a position and an angle but it
|
||||
/// uses legacy syntax for position. That means we can't specify both keyword and
|
||||
/// length for each horizontal/vertical components.
|
||||
#[cfg(feature = "gecko")]
|
||||
MozPosition(Option<LegacyPosition>, Option<Angle>),
|
||||
}
|
||||
|
||||
/// A binary enum to hold either Position or LegacyPosition.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToShmem)]
|
||||
#[cfg(feature = "gecko")]
|
||||
pub enum GradientPosition {
|
||||
/// 1, 2, 3, 4-valued <position>.
|
||||
Modern(Position),
|
||||
/// 1, 2-valued <position>.
|
||||
Legacy(LegacyPosition),
|
||||
}
|
||||
|
||||
/// A specified ending shape.
|
||||
|
@ -434,18 +401,8 @@ impl Gradient {
|
|||
let shape = generic::EndingShape::Circle(rad);
|
||||
let position: Position = point.into();
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
let pos = GradientPosition::Modern(position);
|
||||
let kind = generic::GradientKind::Radial(shape, pos, None);
|
||||
let kind = generic::GradientKind::Radial(shape, position);
|
||||
(kind, reverse_stops)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
{
|
||||
let kind = generic::GradientKind::Radial(shape, position, None);
|
||||
(kind, reverse_stops)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let e = SelectorParseErrorKind::UnexpectedIdent(ident.clone());
|
||||
|
@ -544,16 +501,6 @@ impl Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn simple_moz_gradient() -> bool {
|
||||
#[cfg(feature = "gecko")]
|
||||
unsafe {
|
||||
return structs::StaticPrefs_sVarCache_layout_css_simple_moz_gradient_enabled;
|
||||
}
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
return false;
|
||||
}
|
||||
|
||||
impl GradientKind {
|
||||
/// Parses a linear gradient.
|
||||
/// CompatMode can change during `-moz-` prefixed gradient parsing if it come across a `to` keyword.
|
||||
|
@ -574,46 +521,19 @@ impl GradientKind {
|
|||
};
|
||||
Ok(generic::GradientKind::Linear(direction))
|
||||
}
|
||||
|
||||
fn parse_radial<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
compat_mode: &mut CompatMode,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let (shape, position, angle, moz_position) = match *compat_mode {
|
||||
let (shape, position) = match *compat_mode {
|
||||
CompatMode::Modern => {
|
||||
let shape = input.try(|i| EndingShape::parse(context, i, *compat_mode));
|
||||
let position = input.try(|i| {
|
||||
i.expect_ident_matching("at")?;
|
||||
Position::parse(context, i)
|
||||
});
|
||||
(shape, position.ok(), None, None)
|
||||
},
|
||||
// The syntax of `-moz-` prefixed radial gradient is:
|
||||
// -moz-radial-gradient(
|
||||
// [ [ <position> || <angle> ]? [ ellipse | [ <length> | <percentage> ]{2} ] , |
|
||||
// [ <position> || <angle> ]? [ [ circle | ellipse ] | <extent-keyword> ] , |
|
||||
// ]?
|
||||
// <color-stop> [ , <color-stop> ]+
|
||||
// )
|
||||
// where <extent-keyword> = closest-corner | closest-side | farthest-corner | farthest-side |
|
||||
// cover | contain
|
||||
// and <color-stop> = <color> [ <percentage> | <length> ]?
|
||||
CompatMode::Moz if !simple_moz_gradient() => {
|
||||
let mut position = input.try(|i| LegacyPosition::parse(context, i));
|
||||
let angle = input.try(|i| Angle::parse(context, i)).ok();
|
||||
if position.is_err() {
|
||||
position = input.try(|i| LegacyPosition::parse(context, i));
|
||||
}
|
||||
|
||||
let shape = input.try(|i| {
|
||||
if position.is_ok() || angle.is_some() {
|
||||
i.expect_comma()?;
|
||||
}
|
||||
EndingShape::parse(context, i, *compat_mode)
|
||||
});
|
||||
|
||||
(shape, None, angle, position.ok())
|
||||
(shape, position.ok())
|
||||
},
|
||||
_ => {
|
||||
let position = input.try(|i| Position::parse(context, i));
|
||||
|
@ -623,11 +543,11 @@ impl GradientKind {
|
|||
}
|
||||
EndingShape::parse(context, i, *compat_mode)
|
||||
});
|
||||
(shape, position.ok(), None, None)
|
||||
(shape, position.ok())
|
||||
},
|
||||
};
|
||||
|
||||
if shape.is_ok() || position.is_some() || angle.is_some() || moz_position.is_some() {
|
||||
if shape.is_ok() || position.is_some() {
|
||||
input.expect_comma()?;
|
||||
}
|
||||
|
||||
|
@ -635,35 +555,8 @@ impl GradientKind {
|
|||
generic::EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner))
|
||||
});
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
if *compat_mode == CompatMode::Moz && !simple_moz_gradient() {
|
||||
// If this form can be represented in Modern mode, then convert the compat_mode to Modern.
|
||||
if angle.is_none() {
|
||||
*compat_mode = CompatMode::Modern;
|
||||
}
|
||||
let position = moz_position.unwrap_or(LegacyPosition::center());
|
||||
return Ok(generic::GradientKind::Radial(
|
||||
shape,
|
||||
GradientPosition::Legacy(position),
|
||||
angle,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let position = position.unwrap_or(Position::center());
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
return Ok(generic::GradientKind::Radial(
|
||||
shape,
|
||||
GradientPosition::Modern(position),
|
||||
angle,
|
||||
));
|
||||
}
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
{
|
||||
return Ok(generic::GradientKind::Radial(shape, position, angle));
|
||||
}
|
||||
Ok(generic::GradientKind::Radial(shape, position))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,35 +566,6 @@ impl generic::LineDirection for LineDirection {
|
|||
LineDirection::Angle(ref angle) => angle.degrees() == 180.0,
|
||||
LineDirection::Vertical(Y::Bottom) if compat_mode == CompatMode::Modern => true,
|
||||
LineDirection::Vertical(Y::Top) if compat_mode != CompatMode::Modern => true,
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(
|
||||
Some(LegacyPosition {
|
||||
horizontal: ref x,
|
||||
vertical: ref y,
|
||||
}),
|
||||
None,
|
||||
) => {
|
||||
use crate::values::computed::Percentage as ComputedPercentage;
|
||||
use crate::values::specified::transform::OriginComponent;
|
||||
|
||||
// `50% 0%` is the default value for line direction.
|
||||
// These percentage values can also be keywords.
|
||||
let x = match *x {
|
||||
OriginComponent::Center => true,
|
||||
OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(
|
||||
val,
|
||||
))) => val == 0.5,
|
||||
_ => false,
|
||||
};
|
||||
let y = match *y {
|
||||
OriginComponent::Side(Y::Top) => true,
|
||||
OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(
|
||||
val,
|
||||
))) => val == 0.0,
|
||||
_ => false,
|
||||
};
|
||||
x && y
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -732,21 +596,6 @@ impl generic::LineDirection for LineDirection {
|
|||
dest.write_str(" ")?;
|
||||
y.to_css(dest)
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(ref position, ref angle) => {
|
||||
let mut need_space = false;
|
||||
if let Some(ref position) = *position {
|
||||
position.to_css(dest)?;
|
||||
need_space = true;
|
||||
}
|
||||
if let Some(ref angle) = *angle {
|
||||
if need_space {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
angle.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -757,16 +606,11 @@ impl LineDirection {
|
|||
input: &mut Parser<'i, 't>,
|
||||
compat_mode: &mut CompatMode,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut _angle = if *compat_mode == CompatMode::Moz && !simple_moz_gradient() {
|
||||
input.try(|i| Angle::parse(context, i)).ok()
|
||||
} else {
|
||||
// Gradients allow unitless zero angles as an exception, see:
|
||||
// https://github.com/w3c/csswg-drafts/issues/1162
|
||||
if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
||||
return Ok(LineDirection::Angle(angle));
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
input.try(|i| {
|
||||
let to_ident = i.try(|i| i.expect_ident_matching("to"));
|
||||
|
@ -787,22 +631,6 @@ impl LineDirection {
|
|||
_ => {},
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
// `-moz-` prefixed linear gradient can be both Angle and Position.
|
||||
if *compat_mode == CompatMode::Moz && !simple_moz_gradient() {
|
||||
let position = i.try(|i| LegacyPosition::parse(context, i)).ok();
|
||||
if _angle.is_none() {
|
||||
_angle = i.try(|i| Angle::parse(context, i)).ok();
|
||||
};
|
||||
|
||||
if _angle.is_none() && position.is_none() {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
return Ok(LineDirection::MozPosition(position, _angle));
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(x) = i.try(X::parse) {
|
||||
if let Ok(y) = i.try(Y::parse) {
|
||||
return Ok(LineDirection::Corner(x, y));
|
||||
|
@ -818,22 +646,6 @@ impl LineDirection {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToComputedValue for GradientPosition {
|
||||
type ComputedValue = ComputedPosition;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> ComputedPosition {
|
||||
match *self {
|
||||
GradientPosition::Modern(ref pos) => pos.to_computed_value(context),
|
||||
GradientPosition::Legacy(ref pos) => pos.to_computed_value(context),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_computed_value(computed: &ComputedPosition) -> Self {
|
||||
GradientPosition::Modern(ToComputedValue::from_computed_value(computed))
|
||||
}
|
||||
}
|
||||
|
||||
impl EndingShape {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
|
@ -878,9 +690,6 @@ impl EndingShape {
|
|||
ShapeExtent::FarthestCorner,
|
||||
)));
|
||||
}
|
||||
// -moz- prefixed radial gradient doesn't allow EndingShape's Length or LengthPercentage
|
||||
// to come before shape keyword. Otherwise it conflicts with <position>.
|
||||
if compat_mode != CompatMode::Moz || simple_moz_gradient() {
|
||||
if let Ok(length) = input.try(|i| Length::parse(context, i)) {
|
||||
if let Ok(y) = input.try(|i| LengthPercentage::parse(context, i)) {
|
||||
if compat_mode == CompatMode::Modern {
|
||||
|
@ -907,7 +716,6 @@ impl EndingShape {
|
|||
|
||||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||
}
|
||||
}
|
||||
input.try(|i| {
|
||||
let x = Percentage::parse(context, i)?;
|
||||
let y = if let Ok(y) = i.try(|i| LengthPercentage::parse(context, i)) {
|
||||
|
|
|
@ -14,7 +14,6 @@ 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::ZIndex as GenericZIndex;
|
||||
use crate::values::specified::transform::OriginComponent;
|
||||
use crate::values::specified::{AllowQuirks, Integer, LengthPercentage};
|
||||
use crate::values::{Either, None_};
|
||||
use crate::Zero;
|
||||
|
@ -326,117 +325,6 @@ impl Side for Y {
|
|||
}
|
||||
}
|
||||
|
||||
/// The specified value of a legacy CSS `<position>`
|
||||
/// Modern position syntax supports 3 and 4-value syntax. That means:
|
||||
/// If three or four values are given, then each <percentage> or <length> represents an offset
|
||||
/// and must be preceded by a keyword, which specifies from which edge the offset is given.
|
||||
/// For example, `bottom 10px right 20px` represents a `10px` vertical
|
||||
/// offset up from the bottom edge and a `20px` horizontal offset leftward from the right edge.
|
||||
/// If three values are given, the missing offset is assumed to be zero.
|
||||
/// But for some historical reasons we need to keep CSS Level 2 syntax which only supports up to
|
||||
/// 2-value. This type represents this 2-value syntax.
|
||||
pub type LegacyPosition = GenericPosition<LegacyHPosition, LegacyVPosition>;
|
||||
|
||||
/// The specified value of a horizontal position.
|
||||
pub type LegacyHPosition = OriginComponent<X>;
|
||||
|
||||
/// The specified value of a vertical position.
|
||||
pub type LegacyVPosition = OriginComponent<Y>;
|
||||
|
||||
impl Parse for LegacyPosition {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl LegacyPosition {
|
||||
/// Parses a `<position>`, with quirks.
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
match input.try(|i| OriginComponent::parse(context, i)) {
|
||||
Ok(x_pos @ OriginComponent::Center) => {
|
||||
if let Ok(y_pos) = input.try(|i| OriginComponent::parse(context, i)) {
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = input
|
||||
.try(|i| OriginComponent::parse(context, i))
|
||||
.unwrap_or(x_pos);
|
||||
let y_pos = OriginComponent::Center;
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
},
|
||||
Ok(OriginComponent::Side(x_keyword)) => {
|
||||
if let Ok(y_keyword) = input.try(Y::parse) {
|
||||
let x_pos = OriginComponent::Side(x_keyword);
|
||||
let y_pos = OriginComponent::Side(y_keyword);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = OriginComponent::Side(x_keyword);
|
||||
if let Ok(y_lp) =
|
||||
input.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
return Ok(Self::new(x_pos, OriginComponent::Length(y_lp)));
|
||||
}
|
||||
let _ = input.try(|i| i.expect_ident_matching("center"));
|
||||
return Ok(Self::new(x_pos, OriginComponent::Center));
|
||||
},
|
||||
Ok(x_pos @ OriginComponent::Length(_)) => {
|
||||
if let Ok(y_keyword) = input.try(Y::parse) {
|
||||
let y_pos = OriginComponent::Side(y_keyword);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
if let Ok(y_lp) =
|
||||
input.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
let y_pos = OriginComponent::Length(y_lp);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let _ = input.try(|i| i.expect_ident_matching("center"));
|
||||
return Ok(Self::new(x_pos, OriginComponent::Center));
|
||||
},
|
||||
Err(_) => {},
|
||||
}
|
||||
let y_keyword = Y::parse(input)?;
|
||||
let x_pos: Result<_, ParseError> = input.try(|i| {
|
||||
if let Ok(x_keyword) = i.try(X::parse) {
|
||||
let x_pos = OriginComponent::Side(x_keyword);
|
||||
return Ok(x_pos);
|
||||
}
|
||||
i.expect_ident_matching("center")?;
|
||||
Ok(OriginComponent::Center)
|
||||
});
|
||||
if let Ok(x_pos) = x_pos {
|
||||
let y_pos = OriginComponent::Side(y_keyword);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = OriginComponent::Center;
|
||||
let y_pos = OriginComponent::Side(y_keyword);
|
||||
Ok(Self::new(x_pos, y_pos))
|
||||
}
|
||||
|
||||
/// `center center`
|
||||
#[inline]
|
||||
pub fn center() -> Self {
|
||||
Self::new(OriginComponent::Center, OriginComponent::Center)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for LegacyPosition {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.horizontal.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
self.vertical.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue