diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 1c0208c1c40..63c02c56ddb 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -19,7 +19,7 @@ use app_units::Au; use applicable_declarations::ApplicableDeclarationBlock; use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks}; -use data::ElementData; +use data::{ElementData, RestyleData}; use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}; use dom::{OpaqueNode, PresentationalHintsSynthesizer}; use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE}; @@ -63,7 +63,9 @@ use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT; use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS; +use gecko_bindings::structs::nsChangeHint; use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme; +use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; use logical_geometry::WritingMode; use media_queries::Device; @@ -670,6 +672,64 @@ impl<'le> GeckoElement<'le> { pub fn owner_document_quirks_mode(&self) -> QuirksMode { self.as_node().owner_doc().mCompatMode.into() } + + /// Only safe to call on the main thread, with exclusive access to the element and + /// its ancestors. + /// This function is also called after display property changed for SMIL animation. + /// + /// Also this function schedules style flush. + unsafe fn maybe_restyle<'a>(&self, + data: &'a mut ElementData, + animation_only: bool) -> Option<&'a mut RestyleData> { + use dom::{AnimationOnlyDirtyDescendants, DirtyDescendants}; + + // Don't generate a useless RestyleData if the element hasn't been styled. + if !data.has_styles() { + return None; + } + + // Propagate the bit up the chain. + if let Some(p) = self.traversal_parent() { + if animation_only { + p.note_descendants::(); + } else { + p.note_descendants::(); + } + }; + + bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(self.0); + + // Ensure and return the RestyleData. + Some(&mut data.restyle) + } + + /// Set restyle and change hints to the element data. + pub fn note_explicit_hints(&self, + restyle_hint: nsRestyleHint, + change_hint: nsChangeHint) { + use gecko::restyle_damage::GeckoRestyleDamage; + use invalidation::element::restyle_hints::RestyleHint; + + let damage = GeckoRestyleDamage::new(change_hint); + debug!("note_explicit_hints: {:?}, restyle_hint={:?}, change_hint={:?}", + self, restyle_hint, change_hint); + + let restyle_hint: RestyleHint = restyle_hint.into(); + debug_assert!(!(restyle_hint.has_animation_hint() && + restyle_hint.has_non_animation_hint()), + "Animation restyle hints should not appear with non-animation restyle hints"); + + let mut maybe_data = self.mutate_data(); + let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe { + self.maybe_restyle(d, restyle_hint.has_animation_hint()) + }); + if let Some(restyle_data) = maybe_restyle_data { + restyle_data.hint.insert(restyle_hint.into()); + restyle_data.damage |= damage; + } else { + debug!("(Element not styled, discarding hints)"); + } + } } /// Converts flags from the layout used by rust-selectors to the layout used diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 779396574aa..7c9eea0cd93 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use atomic_refcell::AtomicRefMut; use cssparser::{Parser, ParserInput}; use cssparser::ToCss as ParserToCss; use env_logger::LogBuilder; @@ -14,8 +13,7 @@ use std::fmt::Write; use std::ptr; use style::context::{CascadeInputs, QuirksMode, SharedStyleContext, StyleContext}; use style::context::ThreadLocalStyleContext; -use style::data::{ElementData, ElementStyles, RestyleData}; -use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants}; +use style::data::ElementStyles; use style::dom::{ShowSubtreeData, TElement, TNode}; use style::element_state::ElementState; use style::error_reporting::{NullReporter, ParseErrorReporter}; @@ -26,7 +24,6 @@ use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::selector_parser::PseudoElement; use style::gecko::traversal::RecalcStyleOnly; use style::gecko::wrapper::GeckoElement; -use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoElementBorrowedOrNull}; use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut}; use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong}; @@ -91,7 +88,7 @@ use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong}; use style::gecko_bindings::sugar::refptr::RefPtr; use style::gecko_properties::style_structs; -use style::invalidation::element::restyle_hints::{self, RestyleHint}; +use style::invalidation::element::restyle_hints; use style::media_queries::{MediaList, parse_media_query_list}; use style::parallel; use style::parser::{ParserContext, self}; @@ -2723,57 +2720,11 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool { } } -/// Only safe to call on the main thread, with exclusive access to the element and -/// its ancestors. -unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut, - element: GeckoElement, - animation_only: bool) - -> Option<&'a mut RestyleData> -{ - // Don't generate a useless RestyleData if the element hasn't been styled. - if !data.has_styles() { - return None; - } - - // Propagate the bit up the chain. - if let Some(p) = element.traversal_parent() { - if animation_only { - p.note_descendants::(); - } else { - p.note_descendants::(); - } - }; - - bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(element.0); - - // Ensure and return the RestyleData. - Some(&mut data.restyle) -} - #[no_mangle] pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed, restyle_hint: nsRestyleHint, change_hint: nsChangeHint) { - let element = GeckoElement(element); - let damage = GeckoRestyleDamage::new(change_hint); - debug!("Servo_NoteExplicitHints: {:?}, restyle_hint={:?}, change_hint={:?}", - element, restyle_hint, change_hint); - - let restyle_hint: RestyleHint = restyle_hint.into(); - debug_assert!(!(restyle_hint.has_animation_hint() && - restyle_hint.has_non_animation_hint()), - "Animation restyle hints should not appear with non-animation restyle hints"); - - let mut maybe_data = element.mutate_data(); - let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe { - maybe_restyle(d, element, restyle_hint.has_animation_hint()) - }); - if let Some(restyle_data) = maybe_restyle_data { - restyle_data.hint.insert(restyle_hint.into()); - restyle_data.damage |= damage; - } else { - debug!("(Element not styled, discarding hints)"); - } + GeckoElement(element).note_explicit_hints(restyle_hint, change_hint); } #[no_mangle] diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 37f33245656..7c2c9debc82 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -4,7 +4,6 @@ #![deny(warnings)] -extern crate atomic_refcell; extern crate cssparser; extern crate env_logger; extern crate libc;