Bug 1457332: Derive ToCss for Counters. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sun, 29 Apr 2018 05:12:57 +0200
changeset 472333 54a4ed5b619b646d63b3d7b5b04411d8ea0d151a
parent 472332 2784dccf11ec0ed92c2da46a258abab9fc716d10
child 472334 bfee15c5c84566738fc99380e55cb9de56d619ba
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1457332
milestone61.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
Bug 1457332: Derive ToCss for Counters. r=xidorn MozReview-Commit-ID: 1jOglcqt1Dd
servo/components/style/properties/gecko.mako.rs
servo/components/style/values/generics/counters.rs
servo/components/style/values/specified/counters.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -5692,19 +5692,19 @@ clip-path
 
     % for counter_property in ["Increment", "Reset"]:
         pub fn set_counter_${counter_property.lower()}(
             &mut self,
             v: longhands::counter_${counter_property.lower()}::computed_value::T
         ) {
             unsafe {
                 bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut self.gecko, v.len() as u32);
-                for (i, &(ref name, value)) in v.iter().enumerate() {
-                    self.gecko.m${counter_property}s[i].mCounter.assign(name.0.as_slice());
-                    self.gecko.m${counter_property}s[i].mValue = value;
+                for (i, ref pair) in v.iter().enumerate() {
+                    self.gecko.m${counter_property}s[i].mCounter.assign(pair.name.0.as_slice());
+                    self.gecko.m${counter_property}s[i].mValue = pair.value;
                 }
             }
         }
 
         pub fn copy_counter_${counter_property.lower()}_from(&mut self, other: &Self) {
             unsafe {
                 bindings::Gecko_CopyCounter${counter_property}sFrom(&mut self.gecko, &other.gecko)
             }
@@ -5712,22 +5712,26 @@ clip-path
 
         pub fn reset_counter_${counter_property.lower()}(&mut self, other: &Self) {
             self.copy_counter_${counter_property.lower()}_from(other)
         }
 
         pub fn clone_counter_${counter_property.lower()}(
             &self
         ) -> longhands::counter_${counter_property.lower()}::computed_value::T {
+            use values::generics::counters::CounterPair;
             use values::CustomIdent;
             use gecko_string_cache::Atom;
 
             longhands::counter_${counter_property.lower()}::computed_value::T::new(
                 self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
-                    (CustomIdent(Atom::from(gecko_counter.mCounter.to_string())), gecko_counter.mValue)
+                    CounterPair {
+                        name: CustomIdent(Atom::from(gecko_counter.mCounter.to_string())),
+                        value: gecko_counter.mValue,
+                    }
                 }).collect()
             )
         }
     % endfor
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="UI" skip_longhands="-moz-force-broken-image-icon">
     ${impl_simple_type_with_conversion("_moz_force_broken_image_icon", "mForceBrokenImageIcon")}
--- a/servo/components/style/values/generics/counters.rs
+++ b/servo/components/style/values/generics/counters.rs
@@ -1,96 +1,76 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Generic types for counters-related CSS values.
 
-use std::fmt;
-use std::fmt::Write;
 use std::ops::Deref;
-use style_traits::{CssWriter, ToCss};
 use values::CustomIdent;
 
+/// A name / value pair for counters.
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
+         ToComputedValue, ToCss)]
+pub struct CounterPair<Integer> {
+    /// The name of the counter.
+    pub name: CustomIdent,
+    /// The value of the counter / increment / etc.
+    pub value: Integer,
+}
+
 /// A generic value for the `counter-increment` property.
 #[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
          ToComputedValue, ToCss)]
 pub struct CounterIncrement<I>(Counters<I>);
 
 impl<I> CounterIncrement<I> {
     /// Returns a new value for `counter-increment`.
     #[inline]
-    pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
         CounterIncrement(Counters(counters.into_boxed_slice()))
     }
 }
 
 impl<I> Deref for CounterIncrement<I> {
-    type Target = [(CustomIdent, I)];
+    type Target = [CounterPair<I>];
 
     #[inline]
     fn deref(&self) -> &Self::Target {
         &(self.0).0
     }
 }
 
 /// A generic value for the `counter-reset` property.
 #[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
          ToComputedValue, ToCss)]
 pub struct CounterReset<I>(Counters<I>);
 
 impl<I> CounterReset<I> {
     /// Returns a new value for `counter-reset`.
     #[inline]
-    pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+    pub fn new(counters: Vec<CounterPair<I>>) -> Self {
         CounterReset(Counters(counters.into_boxed_slice()))
     }
 }
 
 impl<I> Deref for CounterReset<I> {
-    type Target = [(CustomIdent, I)];
+    type Target = [CounterPair<I>];
 
     #[inline]
     fn deref(&self) -> &Self::Target {
         &(self.0).0
     }
 }
 
 /// A generic value for lists of counters.
 ///
 /// Keyword `none` is represented by an empty vector.
 #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
-         ToComputedValue)]
-pub struct Counters<I>(#[css(if_empty = "none")] Box<[(CustomIdent, I)]>);
+         ToComputedValue, ToCss)]
+pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);
 
 impl<I> Default for Counters<I> {
     #[inline]
     fn default() -> Self {
         Counters(vec![].into_boxed_slice())
     }
 }
-
-impl<I> ToCss for Counters<I>
-where
-    I: ToCss,
-{
-    #[inline]
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        if self.0.is_empty() {
-            return dest.write_str("none");
-        }
-
-        let mut first = true;
-        for &(ref name, ref value) in &*self.0 {
-            if !first {
-                dest.write_str(" ")?;
-            }
-            first = false;
-            name.to_css(dest)?;
-            dest.write_str(" ")?;
-            value.to_css(dest)?;
-        }
-        Ok(())
-    }
-}
--- a/servo/components/style/values/specified/counters.rs
+++ b/servo/components/style/values/specified/counters.rs
@@ -7,16 +7,17 @@
 #[cfg(feature = "servo")]
 use computed_values::list_style_type::T as ListStyleType;
 use cssparser::{Parser, Token};
 use parser::{Parse, ParserContext};
 use style_traits::{ParseError, StyleParseErrorKind};
 use values::CustomIdent;
 #[cfg(feature = "gecko")]
 use values::generics::CounterStyleOrNone;
+use values::generics::counters::CounterPair;
 use values::generics::counters::CounterIncrement as GenericCounterIncrement;
 use values::generics::counters::CounterReset as GenericCounterReset;
 #[cfg(feature = "gecko")]
 use values::specified::Attr;
 use values::specified::Integer;
 #[cfg(feature = "gecko")]
 use values::specified::url::SpecifiedImageUrl;
 
@@ -43,37 +44,37 @@ impl Parse for CounterReset {
         Ok(Self::new(parse_counters(context, input, 0)?))
     }
 }
 
 fn parse_counters<'i, 't>(
     context: &ParserContext,
     input: &mut Parser<'i, 't>,
     default_value: i32,
-) -> Result<Vec<(CustomIdent, Integer)>, ParseError<'i>> {
+) -> Result<Vec<CounterPair<Integer>>, ParseError<'i>> {
     if input
         .try(|input| input.expect_ident_matching("none"))
         .is_ok()
     {
         return Ok(vec![]);
     }
 
     let mut counters = Vec::new();
     loop {
         let location = input.current_source_location();
-        let counter_name = match input.next() {
+        let name = match input.next() {
             Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?,
             Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
             Err(_) => break,
         };
 
-        let counter_delta = input
+        let value = input
             .try(|input| Integer::parse(context, input))
             .unwrap_or(Integer::new(default_value));
-        counters.push((counter_name, counter_delta))
+        counters.push(CounterPair { name, value });
     }
 
     if !counters.is_empty() {
         Ok(counters)
     } else {
         Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }