mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Add methods to iterate a subtree in preorder.
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
6ae8bdee61
commit
4f997bf333
2 changed files with 65 additions and 2 deletions
|
@ -110,9 +110,32 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// An iterator over the DOM descendants of a node in pre-order.
|
||||
pub struct DomDescendants<N> {
|
||||
previous: Option<N>,
|
||||
scope: N,
|
||||
}
|
||||
|
||||
impl<N> Iterator for DomDescendants<N>
|
||||
where
|
||||
N: TNode
|
||||
{
|
||||
type Item = N;
|
||||
|
||||
fn next(&mut self) -> Option<N> {
|
||||
let prev = match self.previous.take() {
|
||||
None => return None,
|
||||
Some(n) => n,
|
||||
};
|
||||
|
||||
self.previous = prev.next_in_preorder(Some(self.scope));
|
||||
self.previous
|
||||
}
|
||||
}
|
||||
|
||||
/// The `TNode` trait. This is the main generic trait over which the style
|
||||
/// system can be implemented.
|
||||
pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
|
||||
pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo + PartialEq {
|
||||
/// The concrete `TElement` type.
|
||||
type ConcreteElement: TElement<ConcreteNode = Self>;
|
||||
|
||||
|
@ -131,11 +154,45 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
|
|||
/// Get this node's next sibling.
|
||||
fn next_sibling(&self) -> Option<Self>;
|
||||
|
||||
/// Iterate over the DOM children of an element.
|
||||
/// Iterate over the DOM children of a node.
|
||||
fn dom_children(&self) -> DomChildren<Self> {
|
||||
DomChildren(self.first_child())
|
||||
}
|
||||
|
||||
/// Iterate over the DOM children of a node, in preorder.
|
||||
fn dom_descendants(&self) -> DomDescendants<Self> {
|
||||
DomDescendants {
|
||||
previous: Some(*self),
|
||||
scope: *self,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the next children in pre-order, optionally scoped to a subtree
|
||||
/// root.
|
||||
fn next_in_preorder(&self, scoped_to: Option<Self>) -> Option<Self> {
|
||||
if let Some(c) = self.first_child() {
|
||||
return Some(c);
|
||||
}
|
||||
|
||||
if Some(*self) == scoped_to {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut current = *self;
|
||||
loop {
|
||||
if let Some(s) = current.next_sibling() {
|
||||
return Some(s);
|
||||
}
|
||||
|
||||
let parent = current.parent_node();
|
||||
if parent == scoped_to {
|
||||
return None;
|
||||
}
|
||||
|
||||
current = parent.expect("Not a descendant of the scope?");
|
||||
}
|
||||
}
|
||||
|
||||
/// Get this node's parent element from the perspective of a restyle
|
||||
/// traversal.
|
||||
fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
|
||||
|
|
|
@ -104,6 +104,12 @@ use stylist::Stylist;
|
|||
#[derive(Clone, Copy)]
|
||||
pub struct GeckoNode<'ln>(pub &'ln RawGeckoNode);
|
||||
|
||||
impl<'ln> PartialEq for GeckoNode<'ln> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 as *const _ == other.0 as *const _
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ln> fmt::Debug for GeckoNode<'ln> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(el) = self.as_element() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue