aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/display_list_builder.rs4
-rw-r--r--components/style/gecko/conversions.rs5
-rw-r--r--components/style/values/computed/image.rs79
-rw-r--r--components/style/values/computed/mod.rs2
-rw-r--r--components/style/values/specified/image.rs53
-rw-r--r--tests/unit/style/parsing/image.rs19
6 files changed, 113 insertions, 49 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 5f66f5f5259..be11ba66edd 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -54,8 +54,8 @@ use style::properties::{self, ServoComputedValues};
use style::properties::style_structs;
use style::servo::restyle_damage::REPAINT;
use style::values::{self, Either, RGBA, computed};
-use style::values::computed::{Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto};
-use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
+use style::values::computed::{AngleOrCorner, Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto};
+use style::values::specified::{HorizontalDirection, VerticalDirection};
use style_traits::cursor::Cursor;
use table_cell::CollapsedBordersForCell;
use webrender_traits::{ColorF, GradientStop};
diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs
index e32168a436d..e336dee635e 100644
--- a/components/style/gecko/conversions.rs
+++ b/components/style/gecko/conversions.rs
@@ -160,10 +160,9 @@ impl nsStyleImage {
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE, NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE};
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER, NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE};
use gecko_bindings::structs::nsStyleCoord;
- use values::computed::{GradientKind, GradientShape, LengthOrKeyword};
+ use values::computed::{AngleOrCorner, GradientKind, GradientShape, LengthOrKeyword};
use values::computed::LengthOrPercentageOrKeyword;
- use values::specified::{AngleOrCorner, HorizontalDirection};
- use values::specified::{SizeKeyword, VerticalDirection};
+ use values::specified::{HorizontalDirection, SizeKeyword, VerticalDirection};
let stop_count = gradient.stops.len();
if stop_count >= ::std::u32::MAX as usize {
diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs
index f99ed74ac5e..007cbdad9df 100644
--- a/components/style/values/computed/image.rs
+++ b/components/style/values/computed/image.rs
@@ -8,11 +8,12 @@
//! [image]: https://drafts.csswg.org/css-images/#image-values
use cssparser::Color as CSSColor;
+use std::f32::consts::PI;
use std::fmt;
use style_traits::ToCss;
-use values::computed::{Context, Length, LengthOrPercentage, ToComputedValue};
+use values::computed::{Angle, Context, Length, LengthOrPercentage, ToComputedValue};
use values::computed::position::Position;
-use values::specified::{self, AngleOrCorner, SizeKeyword};
+use values::specified::{self, HorizontalDirection, SizeKeyword, VerticalDirection};
use values::specified::url::SpecifiedUrl;
@@ -185,7 +186,7 @@ impl ToComputedValue for specified::GradientKind {
fn to_computed_value(&self, context: &Context) -> GradientKind {
match *self {
specified::GradientKind::Linear(angle_or_corner) => {
- GradientKind::Linear(angle_or_corner)
+ GradientKind::Linear(angle_or_corner.to_computed_value(context))
},
specified::GradientKind::Radial(ref shape, position) => {
GradientKind::Radial(shape.to_computed_value(context),
@@ -454,3 +455,75 @@ impl ToComputedValue for specified::LengthOrPercentageOrKeyword {
}
}
}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum AngleOrCorner {
+ Angle(Angle),
+ Corner(HorizontalDirection, VerticalDirection)
+}
+
+impl ToComputedValue for specified::AngleOrCorner {
+ type ComputedValue = AngleOrCorner;
+
+ #[inline]
+ fn to_computed_value(&self, _: &Context) -> AngleOrCorner {
+ match *self {
+ specified::AngleOrCorner::None => {
+ AngleOrCorner::Angle(Angle(0.0))
+ },
+ specified::AngleOrCorner::Angle(angle) => {
+ AngleOrCorner::Angle(angle)
+ },
+ specified::AngleOrCorner::Corner(horizontal, vertical) => {
+ match (horizontal, vertical) {
+ (None, Some(VerticalDirection::Top)) => {
+ AngleOrCorner::Angle(Angle(0.0))
+ },
+ (Some(HorizontalDirection::Right), None) => {
+ AngleOrCorner::Angle(Angle(PI * 0.5))
+ },
+ (None, Some(VerticalDirection::Bottom)) => {
+ AngleOrCorner::Angle(Angle(PI))
+ },
+ (Some(HorizontalDirection::Left), None) => {
+ AngleOrCorner::Angle(Angle(PI * 1.5))
+ },
+ (Some(horizontal), Some(vertical)) => {
+ AngleOrCorner::Corner(horizontal, vertical)
+ },
+ (None, None) => {
+ unreachable!()
+ }
+ }
+ }
+ }
+ }
+
+ #[inline]
+ fn from_computed_value(computed: &AngleOrCorner) -> Self {
+ match *computed {
+ AngleOrCorner::Angle(angle) => {
+ specified::AngleOrCorner::Angle(angle)
+ },
+ AngleOrCorner::Corner(horizontal, vertical) => {
+ specified::AngleOrCorner::Corner(Some(horizontal), Some(vertical))
+ }
+ }
+ }
+}
+
+impl ToCss for AngleOrCorner {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ AngleOrCorner::Angle(angle) => angle.to_css(dest),
+ AngleOrCorner::Corner(horizontal, vertical) => {
+ try!(dest.write_str("to "));
+ try!(horizontal.to_css(dest));
+ try!(dest.write_str(" "));
+ try!(vertical.to_css(dest));
+ Ok(())
+ }
+ }
+ }
+}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 8a31d59ce10..a22a799206f 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -11,7 +11,7 @@ use style_traits::ToCss;
use super::{CSSFloat, specified};
pub use cssparser::Color as CSSColor;
-pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
+pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
pub use super::{Either, None_};
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs
index 94a56d73541..479d378a680 100644
--- a/components/style/values/specified/image.rs
+++ b/components/style/values/specified/image.rs
@@ -10,10 +10,8 @@
use cssparser::Parser;
use parser::{Parse, ParserContext};
use servo_url::ServoUrl;
-use std::f32::consts::PI;
use std::fmt;
use style_traits::ToCss;
-use values::computed::ComputedValueAsSpecified;
use values::specified::{Angle, CSSColor, Length, LengthOrPercentage};
use values::specified::position::Position;
use values::specified::url::{SpecifiedUrl, UrlExtraData};
@@ -70,10 +68,14 @@ impl ToCss for Gradient {
if self.repeating {
try!(dest.write_str("repeating-"));
}
+ let mut skipcomma = false;
match self.gradient_kind {
GradientKind::Linear(angle_or_corner) => {
try!(dest.write_str("linear-gradient("));
try!(angle_or_corner.to_css(dest));
+ if angle_or_corner == AngleOrCorner::None {
+ skipcomma = true;
+ }
},
GradientKind::Radial(ref shape, position) => {
try!(dest.write_str("radial-gradient("));
@@ -83,7 +85,11 @@ impl ToCss for Gradient {
},
}
for stop in &self.stops {
- try!(dest.write_str(", "));
+ if !skipcomma {
+ try!(dest.write_str(", "));
+ } else {
+ skipcomma = false;
+ }
try!(stop.to_css(dest));
}
dest.write_str(")")
@@ -230,18 +236,28 @@ fn parse_position(context: &ParserContext, input: &mut Parser) -> Result<Positio
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum AngleOrCorner {
Angle(Angle),
- Corner(HorizontalDirection, VerticalDirection),
+ Corner(Option<HorizontalDirection>, Option<VerticalDirection>),
+ None,
}
impl ToCss for AngleOrCorner {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
+ AngleOrCorner::None => Ok(()),
AngleOrCorner::Angle(angle) => angle.to_css(dest),
AngleOrCorner::Corner(horizontal, vertical) => {
try!(dest.write_str("to "));
- try!(horizontal.to_css(dest));
- try!(dest.write_str(" "));
- try!(vertical.to_css(dest));
+ let mut horizontal_present = false;
+ if let Some(horizontal) = horizontal {
+ try!(horizontal.to_css(dest));
+ horizontal_present = true;
+ }
+ if let Some(vertical) = vertical {
+ if horizontal_present {
+ try!(dest.write_str(" "));
+ }
+ try!(vertical.to_css(dest));
+ }
Ok(())
}
}
@@ -259,35 +275,16 @@ impl Parse for AngleOrCorner {
(input.try(HorizontalDirection::parse).ok(), Some(value))
};
try!(input.expect_comma());
- match (horizontal, vertical) {
- (None, Some(VerticalDirection::Top)) => {
- Ok(AngleOrCorner::Angle(Angle(0.0)))
- },
- (Some(HorizontalDirection::Right), None) => {
- Ok(AngleOrCorner::Angle(Angle(PI * 0.5)))
- },
- (None, Some(VerticalDirection::Bottom)) => {
- Ok(AngleOrCorner::Angle(Angle(PI)))
- },
- (Some(HorizontalDirection::Left), None) => {
- Ok(AngleOrCorner::Angle(Angle(PI * 1.5)))
- },
- (Some(horizontal), Some(vertical)) => {
- Ok(AngleOrCorner::Corner(horizontal, vertical))
- }
- (None, None) => unreachable!(),
- }
+ Ok(AngleOrCorner::Corner(horizontal, vertical))
} else if let Ok(angle) = input.try(|i| Angle::parse(context, i)) {
try!(input.expect_comma());
Ok(AngleOrCorner::Angle(angle))
} else {
- Ok(AngleOrCorner::Angle(Angle(PI)))
+ Ok(AngleOrCorner::None)
}
}
}
-impl ComputedValueAsSpecified for AngleOrCorner {}
-
/// Specified values for one color stop in a linear gradient.
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
#[derive(Clone, PartialEq, Debug)]
diff --git a/tests/unit/style/parsing/image.rs b/tests/unit/style/parsing/image.rs
index 5565a72dc3e..16eb63b6725 100644
--- a/tests/unit/style/parsing/image.rs
+++ b/tests/unit/style/parsing/image.rs
@@ -12,12 +12,10 @@ use style_traits::ToCss;
#[test]
fn test_linear_gradient() {
// Parsing from the right
- assert_roundtrip_with_context!(Image::parse, "linear-gradient(to left, red, green)",
- "linear-gradient(4.712389rad, red, green)");
+ assert_roundtrip_with_context!(Image::parse, "linear-gradient(to left, red, green)");
// Parsing from the left
- assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right, red, green)",
- "linear-gradient(1.5707964rad, red, green)");
+ assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right, red, green)");
// Parsing with two values for <side-or-corner>
assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right top, red, green)");
@@ -26,17 +24,14 @@ fn test_linear_gradient() {
assert_roundtrip_with_context!(Image::parse, "linear-gradient(45deg, red, green)",
"linear-gradient(0.7853982rad, red, green)");
- // Parsing with more than two entries in <color-stop-list>
- assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, yellow, green)",
- "linear-gradient(3.1415927rad, red, yellow, green)");
+ // Parsing with more than two entries in <color-stop-list>
+ assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, yellow, green)");
- // Parsing with percentage in the <color-stop-list>
- assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green, yellow 50%)",
- "linear-gradient(3.1415927rad, red, green, yellow 50%)");
+ // Parsing with percentage in the <color-stop-list>
+ assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green, yellow 50%)");
// Parsing without <angle> and <side-or-corner>
- assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green)",
- "linear-gradient(3.1415927rad, red, green)");
+ assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green)");
}
#[test]