servo: Merge #17813 - Store raw string for prop decl in @supports (from upsuper:supports-decl); r=SimonSapin
authorXidorn Quan <me@upsuper.org>
Fri, 21 Jul 2017 09:01:57 -0700
changeset 418947 fda487b4114add204e118e7cbccb924326f1c471
parent 418946 a112a1a624cd3b7422d037bcb05464a171a3bf9a
child 418948 9aa5577c8716fa2f4dbbb0497cb9425245568e46
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersSimonSapin
milestone56.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 #17813 - Store raw string for prop decl in @supports (from upsuper:supports-decl); r=SimonSapin This fixes the serialization issue of `@supports` rule that whitespaces are not preserved like in other browsers. It makes the work a bit redundant (the property name and colon is parsed twice), but I suppose this isn't a big deal. Source-Repo: https://github.com/servo/servo Source-Revision: d1ac8b26e9fe2476d4b97522beb030ae60163d23
servo/components/script/dom/css.rs
servo/components/style/stylesheets/supports_rule.rs
--- a/servo/components/script/dom/css.rs
+++ b/servo/components/script/dom/css.rs
@@ -25,17 +25,21 @@ impl CSS {
     pub fn Escape(_: &Window, ident: DOMString) -> Fallible<DOMString> {
         let mut escaped = String::new();
         serialize_identifier(&ident, &mut escaped).unwrap();
         Ok(DOMString::from(escaped))
     }
 
     /// https://drafts.csswg.org/css-conditional/#dom-css-supports
     pub fn Supports(win: &Window, property: DOMString, value: DOMString) -> bool {
-        let decl = Declaration { prop: property.into(), val: value.into() };
+        let mut decl = String::new();
+        serialize_identifier(&property, &mut decl).unwrap();
+        decl.push_str(": ");
+        decl.push_str(&value);
+        let decl = Declaration(decl);
         let url = win.Document().url();
         let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
                                                    PARSING_MODE_DEFAULT,
                                                    QuirksMode::NoQuirks);
         decl.eval(&context)
     }
 
     /// https://drafts.csswg.org/css-conditional/#dom-css-supports
--- a/servo/components/style/stylesheets/supports_rule.rs
+++ b/servo/components/style/stylesheets/supports_rule.rs
@@ -209,62 +209,53 @@ impl ToCss for SupportsCondition {
             }
             SupportsCondition::FutureSyntax(ref s) => dest.write_str(&s),
         }
     }
 }
 
 #[derive(Clone, Debug)]
 /// A possibly-invalid property declaration
-pub struct Declaration {
-    /// The property name
-    pub prop: String,
-    /// The property value
-    pub val: String,
-}
+pub struct Declaration(pub String);
 
 impl ToCss for Declaration {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-        where W: fmt::Write
-    {
-        dest.write_str(&self.prop)?;
-        dest.write_str(":")?;
-        // no space, the `val` already contains any possible spaces
-        dest.write_str(&self.val)
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        dest.write_str(&self.0)
     }
 }
 
 /// https://drafts.csswg.org/css-syntax-3/#typedef-any-value
 fn consume_any_value<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> {
     input.expect_no_error_token().map_err(|err| err.into())
 }
 
 impl Declaration {
     /// Parse a declaration
     pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Declaration, ParseError<'i>> {
-        let prop = input.expect_ident()?.into_owned();
+        let pos = input.position();
+        input.expect_ident()?;
         input.expect_colon()?;
-        let pos = input.position();
         consume_any_value(input)?;
-        Ok(Declaration { prop: prop, val: input.slice_from(pos).to_owned() })
+        Ok(Declaration(input.slice_from(pos).to_owned()))
     }
 
     /// Determine if a declaration parses
     ///
     /// https://drafts.csswg.org/css-conditional-3/#support-definition
     pub fn eval(&self, cx: &ParserContext) -> bool {
-        let id = if let Ok(id) = PropertyId::parse((&*self.prop).into()) {
-            id
-        } else {
-            return false
-        };
-        let mut input = ParserInput::new(&self.val);
+        let mut input = ParserInput::new(&self.0);
         let mut input = Parser::new(&mut input);
-        let context = ParserContext::new_with_rule_type(cx, Some(CssRuleType::Style));
-        let mut declarations = SourcePropertyDeclaration::new();
-        let res = input.parse_until_before(Delimiter::Bang, |input| {
-            PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
-                .map_err(|e| StyleParseError::PropertyDeclaration(e).into())
-        });
-        let _ = input.try(parse_important);
-        res.is_ok() && input.is_exhausted()
+        input.parse_entirely(|input| {
+            let prop = input.expect_ident().unwrap();
+            input.expect_colon().unwrap();
+            let id = PropertyId::parse(&prop)
+                .map_err(|_| StyleParseError::UnspecifiedError)?;
+            let mut declarations = SourcePropertyDeclaration::new();
+            let context = ParserContext::new_with_rule_type(cx, Some(CssRuleType::Style));
+            input.parse_until_before(Delimiter::Bang, |input| {
+                PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
+                    .map_err(|e| StyleParseError::PropertyDeclaration(e).into())
+            })?;
+            let _ = input.try(parse_important);
+            Ok(())
+        }).is_ok()
     }
 }