Skip to content

Commit

Permalink
Add Servo_GetProperties_Overriding_Animation.
Browse files Browse the repository at this point in the history
We add one FFI, Servo_GetProperties_Overriding_Animation, which calls
StrongRuleNode::get_properties_overriding_animations() to get a LonghandIdSet,
which may override animation properties running on compositor.
  • Loading branch information
BorisChiou committed May 20, 2017
1 parent f054911 commit 60e7a89
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
22 changes: 22 additions & 0 deletions components/style/gecko/generated/bindings.rs
Expand Up @@ -10,6 +10,7 @@ use gecko_bindings::structs::mozilla::css::URLValue;
use gecko_bindings::structs::mozilla::Side;
use gecko_bindings::structs::RawGeckoAnimationPropertySegment;
use gecko_bindings::structs::RawGeckoComputedTiming;
use gecko_bindings::structs::RawGeckoCSSPropertyIDList;
use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoKeyframeList;
Expand Down Expand Up @@ -48,6 +49,7 @@ use gecko_bindings::structs::nsCSSCounterStyleRule;
use gecko_bindings::structs::nsCSSFontFaceRule;
use gecko_bindings::structs::nsCSSKeyword;
use gecko_bindings::structs::nsCSSPropertyID;
use gecko_bindings::structs::nsCSSPropertyIDSet;
use gecko_bindings::structs::nsCSSShadowArray;
use gecko_bindings::structs::nsCSSUnit;
use gecko_bindings::structs::nsCSSValue;
Expand Down Expand Up @@ -316,6 +318,10 @@ pub type RawGeckoPresContextBorrowed<'a> = &'a RawGeckoPresContext;
pub type RawGeckoPresContextBorrowedOrNull<'a> = Option<&'a RawGeckoPresContext>;
pub type RawGeckoStyleAnimationListBorrowed<'a> = &'a RawGeckoStyleAnimationList;
pub type RawGeckoStyleAnimationListBorrowedOrNull<'a> = Option<&'a RawGeckoStyleAnimationList>;
pub type nsCSSPropertyIDSetBorrowed<'a> = &'a nsCSSPropertyIDSet;
pub type nsCSSPropertyIDSetBorrowedOrNull<'a> = Option<&'a nsCSSPropertyIDSet>;
pub type nsCSSPropertyIDSetBorrowedMut<'a> = &'a mut nsCSSPropertyIDSet;
pub type nsCSSPropertyIDSetBorrowedMutOrNull<'a> = Option<&'a mut nsCSSPropertyIDSet>;
pub type nsCSSValueBorrowed<'a> = &'a nsCSSValue;
pub type nsCSSValueBorrowedOrNull<'a> = Option<&'a nsCSSValue>;
pub type nsCSSValueBorrowedMut<'a> = &'a mut nsCSSValue;
Expand Down Expand Up @@ -352,6 +358,10 @@ pub type RawGeckoServoStyleRuleListBorrowed<'a> = &'a RawGeckoServoStyleRuleList
pub type RawGeckoServoStyleRuleListBorrowedOrNull<'a> = Option<&'a RawGeckoServoStyleRuleList>;
pub type RawGeckoServoStyleRuleListBorrowedMut<'a> = &'a mut RawGeckoServoStyleRuleList;
pub type RawGeckoServoStyleRuleListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoServoStyleRuleList>;
pub type RawGeckoCSSPropertyIDListBorrowed<'a> = &'a RawGeckoCSSPropertyIDList;
pub type RawGeckoCSSPropertyIDListBorrowedOrNull<'a> = Option<&'a RawGeckoCSSPropertyIDList>;
pub type RawGeckoCSSPropertyIDListBorrowedMut<'a> = &'a mut RawGeckoCSSPropertyIDList;
pub type RawGeckoCSSPropertyIDListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoCSSPropertyIDList>;

extern "C" {
pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
Expand Down Expand Up @@ -1363,6 +1373,10 @@ extern "C" {
ident: *const u16,
set_slow_selector: *mut bool) -> bool;
}
extern "C" {
pub fn Gecko_AddPropertyToSet(arg1: nsCSSPropertyIDSetBorrowedMut,
arg2: nsCSSPropertyID);
}
extern "C" {
pub fn Gecko_Construct_Default_nsStyleFont(ptr: *mut nsStyleFont,
pres_context:
Expand Down Expand Up @@ -2076,6 +2090,14 @@ extern "C" {
pub fn Servo_Property_IsDiscreteAnimatable(property: nsCSSPropertyID)
-> bool;
}
extern "C" {
pub fn Servo_GetProperties_Overriding_Animation(arg1:
RawGeckoElementBorrowed,
arg2:
RawGeckoCSSPropertyIDListBorrowed,
arg3:
nsCSSPropertyIDSetBorrowedMut);
}
extern "C" {
pub fn Servo_AnimationValues_Interpolate(from:
RawServoAnimationValueBorrowed,
Expand Down
2 changes: 1 addition & 1 deletion components/style/properties/properties.mako.rs
Expand Up @@ -954,7 +954,7 @@ impl PropertyId {
}
}

/// Returns a property id from Gecko's nsCSSPropertyID.
/// Returns an nsCSSPropertyID.
#[cfg(feature = "gecko")]
#[allow(non_upper_case_globals)]
pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
Expand Down
38 changes: 37 additions & 1 deletion components/style/rule_tree/mod.rs
Expand Up @@ -8,7 +8,7 @@

#[cfg(feature = "servo")]
use heapsize::HeapSizeOf;
use properties::{Importance, PropertyDeclarationBlock};
use properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use smallvec::SmallVec;
use std::io::{self, Write};
Expand Down Expand Up @@ -1092,6 +1092,42 @@ impl StrongRuleNode {
.take_while(|node| node.cascade_level() >= CascadeLevel::SMILOverride)
.any(|node| node.cascade_level().is_animation())
}

/// Get a set of properties whose CascadeLevel are higher than Animations but not equal to
/// Transitions. If there are any custom properties, we set the boolean value of the returned
/// tuple to true.
pub fn get_properties_overriding_animations(&self, guards: &StylesheetGuards)
-> (LonghandIdSet, bool) {
use properties::PropertyDeclarationId;

// We want to iterate over cascade levels that override the animations level, i.e.
// !important levels and the transitions level. However, we actually want to skip the
// transitions level because although it is higher in the cascade than animations, when
// both transitions and animations are present for a given element and property, transitions
// are suppressed so that they don't actually override animations.
let iter = self.self_and_ancestors()
.skip_while(|node| node.cascade_level() == CascadeLevel::Transitions)
.take_while(|node| node.cascade_level() > CascadeLevel::Animations);
let mut result = (LonghandIdSet::new(), false);
for node in iter {
let style = node.style_source().unwrap();
for &(ref decl, important) in style.read(node.cascade_level().guard(guards))
.declarations()
.iter() {
// Although we are only iterating over cascade levels that override animations,
// in a given property declaration block we can have a mixture of !important and
// non-!important declarations but only the !important declarations actually
// override animations.
if important.important() {
match decl.id() {
PropertyDeclarationId::Longhand(id) => result.0.insert(id),
PropertyDeclarationId::Custom(_) => result.1 = true
}
}
}
}
result
}
}

/// An iterator over a rule node and its ancestors.
Expand Down
36 changes: 35 additions & 1 deletion ports/geckolib/glue.rs
Expand Up @@ -40,11 +40,13 @@ use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedV
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{nsACString, nsAString};
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
use style::gecko_bindings::bindings::RawGeckoAnimationPropertySegmentBorrowed;
use style::gecko_bindings::bindings::RawGeckoCSSPropertyIDListBorrowed;
use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
Expand Down Expand Up @@ -1319,6 +1321,38 @@ pub extern "C" fn Servo_ParseEasing(easing: *const nsAString,
}
}

#[no_mangle]
pub extern "C" fn Servo_GetProperties_Overriding_Animation(element: RawGeckoElementBorrowed,
list: RawGeckoCSSPropertyIDListBorrowed,
set: nsCSSPropertyIDSetBorrowedMut) {
let element = GeckoElement(element);
let element_data = match element.borrow_data() {
Some(data) => data,
None => return
};
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let guards = StylesheetGuards::same(&guard);
let (overridden, custom) =
element_data.styles().primary.rules.get_properties_overriding_animations(&guards);
for p in list.iter() {
match PropertyId::from_nscsspropertyid(*p) {
Ok(property) => {
if let PropertyId::Longhand(id) = property {
if overridden.contains(id) {
unsafe { Gecko_AddPropertyToSet(set, *p) };
}
}
},
Err(_) => {
if *p == nsCSSPropertyID::eCSSPropertyExtra_variable && custom {
unsafe { Gecko_AddPropertyToSet(set, *p) };
}
}
}
}
}

#[no_mangle]
pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
raw_extra_data: *mut URLExtraData,
Expand Down

0 comments on commit 60e7a89

Please sign in to comment.