Bug 1367283 - Part 2: Implements background related properties. r?hiro
In this patch, implements following background related properties
that type is single keyword.
* background-attachment
* background-clip
* background-origin
* background-blend-mode
MozReview-Commit-ID: 95FXL6LTaVE
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -2820,34 +2820,18 @@ fn static_assert() {
}
${impl_simple_copy("touch_action", "mTouchAction")}
</%self:impl_trait>
<%def name="simple_image_array_property(name, shorthand, field_name)">
<%
image_layers_field = "mImage" if shorthand == "background" else "mMask"
+ copy_simple_image_array_property(name, shorthand, image_layers_field, field_name)
%>
- pub fn copy_${shorthand}_${name}_from(&mut self, other: &Self) {
- use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
-
- let count = other.gecko.${image_layers_field}.${field_name}Count;
- unsafe {
- Gecko_EnsureImageLayersLength(&mut self.gecko.${image_layers_field},
- count as usize,
- LayerType::${shorthand.title()});
- }
- for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
- .zip(other.gecko.${image_layers_field}.mLayers.iter())
- .take(count as usize) {
- layer.${field_name} = other.${field_name};
- }
- self.gecko.${image_layers_field}.${field_name}Count = count;
- }
-
pub fn set_${shorthand}_${name}<I>(&mut self, v: I)
where I: IntoIterator<Item=longhands::${shorthand}_${name}::computed_value::single_value::T>,
I::IntoIter: ExactSizeIterator
{
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
let v = v.into_iter();
@@ -2859,19 +2843,112 @@ fn static_assert() {
self.gecko.${image_layers_field}.${field_name}Count = v.len() as u32;
for (servo, geckolayer) in v.zip(self.gecko.${image_layers_field}.mLayers.iter_mut()) {
geckolayer.${field_name} = {
${caller.body()}
};
}
}
</%def>
+
+<%def name="copy_simple_image_array_property(name, shorthand, layers_field_name, field_name)">
+ pub fn copy_${shorthand}_${name}_from(&mut self, other: &Self) {
+ use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
+
+ let count = other.gecko.${layers_field_name}.${field_name}Count;
+ unsafe {
+ Gecko_EnsureImageLayersLength(&mut self.gecko.${layers_field_name},
+ count as usize,
+ LayerType::${shorthand.title()});
+ }
+ for (layer, other) in self.gecko.${layers_field_name}.mLayers.iter_mut()
+ .zip(other.gecko.${layers_field_name}.mLayers.iter())
+ .take(count as usize) {
+ layer.${field_name} = other.${field_name};
+ }
+ self.gecko.${layers_field_name}.${field_name}Count = count;
+ }
+</%def>
+
+<%def name="impl_simple_image_array_property(name, shorthand, layer_field_name, field_name, struct_name)">
+ <%
+ ident = "%s_%s" % (shorthand, name)
+ style_struct = next(x for x in data.style_structs if x.name == struct_name)
+ longhand = next(x for x in style_struct.longhands if x.ident == ident)
+ keyword = longhand.keyword
+ %>
+
+ <% copy_simple_image_array_property(name, shorthand, layer_field_name, field_name) %>
+
+ pub fn set_${ident}<I>(&mut self, v: I)
+ where I: IntoIterator<Item=longhands::${ident}::computed_value::single_value::T>,
+ I::IntoIter: ExactSizeIterator
+ {
+ use properties::longhands::${ident}::single_value::computed_value::T as Keyword;
+ use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
+
+ let v = v.into_iter();
+
+ unsafe {
+ Gecko_EnsureImageLayersLength(&mut self.gecko.${layer_field_name}, v.len(),
+ LayerType::${shorthand.title()});
+ }
+
+ self.gecko.${layer_field_name}.${field_name}Count = v.len() as u32;
+ for (servo, geckolayer) in v.zip(self.gecko.${layer_field_name}.mLayers.iter_mut()) {
+ geckolayer.${field_name} = {
+ match servo {
+ % for value in keyword.values_for("gecko"):
+ Keyword::${to_rust_ident(value)} =>
+ structs::${keyword.gecko_constant(value)} ${keyword.maybe_cast('u8')},
+ % endfor
+ }
+ };
+ }
+ }
+
+ pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T
+ {
+ use properties::longhands::${ident}::single_value::computed_value::T as Keyword;
+
+ % if keyword.needs_cast():
+ % for value in keyword.values_for('gecko'):
+ const ${keyword.casted_constant_name(value, "u8")} : u8 =
+ structs::${keyword.gecko_constant(value)} as u8;
+ % endfor
+ % endif
+
+ longhands::${ident}::computed_value::T (
+ self.gecko.${layer_field_name}.mLayers.iter()
+ .take(self.gecko.${layer_field_name}.${field_name}Count as usize)
+ .map(|ref layer| {
+ match layer.${field_name} {
+ % for value in longhand.keyword.values_for("gecko"):
+ % if keyword.needs_cast():
+ ${keyword.casted_constant_name(value, "u8")}
+ % else:
+ structs::${keyword.gecko_constant(value)}
+ % endif
+ => Keyword::${to_rust_ident(value)},
+ % endfor
+ x => panic!("Found unexpected value in style struct for ${ident} property: {:?}", x),
+ }
+ }).collect()
+ )
+ }
+</%def>
+
<%def name="impl_common_image_layer_properties(shorthand)">
<%
- image_layers_field = "mImage" if shorthand == "background" else "mMask"
+ if shorthand == "background":
+ image_layers_field = "mImage"
+ struct_name = "Background"
+ else:
+ image_layers_field = "mMask"
+ struct_name = "SVG"
%>
<%self:simple_image_array_property name="repeat" shorthand="${shorthand}" field_name="mRepeat">
use properties::longhands::${shorthand}_repeat::single_value::computed_value::RepeatKeyword;
use gecko_bindings::structs::nsStyleImageLayers_Repeat;
use gecko_bindings::structs::NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
use gecko_bindings::structs::NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT;
use gecko_bindings::structs::NS_STYLE_IMAGELAYER_REPEAT_SPACE;
@@ -2889,50 +2966,18 @@ fn static_assert() {
let repeat_x = to_ns(servo.0);
let repeat_y = to_ns(servo.1);
nsStyleImageLayers_Repeat {
mXRepeat: repeat_x as u8,
mYRepeat: repeat_y as u8,
}
</%self:simple_image_array_property>
- <%self:simple_image_array_property name="clip" shorthand="${shorthand}" field_name="mClip">
- use gecko_bindings::structs::StyleGeometryBox;
- use properties::longhands::${shorthand}_clip::single_value::computed_value::T;
-
- match servo {
- T::border_box => StyleGeometryBox::BorderBox,
- T::padding_box => StyleGeometryBox::PaddingBox,
- T::content_box => StyleGeometryBox::ContentBox,
- % if shorthand == "mask":
- T::fill_box => StyleGeometryBox::FillBox,
- T::stroke_box => StyleGeometryBox::StrokeBox,
- T::view_box => StyleGeometryBox::ViewBox,
- T::no_clip => StyleGeometryBox::NoClip,
- % elif shorthand == "background":
- T::text => StyleGeometryBox::Text,
- % endif
- }
- </%self:simple_image_array_property>
-
- <%self:simple_image_array_property name="origin" shorthand="${shorthand}" field_name="mOrigin">
- use gecko_bindings::structs::StyleGeometryBox;
- use properties::longhands::${shorthand}_origin::single_value::computed_value::T;
-
- match servo {
- T::border_box => StyleGeometryBox::BorderBox,
- T::padding_box => StyleGeometryBox::PaddingBox,
- T::content_box => StyleGeometryBox::ContentBox,
- % if shorthand == "mask":
- T::fill_box => StyleGeometryBox::FillBox,
- T::stroke_box => StyleGeometryBox::StrokeBox,
- T::view_box => StyleGeometryBox::ViewBox,
- % endif
- }
- </%self:simple_image_array_property>
+ <% impl_simple_image_array_property("clip", shorthand, image_layers_field, "mClip", struct_name) %>
+ <% impl_simple_image_array_property("origin", shorthand, image_layers_field, "mOrigin", struct_name) %>
% for orientation in ["x", "y"]:
pub fn copy_${shorthand}_position_${orientation}_from(&mut self, other: &Self) {
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
let count = other.gecko.${image_layers_field}.mPosition${orientation.upper()}Count;
unsafe {
@@ -3143,48 +3188,18 @@ fn static_assert() {
background-blend-mode
background-position-x
background-position-y""" %>
<%self:impl_trait style_struct_name="Background"
skip_longhands="${skip_background_longhands}"
skip_additionals="*">
<% impl_common_image_layer_properties("background") %>
-
- <%self:simple_image_array_property name="attachment" shorthand="background" field_name="mAttachment">
- use properties::longhands::background_attachment::single_value::computed_value::T;
- match servo {
- T::scroll => structs::NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL as u8,
- T::fixed => structs::NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED as u8,
- T::local => structs::NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL as u8,
- }
- </%self:simple_image_array_property>
-
- <%self:simple_image_array_property name="blend_mode" shorthand="background" field_name="mBlendMode">
- use properties::longhands::background_blend_mode::single_value::computed_value::T;
-
- match servo {
- T::normal => structs::NS_STYLE_BLEND_NORMAL as u8,
- T::multiply => structs::NS_STYLE_BLEND_MULTIPLY as u8,
- T::screen => structs::NS_STYLE_BLEND_SCREEN as u8,
- T::overlay => structs::NS_STYLE_BLEND_OVERLAY as u8,
- T::darken => structs::NS_STYLE_BLEND_DARKEN as u8,
- T::lighten => structs::NS_STYLE_BLEND_LIGHTEN as u8,
- T::color_dodge => structs::NS_STYLE_BLEND_COLOR_DODGE as u8,
- T::color_burn => structs::NS_STYLE_BLEND_COLOR_BURN as u8,
- T::hard_light => structs::NS_STYLE_BLEND_HARD_LIGHT as u8,
- T::soft_light => structs::NS_STYLE_BLEND_SOFT_LIGHT as u8,
- T::difference => structs::NS_STYLE_BLEND_DIFFERENCE as u8,
- T::exclusion => structs::NS_STYLE_BLEND_EXCLUSION as u8,
- T::hue => structs::NS_STYLE_BLEND_HUE as u8,
- T::saturation => structs::NS_STYLE_BLEND_SATURATION as u8,
- T::color => structs::NS_STYLE_BLEND_COLOR as u8,
- T::luminosity => structs::NS_STYLE_BLEND_LUMINOSITY as u8,
- }
- </%self:simple_image_array_property>
+ <% impl_simple_image_array_property("attachment", "background", "mImage", "mAttachment", "Background") %>
+ <% impl_simple_image_array_property("blend_mode", "background", "mImage", "mBlendMode", "Background") %>
</%self:impl_trait>
<%self:impl_trait style_struct_name="List"
skip_longhands="list-style-image list-style-type quotes -moz-image-region"
skip_additionals="*">
pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) {
use values::Either;
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -344,17 +344,17 @@ impl AnimatedProperty {
/// animation at `progress`.
pub fn update(&self, style: &mut ComputedValues, progress: f64) {
match *self {
% for prop in data.longhands:
% if prop.animatable:
AnimatedProperty::${prop.camel_case}(ref from, ref to) => {
// https://w3c.github.io/web-animations/#discrete-animation-type
% if prop.animation_value_type == "discrete":
- let value = if progress < 0.5 { *from } else { *to };
+ let value = if progress < 0.5 { from.clone() } else { to.clone() };
% else:
let value = match from.interpolate(to, progress) {
Ok(value) => value,
Err(()) => return,
};
% endif
style.mutate_${prop.style_struct.ident.strip("_")}().set_${prop.ident}(value);
}
@@ -586,19 +586,19 @@ impl Animatable for AnimationValue {
-> Result<Self, ()> {
match (self, other) {
% for prop in data.longhands:
% if prop.animatable:
(&AnimationValue::${prop.camel_case}(ref from),
&AnimationValue::${prop.camel_case}(ref to)) => {
% if prop.animation_value_type == "discrete":
if self_portion > other_portion {
- Ok(AnimationValue::${prop.camel_case}(*from))
+ Ok(AnimationValue::${prop.camel_case}(from.clone()))
} else {
- Ok(AnimationValue::${prop.camel_case}(*to))
+ Ok(AnimationValue::${prop.camel_case}(to.clone()))
}
% else:
from.add_weighted(to, self_portion, other_portion)
.map(AnimationValue::${prop.camel_case})
% endif
}
% endif
% endfor
--- a/servo/components/style/properties/longhand/background.mako.rs
+++ b/servo/components/style/properties/longhand/background.mako.rs
@@ -139,39 +139,43 @@
}
}
}
</%helpers:vector_longhand>
${helpers.single_keyword("background-attachment",
"scroll fixed" + (" local" if product == "gecko" else ""),
vector=True,
+ gecko_constant_prefix="NS_STYLE_IMAGELAYER_ATTACHMENT",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
- animation_value_type="none")}
+ animation_value_type="discrete")}
${helpers.single_keyword("background-clip",
"border-box padding-box content-box",
extra_gecko_values="text",
vector=True, extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-clip",
- animation_value_type="none")}
+ animation_value_type="discrete")}
${helpers.single_keyword("background-origin",
"padding-box border-box content-box",
vector=True, extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-origin",
- animation_value_type="none")}
+ animation_value_type="discrete")}
${helpers.predefined_type("background-size", "BackgroundSize",
initial_value="computed::LengthOrPercentageOrAuto::Auto.into()",
initial_specified_value="specified::LengthOrPercentageOrAuto::Auto.into()",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-size",
vector=True,
animation_value_type="ComputedValue",
extra_prefixes="webkit")}
// https://drafts.fxtf.org/compositing/#background-blend-mode
${helpers.single_keyword("background-blend-mode",
"""normal multiply screen overlay darken lighten color-dodge
color-burn hard-light soft-light difference exclusion hue
saturation color luminosity""",
- vector=True, products="gecko", animation_value_type="none",
+ gecko_constant_prefix="NS_STYLE_BLEND",
+ vector=True, products="gecko", animation_value_type="discrete",
spec="https://drafts.fxtf.org/compositing/#background-blend-mode")}
--- a/servo/components/style/properties/longhand/svg.mako.rs
+++ b/servo/components/style/properties/longhand/svg.mako.rs
@@ -98,25 +98,27 @@
% endfor
${helpers.single_keyword("mask-clip",
"border-box content-box padding-box",
extra_gecko_values="fill-box stroke-box view-box no-clip",
vector=True,
products="gecko",
extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
animation_value_type="none",
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-clip")}
${helpers.single_keyword("mask-origin",
"border-box content-box padding-box",
extra_gecko_values="fill-box stroke-box view-box",
vector=True,
products="gecko",
extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
animation_value_type="none",
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-origin")}
<%helpers:longhand name="mask-size" products="gecko" animation_value_type="ComputedValue" extra_prefixes="webkit"
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-size">
use properties::longhands::background_size;
pub use ::properties::longhands::background_size::SpecifiedValue;
pub use ::properties::longhands::background_size::single_value as single_value;