Correctly serialize CSS Custom Property names. draft
authorCameron McCormack <cam@mcc.id.au>
Tue, 02 May 2017 15:04:16 +0800
changeset 571204 d2dd0be00122b05f245ee87ee8d0ea0d6ebd5465
parent 571131 2e7c10a9b86e30691f67855f6c8f98d984508d7c
child 571205 5d034af34129b10322cf025e082d868232a2fc4b
push id56726
push userbmo:cam@mcc.id.au
push dateTue, 02 May 2017 08:49:00 +0000
milestone55.0a1
Correctly serialize CSS Custom Property names. MozReview-Commit-ID: KN2sXaNODke
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -13,17 +13,17 @@
 use std::borrow::Cow;
 use std::collections::HashSet;
 use std::fmt;
 use std::ops::Deref;
 use std::sync::Arc;
 
 use app_units::Au;
 #[cfg(feature = "servo")] use cssparser::{Color as CSSParserColor, RGBA};
-use cssparser::{Parser, TokenSerializationType};
+use cssparser::{Parser, TokenSerializationType, serialize_identifier};
 use error_reporting::ParseErrorReporter;
 #[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
 use computed_values;
 use context::QuirksMode;
 use font_metrics::FontMetricsProvider;
 #[cfg(feature = "gecko")] use gecko_bindings::bindings;
 #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
 #[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
@@ -770,17 +770,19 @@ pub enum PropertyDeclarationId<'a> {
 }
 
 impl<'a> ToCss for PropertyDeclarationId<'a> {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write,
     {
         match *self {
             PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()),
-            PropertyDeclarationId::Custom(name) => write!(dest, "--{}", name),
+            PropertyDeclarationId::Custom(_) => {
+                serialize_identifier(&self.name(), dest)
+            }
         }
     }
 }
 
 impl<'a> PropertyDeclarationId<'a> {
     /// Whether a given declaration id is either the same as `other`, or a
     /// longhand of it.
     pub fn is_or_is_longhand_of(&self, other: &PropertyId) -> bool {
@@ -801,16 +803,28 @@ impl<'a> PropertyDeclarationId<'a> {
     /// Whether a given declaration id is a longhand belonging to this
     /// shorthand.
     pub fn is_longhand_of(&self, shorthand: ShorthandId) -> bool {
         match *self {
             PropertyDeclarationId::Longhand(ref id) => shorthand.longhands().contains(id),
             _ => false,
         }
     }
+
+    /// Returns the name of the property without CSS escaping.
+    pub fn name(&self) -> String {
+        match *self {
+            PropertyDeclarationId::Longhand(id) => id.name().into(),
+            PropertyDeclarationId::Custom(name) => {
+                let mut s = String::from("--");
+                s += name.to_string().as_str();
+                s
+            }
+        }
+    }
 }
 
 /// Servo's representation of a CSS property, that is, either a longhand, a
 /// shorthand, or a custom property.
 #[derive(Eq, PartialEq, Clone)]
 pub enum PropertyId {
     /// A longhand property.
     Longhand(LonghandId),
@@ -828,17 +842,19 @@ impl fmt::Debug for PropertyId {
 
 impl ToCss for PropertyId {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write,
     {
         match *self {
             PropertyId::Longhand(id) => dest.write_str(id.name()),
             PropertyId::Shorthand(id) => dest.write_str(id.name()),
-            PropertyId::Custom(ref name) => write!(dest, "--{}", name),
+            PropertyId::Custom(_) => {
+                serialize_identifier(&self.name(), dest)
+            }
         }
     }
 }
 
 impl PropertyId {
     /// Returns a given property from the string `s`.
     ///
     /// Returns Err(()) for unknown non-custom properties
@@ -930,16 +946,29 @@ impl PropertyId {
     /// `PropertyDeclarationId`.
     pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> {
         match *self {
             PropertyId::Shorthand(id) => Ok(id),
             PropertyId::Longhand(id) => Err(PropertyDeclarationId::Longhand(id)),
             PropertyId::Custom(ref name) => Err(PropertyDeclarationId::Custom(name)),
         }
     }
+
+    /// Returns the name of the property without CSS escaping.
+    pub fn name(&self) -> String {
+        match *self {
+            PropertyId::Shorthand(id) => id.name().into(),
+            PropertyId::Longhand(id) => id.name().into(),
+            PropertyId::Custom(ref name) => {
+                let mut s = String::from("--");
+                s += name.to_string().as_str();
+                s
+            }
+        }
+    }
 }
 
 /// Includes shorthands before expansion
 pub enum ParsedDeclaration {
     % for shorthand in data.shorthands:
         % if shorthand.name == "all":
         // No need for an All(shorthands::all::Longhands) case, since we can
         // never have any values for 'all' other than the CSS-wide keywords
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1162,17 +1162,17 @@ pub extern "C" fn Servo_DeclarationBlock
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed,
                                                         index: u32, result: *mut nsAString) -> bool {
     read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
         if let Some(&(ref decl, _)) = decls.declarations().get(index as usize) {
             let result = unsafe { result.as_mut().unwrap() };
-            decl.id().to_css(result).unwrap();
+            result.assign_utf8(&decl.id().name());
             true
         } else {
             false
         }
     })
 }
 
 macro_rules! get_property_id_from_property {