aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/generated/bindings.rs22
-rw-r--r--components/style/properties/properties.mako.rs2
-rw-r--r--components/style/rule_tree/mod.rs38
-rw-r--r--ports/geckolib/glue.rs36
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)