servo: Merge #17970 - Preserve unit in specified time value (from upsuper:time-unit); r=emilio
authorXidorn Quan <me@upsuper.org>
Fri, 04 Aug 2017 05:35:41 -0500
changeset 422369 797d8666721f4f192ee1f075b41faccf4fc0cdec
parent 422368 76dcd1e6797b48a6e4b061b6c1865ae037e24812
child 422370 fd5645e639c87c59cc80f2ffe6fc4a6423803715
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs17970, 15346
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #17970 - Preserve unit in specified time value (from upsuper:time-unit); r=emilio This fixes #15346. Source-Repo: https://github.com/servo/servo Source-Revision: 7b299caf9b547412390512ff07a119a47d0cc1bf
servo/components/style/values/specified/mod.rs
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -306,29 +306,41 @@ no_viewport_percentage!(BorderStyle);
 
 impl BorderStyle {
     /// Whether this border style is either none or hidden.
     pub fn none_or_hidden(&self) -> bool {
         matches!(*self, BorderStyle::none | BorderStyle::hidden)
     }
 }
 
+/// Time unit.
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, Eq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum TimeUnit {
+    /// `s`
+    Second,
+    /// `ms`
+    Millisecond,
+}
+
 /// A time in seconds according to CSS-VALUES § 6.2.
-#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd)]
+#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct Time {
     seconds: CSSFloat,
+    unit: TimeUnit,
     was_calc: bool,
 }
 
 impl Time {
     /// Return a `<time>` value that represents `seconds` seconds.
     pub fn from_seconds(seconds: CSSFloat) -> Self {
         Time {
             seconds: seconds,
+            unit: TimeUnit::Second,
             was_calc: false,
         }
     }
 
     /// Returns a time that represents a duration of zero.
     pub fn zero() -> Self {
         Self::from_seconds(0.0)
     }
@@ -340,32 +352,34 @@ impl Time {
 
     /// Parses a time according to CSS-VALUES § 6.2.
     pub fn parse_dimension(
         value: CSSFloat,
         unit: &str,
         from_calc: bool)
         -> Result<Time, ()>
     {
-        let seconds = match_ignore_ascii_case! { unit,
-            "s" => value,
-            "ms" => value / 1000.0,
+        let (seconds, unit) = match_ignore_ascii_case! { unit,
+            "s" => (value, TimeUnit::Second),
+            "ms" => (value / 1000.0, TimeUnit::Millisecond),
             _ => return Err(())
         };
 
         Ok(Time {
             seconds: seconds,
+            unit: unit,
             was_calc: from_calc,
         })
     }
 
     /// Returns a `Time` value from a CSS `calc()` expression.
     pub fn from_calc(seconds: CSSFloat) -> Self {
         Time {
             seconds: seconds,
+            unit: TimeUnit::Second,
             was_calc: true,
         }
     }
 
     fn parse_with_clamping_mode<'i, 't>(context: &ParserContext,
                                         input: &mut Parser<'i, 't>,
                                         clamping_mode: AllowedNumericType)
                                         -> Result<Self, ParseError<'i>> {
@@ -404,33 +418,43 @@ impl ToComputedValue for Time {
 
     fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
         computed::Time::from_seconds(self.seconds())
     }
 
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         Time {
             seconds: computed.seconds(),
+            unit: TimeUnit::Second,
             was_calc: false,
         }
     }
 }
 
 impl Parse for Time {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
     }
 }
 
 impl ToCss for Time {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         if self.was_calc {
             dest.write_str("calc(")?;
         }
-        write!(dest, "{}s", self.seconds)?;
+        match self.unit {
+            TimeUnit::Second => {
+                self.seconds.to_css(dest)?;
+                dest.write_str("s")?;
+            }
+            TimeUnit::Millisecond => {
+                (self.seconds * 1000.).to_css(dest)?;
+                dest.write_str("ms")?;
+            }
+        }
         if self.was_calc {
             dest.write_str(")")?;
         }
         Ok(())
     }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]