diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 69fbfda33f71..c77274bbf39d 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -2562,7 +2562,9 @@ extern "C" { pub fn Servo_DeclarationBlock_SerializeOneValue(declarations: RawServoDeclarationBlockBorrowed, property: nsCSSPropertyID, - buffer: *mut nsAString); + buffer: *mut nsAString, + computed_values: + ServoStyleContextBorrowedOrNull); } extern "C" { pub fn Servo_DeclarationBlock_Count(declarations: diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 625ef96465ee..07bc5eeab1dd 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -518,13 +518,35 @@ impl PropertyDeclarationBlock { } /// Take a declaration block known to contain a single property and serialize it. - pub fn single_value_to_css(&self, property: &PropertyId, dest: &mut W) -> fmt::Result - where W: fmt::Write, + pub fn single_value_to_css( + &self, + property: &PropertyId, + dest: &mut W, + computed_values: Option<&ComputedValues>, + ) -> fmt::Result + where + W: fmt::Write, { match property.as_shorthand() { Err(_longhand_or_custom) => { if self.declarations.len() == 1 { - self.declarations[0].0.to_css(dest) + let declaration = &self.declarations[0].0; + // If we have a longhand declaration with variables, those variables will be + // stored as unparsed values. As a temporary measure to produce sensible results + // in Gecko's getKeyframes() implementation for CSS animations, if + // |computed_values| is supplied, we use it to expand such variable + // declarations. This will be fixed properly in Gecko bug 1391537. + match (declaration, computed_values) { + (&PropertyDeclaration::WithVariables(id, ref unparsed), + Some(ref computed_values)) => unparsed + .substitute_variables( + id, + &computed_values.custom_properties(), + QuirksMode::NoQuirks, + ) + .to_css(dest), + (ref d, _) => d.to_css(dest), + } } else { Err(fmt::Error) } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4a1d04d519ca..c0b778555651 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -564,7 +564,8 @@ pub extern "C" fn Servo_AnimationValue_Serialize(value: RawServoAnimationValueBo let uncomputed_value = AnimationValue::as_arc(&value).uncompute(); let mut string = String::new(); let rv = PropertyDeclarationBlock::with_one(uncomputed_value, Importance::Normal) - .single_value_to_css(&get_property_id_from_nscsspropertyid!(property, ()), &mut string); + .single_value_to_css(&get_property_id_from_nscsspropertyid!(property, ()), &mut string, + None); debug_assert!(rv.is_ok()); let buffer = unsafe { buffer.as_mut().unwrap() }; @@ -2142,12 +2143,13 @@ pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclar #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue( declarations: RawServoDeclarationBlockBorrowed, - property_id: nsCSSPropertyID, buffer: *mut nsAString) + property_id: nsCSSPropertyID, buffer: *mut nsAString, + computed_values: ServoStyleContextBorrowedOrNull) { let property_id = get_property_id_from_nscsspropertyid!(property_id, ()); read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| { let mut string = String::new(); - let rv = decls.single_value_to_css(&property_id, &mut string); + let rv = decls.single_value_to_css(&property_id, &mut string, computed_values); debug_assert!(rv.is_ok()); let buffer = unsafe { buffer.as_mut().unwrap() };