Compute css variables with custom properties in keyframes for getKeyframes()

This commit is contained in:
Hiroyuki Ikezoe 2017-09-27 12:50:58 +09:00
parent 1b39041a8c
commit 5481d8ed6f
2 changed files with 48 additions and 17 deletions

View file

@ -584,6 +584,7 @@ impl PropertyDeclarationBlock {
property: &PropertyId, property: &PropertyId,
dest: &mut W, dest: &mut W,
computed_values: Option<&ComputedValues>, computed_values: Option<&ComputedValues>,
custom_properties_block: Option<&PropertyDeclarationBlock>,
) -> fmt::Result ) -> fmt::Result
where where
W: fmt::Write, W: fmt::Write,
@ -592,17 +593,29 @@ impl PropertyDeclarationBlock {
Err(_longhand_or_custom) => { Err(_longhand_or_custom) => {
if self.declarations.len() == 1 { if self.declarations.len() == 1 {
let declaration = &self.declarations[0]; let declaration = &self.declarations[0];
// If we have a longhand declaration with variables, those variables will be let custom_properties = if let Some(cv) = computed_values {
// stored as unparsed values. As a temporary measure to produce sensible results // If there are extra custom properties for this declaration block,
// in Gecko's getKeyframes() implementation for CSS animations, if // factor them in too.
// |computed_values| is supplied, we use it to expand such variable if let Some(block) = custom_properties_block {
// declarations. This will be fixed properly in Gecko bug 1391537. block.cascade_custom_properties(cv.custom_properties())
} else {
cv.custom_properties()
}
} else {
None
};
match (declaration, computed_values) { 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), (&PropertyDeclaration::WithVariables(id, ref unparsed),
Some(ref computed_values)) => unparsed Some(ref _computed_values)) => unparsed
.substitute_variables( .substitute_variables(
id, id,
&computed_values.custom_properties(), &custom_properties,
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
) )
.to_css(dest), .to_css(dest),
@ -671,7 +684,16 @@ impl PropertyDeclarationBlock {
&self, &self,
context: &Context, context: &Context,
) -> Option<Arc<::custom_properties::CustomPropertiesMap>> { ) -> Option<Arc<::custom_properties::CustomPropertiesMap>> {
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<Arc<::custom_properties::CustomPropertiesMap>>,
) -> Option<Arc<::custom_properties::CustomPropertiesMap>> {
let mut custom_properties = None; let mut custom_properties = None;
// FIXME: Use PrecomputedHasher instead. // FIXME: Use PrecomputedHasher instead.
let mut seen_custom = HashSet::new(); let mut seen_custom = HashSet::new();

View file

@ -69,6 +69,7 @@ use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut; use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueStrong; use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
use style::gecko_bindings::bindings::RawServoAnimationValueTableBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueTableBorrowed;
use style::gecko_bindings::bindings::RawServoDeclarationBlockBorrowedOrNull;
use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed; use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
use style::gecko_bindings::bindings::RawServoStyleSet; use style::gecko_bindings::bindings::RawServoStyleSet;
use style::gecko_bindings::bindings::ServoStyleContextBorrowedOrNull; 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 mut string = String::new();
let rv = PropertyDeclarationBlock::with_one(uncomputed_value, Importance::Normal) 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); None, None /* No extra custom properties */);
debug_assert!(rv.is_ok()); debug_assert!(rv.is_ok());
let buffer = unsafe { buffer.as_mut().unwrap() }; 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( pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
declarations: RawServoDeclarationBlockBorrowed, declarations: RawServoDeclarationBlockBorrowed,
property_id: nsCSSPropertyID, buffer: *mut nsAString, 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, ()); 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() }; let global_style_data = &*GLOBAL_STYLE_DATA;
buffer.assign_utf8(&string); let guard = global_style_data.shared_lock.read();
}) let decls = Locked::<PropertyDeclarationBlock>::as_arc(&declarations).read_with(&guard);
let mut string = String::new();
let custom_properties = Locked::<PropertyDeclarationBlock>::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] #[no_mangle]