Bug 1344966 - Introduce TraversalFlags to represents target elements of the traversal we are about to do. r?heycam draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 25 Mar 2017 19:20:03 +0900
changeset 551280 abf0fd2b7c85d6e31a0ad8fcafc83ceb842974ff
parent 551275 3c45d95cbb21a6ccf6270e1028c072de25425507
child 551281 49cc48fe9978bc4759742ef68784cb7e107cb47c
push id51007
push userhikezoe@mozilla.com
push dateSat, 25 Mar 2017 10:33:03 +0000
reviewersheycam
bugs1344966
milestone55.0a1
Bug 1344966 - Introduce TraversalFlags to represents target elements of the traversal we are about to do. r?heycam MozReview-Commit-ID: BJU79ctKbAn
servo/components/style/traversal.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -26,16 +26,38 @@ use stylist::Stylist;
 pub struct PerLevelTraversalData {
     /// The current dom depth, if known, or `None` otherwise.
     ///
     /// This is kept with cooperation from the traversal code and the bloom
     /// filter.
     pub current_dom_depth: Option<usize>,
 }
 
+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(&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 {
     traverse: bool,
     unstyled_children_only: bool,
 }
 
 impl PreTraverseToken {
@@ -106,20 +128,20 @@ pub trait DomTraversal<E: TElement> : Sy
     fn needs_postorder_traversal() -> bool { true }
 
     /// Must be invoked before traversing the root element to determine whether
     /// 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-
     /// 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() {
             return PreTraverseToken {
                 traverse: true,
                 unstyled_children_only: true,
             };
         }
 
         // Expand the snapshot, if any. This is normally handled by the parent, so
         // we need a special case for the root.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -78,17 +78,18 @@ use style::sequential;
 use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
 use style::string_cache::Atom;
 use style::stylesheets::{CssRule, CssRules, ImportRule, MediaRule, NamespaceRule};
 use style::stylesheets::{Origin, Stylesheet, StyleRule};
 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::{ANIMATION_ONLY, UNSTYLED_CHILDREN_ONLY};
 use style_traits::ToCss;
 use super::stylesheet_loader::StylesheetLoader;
 
 /*
  * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
  * the C header in Gecko. In order to catch accidental mismatches, we run rust-bindgen against
  * those signatures as well, giving us a second declaration of all the Servo_* functions in this
  * crate. If there's a mismatch, LLVM will assert and abort, which is a rather awful thing to
@@ -138,29 +139,29 @@ fn create_shared_context<'a>(guard: &'a 
         local_context_creation_data: Mutex::new(local_context_data),
         timer: Timer::new(),
         // FIXME Find the real QuirksMode information for this document
         quirks_mode: QuirksMode::NoQuirks,
     }
 }
 
 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() {
         if parent.borrow_data().map_or(true, |d| d.styles().is_display_none()) {
             debug!("{:?} has unstyled parent - ignoring call to traverse_subtree", parent);
             return;
         }
     }
 
     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;
     }
 
     debug!("Traversing subtree:");
     debug!("{:?}", ShowSubtreeData(element.as_node()));
 
     let global_style_data = &*GLOBAL_STYLE_DATA;