mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Introduce TraversalFlags to represents target elements of the traversal we are about to do.
This commit is contained in:
parent
7c4f4d5be9
commit
499d1c4117
3 changed files with 39 additions and 10 deletions
|
@ -120,7 +120,7 @@ use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets};
|
||||||
use style::stylist::Stylist;
|
use style::stylist::Stylist;
|
||||||
use style::thread_state;
|
use style::thread_state;
|
||||||
use style::timer::Timer;
|
use style::timer::Timer;
|
||||||
use style::traversal::{DomTraversal, TraversalDriver};
|
use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags};
|
||||||
|
|
||||||
/// Information needed by the layout thread.
|
/// Information needed by the layout thread.
|
||||||
pub struct LayoutThread {
|
pub struct LayoutThread {
|
||||||
|
@ -1143,7 +1143,7 @@ impl LayoutThread {
|
||||||
let stylist = &<RecalcStyleAndConstructFlows as
|
let stylist = &<RecalcStyleAndConstructFlows as
|
||||||
DomTraversal<ServoLayoutElement>>::shared_context(&traversal).stylist;
|
DomTraversal<ServoLayoutElement>>::shared_context(&traversal).stylist;
|
||||||
<RecalcStyleAndConstructFlows as
|
<RecalcStyleAndConstructFlows as
|
||||||
DomTraversal<ServoLayoutElement>>::pre_traverse(element, stylist, /* skip_root = */ false)
|
DomTraversal<ServoLayoutElement>>::pre_traverse(element, stylist, TraversalFlags::empty())
|
||||||
};
|
};
|
||||||
|
|
||||||
if token.should_traverse() {
|
if token.should_traverse() {
|
||||||
|
|
|
@ -31,6 +31,28 @@ pub struct PerLevelTraversalData {
|
||||||
pub current_dom_depth: Option<usize>,
|
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_only(&self) -> bool {
|
||||||
|
self.contains(UNSTYLED_CHILDREN_ONLY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This structure exists to enforce that callers invoke pre_traverse, and also
|
/// This structure exists to enforce that callers invoke pre_traverse, and also
|
||||||
/// to pass information from the pre-traversal into the primary traversal.
|
/// to pass information from the pre-traversal into the primary traversal.
|
||||||
pub struct PreTraverseToken {
|
pub struct PreTraverseToken {
|
||||||
|
@ -109,12 +131,13 @@ pub trait DomTraversal<E: TElement> : Sync {
|
||||||
/// a traversal is needed. Returns a token that allows the caller to prove
|
/// a traversal is needed. Returns a token that allows the caller to prove
|
||||||
/// that the call happened.
|
/// 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.
|
/// 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
|
-> PreTraverseToken
|
||||||
{
|
{
|
||||||
if unstyled_children_only {
|
if traversal_flags.for_unstyled_children_only() {
|
||||||
return PreTraverseToken {
|
return PreTraverseToken {
|
||||||
traverse: true,
|
traverse: true,
|
||||||
unstyled_children_only: true,
|
unstyled_children_only: true,
|
||||||
|
|
|
@ -83,7 +83,8 @@ use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
||||||
use style::supports::parse_condition_or_declaration;
|
use style::supports::parse_condition_or_declaration;
|
||||||
use style::thread_state;
|
use style::thread_state;
|
||||||
use style::timer::Timer;
|
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 style_traits::ToCss;
|
||||||
use super::stylesheet_loader::StylesheetLoader;
|
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,
|
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
|
// 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.
|
// servo to try to style it. Detect that here and bail out.
|
||||||
if let Some(parent) = element.parent_element() {
|
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 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() {
|
if !token.should_traverse() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -192,8 +193,13 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
|
||||||
behavior: structs::TraversalRootBehavior) -> bool {
|
behavior: structs::TraversalRootBehavior) -> bool {
|
||||||
let element = GeckoElement(root);
|
let element = GeckoElement(root);
|
||||||
debug!("Servo_TraverseSubtree: {:?}", element);
|
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()
|
element.has_dirty_descendants() || element.mutate_data().unwrap().has_restyle()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue