mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #15287 - hiikezoe:css-animation, r=heycam
Counter part of bug 1328787 - Stylo: Convert Servo's animation keyframes and store them into Gecko's keyframes
<!-- Please describe your changes on the following line: -->
Reviewed by @heycam, An exception is auto-generated bindgen stuff, I did not include it in patches on bugzilla. The bindgen diff included in this PR was generated with b5c94bad37
. It might be bit-rotted.
---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because gecko has test cases.
<!-- 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/15287)
<!-- Reviewable:end -->
This commit is contained in:
commit
0459e1a6dd
13 changed files with 7228 additions and 9083 deletions
|
@ -232,6 +232,7 @@ mod bindings {
|
|||
.include(add_include("gfxFontConstants.h"))
|
||||
.include(add_include("nsThemeConstants.h"))
|
||||
.include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h"))
|
||||
.include(add_include("mozilla/Keyframe.h"))
|
||||
.include(add_include("mozilla/ServoElementSnapshot.h"))
|
||||
.include(add_include("mozilla/dom/Element.h"))
|
||||
.include(add_include("mozilla/ServoBindings.h"))
|
||||
|
@ -288,6 +289,7 @@ mod bindings {
|
|||
"HalfCorner",
|
||||
"Image",
|
||||
"ImageURL",
|
||||
"Keyframe",
|
||||
"nsAttrName",
|
||||
"nsAttrValue",
|
||||
"nsBorderColors",
|
||||
|
@ -362,6 +364,7 @@ mod bindings {
|
|||
"nsTArray",
|
||||
"nsTArrayHeader",
|
||||
"Position",
|
||||
"PropertyValuePair",
|
||||
"Runnable",
|
||||
"ServoAttrSnapshot",
|
||||
"ServoElementSnapshot",
|
||||
|
@ -489,9 +492,11 @@ mod bindings {
|
|||
let structs_types = [
|
||||
"RawGeckoDocument",
|
||||
"RawGeckoElement",
|
||||
"RawGeckoKeyframeList",
|
||||
"RawGeckoNode",
|
||||
"RawGeckoAnimationValueList",
|
||||
"RawServoAnimationValue",
|
||||
"RawServoDeclarationBlock",
|
||||
"RawGeckoPresContext",
|
||||
"RawGeckoPresContextOwned",
|
||||
"ThreadSafeURIHolder",
|
||||
|
@ -500,6 +505,7 @@ mod bindings {
|
|||
"TraversalRootBehavior",
|
||||
"FontFamilyList",
|
||||
"FontFamilyType",
|
||||
"Keyframe",
|
||||
"ServoElementSnapshot",
|
||||
"SheetParsingMode",
|
||||
"StyleBasicShape",
|
||||
|
@ -554,6 +560,7 @@ mod bindings {
|
|||
"nsStyleVariables",
|
||||
"nsStyleVisibility",
|
||||
"nsStyleXUL",
|
||||
"nsTimingFunction",
|
||||
"nscoord",
|
||||
"nsresult",
|
||||
"Loader",
|
||||
|
@ -596,6 +603,7 @@ mod bindings {
|
|||
let servo_borrow_types = [
|
||||
"nsCSSValue",
|
||||
"RawGeckoAnimationValueList",
|
||||
"RawGeckoKeyframeList",
|
||||
];
|
||||
for &ty in structs_types.iter() {
|
||||
builder = builder.hide_type(ty)
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
use app_units::Au;
|
||||
use gecko::values::convert_rgba_to_nscolor;
|
||||
use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue};
|
||||
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoDeclarationBlock, RawServoStyleRule, RawServoImportRule};
|
||||
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
|
||||
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
|
||||
use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
|
||||
use gecko_bindings::structs::RawServoDeclarationBlock;
|
||||
use gecko_bindings::structs::nsresult;
|
||||
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
|
||||
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
|
||||
|
|
|
@ -5,9 +5,11 @@ type nsACString_internal = nsACString;
|
|||
type nsAString_internal = nsAString;
|
||||
use gecko_bindings::structs::RawGeckoDocument;
|
||||
use gecko_bindings::structs::RawGeckoElement;
|
||||
use gecko_bindings::structs::RawGeckoKeyframeList;
|
||||
use gecko_bindings::structs::RawGeckoNode;
|
||||
use gecko_bindings::structs::RawGeckoAnimationValueList;
|
||||
use gecko_bindings::structs::RawServoAnimationValue;
|
||||
use gecko_bindings::structs::RawServoDeclarationBlock;
|
||||
use gecko_bindings::structs::RawGeckoPresContext;
|
||||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use gecko_bindings::structs::ThreadSafeURIHolder;
|
||||
|
@ -16,6 +18,7 @@ use gecko_bindings::structs::CSSPseudoClassType;
|
|||
use gecko_bindings::structs::TraversalRootBehavior;
|
||||
use gecko_bindings::structs::FontFamilyList;
|
||||
use gecko_bindings::structs::FontFamilyType;
|
||||
use gecko_bindings::structs::Keyframe;
|
||||
use gecko_bindings::structs::ServoElementSnapshot;
|
||||
use gecko_bindings::structs::SheetParsingMode;
|
||||
use gecko_bindings::structs::StyleBasicShape;
|
||||
|
@ -146,6 +149,7 @@ unsafe impl Sync for nsStyleVisibility {}
|
|||
use gecko_bindings::structs::nsStyleXUL;
|
||||
unsafe impl Send for nsStyleXUL {}
|
||||
unsafe impl Sync for nsStyleXUL {}
|
||||
use gecko_bindings::structs::nsTimingFunction;
|
||||
use gecko_bindings::structs::nscoord;
|
||||
use gecko_bindings::structs::nsresult;
|
||||
use gecko_bindings::structs::Loader;
|
||||
|
@ -171,8 +175,6 @@ pub struct RawServoStyleSheet(RawServoStyleSheetVoid);
|
|||
pub type RawServoDeclarationBlockStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoDeclarationBlock>;
|
||||
pub type RawServoDeclarationBlockBorrowed<'a> = &'a RawServoDeclarationBlock;
|
||||
pub type RawServoDeclarationBlockBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlock>;
|
||||
enum RawServoDeclarationBlockVoid { }
|
||||
pub struct RawServoDeclarationBlock(RawServoDeclarationBlockVoid);
|
||||
pub type RawServoStyleRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleRule>;
|
||||
pub type RawServoStyleRuleBorrowed<'a> = &'a RawServoStyleRule;
|
||||
pub type RawServoStyleRuleBorrowedOrNull<'a> = Option<&'a RawServoStyleRule>;
|
||||
|
@ -226,6 +228,10 @@ pub type RawGeckoAnimationValueListBorrowed<'a> = &'a RawGeckoAnimationValueList
|
|||
pub type RawGeckoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationValueList>;
|
||||
pub type RawGeckoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoAnimationValueList;
|
||||
pub type RawGeckoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationValueList>;
|
||||
pub type RawGeckoKeyframeListBorrowed<'a> = &'a RawGeckoKeyframeList;
|
||||
pub type RawGeckoKeyframeListBorrowedOrNull<'a> = Option<&'a RawGeckoKeyframeList>;
|
||||
pub type RawGeckoKeyframeListBorrowedMut<'a> = &'a mut RawGeckoKeyframeList;
|
||||
pub type RawGeckoKeyframeListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoKeyframeList>;
|
||||
|
||||
extern "C" {
|
||||
pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
|
||||
|
@ -662,6 +668,14 @@ extern "C" {
|
|||
*mut ::std::os::raw::c_void,
|
||||
len: usize);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_AnimationAppendKeyframe(keyframes:
|
||||
RawGeckoKeyframeListBorrowedMut,
|
||||
offset: f32,
|
||||
timingFunction:
|
||||
*const nsTimingFunction)
|
||||
-> *mut Keyframe;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ResetStyleCoord(unit: *mut nsStyleUnit,
|
||||
value: *mut nsStyleUnion);
|
||||
|
@ -1169,6 +1183,18 @@ extern "C" {
|
|||
pub fn Servo_StyleSet_NoteStyleSheetsChanged(set:
|
||||
RawServoStyleSetBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_FillKeyframesForName(set: RawServoStyleSetBorrowed,
|
||||
property:
|
||||
*const nsACString_internal,
|
||||
timing_function:
|
||||
*const nsTimingFunction,
|
||||
computed_values:
|
||||
ServoComputedValuesBorrowed,
|
||||
keyframe_list:
|
||||
RawGeckoKeyframeListBorrowedMut)
|
||||
-> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
|
||||
result: nsTArrayBorrowed_uintptr_t);
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2,64 +2,109 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use euclid::point::TypedPoint2D;
|
||||
use euclid::point::{Point2D, TypedPoint2D};
|
||||
use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type};
|
||||
use properties::longhands::transition_timing_function::single_value::FunctionKeyword;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
use properties::longhands::transition_timing_function::single_value::computed_value::StartEnd;
|
||||
use properties::longhands::transition_timing_function::single_value::computed_value::T as TransitionTimingFunction;
|
||||
use properties::longhands::transition_timing_function::single_value::computed_value::T as ComputedTimingFunction;
|
||||
use std::mem;
|
||||
|
||||
impl From<TransitionTimingFunction> for nsTimingFunction {
|
||||
fn from(function: TransitionTimingFunction) -> nsTimingFunction {
|
||||
impl nsTimingFunction {
|
||||
fn set_as_step(&mut self, function_type: nsTimingFunction_Type, steps: u32) {
|
||||
debug_assert!(function_type == nsTimingFunction_Type::StepStart ||
|
||||
function_type == nsTimingFunction_Type::StepEnd,
|
||||
"function_type should be step-start or step-end");
|
||||
self.mType = function_type;
|
||||
unsafe {
|
||||
self.__bindgen_anon_1.__bindgen_anon_1.as_mut().mSteps = steps;
|
||||
}
|
||||
}
|
||||
|
||||
fn set_as_cubic_bezier(&mut self, p1: Point2D<f32>, p2: Point2D<f32>) {
|
||||
self.mType = nsTimingFunction_Type::CubicBezier;
|
||||
unsafe {
|
||||
let ref mut gecko_cubic_bezier =
|
||||
unsafe { self.__bindgen_anon_1.mFunc.as_mut() };
|
||||
gecko_cubic_bezier.mX1 = p1.x;
|
||||
gecko_cubic_bezier.mY1 = p1.y;
|
||||
gecko_cubic_bezier.mX2 = p2.x;
|
||||
gecko_cubic_bezier.mY2 = p2.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ComputedTimingFunction> for nsTimingFunction {
|
||||
fn from(function: ComputedTimingFunction) -> nsTimingFunction {
|
||||
let mut tf: nsTimingFunction = unsafe { mem::zeroed() };
|
||||
|
||||
match function {
|
||||
TransitionTimingFunction::Steps(steps, StartEnd::Start) => {
|
||||
tf.mType = nsTimingFunction_Type::StepStart;
|
||||
unsafe {
|
||||
tf.__bindgen_anon_1.__bindgen_anon_1.as_mut().mSteps = steps;
|
||||
}
|
||||
ComputedTimingFunction::Steps(steps, StartEnd::Start) => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepStart, steps);
|
||||
},
|
||||
TransitionTimingFunction::Steps(steps, StartEnd::End) => {
|
||||
tf.mType = nsTimingFunction_Type::StepEnd;
|
||||
unsafe {
|
||||
tf.__bindgen_anon_1.__bindgen_anon_1.as_mut().mSteps = steps;
|
||||
}
|
||||
ComputedTimingFunction::Steps(steps, StartEnd::End) => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepEnd, steps);
|
||||
},
|
||||
TransitionTimingFunction::CubicBezier(p1, p2) => {
|
||||
tf.mType = nsTimingFunction_Type::CubicBezier;
|
||||
let ref mut gecko_cubic_bezier =
|
||||
unsafe { tf.__bindgen_anon_1.mFunc.as_mut() };
|
||||
gecko_cubic_bezier.mX1 = p1.x;
|
||||
gecko_cubic_bezier.mY1 = p1.y;
|
||||
gecko_cubic_bezier.mX2 = p2.x;
|
||||
gecko_cubic_bezier.mY2 = p2.y;
|
||||
ComputedTimingFunction::CubicBezier(p1, p2) => {
|
||||
tf.set_as_cubic_bezier(p1, p2);
|
||||
},
|
||||
// FIXME: we need to add more types once TransitionTimingFunction
|
||||
// has more types.
|
||||
}
|
||||
tf
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nsTimingFunction> for TransitionTimingFunction {
|
||||
fn from(function: nsTimingFunction) -> TransitionTimingFunction {
|
||||
impl From<SpecifiedTimingFunction> for nsTimingFunction {
|
||||
fn from(function: SpecifiedTimingFunction) -> nsTimingFunction {
|
||||
let mut tf: nsTimingFunction = unsafe { mem::zeroed() };
|
||||
|
||||
match function {
|
||||
SpecifiedTimingFunction::Steps(steps, StartEnd::Start) => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepStart, steps);
|
||||
},
|
||||
SpecifiedTimingFunction::Steps(steps, StartEnd::End) => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepEnd, steps);
|
||||
},
|
||||
SpecifiedTimingFunction::CubicBezier(p1, p2) => {
|
||||
tf.set_as_cubic_bezier(p1, p2);
|
||||
},
|
||||
SpecifiedTimingFunction::Keyword(keyword) => {
|
||||
match keyword {
|
||||
FunctionKeyword::Ease => tf.mType = nsTimingFunction_Type::Ease,
|
||||
FunctionKeyword::Linear => tf.mType = nsTimingFunction_Type::Linear,
|
||||
FunctionKeyword::EaseIn => tf.mType = nsTimingFunction_Type::EaseIn,
|
||||
FunctionKeyword::EaseOut => tf.mType = nsTimingFunction_Type::EaseOut,
|
||||
FunctionKeyword::EaseInOut => tf.mType = nsTimingFunction_Type::EaseInOut,
|
||||
FunctionKeyword::StepStart => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepStart, 1);
|
||||
},
|
||||
FunctionKeyword::StepEnd => {
|
||||
tf.set_as_step(nsTimingFunction_Type::StepEnd, 1);
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
tf
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nsTimingFunction> for ComputedTimingFunction {
|
||||
fn from(function: nsTimingFunction) -> ComputedTimingFunction {
|
||||
match function.mType {
|
||||
nsTimingFunction_Type::StepStart => {
|
||||
TransitionTimingFunction::Steps(unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mSteps },
|
||||
StartEnd::Start)
|
||||
ComputedTimingFunction::Steps(unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mSteps },
|
||||
StartEnd::Start)
|
||||
},
|
||||
nsTimingFunction_Type::StepEnd => {
|
||||
TransitionTimingFunction::Steps(unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mSteps },
|
||||
StartEnd::End)
|
||||
ComputedTimingFunction::Steps(unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mSteps },
|
||||
StartEnd::End)
|
||||
},
|
||||
// FIXME: As above, we need to fix here.
|
||||
nsTimingFunction_Type::Ease |
|
||||
nsTimingFunction_Type::Linear |
|
||||
nsTimingFunction_Type::EaseIn |
|
||||
nsTimingFunction_Type::EaseOut |
|
||||
nsTimingFunction_Type::EaseInOut |
|
||||
nsTimingFunction_Type::CubicBezier => {
|
||||
TransitionTimingFunction::CubicBezier(
|
||||
ComputedTimingFunction::CubicBezier(
|
||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX1 },
|
||||
unsafe { function.__bindgen_anon_1.mFunc.as_ref().mY1 }),
|
||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX2 },
|
||||
|
|
|
@ -11,8 +11,10 @@ use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
|
|||
use parking_lot::RwLock;
|
||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
||||
use properties::{PropertyDeclarationId, LonghandId, DeclaredValue};
|
||||
use properties::PropertyDeclarationParseResult;
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use style_traits::ToCss;
|
||||
|
@ -198,6 +200,35 @@ impl KeyframesStep {
|
|||
declared_timing_function: declared_timing_function,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'.
|
||||
pub fn get_animation_timing_function(&self) -> Option<SpecifiedTimingFunction> {
|
||||
if !self.declared_timing_function {
|
||||
return None;
|
||||
}
|
||||
match self.value {
|
||||
KeyframesStepValue::Declarations { ref block } => {
|
||||
let guard = block.read();
|
||||
let &(ref declaration, _) =
|
||||
guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap();
|
||||
match *declaration {
|
||||
PropertyDeclaration::AnimationTimingFunction(ref value) => {
|
||||
match *value {
|
||||
DeclaredValue::Value(ref value) => {
|
||||
// Use the first value.
|
||||
Some(value.0[0])
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
},
|
||||
KeyframesStepValue::ComputedValues => {
|
||||
panic!("Shouldn't happen to set animation-timing-function in missing keyframes")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This structure represents a list of animation steps computed from the list
|
||||
|
@ -271,7 +302,7 @@ impl KeyframesAnimation {
|
|||
}
|
||||
|
||||
if steps.last().unwrap().start_percentage.0 != 1. {
|
||||
steps.push(KeyframesStep::new(KeyframePercentage::new(0.),
|
||||
steps.push(KeyframesStep::new(KeyframePercentage::new(1.),
|
||||
KeyframesStepValue::ComputedValues));
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,14 @@ 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:
|
||||
|
@ -154,6 +157,28 @@ impl ComputedValues {
|
|||
// 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)">
|
||||
|
|
|
@ -665,3 +665,20 @@
|
|||
}
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="alias_to_nscsspropertyid(alias)">
|
||||
<%
|
||||
if alias == "word-wrap":
|
||||
return "nsCSSPropertyID_eCSSPropertyAlias_WordWrap"
|
||||
return "nsCSSPropertyID::eCSSPropertyAlias_%s" % to_camel_case(alias)
|
||||
%>
|
||||
</%def>
|
||||
|
||||
<%def name="to_nscsspropertyid(ident)">
|
||||
<%
|
||||
if ident == "float":
|
||||
ident = "float_"
|
||||
return "nsCSSPropertyID::eCSSProperty_%s" % ident
|
||||
%>
|
||||
</%def>
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
use app_units::Au;
|
||||
use cssparser::{Color as CSSParserColor, Parser, RGBA};
|
||||
use euclid::{Point2D, Size2D};
|
||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID;
|
||||
use properties::{DeclaredValue, PropertyDeclaration};
|
||||
use properties::longhands;
|
||||
use properties::longhands::background_position_x::computed_value::T as BackgroundPositionX;
|
||||
|
@ -19,6 +22,7 @@ use properties::longhands::box_shadow::single_value::computed_value::T as BoxSha
|
|||
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;
|
||||
|
@ -101,6 +105,40 @@ impl ToCss for TransitionProperty {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert to nsCSSPropertyID.
|
||||
#[cfg(feature = "gecko")]
|
||||
#[allow(non_upper_case_globals)]
|
||||
impl From<TransitionProperty> for nsCSSPropertyID {
|
||||
fn from(transition_property: TransitionProperty) -> nsCSSPropertyID {
|
||||
match transition_property {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
TransitionProperty::${prop.camel_case}
|
||||
=> ${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)]
|
||||
|
|
|
@ -830,7 +830,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
animatable="False",
|
||||
extra_prefixes="moz webkit"
|
||||
spec="https://drafts.csswg.org/css-animations/#propdef-animation-timing-function",
|
||||
allowed_in_keyframe_block="False">
|
||||
allowed_in_keyframe_block="True">
|
||||
pub use properties::longhands::transition_timing_function::single_value::computed_value;
|
||||
pub use properties::longhands::transition_timing_function::single_value::get_initial_value;
|
||||
pub use properties::longhands::transition_timing_function::single_value::get_initial_specified_value;
|
||||
|
|
|
@ -737,16 +737,6 @@ enum StaticId {
|
|||
Shorthand(ShorthandId),
|
||||
}
|
||||
include!(concat!(env!("OUT_DIR"), "/static_ids.rs"));
|
||||
<%
|
||||
def alias_to_nscsspropertyid(alias):
|
||||
if alias == "word-wrap":
|
||||
return "nsCSSPropertyID_eCSSPropertyAlias_WordWrap"
|
||||
return "nsCSSPropertyID::eCSSPropertyAlias_%s" % to_camel_case(alias)
|
||||
def to_nscsspropertyid(ident):
|
||||
if ident == "float":
|
||||
ident = "float_"
|
||||
return "nsCSSPropertyID::eCSSProperty_%s" % ident
|
||||
%>
|
||||
impl PropertyId {
|
||||
/// Returns a given property from the string `s`.
|
||||
///
|
||||
|
@ -771,21 +761,21 @@ impl PropertyId {
|
|||
use gecko_bindings::structs::*;
|
||||
match id {
|
||||
% for property in data.longhands:
|
||||
${to_nscsspropertyid(property.ident)} => {
|
||||
${helpers.to_nscsspropertyid(property.ident)} => {
|
||||
Ok(PropertyId::Longhand(LonghandId::${property.camel_case}))
|
||||
}
|
||||
% for alias in property.alias:
|
||||
${alias_to_nscsspropertyid(alias)} => {
|
||||
${helpers.alias_to_nscsspropertyid(alias)} => {
|
||||
Ok(PropertyId::Longhand(LonghandId::${property.camel_case}))
|
||||
}
|
||||
% endfor
|
||||
% endfor
|
||||
% for property in data.shorthands:
|
||||
${to_nscsspropertyid(property.ident)} => {
|
||||
${helpers.to_nscsspropertyid(property.ident)} => {
|
||||
Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case}))
|
||||
}
|
||||
% for alias in property.alias:
|
||||
${alias_to_nscsspropertyid(alias)} => {
|
||||
${helpers.alias_to_nscsspropertyid(alias)} => {
|
||||
Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case}))
|
||||
}
|
||||
% endfor
|
||||
|
@ -804,14 +794,14 @@ impl PropertyId {
|
|||
PropertyId::Longhand(id) => match id {
|
||||
% for property in data.longhands:
|
||||
LonghandId::${property.camel_case} => {
|
||||
Ok(${to_nscsspropertyid(property.ident)})
|
||||
Ok(${helpers.to_nscsspropertyid(property.ident)})
|
||||
}
|
||||
% endfor
|
||||
},
|
||||
PropertyId::Shorthand(id) => match id {
|
||||
% for property in data.shorthands:
|
||||
ShorthandId::${property.camel_case} => {
|
||||
Ok(${to_nscsspropertyid(property.ident)})
|
||||
Ok(${helpers.to_nscsspropertyid(property.ident)})
|
||||
}
|
||||
% endfor
|
||||
},
|
||||
|
@ -921,7 +911,7 @@ impl ToCss for PropertyDeclaration {
|
|||
pref_ident = "float_"
|
||||
%>
|
||||
if structs::root::mozilla::SERVO_PREF_ENABLED_${pref_ident} {
|
||||
let id = structs::${to_nscsspropertyid(property.ident)};
|
||||
let id = structs::${helpers.to_nscsspropertyid(property.ident)};
|
||||
let enabled = unsafe { bindings::Gecko_PropertyId_IsPrefEnabled(id) };
|
||||
if !enabled {
|
||||
return PropertyDeclarationParseResult::ExperimentalProperty
|
||||
|
|
|
@ -35,8 +35,10 @@ use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedV
|
|||
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
|
||||
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
||||
use style::gecko_bindings::bindings::{nsACString, nsAString};
|
||||
use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
|
||||
use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut;
|
||||
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
|
||||
use style::gecko_bindings::bindings::RawGeckoKeyframeListBorrowedMut;
|
||||
use style::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
|
||||
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
|
||||
use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
|
||||
|
@ -51,16 +53,18 @@ use style::gecko_bindings::structs::Loader;
|
|||
use style::gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use style::gecko_bindings::structs::RawServoAnimationValueBorrowedListBorrowed;
|
||||
use style::gecko_bindings::structs::ServoStyleSheet;
|
||||
use style::gecko_bindings::structs::nsTimingFunction;
|
||||
use style::gecko_bindings::structs::nsresult;
|
||||
use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
|
||||
use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
|
||||
use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
|
||||
use style::keyframes::KeyframesStepValue;
|
||||
use style::parallel;
|
||||
use style::parser::{ParserContext, ParserContextExtraData};
|
||||
use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration};
|
||||
use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId};
|
||||
use style::properties::{apply_declarations, parse_one_declaration};
|
||||
use style::properties::animated_properties::{AnimationValue, Interpolate};
|
||||
use style::properties::animated_properties::{AnimationValue, Interpolate, TransitionProperty};
|
||||
use style::restyle_hints::RestyleHint;
|
||||
use style::selector_parser::PseudoElementCascadeType;
|
||||
use style::sequential;
|
||||
|
@ -1139,3 +1143,71 @@ pub extern "C" fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed) {
|
|||
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
let keyframe = unsafe {
|
||||
Gecko_AnimationAppendKeyframe(keyframes,
|
||||
step.start_percentage.0 as f32,
|
||||
&timing_function)
|
||||
};
|
||||
|
||||
match step.value {
|
||||
KeyframesStepValue::ComputedValues => {
|
||||
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, _)| {
|
||||
declaration.is_animatable()
|
||||
});
|
||||
for (index, &(ref declaration, _)) in animatable.enumerate() {
|
||||
unsafe {
|
||||
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
|
||||
(*keyframe).mPropertyValues[index].mProperty =
|
||||
TransitionProperty::from_declaration(declaration).unwrap().into();
|
||||
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
|
||||
Arc::new(RwLock::new(
|
||||
PropertyDeclarationBlock { declarations: vec![ (declaration.clone(),
|
||||
Importance::Normal) ],
|
||||
important_count: 0 })));
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue