mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Use associated types instead of wrapper types.
This commit is contained in:
parent
516619b230
commit
05db7b3652
1 changed files with 71 additions and 61 deletions
|
@ -74,14 +74,10 @@ use util::str::{is_whitespace, search_index};
|
||||||
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
|
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
|
||||||
/// only ever see these and must never see instances of `LayoutJS`.
|
/// only ever see these and must never see instances of `LayoutJS`.
|
||||||
|
|
||||||
pub trait WrapperTypes<'a> : Sized {
|
pub trait LayoutNode<'ln> : Sized + Copy + Clone {
|
||||||
type Node: LayoutNode<'a, Self>;
|
type ConcreteLayoutElement: LayoutElement<'ln>;
|
||||||
type Document: LayoutDocument<'a, Self>;
|
type ConcreteLayoutDocument: LayoutDocument<'ln>;
|
||||||
type Element: LayoutElement<'a, Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LayoutNode<'ln, Wrappers> : Sized + Copy + Clone
|
|
||||||
where Wrappers: WrapperTypes<'ln> {
|
|
||||||
/// Returns the type ID of this node.
|
/// Returns the type ID of this node.
|
||||||
fn type_id(&self) -> NodeTypeId;
|
fn type_id(&self) -> NodeTypeId;
|
||||||
|
|
||||||
|
@ -89,12 +85,12 @@ pub trait LayoutNode<'ln, Wrappers> : Sized + Copy + Clone
|
||||||
|
|
||||||
fn dump(self);
|
fn dump(self);
|
||||||
|
|
||||||
fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Wrappers>;
|
fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Self>;
|
||||||
|
|
||||||
/// Returns an iterator over this node's children.
|
/// Returns an iterator over this node's children.
|
||||||
fn children(self) -> LayoutNodeChildrenIterator<'ln, Wrappers>;
|
fn children(self) -> LayoutNodeChildrenIterator<'ln, Self>;
|
||||||
|
|
||||||
fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Wrappers>;
|
fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Self>;
|
||||||
|
|
||||||
/// Converts self into an `OpaqueNode`.
|
/// Converts self into an `OpaqueNode`.
|
||||||
fn opaque(&self) -> OpaqueNode;
|
fn opaque(&self) -> OpaqueNode;
|
||||||
|
@ -110,9 +106,9 @@ pub trait LayoutNode<'ln, Wrappers> : Sized + Copy + Clone
|
||||||
|
|
||||||
fn debug_id(self) -> usize;
|
fn debug_id(self) -> usize;
|
||||||
|
|
||||||
fn as_element(&self) -> Option<Wrappers::Element>;
|
fn as_element(&self) -> Option<Self::ConcreteLayoutElement>;
|
||||||
|
|
||||||
fn as_document(&self) -> Option<Wrappers::Document>;
|
fn as_document(&self) -> Option<Self::ConcreteLayoutDocument>;
|
||||||
|
|
||||||
fn children_count(&self) -> u32;
|
fn children_count(&self) -> u32;
|
||||||
|
|
||||||
|
@ -154,29 +150,33 @@ pub trait LayoutNode<'ln, Wrappers> : Sized + Copy + Clone
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mutate_layout_data(&self) -> RefMut<Option<LayoutDataWrapper>>;
|
fn mutate_layout_data(&self) -> RefMut<Option<LayoutDataWrapper>>;
|
||||||
|
|
||||||
fn parent_node(&self) -> Option<Wrappers::Node>;
|
fn parent_node(&self) -> Option<Self>;
|
||||||
|
|
||||||
fn first_child(&self) -> Option<Wrappers::Node>;
|
fn first_child(&self) -> Option<Self>;
|
||||||
|
|
||||||
fn last_child(&self) -> Option<Wrappers::Node>;
|
fn last_child(&self) -> Option<Self>;
|
||||||
|
|
||||||
fn prev_sibling(&self) -> Option<Wrappers::Node>;
|
fn prev_sibling(&self) -> Option<Self>;
|
||||||
|
|
||||||
fn next_sibling(&self) -> Option<Wrappers::Node>;
|
fn next_sibling(&self) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayoutDocument<'ld, Wrappers> : Sized + Copy + Clone
|
pub trait LayoutDocument<'ld> : Sized + Copy + Clone {
|
||||||
where Wrappers: WrapperTypes<'ld> {
|
type ConcreteLayoutNode: LayoutNode<'ld>;
|
||||||
fn as_node(&self) -> Wrappers::Node;
|
type ConcreteLayoutElement: LayoutElement<'ld>;
|
||||||
|
|
||||||
fn root_node(&self) -> Option<Wrappers::Node>;
|
fn as_node(&self) -> Self::ConcreteLayoutNode;
|
||||||
|
|
||||||
fn drain_modified_elements(&self) -> Vec<(Wrappers::Element, ElementSnapshot)>;
|
fn root_node(&self) -> Option<Self::ConcreteLayoutNode>;
|
||||||
|
|
||||||
|
fn drain_modified_elements(&self) -> Vec<(Self::ConcreteLayoutElement, ElementSnapshot)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayoutElement<'le, Wrappers> : Sized + Copy + Clone + ::selectors::Element + TElementAttributes
|
pub trait LayoutElement<'le> : Sized + Copy + Clone + ::selectors::Element + TElementAttributes {
|
||||||
where Wrappers: WrapperTypes<'le> {
|
type ConcreteLayoutNode: LayoutNode<'le>;
|
||||||
fn as_node(&self) -> Wrappers::Node;
|
type ConcreteLayoutDocument: LayoutDocument<'le>;
|
||||||
|
|
||||||
|
fn as_node(&self) -> Self::ConcreteLayoutNode;
|
||||||
|
|
||||||
fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock>;
|
fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock>;
|
||||||
|
|
||||||
|
@ -224,17 +224,6 @@ pub trait LayoutElement<'le, Wrappers> : Sized + Copy + Clone + ::selectors::Ele
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ServoWrapperTypes<'a> {
|
|
||||||
// Satisfy the compiler about the unused lifetime.
|
|
||||||
phantom: PhantomData<&'a ()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> WrapperTypes<'a> for ServoWrapperTypes<'a> {
|
|
||||||
type Node = ServoLayoutNode<'a>;
|
|
||||||
type Element = ServoLayoutElement<'a>;
|
|
||||||
type Document = ServoLayoutDocument<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct ServoLayoutNode<'a> {
|
pub struct ServoLayoutNode<'a> {
|
||||||
/// The wrapped node.
|
/// The wrapped node.
|
||||||
|
@ -272,7 +261,10 @@ impl<'ln> ServoLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> LayoutNode<'ln, ServoWrapperTypes<'ln>> for ServoLayoutNode<'ln> {
|
impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
|
type ConcreteLayoutElement = ServoLayoutElement<'ln>;
|
||||||
|
type ConcreteLayoutDocument = ServoLayoutDocument<'ln>;
|
||||||
|
|
||||||
fn type_id(&self) -> NodeTypeId {
|
fn type_id(&self) -> NodeTypeId {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.node.type_id_for_layout()
|
self.node.type_id_for_layout()
|
||||||
|
@ -289,19 +281,21 @@ impl<'ln> LayoutNode<'ln, ServoWrapperTypes<'ln>> for ServoLayoutNode<'ln> {
|
||||||
self.dump_indent(0);
|
self.dump_indent(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse_preorder(self) -> LayoutTreeIterator<'ln, ServoWrapperTypes<'ln>> {
|
fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Self> {
|
||||||
LayoutTreeIterator::new(self)
|
LayoutTreeIterator::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn children(self) -> LayoutNodeChildrenIterator<'ln, ServoWrapperTypes<'ln>> {
|
fn children(self) -> LayoutNodeChildrenIterator<'ln, Self> {
|
||||||
LayoutNodeChildrenIterator {
|
LayoutNodeChildrenIterator {
|
||||||
current: self.first_child(),
|
current: self.first_child(),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, ServoWrapperTypes<'ln>> {
|
fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Self> {
|
||||||
LayoutNodeReverseChildrenIterator {
|
LayoutNodeReverseChildrenIterator {
|
||||||
current: self.last_child()
|
current: self.last_child(),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,49 +446,59 @@ impl<'ln> ServoLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutNodeChildrenIterator<'a, Wrappers: WrapperTypes<'a>> {
|
pub struct LayoutNodeChildrenIterator<'a, ConcreteLayoutNode> where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
current: Option<Wrappers::Node>,
|
current: Option<ConcreteLayoutNode>,
|
||||||
|
// Satisfy the compiler about the unused lifetime.
|
||||||
|
phantom: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Wrappers: WrapperTypes<'a>> Iterator for LayoutNodeChildrenIterator<'a, Wrappers> {
|
impl<'a, ConcreteLayoutNode> Iterator for LayoutNodeChildrenIterator<'a, ConcreteLayoutNode>
|
||||||
type Item = Wrappers::Node;
|
where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
fn next(&mut self) -> Option<Wrappers::Node> {
|
type Item = ConcreteLayoutNode;
|
||||||
|
fn next(&mut self) -> Option<ConcreteLayoutNode> {
|
||||||
let node = self.current;
|
let node = self.current;
|
||||||
self.current = node.and_then(|node| node.next_sibling());
|
self.current = node.and_then(|node| node.next_sibling());
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutNodeReverseChildrenIterator<'a, Wrappers: WrapperTypes<'a>> {
|
pub struct LayoutNodeReverseChildrenIterator<'a, ConcreteLayoutNode> where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
current: Option<Wrappers::Node>,
|
current: Option<ConcreteLayoutNode>,
|
||||||
|
// Satisfy the compiler about the unused lifetime.
|
||||||
|
phantom: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Wrappers: WrapperTypes<'a>> Iterator for LayoutNodeReverseChildrenIterator<'a, Wrappers> {
|
impl<'a, ConcreteLayoutNode> Iterator for LayoutNodeReverseChildrenIterator<'a, ConcreteLayoutNode>
|
||||||
type Item = Wrappers::Node;
|
where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
fn next(&mut self) -> Option<Wrappers::Node> {
|
type Item = ConcreteLayoutNode;
|
||||||
|
fn next(&mut self) -> Option<ConcreteLayoutNode> {
|
||||||
let node = self.current;
|
let node = self.current;
|
||||||
self.current = node.and_then(|node| node.prev_sibling());
|
self.current = node.and_then(|node| node.prev_sibling());
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutTreeIterator<'a, Wrappers: WrapperTypes<'a>> {
|
pub struct LayoutTreeIterator<'a, ConcreteLayoutNode> where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
stack: Vec<Wrappers::Node>,
|
stack: Vec<ConcreteLayoutNode>,
|
||||||
|
// Satisfy the compiler about the unused lifetime.
|
||||||
|
phantom: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Wrappers> LayoutTreeIterator<'a, Wrappers> where Wrappers: WrapperTypes<'a> {
|
impl<'a, ConcreteLayoutNode> LayoutTreeIterator<'a, ConcreteLayoutNode> where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
fn new(root: Wrappers::Node) -> LayoutTreeIterator<'a, Wrappers> {
|
fn new(root: ConcreteLayoutNode) -> LayoutTreeIterator<'a, ConcreteLayoutNode> {
|
||||||
let mut stack = vec!();
|
let mut stack = vec!();
|
||||||
stack.push(root);
|
stack.push(root);
|
||||||
LayoutTreeIterator {
|
LayoutTreeIterator {
|
||||||
stack: stack
|
stack: stack,
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Wrappers> Iterator for LayoutTreeIterator<'a, Wrappers> where Wrappers: WrapperTypes<'a> {
|
impl<'a, ConcreteLayoutNode> Iterator for LayoutTreeIterator<'a, ConcreteLayoutNode>
|
||||||
type Item = Wrappers::Node;
|
where ConcreteLayoutNode: LayoutNode<'a> {
|
||||||
fn next(&mut self) -> Option<Wrappers::Node> {
|
type Item = ConcreteLayoutNode;
|
||||||
|
fn next(&mut self) -> Option<ConcreteLayoutNode> {
|
||||||
let ret = self.stack.pop();
|
let ret = self.stack.pop();
|
||||||
ret.map(|node| self.stack.extend(node.rev_children()));
|
ret.map(|node| self.stack.extend(node.rev_children()));
|
||||||
ret
|
ret
|
||||||
|
@ -508,7 +512,10 @@ pub struct ServoLayoutDocument<'ld> {
|
||||||
chain: PhantomData<&'ld ()>,
|
chain: PhantomData<&'ld ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ld> LayoutDocument<'ld, ServoWrapperTypes<'ld>> for ServoLayoutDocument<'ld> {
|
impl<'ld> LayoutDocument<'ld> for ServoLayoutDocument<'ld> {
|
||||||
|
type ConcreteLayoutNode = ServoLayoutNode<'ld>;
|
||||||
|
type ConcreteLayoutElement = ServoLayoutElement<'ld>;
|
||||||
|
|
||||||
fn as_node(&self) -> ServoLayoutNode<'ld> {
|
fn as_node(&self) -> ServoLayoutNode<'ld> {
|
||||||
ServoLayoutNode::from_layout_js(self.document.upcast())
|
ServoLayoutNode::from_layout_js(self.document.upcast())
|
||||||
}
|
}
|
||||||
|
@ -539,7 +546,10 @@ pub struct ServoLayoutElement<'le> {
|
||||||
chain: PhantomData<&'le ()>,
|
chain: PhantomData<&'le ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'le> LayoutElement<'le, ServoWrapperTypes<'le>> for ServoLayoutElement<'le> {
|
impl<'le> LayoutElement<'le> for ServoLayoutElement<'le> {
|
||||||
|
type ConcreteLayoutNode = ServoLayoutNode<'le>;
|
||||||
|
type ConcreteLayoutDocument = ServoLayoutDocument<'le>;
|
||||||
|
|
||||||
fn as_node(&self) -> ServoLayoutNode<'le> {
|
fn as_node(&self) -> ServoLayoutNode<'le> {
|
||||||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue