mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +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
|
/// The `TNode` trait. This is the main generic trait over which the style
|
||||||
/// system can be implemented.
|
/// 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.
|
/// The concrete `TElement` type.
|
||||||
type ConcreteElement: TElement<ConcreteNode = Self>;
|
type ConcreteElement: TElement<ConcreteNode = Self>;
|
||||||
|
|
||||||
|
@ -131,11 +154,45 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
|
||||||
/// Get this node's next sibling.
|
/// Get this node's next sibling.
|
||||||
fn next_sibling(&self) -> Option<Self>;
|
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> {
|
fn dom_children(&self) -> DomChildren<Self> {
|
||||||
DomChildren(self.first_child())
|
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
|
/// Get this node's parent element from the perspective of a restyle
|
||||||
/// traversal.
|
/// traversal.
|
||||||
fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
|
fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
|
||||||
|
|
|
@ -104,6 +104,12 @@ use stylist::Stylist;
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct GeckoNode<'ln>(pub &'ln RawGeckoNode);
|
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> {
|
impl<'ln> fmt::Debug for GeckoNode<'ln> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if let Some(el) = self.as_element() {
|
if let Some(el) = self.as_element() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue