diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 31500461fa4..73bf9b1036a 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -120,7 +120,7 @@ use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets}; use style::stylist::Stylist; use style::thread_state; use style::timer::Timer; -use style::traversal::{DomTraversal, TraversalDriver}; +use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags}; /// Information needed by the layout thread. pub struct LayoutThread { @@ -1143,7 +1143,7 @@ impl LayoutThread { let stylist = &>::shared_context(&traversal).stylist; >::pre_traverse(element, stylist, /* skip_root = */ false) + DomTraversal>::pre_traverse(element, stylist, TraversalFlags::empty()) }; if token.should_traverse() { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 767547f3a28..69e413d64a8 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -31,6 +31,28 @@ pub struct PerLevelTraversalData { pub current_dom_depth: Option, } +bitflags! { + /// Represents that target elements of the traversal. + pub flags TraversalFlags: u8 { + /// Traverse only unstyled children. + const UNSTYLED_CHILDREN_ONLY = 0x01, + /// Traverse only elements for animation restyles + const ANIMATION_ONLY = 0x02, + } +} + +impl TraversalFlags { + /// Returns true if the traversal is for animation-only restyles. + pub fn for_animation_only(&self) -> bool { + self.contains(ANIMATION_ONLY) + } + + /// Returns true if the traversal is for unstyled children. + pub fn for_unstyled_children_only(&self) -> bool { + self.contains(UNSTYLED_CHILDREN_ONLY) + } +} + /// This structure exists to enforce that callers invoke pre_traverse, and also /// to pass information from the pre-traversal into the primary traversal. pub struct PreTraverseToken { @@ -109,12 +131,13 @@ pub trait DomTraversal : Sync { /// a traversal is needed. Returns a token that allows the caller to prove /// that the call happened. /// - /// The unstyled_children_only parameter is used in Gecko to style newly- + /// The traversal_flag is used in Gecko. + /// If traversal_flag::UNSTYLED_CHILDREN_ONLY is specified, style newly- /// appended children without restyling the parent. - fn pre_traverse(root: E, stylist: &Stylist, unstyled_children_only: bool) + fn pre_traverse(root: E, stylist: &Stylist, traversal_flags: TraversalFlags) -> PreTraverseToken { - if unstyled_children_only { + if traversal_flags.for_unstyled_children_only() { return PreTraverseToken { traverse: true, unstyled_children_only: true, diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index f5fa8dc19d4..81bab36febc 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -83,7 +83,8 @@ use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; use style::supports::parse_condition_or_declaration; use style::thread_state; use style::timer::Timer; -use style::traversal::{resolve_style, DomTraversal, TraversalDriver}; +use style::traversal::{resolve_style, DomTraversal, TraversalDriver, TraversalFlags}; +use style::traversal::UNSTYLED_CHILDREN_ONLY; use style_traits::ToCss; use super::stylesheet_loader::StylesheetLoader; @@ -143,7 +144,7 @@ fn create_shared_context<'a>(guard: &'a SharedRwLockReadGuard, } fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, - unstyled_children_only: bool) { + traversal_flags: TraversalFlags) { // When new content is inserted in a display:none subtree, we will call into // servo to try to style it. Detect that here and bail out. if let Some(parent) = element.parent_element() { @@ -155,7 +156,7 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); - let token = RecalcStyleOnly::pre_traverse(element, &per_doc_data.stylist, unstyled_children_only); + let token = RecalcStyleOnly::pre_traverse(element, &per_doc_data.stylist, traversal_flags); if !token.should_traverse() { return; } @@ -192,8 +193,13 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, behavior: structs::TraversalRootBehavior) -> bool { let element = GeckoElement(root); debug!("Servo_TraverseSubtree: {:?}", element); - traverse_subtree(element, raw_data, - behavior == structs::TraversalRootBehavior::UnstyledChildrenOnly); + + let traversal_flags = match behavior { + structs::TraversalRootBehavior::UnstyledChildrenOnly => UNSTYLED_CHILDREN_ONLY, + _ => TraversalFlags::empty(), + }; + + traverse_subtree(element, raw_data, traversal_flags); element.has_dirty_descendants() || element.mutate_data().unwrap().has_restyle() }