Bug 1344966 - Introduce TraversalFlags to represents target elements of the traversal we are about to do. r?heycam
MozReview-Commit-ID: BJU79ctKbAn
--- 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;