mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
Factor out the bottom-up postorder traversal logic.
This commit is contained in:
parent
63988b9103
commit
1b363ac909
2 changed files with 53 additions and 55 deletions
|
@ -121,18 +121,8 @@ fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode<E::ConcreteNode>],
|
|||
});
|
||||
}
|
||||
|
||||
// Reset the count of children if we need to do a bottom-up traversal
|
||||
// after the top up.
|
||||
if D::needs_postorder_traversal() {
|
||||
if children_to_process == 0 {
|
||||
// If there were no more children, start walking back up.
|
||||
bottom_up_dom(traversal, &mut *tlc, root, node)
|
||||
} else {
|
||||
// Otherwise record the number of children to process when the
|
||||
// time comes.
|
||||
node.as_element().unwrap().store_children_to_process(children_to_process);
|
||||
}
|
||||
}
|
||||
traversal.handle_postorder_traversal(&mut *tlc, root, node,
|
||||
children_to_process);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,45 +163,3 @@ fn traverse_nodes<'a, 'scope, E, D>(nodes: Vec<SendNode<E::ConcreteNode>>, root:
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Process current node and potentially traverse its ancestors.
|
||||
///
|
||||
/// If we are the last child that finished processing, recursively process
|
||||
/// our parent. Else, stop. Also, stop at the root.
|
||||
///
|
||||
/// Thus, if we start with all the leaves of a tree, we end up traversing
|
||||
/// the whole tree bottom-up because each parent will be processed exactly
|
||||
/// once (by the last child that finishes processing).
|
||||
///
|
||||
/// The only communication between siblings is that they both
|
||||
/// fetch-and-subtract the parent's children count.
|
||||
fn bottom_up_dom<E, D>(traversal: &D,
|
||||
thread_local: &mut D::ThreadLocalContext,
|
||||
root: OpaqueNode,
|
||||
mut node: E::ConcreteNode)
|
||||
where E: TElement,
|
||||
D: DomTraversal<E>,
|
||||
{
|
||||
loop {
|
||||
// Perform the appropriate operation.
|
||||
traversal.process_postorder(thread_local, node);
|
||||
|
||||
if node.opaque() == root {
|
||||
break;
|
||||
}
|
||||
|
||||
let parent = match node.parent_element() {
|
||||
None => unreachable!("How can this happen after the break above?"),
|
||||
Some(parent) => parent,
|
||||
};
|
||||
|
||||
let remaining = parent.did_process_child();
|
||||
if remaining != 0 {
|
||||
// Get out of here and find another node to work on.
|
||||
break
|
||||
}
|
||||
|
||||
// We were the last child of our parent. Construct flows for our parent.
|
||||
node = parent.as_node();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue