diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 69ad65ac70c..af738ad4f9c 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -28,7 +28,7 @@ use style_traits::{CSSPixel, CssWriter, DevicePixel}; use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::ViewportConstraints; use stylesheets::Origin; -use values::{CSSFloat, CustomIdent}; +use values::{CSSFloat, CustomIdent, KeyframesName}; use values::computed::{self, ToComputedValue}; use values::computed::font::FontSize; use values::specified::{Integer, Length, Number}; @@ -71,7 +71,7 @@ impl Device { pub fn new(pres_context: RawGeckoPresContextOwned) -> Self { assert!(!pres_context.is_null()); Device { - pres_context: pres_context, + pres_context, default_values: ComputedValues::default_values(unsafe { &*pres_context }), // FIXME(bz): Seems dubious? root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize), @@ -85,11 +85,22 @@ impl Device { /// relevant viewport constraints. pub fn account_for_viewport_rule( &mut self, - _constraints: &ViewportConstraints + _constraints: &ViewportConstraints, ) { unreachable!("Gecko doesn't support @viewport"); } + /// Whether any animation name may be referenced from the style of any + /// element. + pub fn animation_name_may_be_referenced(&self, name: &KeyframesName) -> bool { + unsafe { + bindings::Gecko_AnimationNameMayBeReferencedFromStyle( + self.pres_context(), + name.as_atom().as_ptr(), + ) + } + } + /// Returns the default computed values as a reference, in order to match /// Servo. pub fn default_computed_values(&self) -> &ComputedValues { diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs index 0747bdaa6b1..5569628dc24 100644 --- a/components/style/invalidation/stylesheets.rs +++ b/components/style/invalidation/stylesheets.rs @@ -151,7 +151,7 @@ impl StylesheetInvalidationSet { } for rule in stylesheet.effective_rules(device, guard) { - self.collect_invalidations_for_rule(rule, guard); + self.collect_invalidations_for_rule(rule, guard, device); if self.fully_invalid { self.invalid_scopes.clear(); self.invalid_elements.clear(); @@ -393,8 +393,9 @@ impl StylesheetInvalidationSet { fn collect_invalidations_for_rule( &mut self, rule: &CssRule, - guard: &SharedRwLockReadGuard) - { + guard: &SharedRwLockReadGuard, + device: &Device, + ) { use stylesheets::CssRule::*; debug!("StylesheetInvalidationSet::collect_invalidations_for_rule"); debug_assert!(!self.fully_invalid, "Not worth to be here!"); @@ -422,7 +423,17 @@ impl StylesheetInvalidationSet { // information. We'll restyle when the font face loads, if // needed. } - Keyframes(..) | + Keyframes(ref lock) => { + let keyframes_rule = lock.read_with(guard); + if device.animation_name_may_be_referenced(&keyframes_rule.name) { + debug!(" > Found @keyframes rule potentially referenced \ + from the page, marking the whole tree invalid."); + self.fully_invalid = true; + } else { + // Do nothing, this animation can't affect the style of + // existing elements. + } + } CounterStyle(..) | Page(..) | Viewport(..) | diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 79bc288b775..793bf042d47 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -16,9 +16,9 @@ use std::fmt::{self, Write}; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use style_traits::{CSSPixel, CssWriter, DevicePixel, ToCss, ParseError}; use style_traits::viewport::ViewportConstraints; +use values::{specified, KeyframesName}; use values::computed::{self, ToComputedValue}; use values::computed::font::FontSize; -use values::specified; /// A device is a structure that represents the current media a given document /// is displayed in. @@ -96,6 +96,12 @@ impl Device { // Servo doesn't implement this quirk (yet) } + /// Whether a given animation name may be referenced from style. + pub fn animation_name_may_be_referenced(&self, _: &KeyframesName) -> bool { + // Assume it is, since we don't have any good way to prove it's not. + true + } + /// Returns whether we ever looked up the root font size of the Device. pub fn used_root_font_size(&self) -> bool { self.used_root_font_size.load(Ordering::Relaxed)