Bug 1434130 part 6 - Allow shorthands to specify their own impl of SpecifiedValueInfo and manual impl it for font and border. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Thu, 26 Apr 2018 15:09:40 +1000
changeset 788772 fe72d293e8420ddb903883fb6c0b5970aead6a26
parent 788771 29990f9171efe771ea4d09fd129d37a4a1ec3870
child 788773 19f96541b1c1d147d92bf055b36abe4a7ed5c43d
push id108088
push userxquan@mozilla.com
push dateFri, 27 Apr 2018 00:40:56 +0000
reviewersemilio
bugs1434130
milestone61.0a1
Bug 1434130 part 6 - Allow shorthands to specify their own impl of SpecifiedValueInfo and manual impl it for font and border. r?emilio MozReview-Commit-ID: 3B9OfkWU0Eq
servo/components/style/properties/helpers.mako.rs
servo/components/style/properties/shorthand/border.mako.rs
servo/components/style/properties/shorthand/font.mako.rs
--- a/servo/components/style/properties/helpers.mako.rs
+++ b/servo/components/style/properties/helpers.mako.rs
@@ -614,35 +614,43 @@
                          extra_specified=extra_specified, needs_conversion=needs_conversion)}
             % if caller:
             ${caller.body()}
             % endif
         </%call>
     % endif
 </%def>
 
-<%def name="shorthand(name, sub_properties, derive_serialize=False, **kwargs)">
+<%def name="shorthand(name, sub_properties, derive_serialize=False,
+                      derive_value_info=True, **kwargs)">
 <%
     shorthand = data.declare_shorthand(name, sub_properties.split(), **kwargs)
+    # mako doesn't accept non-string value in parameters with <% %> form, so
+    # we have to workaround it this way.
+    if not isinstance(derive_value_info, bool):
+        derive_value_info = eval(derive_value_info)
 %>
     % if shorthand:
     /// ${shorthand.spec}
     pub mod ${shorthand.ident} {
         use cssparser::Parser;
         use parser::ParserContext;
         use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands};
         #[allow(unused_imports)]
         use selectors::parser::SelectorParseErrorKind;
         #[allow(unused_imports)]
         use std::fmt::{self, Write};
         #[allow(unused_imports)]
         use style_traits::{ParseError, StyleParseErrorKind};
         #[allow(unused_imports)]
-        use style_traits::{CssWriter, SpecifiedValueInfo, ToCss};
+        use style_traits::{CssWriter, KeywordsCollectFn, SpecifiedValueInfo, ToCss};
 
+        % if derive_value_info:
+        #[derive(SpecifiedValueInfo)]
+        % endif
         pub struct Longhands {
             % for sub_property in shorthand.sub_properties:
                 pub ${sub_property.ident}:
                     % if sub_property.boxed:
                         Box<
                     % endif
                     longhands::${sub_property.ident}::SpecifiedValue
                     % if sub_property.boxed:
@@ -739,36 +747,16 @@
                     ));
                 % if sub_property.may_be_disabled_in(shorthand, product):
                 }
                 % endif
                 % endfor
             })
         }
 
-        <%
-            sub_properties_for_value_info = shorthand.sub_properties
-            if shorthand.name == "border":
-                # border-image subproperties are simply reset by border
-                # shorthand, so border cannot accept values of them.
-                # XXX We may want a better mechanism for this, but this
-                # is probably fine for now.
-                sub_properties_for_value_info = [
-                    subprop for subprop in shorthand.sub_properties
-                    if not subprop.name.startswith("border-image")
-                ]
-        %>
-        impl SpecifiedValueInfo for Longhands {
-            const SUPPORTED_TYPES: u8 = 0
-                % for subprop in sub_properties_for_value_info:
-                | <longhands::${subprop.ident}::SpecifiedValue as SpecifiedValueInfo>::SUPPORTED_TYPES
-                % endfor
-                ;
-        }
-
         ${caller.body()}
     }
     % endif
 </%def>
 
 <%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
                                  needs_context=True, allow_quirks=False, **kwargs)">
     <% sub_properties=' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left']) %>
--- a/servo/components/style/properties/shorthand/border.mako.rs
+++ b/servo/components/style/properties/shorthand/border.mako.rs
@@ -135,16 +135,17 @@ pub fn parse_border<'i, 't>(
 % endfor
 
 <%helpers:shorthand name="border"
     sub_properties="${' '.join('border-%s-%s' % (side, prop)
         for side in PHYSICAL_SIDES
         for prop in ['color', 'style', 'width'])}
         ${' '.join('border-image-%s' % name
         for name in ['outset', 'repeat', 'slice', 'source', 'width'])}"
+    derive_value_info="False"
     spec="https://drafts.csswg.org/css-backgrounds/#border">
 
     pub fn parse_value<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Longhands, ParseError<'i>> {
         use properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
         use properties::longhands::{border_image_source, border_image_width};
@@ -197,16 +198,27 @@ pub fn parse_border<'i, 't>(
                     self.border_${side}_color
                 )
             } else {
                 Ok(())
             }
         }
     }
 
+    // Just use the same as border-left. The border shorthand can't accept
+    // any value that the sub-shorthand couldn't.
+    <%
+        border_left = "<::properties::shorthands::border_left::Longhands as SpecifiedValueInfo>"
+    %>
+    impl SpecifiedValueInfo for Longhands {
+        const SUPPORTED_TYPES: u8 = ${border_left}::SUPPORTED_TYPES;
+        fn collect_completion_keywords(f: KeywordsCollectFn) {
+            ${border_left}::collect_completion_keywords(f);
+        }
+    }
 </%helpers:shorthand>
 
 <%helpers:shorthand name="border-radius" sub_properties="${' '.join(
     'border-%s-radius' % (corner)
      for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left']
 )}" extra_prefixes="webkit" spec="https://drafts.csswg.org/css-backgrounds/#border-radius">
     use values::generics::rect::Rect;
     use values::generics::border::BorderCornerRadius;
--- a/servo/components/style/properties/shorthand/font.mako.rs
+++ b/servo/components/style/properties/shorthand/font.mako.rs
@@ -14,16 +14,17 @@
                                     ${'font-variant-alternates' if product == 'gecko' else ''}
                                     ${'font-variant-east-asian' if product == 'gecko' else ''}
                                     ${'font-variant-ligatures' if product == 'gecko' else ''}
                                     ${'font-variant-numeric' if product == 'gecko' else ''}
                                     ${'font-variant-position' if product == 'gecko' else ''}
                                     ${'font-language-override' if product == 'gecko' else ''}
                                     ${'font-feature-settings' if product == 'gecko' else ''}
                                     ${'font-variation-settings' if product == 'gecko' else ''}"
+                    derive_value_info="False"
                     spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
     use parser::Parse;
     use properties::longhands::{font_family, font_style, font_weight, font_stretch};
     use properties::longhands::font_variant_caps;
     #[cfg(feature = "gecko")]
     use properties::longhands::system_font::SystemFont;
     use values::specified::text::LineHeight;
     use values::specified::FontSize;
@@ -253,16 +254,39 @@
             } else if sys.is_some() {
                 CheckSystemResult::SomeSystem
             } else {
                 CheckSystemResult::None
             }
         }
         % endif
     }
+
+    <%
+        subprops_for_value_info = ["font_style", "font_weight", "font_stretch",
+                                   "font_variant_caps", "font_size", "font_family"]
+        subprops_for_value_info = [
+            "<longhands::{}::SpecifiedValue as SpecifiedValueInfo>".format(p)
+            for p in subprops_for_value_info
+        ]
+    %>
+    impl SpecifiedValueInfo for Longhands {
+        const SUPPORTED_TYPES: u8 = 0
+            % for p in subprops_for_value_info:
+            | ${p}::SUPPORTED_TYPES
+            % endfor
+            ;
+
+        fn collect_completion_keywords(f: KeywordsCollectFn) {
+            % for p in subprops_for_value_info:
+            ${p}::collect_completion_keywords(f);
+            % endfor
+            <longhands::system_font::SystemFont as SpecifiedValueInfo>::collect_completion_keywords(f);
+        }
+    }
 </%helpers:shorthand>
 
 <%helpers:shorthand name="font-variant"
                     sub_properties="font-variant-caps
                                     ${'font-variant-alternates' if product == 'gecko' else ''}
                                     ${'font-variant-east-asian' if product == 'gecko' else ''}
                                     ${'font-variant-ligatures' if product == 'gecko' else ''}
                                     ${'font-variant-numeric' if product == 'gecko' else ''}