diff --git a/components/style/properties/data.py b/components/style/properties/data.py index d8327955fd5..6be3ec6e8b4 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -46,10 +46,11 @@ class Keyword(object): class Longhand(object): def __init__(self, style_struct, name, derived_from=None, keyword=None, - custom_cascade=False, experimental=False, internal=False, + predefined_type=None, custom_cascade=False, experimental=False, internal=False, need_clone=False, gecko_ffi_name=None): self.name = name self.keyword = keyword + self.predefined_type = predefined_type self.ident = to_rust_ident(name) self.camel_case = to_camel_case(self.ident) self.style_struct = style_struct diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 73ff84cadd5..fcf30e83d87 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -17,7 +17,7 @@ <%def name="predefined_type(name, type, initial_value, parse_method='parse', **kwargs)"> - <%call expr="longhand(name, **kwargs)"> + <%call expr="longhand(name, predefined_type=type, **kwargs)"> #[allow(unused_imports)] use app_units::Au; pub type SpecifiedValue = specified::${type}; diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 0852ef5dd4e..a927e487a6a 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -7,46 +7,9 @@ // Box-shadow, etc. <% data.new_style_struct("Effects", inherited=False) %> -<%helpers:longhand name="opacity"> - use cssparser::ToCss; - use std::fmt; - use values::CSSFloat; - - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } - - #[derive(Debug, Clone, PartialEq, HeapSizeOf)] - pub struct SpecifiedValue(pub CSSFloat); - pub mod computed_value { - use values::CSSFloat; - pub type T = CSSFloat; - } - #[inline] - pub fn get_initial_value() -> computed_value::T { - 1.0 - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, _context: &Cx) -> computed_value::T { - if self.0 < 0.0 { - 0.0 - } else if self.0 > 1.0 { - 1.0 - } else { - self.0 - } - } - } - fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - specified::parse_number(input).map(SpecifiedValue) - } - +${helpers.predefined_type("opacity", + "Opacity", + "1.0")} <%helpers:longhand name="box-shadow"> use cssparser::{self, ToCss}; diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index bd82f09519c..41dc76ee3b6 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -63,6 +63,11 @@ // Flex container properties ${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)} +// Flex item properties +${helpers.predefined_type("flex-grow", "Number", "0.0", "parse_non_negative", products="gecko")} + +${helpers.predefined_type("flex-shrink", "Number", "1.0", "parse_non_negative", products="gecko")} + // https://drafts.csswg.org/css-flexbox/#propdef-order <%helpers:longhand name="order"> use values::computed::ComputedValueAsSpecified; diff --git a/components/style/properties/longhand/svg.mako.rs b/components/style/properties/longhand/svg.mako.rs index 16e884d8227..4309926a99c 100644 --- a/components/style/properties/longhand/svg.mako.rs +++ b/components/style/properties/longhand/svg.mako.rs @@ -13,6 +13,14 @@ ${helpers.single_keyword("dominant-baseline", ${helpers.single_keyword("vector-effect", "none non-scaling-stroke", products="gecko")} +// Section 13 - Gradients and Patterns + +${helpers.predefined_type("stop-opacity", "Opacity", "1.0", products="gecko")} + +// Section 15 - Filter Effects + +${helpers.predefined_type("flood-opacity", "Opacity", "1.0", products="gecko")} + // CSS Masking Module Level 1 // https://www.w3.org/TR/css-masking-1/ ${helpers.single_keyword("mask-type", "luminance alpha", products="gecko")} diff --git a/components/style/properties/longhand/svg_inherited.mako.rs b/components/style/properties/longhand/svg_inherited.mako.rs index a2c2be61fb4..445d4948cf0 100644 --- a/components/style/properties/longhand/svg_inherited.mako.rs +++ b/components/style/properties/longhand/svg_inherited.mako.rs @@ -22,6 +22,8 @@ ${helpers.single_keyword("color-interpolation-filters", products="gecko", gecko_constant_prefix="NS_STYLE_COLOR_INTERPOLATION")} +${helpers.predefined_type("fill-opacity", "Opacity", "1.0", products="gecko")} + ${helpers.single_keyword("fill-rule", "nonzero evenodd", products="gecko")} ${helpers.single_keyword("shape-rendering", @@ -32,6 +34,11 @@ ${helpers.single_keyword("stroke-linecap", "butt round square", products="gecko" ${helpers.single_keyword("stroke-linejoin", "miter round bevel", products="gecko")} +${helpers.predefined_type("stroke-miterlimit", "Number", "4.0", "parse_at_least_one", + products="gecko")} + +${helpers.predefined_type("stroke-opacity", "Opacity", "1.0", products="gecko")} + // Section 14 - Clipping, Masking and Compositing ${helpers.single_keyword("clip-rule", "nonzero evenodd", products="gecko", diff --git a/components/style/properties/longhand/xul.mako.rs b/components/style/properties/longhand/xul.mako.rs index 84e874849eb..cb5db00717c 100644 --- a/components/style/properties/longhand/xul.mako.rs +++ b/components/style/properties/longhand/xul.mako.rs @@ -10,3 +10,6 @@ ${helpers.single_keyword("-moz-box-align", "stretch start center baseline end", products="gecko", gecko_ffi_name="mBoxAlign", gecko_constant_prefix="NS_STYLE_BOX_ALIGN")} + +${helpers.predefined_type("-moz-box-flex", "Number", "0.0", "parse_non_negative", products="gecko", + gecko_ffi_name="mBoxFlex")} diff --git a/components/style/values.rs b/components/style/values.rs index 23c933bc394..77a521469ad 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -1475,6 +1475,73 @@ pub mod specified { write!(dest, "{}s", self.0) } } + + #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)] + pub struct Number(pub CSSFloat); + + impl Number { + pub fn parse(input: &mut Parser) -> Result { + parse_number(input).map(Number) + } + + fn parse_with_minimum(input: &mut Parser, min: CSSFloat) -> Result { + match parse_number(input) { + Ok(value) if value < min => Err(()), + value => value.map(Number), + } + } + + pub fn parse_non_negative(input: &mut Parser) -> Result { + Number::parse_with_minimum(input, 0.0) + } + + pub fn parse_at_least_one(input: &mut Parser) -> Result { + Number::parse_with_minimum(input, 1.0) + } + } + + impl ToComputedValue for Number { + type ComputedValue = CSSFloat; + + #[inline] + fn to_computed_value(&self, _: &Cx) -> CSSFloat { self.0 } + } + + impl ToCss for Number { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) + } + } + + #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)] + pub struct Opacity(pub CSSFloat); + + impl Opacity { + pub fn parse(input: &mut Parser) -> Result { + parse_number(input).map(Opacity) + } + } + + impl ToComputedValue for Opacity { + type ComputedValue = CSSFloat; + + #[inline] + fn to_computed_value(&self, _: &Cx) -> CSSFloat { + if self.0 < 0.0 { + 0.0 + } else if self.0 > 1.0 { + 1.0 + } else { + self.0 + } + } + } + + impl ToCss for Opacity { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) + } + } } pub mod computed { @@ -2087,4 +2154,6 @@ pub mod computed { } } pub type Length = Au; + pub type Number = CSSFloat; + pub type Opacity = CSSFloat; } diff --git a/ports/geckolib/properties.mako.rs b/ports/geckolib/properties.mako.rs index f18659c0ea0..47d4b5c7d72 100644 --- a/ports/geckolib/properties.mako.rs +++ b/ports/geckolib/properties.mako.rs @@ -128,6 +128,12 @@ pub struct ${style_struct.gecko_struct_name} { } +<%def name="impl_simple_setter(ident, gecko_ffi_name)"> + fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { + ${set_gecko_property(gecko_ffi_name, "v")} + } + + <%def name="impl_simple_copy(ident, gecko_ffi_name)"> fn copy_${ident}_from(&mut self, other: &Self) { self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}; @@ -186,6 +192,11 @@ def set_gecko_property(ffi_name, expr): % endif +<%def name="impl_simple(ident, gecko_ffi_name)"> +<%call expr="impl_simple_setter(ident, gecko_ffi_name)"> +<%call expr="impl_simple_copy(ident, gecko_ffi_name)"> + + <%def name="impl_app_units(ident, gecko_ffi_name, need_clone)"> fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { self.gecko.${gecko_ffi_name} = v.0; @@ -284,8 +295,14 @@ impl Debug for ${style_struct.gecko_ffi_name} { # These are booleans. force_stub += ["page-break-after", "page-break-before"] + simple_types = ["Number", "Opacity"] + keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub] - stub_longhands = [x for x in longhands if x not in keyword_longhands] + simple_longhands = [x for x in longhands + if x.predefined_type in simple_types and not x.name in force_stub] + + autogenerated_longhands = keyword_longhands + simple_longhands + stub_longhands = [x for x in longhands if x not in autogenerated_longhands] %> impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} { /* @@ -299,6 +316,9 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} { % for longhand in keyword_longhands: <%call expr="impl_keyword(longhand.ident, longhand.gecko_ffi_name, longhand.keyword, longhand.need_clone)"> % endfor + % for longhand in simple_longhands: + <%call expr="impl_simple(longhand.ident, longhand.gecko_ffi_name)"> + % endfor /* * Stubs.