From c81d62d36f26663ef9edd22168e1a9d4ac826be7 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 24 Jul 2017 19:22:07 +0800 Subject: [PATCH 1/2] style: Record on a computed::Context whether we are computing a SMIL animated value. --- components/style/gecko/media_queries.rs | 1 + .../style/properties/properties.mako.rs | 1 + components/style/servo/media_queries.rs | 1 + components/style/stylesheets/viewport_rule.rs | 1 + components/style/values/computed/mod.rs | 6 ++++ ports/geckolib/glue.rs | 29 +++++++++++++++++-- tests/unit/style/parsing/mod.rs | 1 + 7 files changed, 37 insertions(+), 3 deletions(-) diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 8b0e00b91fe..e27066c0848 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -642,6 +642,7 @@ impl Expression { in_media_query: true, // TODO: pass the correct value here. quirks_mode: quirks_mode, + for_smil_animation: false, }; let required_value = match self.value { diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index b2445f53dfb..c40028a2e93 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2996,6 +2996,7 @@ where cached_system_font: None, in_media_query: false, quirks_mode: quirks_mode, + for_smil_animation: false, }; let ignore_colors = !device.use_document_colors(); diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 7583a89f7da..d23fbaca16e 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -246,6 +246,7 @@ impl Range { in_media_query: true, cached_system_font: None, quirks_mode: quirks_mode, + for_smil_animation: false, }; match *self { diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index 015eb33a4f6..2282c9f26a3 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -709,6 +709,7 @@ impl MaybeNew for ViewportConstraints { cached_system_font: None, in_media_query: false, quirks_mode: quirks_mode, + for_smil_animation: false, }; // DEVICE-ADAPT ยง 9.3 Resolving 'extend-to-zoom' diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index b8a1f1bcb8a..6a82b8cf8bb 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -95,6 +95,12 @@ pub struct Context<'a> { /// The quirks mode of this context. pub quirks_mode: QuirksMode, + + /// Whether this computation is being done for a SMIL animation. + /// + /// This is used to allow certain properties to generate out-of-range + /// values, which SMIL allows. + pub for_smil_animation: bool, } impl<'a> Context<'a> { diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 0026c7212e8..9e1ce47c893 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -2907,6 +2907,7 @@ fn create_context<'a>( style: &'a ComputedValues, parent_style: Option<&'a ComputedValues>, pseudo: Option<&'a PseudoElement>, + for_smil_animation: bool, ) -> Context<'a> { Context { is_root_element: false, @@ -2920,6 +2921,7 @@ fn create_context<'a>( cached_system_font: None, in_media_query: false, quirks_mode: per_doc_data.stylist.quirks_mode(), + for_smil_animation, } } @@ -2989,7 +2991,14 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x); let pseudo = style.pseudo(); - let mut context = create_context(&data, &metrics, &style, parent_style, pseudo.as_ref()); + let mut context = create_context( + &data, + &metrics, + &style, + parent_style, + pseudo.as_ref(), + /* for_smil_animation = */ false, + ); let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); @@ -3069,7 +3078,14 @@ pub extern "C" fn Servo_GetAnimationValues(declarations: RawServoDeclarationBloc let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x); let pseudo = style.pseudo(); - let mut context = create_context(&data, &metrics, &style, parent_style, pseudo.as_ref()); + let mut context = create_context( + &data, + &metrics, + &style, + parent_style, + pseudo.as_ref(), + /* for_smil_animation = */ true + ); let default_values = data.default_computed_values(); let global_style_data = &*GLOBAL_STYLE_DATA; @@ -3098,7 +3114,14 @@ pub extern "C" fn Servo_AnimationValue_Compute(element: RawGeckoElementBorrowed, let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x); let pseudo = style.pseudo(); - let mut context = create_context(&data, &metrics, style, parent_style, pseudo.as_ref()); + let mut context = create_context( + &data, + &metrics, + style, + parent_style, + pseudo.as_ref(), + /* for_smil_animation = */ false + ); let default_values = data.default_computed_values(); let global_style_data = &*GLOBAL_STYLE_DATA; diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs index ed69ee9fe70..5f2a86514d2 100644 --- a/tests/unit/style/parsing/mod.rs +++ b/tests/unit/style/parsing/mod.rs @@ -60,6 +60,7 @@ fn assert_computed_serialization(f: F, input: &'static str, output: &st font_metrics_provider: &ServoMetricsProvider, in_media_query: false, quirks_mode: QuirksMode::NoQuirks, + for_smil_animation: false, }; let parsed = parse(f, input).unwrap(); From 6171b5c465d372333fe7f922e12ce6a72595fee6 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 24 Jul 2017 17:01:24 +0800 Subject: [PATCH 2/2] style: Don't clamp Opacity values when computing them for SMIL. --- components/style/values/specified/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index dd34f9bdbeb..158c33a5b6a 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -563,7 +563,14 @@ impl ToComputedValue for Opacity { #[inline] fn to_computed_value(&self, context: &Context) -> CSSFloat { - self.0.to_computed_value(context).min(1.0).max(0.0) + let value = self.0.to_computed_value(context); + if context.for_smil_animation { + // SMIL expects to be able to interpolate between out-of-range + // opacity values. + value + } else { + value.min(1.0).max(0.0) + } } #[inline]