servo: Merge #17215 - Derive more ToCss impls (from servo:derive-all-the-things); r=emilio
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 09 Jun 2017 05:00:45 -0700
changeset 411348 8ae6f0335b204177f90e9c964ede65da3054fe76
parent 411347 17c92027f70b7d4f4ca6218d09aa77672fd0608d
child 411349 1efa46c863a0fcc79dc66757d7e3a22c88475e18
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone55.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 #17215 - Derive more ToCss impls (from servo:derive-all-the-things); r=emilio Source-Repo: https://github.com/servo/servo Source-Revision: 1555f0fc413415d5c8f7c5a5f3fec2eecfce640e
servo/components/layout/display_list_builder.rs
servo/components/style/counter_style/mod.rs
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/longhand/counters.mako.rs
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/components/style/properties/longhand/list.mako.rs
servo/components/style/properties/longhand/pointing.mako.rs
servo/components/style/properties/longhand/position.mako.rs
servo/components/style/properties/longhand/text.mako.rs
servo/components/style/properties/shorthand/position.mako.rs
servo/components/style/stylesheets/document_rule.rs
servo/components/style/values/generics/mod.rs
servo/components/style/values/mod.rs
servo/components/style_traits/values.rs
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -2848,18 +2848,18 @@ trait ServoComputedValuesCursorUtility {
 impl ServoComputedValuesCursorUtility for ServoComputedValues {
     /// Gets the cursor to use given the specific ServoComputedValues.  `default_cursor` specifies
     /// the cursor to use if `cursor` is `auto`. Typically, this will be `PointerCursor`, but for
     /// text display items it may be `TextCursor` or `VerticalTextCursor`.
     #[inline]
     fn get_cursor(&self, default_cursor: Cursor) -> Option<Cursor> {
         match (self.get_pointing().pointer_events, self.get_pointing().cursor) {
             (pointer_events::T::none, _) => None,
-            (pointer_events::T::auto, cursor::Keyword::AutoCursor) => Some(default_cursor),
-            (pointer_events::T::auto, cursor::Keyword::SpecifiedCursor(cursor)) => Some(cursor),
+            (pointer_events::T::auto, cursor::Keyword::Auto) => Some(default_cursor),
+            (pointer_events::T::auto, cursor::Keyword::Cursor(cursor)) => Some(cursor),
         }
     }
 }
 
 // A helper data structure for gradients.
 #[derive(Copy, Clone)]
 struct StopRun {
     start_offset: f32,
--- a/servo/components/style/counter_style/mod.rs
+++ b/servo/components/style/counter_style/mod.rs
@@ -2,18 +2,18 @@
  * 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/. */
 
 //! The [`@counter-style`][counter-style] at-rule.
 //!
 //! [counter-style]: https://drafts.csswg.org/css-counter-styles/
 
 use Atom;
-use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, Token};
-use cssparser::{serialize_string, serialize_identifier};
+use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
+use cssparser::{Parser, Token, serialize_identifier};
 #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
 #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc;
 use parser::{ParserContext, log_css_error, Parse};
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt;
 use std::ops::Range;
@@ -356,17 +356,17 @@ impl Parse for Symbol {
             _ => Err(())
         }
     }
 }
 
 impl ToCss for Symbol {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         match *self {
-            Symbol::String(ref s) => serialize_string(s, dest),
+            Symbol::String(ref s) => s.to_css(dest),
             Symbol::Ident(ref s) => serialize_identifier(s, dest),
         }
     }
 }
 
 impl Symbol {
     /// Returns whether this symbol is allowed in symbols() function.
     pub fn is_allowed_in_symbols(&self) -> bool {
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -4236,18 +4236,18 @@ clip-path
 
 <%self:impl_trait style_struct_name="Pointing"
                   skip_longhands="cursor caret-color">
     pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
         use properties::longhands::cursor::computed_value::Keyword;
         use style_traits::cursor::Cursor;
 
         self.gecko.mCursor = match v.keyword {
-            Keyword::AutoCursor => structs::NS_STYLE_CURSOR_AUTO,
-            Keyword::SpecifiedCursor(cursor) => match cursor {
+            Keyword::Auto => structs::NS_STYLE_CURSOR_AUTO,
+            Keyword::Cursor(cursor) => match cursor {
                 Cursor::None => structs::NS_STYLE_CURSOR_NONE,
                 Cursor::Default => structs::NS_STYLE_CURSOR_DEFAULT,
                 Cursor::Pointer => structs::NS_STYLE_CURSOR_POINTER,
                 Cursor::ContextMenu => structs::NS_STYLE_CURSOR_CONTEXT_MENU,
                 Cursor::Help => structs::NS_STYLE_CURSOR_HELP,
                 Cursor::Progress => structs::NS_STYLE_CURSOR_DEFAULT, // Gecko doesn't support "progress" yet
                 Cursor::Wait => structs::NS_STYLE_CURSOR_WAIT,
                 Cursor::Cell => structs::NS_STYLE_CURSOR_CELL,
--- a/servo/components/style/properties/longhand/counters.mako.rs
+++ b/servo/components/style/properties/longhand/counters.mako.rs
@@ -65,33 +65,31 @@
                 /// `url(url)`
                 Url(SpecifiedUrl),
             % endif
         }
 
         impl ToCss for ContentItem {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match *self {
-                    ContentItem::String(ref s) => {
-                        cssparser::serialize_string(&**s, dest)
-                    }
+                    ContentItem::String(ref s) => s.to_css(dest),
                     ContentItem::Counter(ref s, ref counter_style) => {
                         try!(dest.write_str("counter("));
                         try!(cssparser::serialize_identifier(&**s, dest));
                         try!(dest.write_str(", "));
                         try!(counter_style.to_css(dest));
                         dest.write_str(")")
                     }
                     ContentItem::Counters(ref s, ref separator, ref counter_style) => {
                         try!(dest.write_str("counters("));
                         try!(cssparser::serialize_identifier(&**s, dest));
                         try!(dest.write_str(", "));
-                        try!(cssparser::serialize_string(&**separator, dest));
+                        separator.to_css(dest)?;
                         try!(dest.write_str(", "));
-                        try!(counter_style.to_css(dest));
+                        counter_style.to_css(dest)?;
                         dest.write_str(")")
                     }
                     ContentItem::OpenQuote => dest.write_str("open-quote"),
                     ContentItem::CloseQuote => dest.write_str("close-quote"),
                     ContentItem::NoOpenQuote => dest.write_str("no-open-quote"),
                     ContentItem::NoCloseQuote => dest.write_str("no-close-quote"),
 
                     % if product == "gecko":
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -1889,21 +1889,19 @@ https://drafts.csswg.org/css-fonts-4/#lo
     pub enum SpecifiedValue {
         Normal,
         Override(String),
         System(SystemFont)
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            use cssparser;
             match *self {
                 SpecifiedValue::Normal => dest.write_str("normal"),
-                SpecifiedValue::Override(ref lang) =>
-                    cssparser::serialize_string(lang, dest),
+                SpecifiedValue::Override(ref lang) => lang.to_css(dest),
                 SpecifiedValue::System(_) => Ok(())
             }
         }
     }
 
     impl SpecifiedValue {
         pub fn system_font(f: SystemFont) -> Self {
             SpecifiedValue::System(f)
@@ -1916,32 +1914,31 @@ https://drafts.csswg.org/css-fonts-4/#lo
             }
         }
     }
 
     pub mod computed_value {
         use std::{fmt, str};
         use style_traits::ToCss;
         use byteorder::{BigEndian, ByteOrder};
-        use cssparser;
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 if self.0 == 0 {
                     return dest.write_str("normal")
                 }
                 let mut buf = [0; 4];
                 BigEndian::write_u32(&mut buf, self.0);
                 // Safe because we ensure it's ASCII during computing
                 let slice = if cfg!(debug_assertions) {
                     str::from_utf8(&buf).unwrap()
                 } else {
                     unsafe { str::from_utf8_unchecked(&buf) }
                 };
-                cssparser::serialize_string(slice.trim_right(), dest)
+                slice.trim_right().to_css(dest)
             }
         }
 
         // font-language-override can only have a single three-letter
         // OpenType "language system" tag, so we should be able to compute
         // it and store it as a 32-bit integer
         // (see http://www.microsoft.com/typography/otspec/languagetags.htm).
         #[derive(PartialEq, Clone, Copy, Debug)]
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -422,59 +422,40 @@
     use computed_values::writing_mode::T as writing_mode;
     use std::fmt;
     use style_traits::ToCss;
     use unicode_segmentation::UnicodeSegmentation;
 
     no_viewport_percentage!(SpecifiedValue);
 
     pub mod computed_value {
-        #[derive(Debug, Clone, PartialEq)]
         #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+        #[derive(Clone, Debug, PartialEq, ToCss)]
         pub enum T {
             Keyword(KeywordValue),
             None,
             String(String),
         }
 
         #[derive(Debug, Clone, PartialEq)]
         #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct KeywordValue {
             pub fill: bool,
             pub shape: super::ShapeKeyword,
         }
     }
 
-    #[derive(Debug, Clone, PartialEq)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+    #[derive(Clone, Debug, PartialEq, ToCss)]
     pub enum SpecifiedValue {
         Keyword(KeywordValue),
         None,
         String(String),
     }
 
-    impl ToCss for computed_value::T {
-        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            match *self {
-                computed_value::T::Keyword(ref keyword) => keyword.to_css(dest),
-                computed_value::T::None => dest.write_str("none"),
-                computed_value::T::String(ref string) => write!(dest, "\"{}\"", string),
-            }
-        }
-    }
-    impl ToCss for SpecifiedValue {
-        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            match *self {
-                SpecifiedValue::Keyword(ref keyword) => keyword.to_css(dest),
-                SpecifiedValue::None => dest.write_str("none"),
-                SpecifiedValue::String(ref string) => write!(dest, "\"{}\"", string),
-            }
-        }
-    }
-
     #[derive(Debug, Clone, PartialEq)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum KeywordValue {
         Fill(bool),
         Shape(ShapeKeyword),
         FillAndShape(bool, ShapeKeyword),
     }
 
--- a/servo/components/style/properties/longhand/list.mako.rs
+++ b/servo/components/style/properties/longhand/list.mako.rs
@@ -28,48 +28,36 @@
         malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch
         cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha""",
         needs_conversion="True",
         animation_value_type="none",
         spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")}
 % else:
     <%helpers:longhand name="list-style-type" animation_value_type="none" boxed="True"
                        spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type">
-        use cssparser;
-        use std::fmt;
-        use style_traits::ToCss;
         use values::CustomIdent;
         use values::computed::ComputedValueAsSpecified;
         use values::generics::CounterStyleOrNone;
 
         pub use self::computed_value::T as SpecifiedValue;
 
         pub mod computed_value {
             use values::generics::CounterStyleOrNone;
 
             /// <counter-style> | <string> | none
-            #[derive(Debug, Clone, PartialEq, Eq)]
+            #[derive(Debug, Clone, Eq, PartialEq, ToCss)]
             pub enum T {
                 CounterStyle(CounterStyleOrNone),
                 String(String),
             }
         }
 
         impl ComputedValueAsSpecified for SpecifiedValue {}
         no_viewport_percentage!(SpecifiedValue);
 
-        impl ToCss for SpecifiedValue {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-                match *self {
-                    SpecifiedValue::CounterStyle(ref s) => s.to_css(dest),
-                    SpecifiedValue::String(ref s) => cssparser::serialize_string(s, dest)
-                }
-            }
-        }
-
         #[cfg(feature = "gecko")]
         impl SpecifiedValue {
             /// Convert from gecko keyword to list-style-type.
             ///
             /// This should only be used for mapping type attribute to
             /// list-style-type, and thus only values possible in that
             /// attribute is considered here.
             pub fn from_gecko_keyword(value: u32) -> Self {
--- a/servo/components/style/properties/longhand/pointing.mako.rs
+++ b/servo/components/style/properties/longhand/pointing.mako.rs
@@ -12,27 +12,29 @@
     use values::computed::ComputedValueAsSpecified;
     #[cfg(feature = "gecko")]
     use values::specified::url::SpecifiedUrl;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
     no_viewport_percentage!(SpecifiedValue);
 
     pub mod computed_value {
+        #[cfg(feature = "gecko")]
         use std::fmt;
+        #[cfg(feature = "gecko")]
+        use style_traits::ToCss;
         use style_traits::cursor::Cursor;
-        use style_traits::ToCss;
         #[cfg(feature = "gecko")]
         use values::specified::url::SpecifiedUrl;
 
-        #[derive(Clone, PartialEq, Copy, Debug)]
         #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+        #[derive(Clone, Copy, Debug, PartialEq, ToCss)]
         pub enum Keyword {
-            AutoCursor,
-            SpecifiedCursor(Cursor),
+            Auto,
+            Cursor(Cursor),
         }
 
         #[cfg(not(feature = "gecko"))]
         pub type T = Keyword;
 
         #[cfg(feature = "gecko")]
         #[derive(Clone, PartialEq, Debug)]
         pub struct Image {
@@ -42,25 +44,16 @@
 
         #[cfg(feature = "gecko")]
         #[derive(Clone, PartialEq, Debug)]
         pub struct T {
             pub images: Vec<Image>,
             pub keyword: Keyword,
         }
 
-        impl ToCss for Keyword {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-                match *self {
-                    Keyword::AutoCursor => dest.write_str("auto"),
-                    Keyword::SpecifiedCursor(c) => c.to_css(dest),
-                }
-            }
-        }
-
         #[cfg(feature = "gecko")]
         impl ToCss for Image {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 try!(self.url.to_css(dest));
                 if let Some((x, y)) = self.hotspot {
                     try!(dest.write_str(" "));
                     try!(x.to_css(dest));
                     try!(dest.write_str(" "));
@@ -80,37 +73,37 @@
                 self.keyword.to_css(dest)
             }
         }
     }
 
     #[cfg(not(feature = "gecko"))]
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
-        computed_value::Keyword::AutoCursor
+        computed_value::Keyword::Auto
     }
 
     #[cfg(feature = "gecko")]
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         computed_value::T {
             images: vec![],
-            keyword: computed_value::Keyword::AutoCursor
+            keyword: computed_value::Keyword::Auto
         }
     }
 
     impl Parse for computed_value::Keyword {
         fn parse(_context: &ParserContext, input: &mut Parser) -> Result<computed_value::Keyword, ()> {
             use std::ascii::AsciiExt;
             use style_traits::cursor::Cursor;
             let ident = try!(input.expect_ident());
             if ident.eq_ignore_ascii_case("auto") {
-                Ok(computed_value::Keyword::AutoCursor)
+                Ok(computed_value::Keyword::Auto)
             } else {
-                Cursor::from_css_keyword(&ident).map(computed_value::Keyword::SpecifiedCursor)
+                Cursor::from_css_keyword(&ident).map(computed_value::Keyword::Cursor)
             }
         }
     }
 
     #[cfg(feature = "gecko")]
     fn parse_image(context: &ParserContext, input: &mut Parser) -> Result<computed_value::Image, ()> {
         Ok(computed_value::Image {
             url: try!(SpecifiedUrl::parse(context, input)),
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -349,17 +349,16 @@
 </%helpers:longhand>
 
 <%helpers:longhand name="grid-template-areas"
         spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas"
         products="gecko"
         animation_value_type="none"
         disable_when_testing="True"
         boxed="True">
-    use cssparser::serialize_string;
     use std::collections::HashMap;
     use std::fmt;
     use std::ops::Range;
     use str::HTML_SPACE_CHARACTERS;
     use style_traits::ToCss;
     use values::computed::ComputedValueAsSpecified;
 
     pub mod computed_value {
@@ -481,17 +480,17 @@
     }
 
     impl ToCss for TemplateAreas {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             for (i, string) in self.strings.iter().enumerate() {
                 if i != 0 {
                     dest.write_str(" ")?;
                 }
-                serialize_string(string, dest)?;
+                string.to_css(dest)?;
             }
             Ok(())
         }
     }
 
     struct Tokenizer<'a>(&'a str);
 
     impl<'a> Iterator for Tokenizer<'a> {
--- a/servo/components/style/properties/longhand/text.mako.rs
+++ b/servo/components/style/properties/longhand/text.mako.rs
@@ -11,22 +11,21 @@
                          additional_methods=[Method("has_underline", "bool"),
                                              Method("has_overline", "bool"),
                                              Method("has_line_through", "bool")]) %>
 
 <%helpers:longhand name="text-overflow" animation_value_type="none" boxed="True"
                    spec="https://drafts.csswg.org/css-ui/#propdef-text-overflow">
     use std::fmt;
     use style_traits::ToCss;
-    use cssparser;
 
     no_viewport_percentage!(SpecifiedValue);
 
-    #[derive(PartialEq, Eq, Clone, Debug)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+    #[derive(Clone, Debug, Eq, PartialEq, ToCss)]
     pub enum Side {
         Clip,
         Ellipsis,
         String(Box<str>),
     }
 
     #[derive(PartialEq, Eq, Clone, Debug)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@@ -122,28 +121,16 @@
                     _ => Err(())
                 }
             } else {
                 Ok(Side::String(try!(input.expect_string()).into_owned().into_boxed_str()))
             }
         }
     }
 
-    impl ToCss for Side {
-        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            match *self {
-                Side::Clip => dest.write_str("clip"),
-                Side::Ellipsis => dest.write_str("ellipsis"),
-                Side::String(ref s) => {
-                    cssparser::serialize_string(s, dest)
-                }
-            }
-        }
-    }
-
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.first.to_css(dest));
             if let Some(ref second) = self.second {
                 try!(dest.write_str(" "));
                 try!(second.to_css(dest));
             }
             Ok(())
--- a/servo/components/style/properties/shorthand/position.mako.rs
+++ b/servo/components/style/properties/shorthand/position.mako.rs
@@ -245,17 +245,16 @@
     }
 </%helpers:shorthand>
 
 <%helpers:shorthand name="grid-template"
                     sub_properties="grid-template-rows grid-template-columns grid-template-areas"
                     spec="https://drafts.csswg.org/css-grid/#propdef-grid-template"
                     disable_when_testing="True"
                     products="gecko">
-    use cssparser::serialize_string;
     use parser::Parse;
     use properties::longhands::grid_template_rows;
     use properties::longhands::grid_template_areas::TemplateAreas;
     use values::{Either, None_};
     use values::generics::grid::{TrackSize, TrackList, TrackListType, concat_serialize_idents};
     use values::specified::TrackListOrNone;
     use values::specified::grid::parse_line_names;
 
@@ -365,17 +364,17 @@
                     if i > 0 {
                         dest.write_str(" ")?;
                     }
 
                     if !names.is_empty() {
                         concat_serialize_idents("[", "] ", names, " ", dest)?;
                     }
 
-                    serialize_string(string, dest)?;
+                    string.to_css(dest)?;
                     dest.write_str(" ")?;
                     size.to_css(dest)?;
                 }
 
                 if let Some(names) = names_iter.next() {
                     concat_serialize_idents(" [", "]", names, " ", dest)?;
                 }
 
--- a/servo/components/style/stylesheets/document_rule.rs
+++ b/servo/components/style/stylesheets/document_rule.rs
@@ -1,17 +1,17 @@
 /* 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/. */
 
 //! [@document rules](https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#at-document)
 //! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4.
 //! We implement the prefixed `@-moz-document`.
 
-use cssparser::{Parser, Token, SourceLocation, serialize_string};
+use cssparser::{Parser, Token, SourceLocation};
 use media_queries::Device;
 use parser::{Parse, ParserContext};
 use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
 use std::fmt;
 use style_traits::ToCss;
 use stylearc::Arc;
 use stylesheets::CssRules;
 use values::specified::url::SpecifiedUrl;
@@ -155,27 +155,27 @@ impl ToCss for UrlMatchingFunction {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write {
         match *self {
             UrlMatchingFunction::Url(ref url) => {
                 url.to_css(dest)
             },
             UrlMatchingFunction::UrlPrefix(ref url_prefix) => {
                 dest.write_str("url-prefix(")?;
-                serialize_string(url_prefix, dest)?;
+                url_prefix.to_css(dest)?;
                 dest.write_str(")")
             },
             UrlMatchingFunction::Domain(ref domain) => {
                 dest.write_str("domain(")?;
-                serialize_string(domain, dest)?;
+                domain.to_css(dest)?;
                 dest.write_str(")")
             },
             UrlMatchingFunction::RegExp(ref regex) => {
                 dest.write_str("regexp(")?;
-                serialize_string(regex, dest)?;
+                regex.to_css(dest)?;
                 dest.write_str(")")
             },
         }
     }
 }
 
 /// A `@document` rule's condition.
 ///
--- a/servo/components/style/values/generics/mod.rs
+++ b/servo/components/style/values/generics/mod.rs
@@ -138,22 +138,21 @@ pub struct FontSettingTag<T> {
     pub value: T,
 }
 
 impl<T> OneOrMoreCommaSeparated for FontSettingTag<T> {}
 
 impl<T: ToCss> ToCss for FontSettingTag<T> {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         use byteorder::{BigEndian, ByteOrder};
-        use cssparser::serialize_string;
         use std::str;
 
         let mut raw = [0u8; 4];
         BigEndian::write_u32(&mut raw, self.tag);
-        serialize_string(str::from_utf8(&raw).unwrap_or_default(), dest)?;
+        str::from_utf8(&raw).unwrap_or_default().to_css(dest)?;
 
         self.value.to_css(dest)
     }
 }
 
 impl<T: Parse> Parse for FontSettingTag<T> {
     /// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings
     /// https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-
--- a/servo/components/style/values/mod.rs
+++ b/servo/components/style/values/mod.rs
@@ -4,17 +4,17 @@
 
 //! Common [values][values] used in CSS.
 //!
 //! [values]: https://drafts.csswg.org/css-values/
 
 #![deny(missing_docs)]
 
 use Atom;
-pub use cssparser::{RGBA, Token, Parser, serialize_identifier, serialize_string};
+pub use cssparser::{RGBA, Token, Parser, serialize_identifier};
 use parser::{Parse, ParserContext};
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt::{self, Debug};
 use std::hash;
 use style_traits::ToCss;
 
 pub mod computed;
@@ -161,17 +161,17 @@ impl Parse for KeyframesName {
         }
     }
 }
 
 impl ToCss for KeyframesName {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         match *self {
             KeyframesName::Ident(ref ident) => ident.to_css(dest),
-            KeyframesName::QuotedString(ref atom) => serialize_string(&atom.to_string(), dest),
+            KeyframesName::QuotedString(ref atom) => atom.to_string().to_css(dest),
         }
     }
 }
 
 // A type for possible values for min- and max- flavors of width,
 // height, block-size, and inline-size.
 define_css_keyword_enum!(ExtremumLength:
                          "-moz-max-content" => MaxContent,
--- a/servo/components/style_traits/values.rs
+++ b/servo/components/style_traits/values.rs
@@ -1,20 +1,23 @@
 /* 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/. */
 
 //! Helper types and traits for the handling of CSS values.
 
 use app_units::Au;
-use cssparser::UnicodeRange;
+use cssparser::{UnicodeRange, serialize_string};
 use std::fmt;
 
 /// Serialises a value according to its CSS representation.
 ///
+/// This trait is implemented for `str` and its friends, serialising the string
+/// contents as a CSS quoted string.
+///
 /// This trait is derivable with `#[derive(ToCss)]`, with the following behaviour:
 /// * unit variants get serialised as the `snake-case` representation
 ///   of their name;
 /// * unit variants whose name starts with "Moz" or "Webkit" are prepended
 ///   with a "-";
 /// * variants with fields get serialised as the space-separated serialisations
 ///   of their fields.
 pub trait ToCss {
@@ -33,16 +36,30 @@ pub trait ToCss {
 }
 
 impl<'a, T> ToCss for &'a T where T: ToCss + ?Sized {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         (*self).to_css(dest)
     }
 }
 
+impl ToCss for str {
+    #[inline]
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        serialize_string(self, dest)
+    }
+}
+
+impl ToCss for String {
+    #[inline]
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        serialize_string(self, dest)
+    }
+}
+
 /// Marker trait to automatically implement ToCss for Vec<T>.
 pub trait OneOrMoreCommaSeparated {}
 
 impl OneOrMoreCommaSeparated for UnicodeRange {}
 
 impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreCommaSeparated {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         let mut iter = self.iter();
@@ -50,17 +67,17 @@ impl<T> ToCss for Vec<T> where T: ToCss 
         for item in iter {
             dest.write_str(", ")?;
             item.to_css(dest)?;
         }
         Ok(())
     }
 }
 
-impl<T: ToCss> ToCss for Box<T> {
+impl<T> ToCss for Box<T> where T: ?Sized + ToCss {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write,
     {
         (**self).to_css(dest)
     }
 }
 
 impl ToCss for Au {