Auto merge of #16280 - hiikezoe:handle-base-style, r=heycam,birtles

Handle base style

<!-- Please describe your changes on the following line: -->
This is a PR for https://bugzilla.mozilla.org/show_bug.cgi?id=1311257

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [X] These changes do not require tests because it's for stylo.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16280)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-04-05 22:53:30 -05:00 committed by GitHub
commit d7fb2cc27f
7 changed files with 9113 additions and 8073 deletions

View file

@ -273,6 +273,9 @@ mod bindings {
.include(add_include("gfxFontConstants.h")) .include(add_include("gfxFontConstants.h"))
.include(add_include("nsThemeConstants.h")) .include(add_include("nsThemeConstants.h"))
.include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h")) .include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h"))
.include(add_include("mozilla/AnimationPropertySegment.h"))
.include(add_include("mozilla/ComputedTiming.h"))
.include(add_include("mozilla/ComputedTimingFunction.h"))
.include(add_include("mozilla/Keyframe.h")) .include(add_include("mozilla/Keyframe.h"))
.include(add_include("mozilla/ServoElementSnapshot.h")) .include(add_include("mozilla/ServoElementSnapshot.h"))
.include(add_include("mozilla/dom/Element.h")) .include(add_include("mozilla/dom/Element.h"))
@ -308,6 +311,10 @@ mod bindings {
]; ];
let whitelist = [ let whitelist = [
"RawGecko.*", "RawGecko.*",
"mozilla::AnimationPropertySegment",
"mozilla::ComputedTiming",
"mozilla::ComputedTimingFunction",
"mozilla::ComputedTimingFunction::BeforeFlag",
"mozilla::ServoStyleSheet", "mozilla::ServoStyleSheet",
"mozilla::ServoElementSnapshot.*", "mozilla::ServoElementSnapshot.*",
"mozilla::CSSPseudoClassType", "mozilla::CSSPseudoClassType",
@ -591,6 +598,8 @@ mod bindings {
.whitelisted_function("Gecko_.*"); .whitelisted_function("Gecko_.*");
let structs_types = [ let structs_types = [
"mozilla::css::URLValue", "mozilla::css::URLValue",
"RawGeckoAnimationPropertySegment",
"RawGeckoComputedTiming",
"RawGeckoDocument", "RawGeckoDocument",
"RawGeckoElement", "RawGeckoElement",
"RawGeckoKeyframeList", "RawGeckoKeyframeList",
@ -608,6 +617,7 @@ mod bindings {
"RefPtr", "RefPtr",
"CSSPseudoClassType", "CSSPseudoClassType",
"TraversalRootBehavior", "TraversalRootBehavior",
"ComputedTimingFunction_BeforeFlag",
"FontFamilyList", "FontFamilyList",
"FontFamilyType", "FontFamilyType",
"Keyframe", "Keyframe",
@ -708,7 +718,9 @@ mod bindings {
let servo_borrow_types = [ let servo_borrow_types = [
"nsCSSValue", "nsCSSValue",
"nsTimingFunction", "nsTimingFunction",
"RawGeckoAnimationPropertySegment",
"RawGeckoAnimationValueList", "RawGeckoAnimationValueList",
"RawGeckoComputedTiming",
"RawGeckoKeyframeList", "RawGeckoKeyframeList",
"RawGeckoComputedKeyframeValuesList", "RawGeckoComputedKeyframeValuesList",
"RawGeckoFontFaceRuleList", "RawGeckoFontFaceRuleList",

View file

@ -4,6 +4,8 @@ pub use nsstring::{nsACString, nsAString, nsString};
type nsACString_internal = nsACString; type nsACString_internal = nsACString;
type nsAString_internal = nsAString; type nsAString_internal = nsAString;
use gecko_bindings::structs::mozilla::css::URLValue; use gecko_bindings::structs::mozilla::css::URLValue;
use gecko_bindings::structs::RawGeckoAnimationPropertySegment;
use gecko_bindings::structs::RawGeckoComputedTiming;
use gecko_bindings::structs::RawGeckoDocument; use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoKeyframeList; use gecko_bindings::structs::RawGeckoKeyframeList;
@ -21,6 +23,7 @@ use gecko_bindings::structs::RawGeckoURLExtraData;
use gecko_bindings::structs::RefPtr; use gecko_bindings::structs::RefPtr;
use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::CSSPseudoClassType;
use gecko_bindings::structs::TraversalRootBehavior; use gecko_bindings::structs::TraversalRootBehavior;
use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
use gecko_bindings::structs::FontFamilyList; use gecko_bindings::structs::FontFamilyList;
use gecko_bindings::structs::FontFamilyType; use gecko_bindings::structs::FontFamilyType;
use gecko_bindings::structs::Keyframe; use gecko_bindings::structs::Keyframe;
@ -269,10 +272,18 @@ pub type nsTimingFunctionBorrowed<'a> = &'a nsTimingFunction;
pub type nsTimingFunctionBorrowedOrNull<'a> = Option<&'a nsTimingFunction>; pub type nsTimingFunctionBorrowedOrNull<'a> = Option<&'a nsTimingFunction>;
pub type nsTimingFunctionBorrowedMut<'a> = &'a mut nsTimingFunction; pub type nsTimingFunctionBorrowedMut<'a> = &'a mut nsTimingFunction;
pub type nsTimingFunctionBorrowedMutOrNull<'a> = Option<&'a mut nsTimingFunction>; pub type nsTimingFunctionBorrowedMutOrNull<'a> = Option<&'a mut nsTimingFunction>;
pub type RawGeckoAnimationPropertySegmentBorrowed<'a> = &'a RawGeckoAnimationPropertySegment;
pub type RawGeckoAnimationPropertySegmentBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationPropertySegment>;
pub type RawGeckoAnimationPropertySegmentBorrowedMut<'a> = &'a mut RawGeckoAnimationPropertySegment;
pub type RawGeckoAnimationPropertySegmentBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationPropertySegment>;
pub type RawGeckoAnimationValueListBorrowed<'a> = &'a RawGeckoAnimationValueList; pub type RawGeckoAnimationValueListBorrowed<'a> = &'a RawGeckoAnimationValueList;
pub type RawGeckoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationValueList>; pub type RawGeckoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationValueList>;
pub type RawGeckoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoAnimationValueList; pub type RawGeckoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoAnimationValueList;
pub type RawGeckoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationValueList>; pub type RawGeckoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationValueList>;
pub type RawGeckoComputedTimingBorrowed<'a> = &'a RawGeckoComputedTiming;
pub type RawGeckoComputedTimingBorrowedOrNull<'a> = Option<&'a RawGeckoComputedTiming>;
pub type RawGeckoComputedTimingBorrowedMut<'a> = &'a mut RawGeckoComputedTiming;
pub type RawGeckoComputedTimingBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoComputedTiming>;
pub type RawGeckoKeyframeListBorrowed<'a> = &'a RawGeckoKeyframeList; pub type RawGeckoKeyframeListBorrowed<'a> = &'a RawGeckoKeyframeList;
pub type RawGeckoKeyframeListBorrowedOrNull<'a> = Option<&'a RawGeckoKeyframeList>; pub type RawGeckoKeyframeListBorrowedOrNull<'a> = Option<&'a RawGeckoKeyframeList>;
pub type RawGeckoKeyframeListBorrowedMut<'a> = &'a mut RawGeckoKeyframeList; pub type RawGeckoKeyframeListBorrowedMut<'a> = &'a mut RawGeckoKeyframeList;
@ -450,18 +461,9 @@ extern "C" {
extern "C" { extern "C" {
pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64; pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64;
} }
extern "C" {
pub fn Gecko_IsLink(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" { extern "C" {
pub fn Gecko_IsTextNode(node: RawGeckoNodeBorrowed) -> bool; pub fn Gecko_IsTextNode(node: RawGeckoNodeBorrowed) -> bool;
} }
extern "C" {
pub fn Gecko_IsVisitedLink(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" {
pub fn Gecko_IsUnvisitedLink(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" { extern "C" {
pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool; pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool;
} }
@ -587,7 +589,8 @@ extern "C" {
-> RawServoDeclarationBlockStrongBorrowedOrNull; -> RawServoDeclarationBlockStrongBorrowedOrNull;
} }
extern "C" { extern "C" {
pub fn Gecko_GetExtraContentStyleDeclarations(element: RawGeckoElementBorrowed) pub fn Gecko_GetExtraContentStyleDeclarations(element:
RawGeckoElementBorrowed)
-> RawServoDeclarationBlockStrongBorrowedOrNull; -> RawServoDeclarationBlockStrongBorrowedOrNull;
} }
extern "C" { extern "C" {
@ -624,6 +627,25 @@ extern "C" {
aPseudoTagOrNull: *mut nsIAtom) aPseudoTagOrNull: *mut nsIAtom)
-> bool; -> bool;
} }
extern "C" {
pub fn Gecko_GetProgressFromComputedTiming(aComputedTiming:
RawGeckoComputedTimingBorrowed)
-> f64;
}
extern "C" {
pub fn Gecko_GetPositionInSegment(aSegment:
RawGeckoAnimationPropertySegmentBorrowed,
aProgress: f64,
aBeforeFlag:
ComputedTimingFunction_BeforeFlag)
-> f64;
}
extern "C" {
pub fn Gecko_AnimationGetBaseStyle(aBaseStyles:
*mut ::std::os::raw::c_void,
aProperty: nsCSSPropertyID)
-> RawServoAnimationValueBorrowedOrNull;
}
extern "C" { extern "C" {
pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32) pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32)
-> *mut nsIAtom; -> *mut nsIAtom;
@ -1585,6 +1607,13 @@ extern "C" {
value: value:
RawServoAnimationValueBorrowed); RawServoAnimationValueBorrowed);
} }
extern "C" {
pub fn Servo_ComputedValues_ExtractAnimationValue(computed_values:
ServoComputedValuesBorrowed,
property:
nsCSSPropertyID)
-> RawServoAnimationValueStrong;
}
extern "C" { extern "C" {
pub fn Servo_AnimationValues_Interpolate(from: pub fn Servo_AnimationValues_Interpolate(from:
RawServoAnimationValueBorrowed, RawServoAnimationValueBorrowed,
@ -1710,6 +1739,16 @@ extern "C" {
property: property:
nsCSSPropertyID); nsCSSPropertyID);
} }
extern "C" {
pub fn Servo_AnimationCompose(animation_values:
RawServoAnimationValueMapBorrowed,
base_values: *mut ::std::os::raw::c_void,
property: nsCSSPropertyID,
animation_segment:
RawGeckoAnimationPropertySegmentBorrowed,
computed_timing:
RawGeckoComputedTimingBorrowed);
}
extern "C" { extern "C" {
pub fn Servo_DeclarationBlock_PropertyIsSet(declarations: pub fn Servo_DeclarationBlock_PropertyIsSet(declarations:
RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockBorrowed,
@ -1841,8 +1880,7 @@ extern "C" {
extern "C" { extern "C" {
pub fn Servo_ResolveStyle(element: RawGeckoElementBorrowed, pub fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
set: RawServoStyleSetBorrowed, set: RawServoStyleSetBorrowed,
allow_stale: bool) allow_stale: bool) -> ServoComputedValuesStrong;
-> ServoComputedValuesStrong;
} }
extern "C" { extern "C" {
pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
@ -1865,6 +1903,15 @@ extern "C" {
extern "C" { extern "C" {
pub fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed); pub fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed);
} }
extern "C" {
pub fn Servo_StyleSet_GetBaseComputedValuesForElement(set:
RawServoStyleSetBorrowed,
element:
RawGeckoElementBorrowed,
pseudo_tag:
*mut nsIAtom)
-> ServoComputedValuesStrong;
}
extern "C" { extern "C" {
pub fn Servo_GetStyleFont(computed_values: pub fn Servo_GetStyleFont(computed_values:
ServoComputedValuesBorrowedOrNull) ServoComputedValuesBorrowedOrNull)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -468,19 +468,18 @@ trait PrivateMatchMethods: TElement {
} }
fn cascade_with_rules(&self, fn cascade_with_rules(&self,
context: &StyleContext<Self>, shared_context: &SharedStyleContext,
rule_node: &StrongRuleNode, rule_node: &StrongRuleNode,
primary_style: &ComputedStyle, primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &mut ComputedStyle)>, cascade_flags: CascadeFlags,
cascade_flags: CascadeFlags) is_pseudo: bool)
-> Arc<ComputedValues> { -> Arc<ComputedValues> {
let shared_context = context.shared;
let mut cascade_info = CascadeInfo::new(); let mut cascade_info = CascadeInfo::new();
// Grab the inherited values. // Grab the inherited values.
let parent_el; let parent_el;
let parent_data; let parent_data;
let inherited_values_ = if pseudo_style.is_none() { let inherited_values_ = if !is_pseudo {
parent_el = self.parent_element(); parent_el = self.parent_element();
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data()); parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
let parent_values = parent_data.as_ref().map(|d| { let parent_values = parent_data.as_ref().map(|d| {
@ -517,7 +516,7 @@ trait PrivateMatchMethods: TElement {
// //
// Note that this is not needed for pseudos since we already do that // Note that this is not needed for pseudos since we already do that
// when we resolve the non-pseudo style. // when we resolve the non-pseudo style.
if pseudo_style.is_none() { if !is_pseudo {
if let Some(ref p) = layout_parent_style { if let Some(ref p) = layout_parent_style {
let can_be_fragmented = let can_be_fragmented =
p.is_multicol() || p.is_multicol() ||
@ -557,7 +556,7 @@ trait PrivateMatchMethods: TElement {
// Grab the rule node. // Grab the rule node.
let rule_node = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1).rules; let rule_node = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1).rules;
self.cascade_with_rules(context, rule_node, primary_style, pseudo_style, cascade_flags) self.cascade_with_rules(context.shared, rule_node, primary_style, cascade_flags, pseudo_style.is_some())
} }
/// Computes values and damage for the primary or pseudo style of an element, /// Computes values and damage for the primary or pseudo style of an element,
@ -606,7 +605,7 @@ trait PrivateMatchMethods: TElement {
fn get_after_change_style(&self, fn get_after_change_style(&self,
context: &mut StyleContext<Self>, context: &mut StyleContext<Self>,
primary_style: &ComputedStyle, primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &mut ComputedStyle)>) pseudo_style: &Option<(&PseudoElement, &ComputedStyle)>)
-> Arc<ComputedValues> { -> Arc<ComputedValues> {
let style = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1); let style = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1);
let rule_node = &style.rules; let rule_node = &style.rules;
@ -622,11 +621,11 @@ trait PrivateMatchMethods: TElement {
if self.skip_root_and_item_based_display_fixup() { if self.skip_root_and_item_based_display_fixup() {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP) cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
} }
self.cascade_with_rules(context, self.cascade_with_rules(context.shared,
&without_transition_rules, &without_transition_rules,
primary_style, primary_style,
&pseudo_style, cascade_flags,
cascade_flags) pseudo_style.is_some())
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
@ -1211,6 +1210,34 @@ pub trait MatchMethods : TElement {
}); });
} }
} }
/// Returns computed values without animation and transition rules.
fn get_base_style(&self,
shared_context: &SharedStyleContext,
primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &ComputedStyle)>)
-> Arc<ComputedValues> {
let style = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1);
let rule_node = &style.rules;
let without_animation_rules =
shared_context.stylist.rule_tree.remove_animation_and_transition_rules(rule_node);
if without_animation_rules == *rule_node {
// Note that unwrapping here is fine, because the style is
// only incomplete during the styling process.
return style.values.as_ref().unwrap().clone();
}
let mut cascade_flags = CascadeFlags::empty();
if self.skip_root_and_item_based_display_fixup() {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
self.cascade_with_rules(shared_context,
&without_animation_rules,
primary_style,
cascade_flags,
pseudo_style.is_some())
}
} }
impl<E: TElement> MatchMethods for E {} impl<E: TElement> MatchMethods for E {}

View file

@ -81,6 +81,7 @@ impl TransitionProperty {
/// Get a transition property from a property declaration. /// Get a transition property from a property declaration.
pub fn from_declaration(declaration: &PropertyDeclaration) -> Option<Self> { pub fn from_declaration(declaration: &PropertyDeclaration) -> Option<Self> {
use properties::LonghandId;
match *declaration { match *declaration {
% for prop in data.longhands: % for prop in data.longhands:
% if prop.animatable: % if prop.animatable:
@ -88,6 +89,18 @@ impl TransitionProperty {
=> Some(TransitionProperty::${prop.camel_case}), => Some(TransitionProperty::${prop.camel_case}),
% endif % endif
% endfor % endfor
PropertyDeclaration::CSSWideKeyword(id, _) |
PropertyDeclaration::WithVariables(id, _) => {
match id {
% for prop in data.longhands:
% if prop.animatable:
LonghandId::${prop.camel_case} =>
Some(TransitionProperty::${prop.camel_case}),
% endif
% endfor
_ => None,
}
},
_ => None, _ => None,
} }
} }
@ -386,6 +399,23 @@ impl AnimationValue {
_ => None // non animatable properties will get included because of shorthands. ignore. _ => None // non animatable properties will get included because of shorthands. ignore.
} }
} }
/// Get an AnimationValue for a TransitionProperty from a given computed values.
pub fn from_computed_values(transition_property: &TransitionProperty,
computed_values: &ComputedValues)
-> Self {
match *transition_property {
TransitionProperty::All => panic!("Can't use TransitionProperty::All here."),
% for prop in data.longhands:
% if prop.animatable:
TransitionProperty::${prop.camel_case} => {
AnimationValue::${prop.camel_case}(
computed_values.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
}
% endif
% endfor
}
}
} }
impl Interpolate for AnimationValue { impl Interpolate for AnimationValue {

View file

@ -39,7 +39,9 @@ use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedVal
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong}; use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{nsACString, nsAString}; use style::gecko_bindings::bindings::{nsACString, nsAString};
use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe; use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
use style::gecko_bindings::bindings::RawGeckoAnimationPropertySegmentBorrowed;
use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut; use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
use style::gecko_bindings::bindings::RawGeckoElementBorrowed; use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut; use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
@ -253,6 +255,82 @@ pub extern "C" fn Servo_AnimationValueMap_Push(value_map: RawServoAnimationValue
value_map.write().insert(property.into(), value.clone()); value_map.write().insert(property.into(), value.clone());
} }
#[no_mangle]
pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMapBorrowed,
base_values: *mut ::std::os::raw::c_void,
css_property: nsCSSPropertyID,
segment: RawGeckoAnimationPropertySegmentBorrowed,
computed_timing: RawGeckoComputedTimingBorrowed)
{
use style::gecko_bindings::bindings::Gecko_AnimationGetBaseStyle;
use style::gecko_bindings::bindings::Gecko_GetPositionInSegment;
use style::gecko_bindings::bindings::Gecko_GetProgressFromComputedTiming;
use style::properties::animated_properties::AnimationValueMap;
let property: TransitionProperty = css_property.into();
let value_map = RwLock::<AnimationValueMap>::as_arc(&raw_value_map);
// If either of the segment endpoints are null, get the underlying value to
// use from the current value in the values map (set by a lower-priority
// effect), or, if there is no current value, look up the cached base value
// for this property.
let underlying_value = if segment.mFromValue.mServo.mRawPtr.is_null() ||
segment.mToValue.mServo.mRawPtr.is_null() {
let previous_composed_value = value_map.read().get(&property).cloned();
previous_composed_value.or_else(|| {
let raw_base_style = unsafe { Gecko_AnimationGetBaseStyle(base_values, css_property) };
AnimationValue::arc_from_borrowed(&raw_base_style).map(|v| v.as_ref()).cloned()
})
} else {
None
};
if (segment.mFromValue.mServo.mRawPtr.is_null() ||
segment.mToValue.mServo.mRawPtr.is_null()) &&
underlying_value.is_none() {
warn!("Underlying value should be valid in the case where either 'from' value or 'to' value is null");
return;
}
// Declare for making derefenced raw pointer alive outside the if block.
let raw_from_value;
let from_value = if !segment.mFromValue.mServo.mRawPtr.is_null() {
raw_from_value = unsafe { &*segment.mFromValue.mServo.mRawPtr };
AnimationValue::as_arc(&raw_from_value).as_ref()
} else {
underlying_value.as_ref().unwrap()
};
let raw_to_value;
let to_value = if !segment.mToValue.mServo.mRawPtr.is_null() {
raw_to_value = unsafe { &*segment.mToValue.mServo.mRawPtr };
AnimationValue::as_arc(&raw_to_value).as_ref()
} else {
underlying_value.as_ref().unwrap()
};
let progress = unsafe { Gecko_GetProgressFromComputedTiming(computed_timing) };
if segment.mToKey == segment.mFromKey {
if progress < 0. {
value_map.write().insert(property, from_value.clone());
} else {
value_map.write().insert(property, to_value.clone());
}
return;
}
let position = unsafe {
Gecko_GetPositionInSegment(segment, progress, computed_timing.mBeforeFlag)
};
if let Ok(value) = from_value.interpolate(to_value, position) {
value_map.write().insert(property, value);
} else if progress < 0.5 {
value_map.write().insert(property, from_value.clone());
} else {
value_map.write().insert(property, to_value.clone());
}
}
macro_rules! get_property_id_from_nscsspropertyid { macro_rules! get_property_id_from_nscsspropertyid {
($property_id: ident, $ret: expr) => {{ ($property_id: ident, $ret: expr) => {{
match PropertyId::from_nscsspropertyid($property_id) { match PropertyId::from_nscsspropertyid($property_id) {
@ -310,6 +388,45 @@ pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBor
this_value == other_value this_value == other_value
} }
#[no_mangle]
pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawServoStyleSetBorrowed,
element: RawGeckoElementBorrowed,
pseudo_tag: *mut nsIAtom)
-> ServoComputedValuesStrong
{
use style::matching::MatchMethods;
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let shared_context = &create_shared_context(&guard, &doc_data, false);
let element = GeckoElement(element);
let element_data = element.borrow_data().unwrap();
let styles = element_data.styles();
let pseudo = if pseudo_tag.is_null() {
None
} else {
let atom = Atom::from(pseudo_tag);
Some(PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false))
};
let pseudos = &styles.pseudos;
let pseudo_style = pseudo.as_ref().map(|p| (p, pseudos.get(p).unwrap()));
element.get_base_style(shared_context, &styles.primary, &pseudo_style)
.into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_ExtractAnimationValue(computed_values: ServoComputedValuesBorrowed,
property_id: nsCSSPropertyID)
-> RawServoAnimationValueStrong
{
let computed_values = ComputedValues::as_arc(&computed_values);
Arc::new(AnimationValue::from_computed_values(&property_id.into(), computed_values)).into_strong()
}
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
GLOBAL_STYLE_DATA.num_threads as u32 GLOBAL_STYLE_DATA.num_threads as u32