mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
style: Refactor children handling.
Moving traversal_children away from TNode I can make TNode trivial enough, in order to share a QuerySelector implementation between Servo and Gecko.
This commit is contained in:
parent
7c2265360f
commit
a11d268468
9 changed files with 149 additions and 158 deletions
|
@ -158,32 +158,6 @@ impl<'ln> GeckoNode<'ln> {
|
|||
unsafe { &*self.node_info().mDocument }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn first_child(&self) -> Option<GeckoNode<'ln>> {
|
||||
unsafe { self.0.mFirstChild.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_child(&self) -> Option<GeckoNode<'ln>> {
|
||||
unsafe { Gecko_GetLastChild(self.0).map(GeckoNode) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_sibling(&self) -> Option<GeckoNode<'ln>> {
|
||||
unsafe { self.0.mPreviousSibling.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_sibling(&self) -> Option<GeckoNode<'ln>> {
|
||||
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
/// Simple iterator over all this node's children. Unlike `.children()`, this iterator does
|
||||
/// not filter out nodes that don't need layout.
|
||||
fn dom_children(self) -> GeckoChildrenIterator<'ln> {
|
||||
GeckoChildrenIterator::Current(self.first_child())
|
||||
}
|
||||
|
||||
/// WARNING: This logic is duplicated in Gecko's FlattenedTreeParentIsParent.
|
||||
/// Make sure to mirror any modifications in both places.
|
||||
fn flattened_tree_parent_is_parent(&self) -> bool {
|
||||
|
@ -222,11 +196,6 @@ impl<'ln> GeckoNode<'ln> {
|
|||
fn contains_non_whitespace_content(&self) -> bool {
|
||||
unsafe { Gecko_IsSignificantChild(self.0, true, false) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn may_have_anonymous_children(&self) -> bool {
|
||||
self.get_bool_flag(nsINode_BooleanFlag::ElementMayHaveAnonymousChildren)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ln> NodeInfo for GeckoNode<'ln> {
|
||||
|
@ -244,40 +213,35 @@ impl<'ln> NodeInfo for GeckoNode<'ln> {
|
|||
|
||||
impl<'ln> TNode for GeckoNode<'ln> {
|
||||
type ConcreteElement = GeckoElement<'ln>;
|
||||
type ConcreteChildrenIterator = GeckoChildrenIterator<'ln>;
|
||||
|
||||
fn parent_node(&self) -> Option<Self> {
|
||||
unsafe { self.0.mParent.as_ref().map(GeckoNode) }
|
||||
}
|
||||
|
||||
fn children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
|
||||
LayoutIterator(self.dom_children())
|
||||
#[inline]
|
||||
fn first_child(&self) -> Option<Self> {
|
||||
unsafe { self.0.mFirstChild.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_child(&self) -> Option<Self> {
|
||||
unsafe { Gecko_GetLastChild(self.0).map(GeckoNode) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_sibling(&self) -> Option<Self> {
|
||||
unsafe { self.0.mPreviousSibling.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_sibling(&self) -> Option<Self> {
|
||||
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
fn traversal_parent(&self) -> Option<GeckoElement<'ln>> {
|
||||
self.flattened_tree_parent().and_then(|n| n.as_element())
|
||||
}
|
||||
|
||||
fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
|
||||
if let Some(element) = self.as_element() {
|
||||
// This condition is similar to the check that
|
||||
// StyleChildrenIterator::IsNeeded does, except that it might return
|
||||
// true if we used to (but no longer) have anonymous content from
|
||||
// ::before/::after, XBL bindings, or nsIAnonymousContentCreators.
|
||||
if element.is_in_anonymous_subtree() ||
|
||||
element.has_xbl_binding_with_content() ||
|
||||
self.may_have_anonymous_children() {
|
||||
unsafe {
|
||||
let mut iter: structs::StyleChildrenIterator = ::std::mem::zeroed();
|
||||
Gecko_ConstructStyleChildrenIterator(element.0, &mut iter);
|
||||
return LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LayoutIterator(self.dom_children())
|
||||
}
|
||||
|
||||
fn opaque(&self) -> OpaqueNode {
|
||||
let ptr: usize = self.0 as *const _ as usize;
|
||||
OpaqueNode(ptr)
|
||||
|
@ -447,6 +411,11 @@ impl<'le> fmt::Debug for GeckoElement<'le> {
|
|||
}
|
||||
|
||||
impl<'le> GeckoElement<'le> {
|
||||
#[inline]
|
||||
fn may_have_anonymous_children(&self) -> bool {
|
||||
self.as_node().get_bool_flag(nsINode_BooleanFlag::ElementMayHaveAnonymousChildren)
|
||||
}
|
||||
|
||||
/// Parse the style attribute of an element.
|
||||
pub fn parse_style_attribute<R>(
|
||||
value: &str,
|
||||
|
@ -883,6 +852,7 @@ impl structs::FontSizePrefs {
|
|||
impl<'le> TElement for GeckoElement<'le> {
|
||||
type ConcreteNode = GeckoNode<'le>;
|
||||
type FontMetricsProvider = GeckoFontMetricsProvider;
|
||||
type TraversalChildrenIterator = GeckoChildrenIterator<'le>;
|
||||
|
||||
fn inheritance_parent(&self) -> Option<Self> {
|
||||
if self.is_native_anonymous() {
|
||||
|
@ -894,6 +864,24 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'le>> {
|
||||
// This condition is similar to the check that
|
||||
// StyleChildrenIterator::IsNeeded does, except that it might return
|
||||
// true if we used to (but no longer) have anonymous content from
|
||||
// ::before/::after, XBL bindings, or nsIAnonymousContentCreators.
|
||||
if self.is_in_anonymous_subtree() ||
|
||||
self.has_xbl_binding_with_content() ||
|
||||
self.may_have_anonymous_children() {
|
||||
unsafe {
|
||||
let mut iter: structs::StyleChildrenIterator = ::std::mem::zeroed();
|
||||
Gecko_ConstructStyleChildrenIterator(self.0, &mut iter);
|
||||
return LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter));
|
||||
}
|
||||
}
|
||||
|
||||
LayoutIterator(GeckoChildrenIterator::Current(self.as_node().first_child()))
|
||||
}
|
||||
|
||||
fn before_pseudo_element(&self) -> Option<Self> {
|
||||
self.get_before_or_after_pseudo(/* is_before = */ true)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue