diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index ed564248d08..d5f85f767b9 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -14,7 +14,7 @@ use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use servo_config::opts; use style::context::{SharedStyleContext, StyleContext}; use style::data::ElementData; -use style::dom::{TElement, TNode}; +use style::dom::{NodeInfo, TElement, TNode}; use style::selector_parser::RestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT}; use style::traversal::{DomTraversal, recalc_style_at}; @@ -48,14 +48,14 @@ impl RecalcStyleAndConstructFlows { } #[allow(unsafe_code)] -impl DomTraversal for RecalcStyleAndConstructFlows - where N: LayoutNode + TNode, - N::ConcreteElement: TElement +impl DomTraversal for RecalcStyleAndConstructFlows + where E: TElement, + E::ConcreteNode: LayoutNode, { - type ThreadLocalContext = ScopedThreadLocalLayoutContext; + type ThreadLocalContext = ScopedThreadLocalLayoutContext; fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData, - thread_local: &mut Self::ThreadLocalContext, node: N) { + thread_local: &mut Self::ThreadLocalContext, node: E::ConcreteNode) { // FIXME(pcwalton): Stop allocating here. Ideally this should just be // done by the HTML parser. node.initialize_data(); @@ -71,12 +71,12 @@ impl DomTraversal for RecalcStyleAndConstructFlows } } - fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: N) { + fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: E::ConcreteNode) { let context = LayoutContext::new(&self.shared); construct_flows_at(&context, thread_local, node); } - fn text_node_needs_traversal(node: N) -> bool { + fn text_node_needs_traversal(node: E::ConcreteNode) -> bool { // Text nodes never need styling. However, there are two cases they may need // flow construction: // (1) They child doesn't yet have layout data (preorder traversal initializes it). @@ -85,12 +85,12 @@ impl DomTraversal for RecalcStyleAndConstructFlows node.parent_node().unwrap().to_threadsafe().restyle_damage() != RestyleDamage::empty() } - unsafe fn ensure_element_data(element: &N::ConcreteElement) -> &AtomicRefCell { + unsafe fn ensure_element_data(element: &E) -> &AtomicRefCell { element.as_node().initialize_data(); element.get_data().unwrap() } - unsafe fn clear_element_data(element: &N::ConcreteElement) { + unsafe fn clear_element_data(element: &E) { element.as_node().clear_data(); } diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index a9160cbf269..25192893290 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1157,9 +1157,9 @@ impl LayoutThread { let dom_depth = Some(0); // This is always the root node. let token = { let stylist = &>::shared_context(&traversal).stylist; + DomTraversal>::shared_context(&traversal).stylist; >::pre_traverse(element, stylist, /* skip_root = */ false) + DomTraversal>::pre_traverse(element, stylist, /* skip_root = */ false) }; if token.should_traverse() { @@ -1171,11 +1171,11 @@ impl LayoutThread { // Perform CSS selector matching and flow construction. if let (true, Some(pool)) = (self.parallel_flag, self.parallel_traversal.as_mut()) { // Parallel mode - parallel::traverse_dom::( + parallel::traverse_dom::( &traversal, element, dom_depth, token, pool); } else { // Sequential mode - sequential::traverse_dom::( + sequential::traverse_dom::( &traversal, element, token); } }); diff --git a/components/style/gecko/traversal.rs b/components/style/gecko/traversal.rs index 13c9ddabddf..cdf3f141f16 100644 --- a/components/style/gecko/traversal.rs +++ b/components/style/gecko/traversal.rs @@ -26,12 +26,12 @@ impl RecalcStyleOnly { } } -impl<'ln> DomTraversal> for RecalcStyleOnly { - type ThreadLocalContext = ThreadLocalStyleContext>; +impl<'le> DomTraversal> for RecalcStyleOnly { + type ThreadLocalContext = ThreadLocalStyleContext>; fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData, thread_local: &mut Self::ThreadLocalContext, - node: GeckoNode<'ln>) + node: GeckoNode<'le>) { if node.is_element() { let el = node.as_element().unwrap(); @@ -44,18 +44,18 @@ impl<'ln> DomTraversal> for RecalcStyleOnly { } } - fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'ln>) { + fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'le>) { unreachable!(); } /// We don't use the post-order traversal for anything. fn needs_postorder_traversal() -> bool { false } - unsafe fn ensure_element_data<'a>(element: &'a GeckoElement<'ln>) -> &'a AtomicRefCell { + unsafe fn ensure_element_data<'a>(element: &'a GeckoElement<'le>) -> &'a AtomicRefCell { element.ensure_data() } - unsafe fn clear_element_data<'a>(element: &'a GeckoElement<'ln>) { + unsafe fn clear_element_data<'a>(element: &'a GeckoElement<'le>) { element.clear_data() } diff --git a/components/style/parallel.rs b/components/style/parallel.rs index a05b8185b73..e121f81c34b 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -37,13 +37,13 @@ pub const CHUNK_SIZE: usize = 64; /// A parallel top down traversal, generic over `D`. #[allow(unsafe_code)] -pub fn traverse_dom(traversal: &D, - root: N::ConcreteElement, +pub fn traverse_dom(traversal: &D, + root: E, known_root_dom_depth: Option, token: PreTraverseToken, queue: &rayon::ThreadPool) - where N: TNode, - D: DomTraversal, + where E: TElement, + D: DomTraversal, { if opts::get().style_sharing_stats { STYLE_SHARING_CACHE_HITS.store(0, Ordering::SeqCst); @@ -91,14 +91,14 @@ pub fn traverse_dom(traversal: &D, /// A parallel top-down DOM traversal. #[inline(always)] #[allow(unsafe_code)] -fn top_down_dom<'a, 'scope, N, D>(nodes: &'a [SendNode], +fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode], root: OpaqueNode, mut traversal_data: PerLevelTraversalData, scope: &'a rayon::Scope<'scope>, traversal: &'scope D, tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>) - where N: TNode + 'scope, - D: DomTraversal, + where E: TElement + 'scope, + D: DomTraversal, { let mut discovered_child_nodes = vec![]; { @@ -140,13 +140,13 @@ fn top_down_dom<'a, 'scope, N, D>(nodes: &'a [SendNode], traverse_nodes(discovered_child_nodes, root, traversal_data, scope, traversal, tls); } -fn traverse_nodes<'a, 'scope, N, D>(nodes: Vec>, root: OpaqueNode, +fn traverse_nodes<'a, 'scope, E, D>(nodes: Vec>, root: OpaqueNode, traversal_data: PerLevelTraversalData, scope: &'a rayon::Scope<'scope>, traversal: &'scope D, tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>) - where N: TNode + 'scope, - D: DomTraversal, + where E: TElement + 'scope, + D: DomTraversal, { if nodes.is_empty() { return; @@ -182,12 +182,12 @@ fn traverse_nodes<'a, 'scope, N, D>(nodes: Vec>, root: OpaqueNode, /// /// The only communication between siblings is that they both /// fetch-and-subtract the parent's children count. -fn bottom_up_dom(traversal: &D, +fn bottom_up_dom(traversal: &D, thread_local: &mut D::ThreadLocalContext, root: OpaqueNode, - mut node: N) - where N: TNode, - D: DomTraversal, + mut node: E::ConcreteNode) + where E: TElement, + D: DomTraversal, { loop { // Perform the appropriate operation. diff --git a/components/style/sequential.rs b/components/style/sequential.rs index 68a57215612..a6af5a52cdb 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -10,18 +10,18 @@ use dom::{TElement, TNode}; use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; /// Do a sequential DOM traversal for layout or styling, generic over `D`. -pub fn traverse_dom(traversal: &D, - root: N::ConcreteElement, +pub fn traverse_dom(traversal: &D, + root: E, token: PreTraverseToken) - where N: TNode, - D: DomTraversal, + where E: TElement, + D: DomTraversal, { debug_assert!(token.should_traverse()); - fn doit(traversal: &D, traversal_data: &mut PerLevelTraversalData, - thread_local: &mut D::ThreadLocalContext, node: N) - where N: TNode, - D: DomTraversal + fn doit(traversal: &D, traversal_data: &mut PerLevelTraversalData, + thread_local: &mut D::ThreadLocalContext, node: E::ConcreteNode) + where E: TElement, + D: DomTraversal { traversal.process_preorder(traversal_data, thread_local, node); if let Some(el) = node.as_element() { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index a7dbcc6487b..8f62d8c57bc 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -9,11 +9,10 @@ use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use context::{SharedStyleContext, StyleContext}; use data::{ElementData, ElementStyles, StoredRestyleHint}; -use dom::{TElement, TNode}; +use dom::{NodeInfo, TElement, TNode}; use matching::{MatchMethods, StyleSharingResult}; use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF}; use selector_parser::RestyleDamage; -use selectors::Element; use servo_config::opts; use std::mem; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; @@ -72,7 +71,7 @@ impl LogBehavior { /// A DOM Traversal trait, that is used to generically implement styling for /// Gecko and Servo. -pub trait DomTraversal : Sync { +pub trait DomTraversal : Sync { /// The thread-local context, used to store non-thread-safe stuff that needs /// to be used in the traversal, and of which we use one per worker, like /// the bloom filter, for example. @@ -80,12 +79,15 @@ pub trait DomTraversal : Sync { /// Process `node` on the way down, before its children have been processed. fn process_preorder(&self, data: &mut PerLevelTraversalData, - thread_local: &mut Self::ThreadLocalContext, node: N); + thread_local: &mut Self::ThreadLocalContext, + node: E::ConcreteNode); /// Process `node` on the way up, after its children have been processed. /// /// This is only executed if `needs_postorder_traversal` returns true. - fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: N); + fn process_postorder(&self, + thread_local: &mut Self::ThreadLocalContext, + node: E::ConcreteNode); /// Boolean that specifies whether a bottom up traversal should be /// performed. @@ -99,8 +101,7 @@ pub trait DomTraversal : Sync { /// /// The unstyled_children_only parameter is used in Gecko to style newly- /// appended children without restyling the parent. - fn pre_traverse(root: N::ConcreteElement, stylist: &Stylist, - unstyled_children_only: bool) + fn pre_traverse(root: E, stylist: &Stylist, unstyled_children_only: bool) -> PreTraverseToken { if unstyled_children_only { @@ -132,10 +133,13 @@ pub trait DomTraversal : Sync { /// Returns true if traversal should visit a text node. The style system never /// processes text nodes, but Servo overrides this to visit them for flow /// construction when necessary. - fn text_node_needs_traversal(node: N) -> bool { debug_assert!(node.is_text_node()); false } + fn text_node_needs_traversal(node: E::ConcreteNode) -> bool { + debug_assert!(node.is_text_node()); + false + } /// Returns true if traversal is needed for the given node and subtree. - fn node_needs_traversal(node: N) -> bool { + fn node_needs_traversal(node: E::ConcreteNode) -> bool { // Non-incremental layout visits every node. if cfg!(feature = "servo") && opts::get().nonincremental_layout { return true; @@ -189,8 +193,7 @@ pub trait DomTraversal : Sync { /// /// This may be called multiple times when processing an element, so we pass /// a parameter to keep the logs tidy. - fn should_traverse_children(parent: N::ConcreteElement, parent_data: &ElementData, - log: LogBehavior) -> bool + fn should_traverse_children(parent: E, parent_data: &ElementData, log: LogBehavior) -> bool { // See the comment on `cascade_node` for why we allow this on Gecko. debug_assert!(cfg!(feature = "gecko") || parent_data.has_current_styles()); @@ -234,7 +237,7 @@ pub trait DomTraversal : Sync { /// Helper for the traversal implementations to select the children that /// should be enqueued for processing. - fn traverse_children(parent: N::ConcreteElement, mut f: F) + fn traverse_children(parent: E, mut f: F) { // Check if we're allowed to traverse past this element. if !Self::should_traverse_children(parent, &parent.borrow_data().unwrap(), MayLog) { @@ -260,13 +263,13 @@ pub trait DomTraversal : Sync { /// /// This is only safe to call in top-down traversal before processing the /// children of |element|. - unsafe fn ensure_element_data(element: &N::ConcreteElement) -> &AtomicRefCell; + unsafe fn ensure_element_data(element: &E) -> &AtomicRefCell; /// Clears the ElementData attached to this element, if any. /// /// This is only safe to call in top-down traversal before processing the /// children of |element|. - unsafe fn clear_element_data(element: &N::ConcreteElement); + unsafe fn clear_element_data(element: &E); /// Return the shared style context common to all worker threads. fn shared_context(&self) -> &SharedStyleContext; @@ -364,7 +367,7 @@ pub fn recalc_style_at(traversal: &D, element: E, mut data: &mut AtomicRefMut) where E: TElement, - D: DomTraversal + D: DomTraversal { debug_assert!(data.as_restyle().map_or(true, |r| r.snapshot.is_none()), "Snapshots should be expanded by the caller"); @@ -411,7 +414,7 @@ fn compute_style(_traversal: &D, element: E, mut data: &mut AtomicRefMut) -> bool where E: TElement, - D: DomTraversal, + D: DomTraversal, { let shared_context = context.shared; // Ensure the bloom filter is up to date. @@ -498,7 +501,7 @@ fn preprocess_children(traversal: &D, mut propagated_hint: StoredRestyleHint, parent_inherited_style_changed: bool) where E: TElement, - D: DomTraversal + D: DomTraversal { // Loop over all the children. for child in element.as_node().children() {