servo: Merge #15739 - Disallow keyword values in min/max-size properties in the block direction (from Manishearth:fix-wm); r=xidorn
authorManish Goregaokar <manishsmail@gmail.com>
Sat, 25 Feb 2017 23:26:34 -0800
changeset 373984 514c4898395dfac72118f60995f435ed5a595150
parent 373983 6a97e4643b57698053455366ae29329f8e9ff131
child 373985 0a3f512c84511c9418982a6e1a1cfe17444bd174
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs15739, 1342710
milestone54.0a1
servo: Merge #15739 - Disallow keyword values in min/max-size properties in the block direction (from Manishearth:fix-wm); r=xidorn r=xidorn from https://bugzilla.mozilla.org/show_bug.cgi?id=1342710 Source-Repo: https://github.com/servo/servo Source-Revision: f8f7b37dbdb918db25ebf3881478e4e1a4df8e30
servo/components/style/properties/longhand/position.mako.rs
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -212,49 +212,112 @@
     // width, height, block-size, inline-size
     ${helpers.predefined_type("%s" % size,
                               "LengthOrPercentageOrAuto",
                               "computed::LengthOrPercentageOrAuto::Auto",
                               "parse_non_negative",
                               needs_context=False,
                               spec=spec % size,
                               animatable=True, logical = logical)}
+    % if product == "gecko":
+        % for min_max in ["min", "max"]:
+            <%
+                MinMax = min_max.title()
+                initial = "None" if "max" == min_max else "Auto"
+            %>
 
-    % if product == "gecko":
-        // min-width, min-height, min-block-size, min-inline-size
-        ${helpers.predefined_type("min-%s" % size,
-                                  "MinLength",
-                                  "computed::MinLength::LengthOrPercentage(" +
-                                  "computed::LengthOrPercentage::Length(Au(0)))",
-                                  spec=spec % ("min-%s" % size),
-                                  animatable=True, logical = logical)}
+            // min-width, min-height, min-block-size, min-inline-size,
+            // max-width, max-height, max-block-size, max-inline-size
+            //
+            // Keyword values are only valid in the inline direction; they must
+            // be replaced with auto/none in block.
+            <%helpers:longhand name="${min_max}-${size}" spec="${spec % ('%s-%s' % (min_max, size))}"
+                               animatable="True" logical="${logical}" predefined_type="${MinMax}Length">
+
+                use std::fmt;
+                use style_traits::ToCss;
+                use values::HasViewportPercentage;
+                use values::specified::${MinMax}Length;
+
+                impl HasViewportPercentage for SpecifiedValue {
+                    fn has_viewport_percentage(&self) -> bool {
+                        self.0.has_viewport_percentage()
+                    }
+                }
+
+                pub mod computed_value {
+                    pub type T = ::values::computed::${MinMax}Length;
+                }
+
+                #[derive(PartialEq, Clone, Debug)]
+                #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+                pub struct SpecifiedValue(${MinMax}Length);
+
+                #[inline]
+                pub fn get_initial_value() -> computed_value::T {
+                    use values::computed::${MinMax}Length;
+                    ${MinMax}Length::${initial}
+                }
+                fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
+                    ${MinMax}Length::parse(context, input).map(SpecifiedValue)
+                }
+
+                impl ToCss for SpecifiedValue {
+                    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+                        self.0.to_css(dest)
+                    }
+                }
+
+                impl ToComputedValue for SpecifiedValue {
+                    type ComputedValue = computed_value::T;
+                    #[inline]
+                    fn to_computed_value(&self, context: &Context) -> computed_value::T {
+                        use values::computed::${MinMax}Length;
+                        let computed = self.0.to_computed_value(context);
+
+                        // filter out keyword values in the block direction
+                        % if logical:
+                            % if "block" in size:
+                                if let ${MinMax}Length::ExtremumLength(..) = computed {
+                                    return get_initial_value()
+                                }
+                            % endif
+                        % else:
+                            if let ${MinMax}Length::ExtremumLength(..) = computed {
+                                <% is_height = "true" if "height" in size else "false" %>
+                                if ${is_height} != context.style().writing_mode.is_vertical() {
+                                    return get_initial_value()
+                                }
+                            }
+                        % endif
+                        computed
+                    }
+
+                    #[inline]
+                    fn from_computed_value(computed: &computed_value::T) -> Self {
+                        SpecifiedValue(ToComputedValue::from_computed_value(computed))
+                    }
+                }
+            </%helpers:longhand>
+        % endfor
     % else:
+        // servo versions (no keyword support)
         ${helpers.predefined_type("min-%s" % size,
                                   "LengthOrPercentage",
                                   "computed::LengthOrPercentage::Length(Au(0))",
                                   "parse_non_negative",
                                   needs_context=False,
                                   spec=spec % ("min-%s" % size),
                                   animatable=True, logical = logical)}
-    % endif
-
-    // max-width, max-height, max-block-size, max-inline-size
-    % if product == "gecko":
-        ${helpers.predefined_type("max-%s" % size,
-                                  "MaxLength",
-                                  "computed::MaxLength::None",
-                                  spec=spec % ("max-%s" % size),
-                                  animatable=True, logical = logical)}
-    % else:
         ${helpers.predefined_type("max-%s" % size,
                                   "LengthOrPercentageOrNone",
                                   "computed::LengthOrPercentageOrNone::None",
                                   "parse_non_negative",
                                   needs_context=False,
-                                  spec=spec % ("max-%s" % size),
+                                  spec=spec % ("min-%s" % size),
                                   animatable=True, logical = logical)}
     % endif
 % endfor
 
 ${helpers.single_keyword("box-sizing",
                          "content-box border-box",
                          extra_prefixes="moz webkit",
                          spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",