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