Bug 1328787 - Part 10: Set Keyframe.mPropertyValues for the case where keyframe is not specified. r?heycam
MozReview-Commit-ID: KozUNqxmjK9
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -46,21 +46,24 @@ use gecko_bindings::structs::nsStyleVari
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use gecko_bindings::sugar::ownership::HasArcFFI;
use gecko::values::convert_nscolor_to_rgba;
use gecko::values::convert_rgba_to_nscolor;
use gecko::values::GeckoStyleCoordConvertible;
use gecko::values::round_border_to_device_pixels;
use logical_geometry::WritingMode;
use properties::longhands;
+use properties::{DeclaredValue, Importance, LonghandId};
+use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
use std::fmt::{self, Debug};
use std::mem::{transmute, zeroed};
use std::ptr;
use std::sync::Arc;
use std::cmp;
+use values::computed::ToComputedValue;
pub mod style_structs {
% for style_struct in data.style_structs:
pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
% endfor
}
#[derive(Clone, Debug)]
@@ -149,16 +152,38 @@ impl ComputedValues {
pub fn root_font_size(&self) -> Au { self.root_font_size }
pub fn set_root_font_size(&mut self, s: Au) { self.root_font_size = s; }
pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
// FIXME(bholley): Implement this properly.
#[inline]
pub fn is_multicol(&self) -> bool { false }
+
+ pub fn to_declaration_block(&self, property: PropertyDeclarationId) -> PropertyDeclarationBlock {
+ match property {
+ % for prop in data.longhands:
+ % if prop.animatable:
+ PropertyDeclarationId::Longhand(LonghandId::${prop.camel_case}) => {
+ PropertyDeclarationBlock {
+ declarations: vec![
+ (PropertyDeclaration::${prop.camel_case}(DeclaredValue::Value(
+ longhands::${prop.ident}::SpecifiedValue::from_computed_value(
+ &self.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}()))),
+ Importance::Normal)
+ ],
+ important_count: 0
+ }
+ },
+ % endif
+ % endfor
+ PropertyDeclarationId::Custom(_name) => unimplemented!(),
+ _ => unimplemented!()
+ }
+ }
}
<%def name="declare_style_struct(style_struct)">
pub struct ${style_struct.gecko_struct_name} {
gecko: ${style_struct.gecko_ffi_name},
}
</%def>
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -17,16 +17,17 @@ use properties::longhands::font_weight::
use properties::longhands::line_height::computed_value::T as LineHeight;
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
use properties::longhands::text_shadow::computed_value::TextShadow;
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
+#[cfg(feature = "gecko")] use properties::{PropertyDeclarationId, LonghandId};
use std::cmp;
use std::fmt;
use style_traits::ToCss;
use super::ComputedValues;
use values::Either;
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use values::computed::{BorderRadiusSize, LengthOrNone};
use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage};
@@ -116,16 +117,33 @@ impl From<TransitionProperty> for nsCSSP
=> ${helpers.to_nscsspropertyid(prop.ident)},
% endif
% endfor
TransitionProperty::All => nsCSSPropertyID::eCSSPropertyExtra_all_properties,
}
}
}
+/// Convert to PropertyDeclarationId.
+#[cfg(feature = "gecko")]
+#[allow(non_upper_case_globals)]
+impl<'a> From<TransitionProperty> for PropertyDeclarationId<'a> {
+ fn from(transition_property: TransitionProperty) -> PropertyDeclarationId<'a> {
+ match transition_property {
+ % for prop in data.longhands:
+ % if prop.animatable:
+ TransitionProperty::${prop.camel_case}
+ => PropertyDeclarationId::Longhand(LonghandId::${prop.camel_case}),
+ % endif
+ % endfor
+ TransitionProperty::All => panic!(),
+ }
+ }
+}
+
/// An animated property interpolation between two computed values for that
/// property.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum AnimatedProperty {
% for prop in data.longhands:
% if prop.animatable:
/// ${prop.name}
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1142,21 +1142,22 @@ pub extern "C" fn Servo_AssertTreeIsClea
assert_subtree_is_clean(root);
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSetBorrowed,
name: *const nsACString,
timing_function: *const nsTimingFunction,
- _style: ServoComputedValuesBorrowed,
+ style: ServoComputedValuesBorrowed,
keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
let style_timing_function = unsafe { timing_function.as_ref().unwrap() };
+ let style = ComputedValues::as_arc(&style);
if let Some(ref animation) = data.stylist.animations().get(&name) {
for step in &animation.steps {
// Override timing_function if the keyframe has animation-timing-function.
let timing_function = if let Some(val) = step.get_animation_timing_function() {
val.into()
} else {
*style_timing_function
@@ -1165,17 +1166,25 @@ pub extern "C" fn Servo_StyleSet_FillKey
let keyframe = unsafe {
Gecko_AnimationAppendKeyframe(keyframes,
step.start_percentage.0 as f32,
&timing_function)
};
match step.value {
KeyframesStepValue::ComputedValues => {
- unimplemented!();
+ for (index, property) in animation.properties_changed.iter().enumerate() {
+ let block = style.to_declaration_block(property.clone().into());
+ unsafe {
+ (*keyframe).mPropertyValues.set_len((index + 1) as u32);
+ (*keyframe).mPropertyValues[index].mProperty = property.clone().into();
+ (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
+ Arc::new(RwLock::new(block)));
+ }
+ }
},
KeyframesStepValue::Declarations { ref block } => {
let guard = block.read();
// Filter out non-animatable properties.
let animatable =
guard.declarations
.iter()
.filter(|&&(ref declaration, _)| {