diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 25cb0991626..3f9a54ac0c9 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -584,6 +584,7 @@ impl PropertyDeclarationBlock { property: &PropertyId, dest: &mut W, computed_values: Option<&ComputedValues>, + custom_properties_block: Option<&PropertyDeclarationBlock>, ) -> fmt::Result where W: fmt::Write, @@ -592,17 +593,29 @@ impl PropertyDeclarationBlock { Err(_longhand_or_custom) => { if self.declarations.len() == 1 { let declaration = &self.declarations[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. + let custom_properties = if let Some(cv) = computed_values { + // If there are extra custom properties for this declaration block, + // factor them in too. + if let Some(block) = custom_properties_block { + block.cascade_custom_properties(cv.custom_properties()) + } else { + cv.custom_properties() + } + } else { + None + }; + match (declaration, computed_values) { + // 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. (&PropertyDeclaration::WithVariables(id, ref unparsed), - Some(ref computed_values)) => unparsed + Some(ref _computed_values)) => unparsed .substitute_variables( id, - &computed_values.custom_properties(), + &custom_properties, QuirksMode::NoQuirks, ) .to_css(dest), @@ -671,7 +684,16 @@ impl PropertyDeclarationBlock { &self, context: &Context, ) -> Option> { - let inherited_custom_properties = context.style().custom_properties(); + self.cascade_custom_properties(context.style().custom_properties()) + } + + /// Returns a custom properties map which is the result of cascading custom + /// properties in this declaration block along with the given custom + /// properties. + pub fn cascade_custom_properties( + &self, + inherited_custom_properties: Option>, + ) -> Option> { let mut custom_properties = None; // FIXME: Use PrecomputedHasher instead. let mut seen_custom = HashSet::new(); diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index f49258a5cd3..69c039a9817 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -69,6 +69,7 @@ use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut; use style::gecko_bindings::bindings::RawServoAnimationValueStrong; use style::gecko_bindings::bindings::RawServoAnimationValueTableBorrowed; +use style::gecko_bindings::bindings::RawServoDeclarationBlockBorrowedOrNull; use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed; use style::gecko_bindings::bindings::RawServoStyleSet; use style::gecko_bindings::bindings::ServoStyleContextBorrowedOrNull; @@ -593,7 +594,7 @@ pub extern "C" fn Servo_AnimationValue_Serialize(value: RawServoAnimationValueBo 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, - None); + None, None /* No extra custom properties */); debug_assert!(rv.is_ok()); let buffer = unsafe { buffer.as_mut().unwrap() }; @@ -2286,17 +2287,25 @@ pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclar pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue( declarations: RawServoDeclarationBlockBorrowed, property_id: nsCSSPropertyID, buffer: *mut nsAString, - computed_values: ServoStyleContextBorrowedOrNull) + computed_values: ServoStyleContextBorrowedOrNull, + custom_properties: RawServoDeclarationBlockBorrowedOrNull) { 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, computed_values); - debug_assert!(rv.is_ok()); - let buffer = unsafe { buffer.as_mut().unwrap() }; - buffer.assign_utf8(&string); - }) + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let decls = Locked::::as_arc(&declarations).read_with(&guard); + + let mut string = String::new(); + + let custom_properties = Locked::::arc_from_borrowed(&custom_properties); + let custom_properties = custom_properties.map(|block| block.read_with(&guard)); + let rv = decls.single_value_to_css( + &property_id, &mut string, computed_values, custom_properties); + debug_assert!(rv.is_ok()); + + let buffer = unsafe { buffer.as_mut().unwrap() }; + buffer.assign_utf8(&string); } #[no_mangle]