diff options
-rw-r--r-- | components/style/gecko/generated/bindings.rs | 22 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 2 | ||||
-rw-r--r-- | components/style/rule_tree/mod.rs | 38 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 36 |
4 files changed, 95 insertions, 3 deletions
diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index f086bbbb49f..b9b27518002 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -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; @@ -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; @@ -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; @@ -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, @@ -1364,6 +1374,10 @@ extern "C" { 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: RawGeckoPresContextBorrowed); @@ -2077,6 +2091,14 @@ extern "C" { -> bool; } extern "C" { + pub fn Servo_GetProperties_Overriding_Animation(arg1: + RawGeckoElementBorrowed, + arg2: + RawGeckoCSSPropertyIDListBorrowed, + arg3: + nsCSSPropertyIDSetBorrowedMut); +} +extern "C" { pub fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValueBorrowed, to: diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 01db4868011..5ddff3fae44 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -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, ()> { diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index ead9797ca14..bfc6c19bf96 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -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}; @@ -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. diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 58075cbd063..0cd95543ac1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -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; @@ -1320,6 +1322,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, quirks_mode: nsCompatibility) |