Repository: servo/servo
File: components/script/layout_dom/element.rs (Rust)

Code before:
                old_text.word_spacing != new_text.word_spacing ||
                old_text.text_rendering != new_text.text_rendering
            {
                return true;
            }

            false
        };

        if box_tree_needs_rebuild() {
            RestyleDamage::from_bits_retain(LayoutDamage::REBUILD_BOX.bits())
        } else if text_shaping_needs_recollect() {
            RestyleDamage::from_bits_retain(LayoutDamage::RECOLLECT_BOX_TREE_CHILDREN.bits())
        } else {
            // This element needs to be laid out again, but does not have any damage to
            // its box. In the future, we will distinguish between types of damage to the
            // fragment as well.
            RestyleDamage::RELAYOUT
        }
    }
}

impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> {
    type Impl = SelectorImpl;

    fn opaque(&self) -> ::selectors::OpaqueElement {
        ::selectors::OpaqueElement::new(unsafe { &*(self.as_node().opaque().0 as *const ()) })
    }

    fn parent_element(&self) -> Option<Self> {
        ServoLayoutElement::parent_element(self)
            .filter(|element| Some(*element) != self.containing_shadow_host())
    }

    fn parent_node_is_shadow_root(&self) -> bool {
        match self.as_node().parent_node() {
            None => false,
            Some(node) => {
                node.script_type_id() ==
                    NodeTypeId::DocumentFragment(DocumentFragmentTypeId::ShadowRoot)
            },
        }
    }

    fn containing_shadow_host(&self) -> Option<Self> {
        self.containing_shadow().map(|s| s.host())
    }

    #[inline]
    fn is_pseudo_element(&self) -> bool {
        self.implemented_pseudo_element().is_some()

Review comment (suggestion):
Let's fix `ServoLayoutElement::parent_element` instead, it shouldn't use the composed tree. `inheritance_parent` should tho.

Code after:

            false
        };

        if box_tree_needs_rebuild() {
            RestyleDamage::from_bits_retain(LayoutDamage::REBUILD_BOX.bits())
        } else if text_shaping_needs_recollect() {
            RestyleDamage::from_bits_retain(LayoutDamage::RECOLLECT_BOX_TREE_CHILDREN.bits())
        } else {
            // This element needs to be laid out again, but does not have any damage to
            // its box. In the future, we will distinguish between types of damage to the
            // fragment as well.
            RestyleDamage::RELAYOUT
        }
    }
}

impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> {
    type Impl = SelectorImpl;

    fn opaque(&self) -> ::selectors::OpaqueElement {
        ::selectors::OpaqueElement::new(unsafe { &*(self.as_node().opaque().0 as *const ()) })
    }

    fn parent_element(&self) -> Option<Self> {
        ServoLayoutElement::parent_element(self)
    }

    fn parent_node_is_shadow_root(&self) -> bool {
        match self.as_node().parent_node() {
            None => false,
            Some(node) => {
                node.script_type_id() ==
                    NodeTypeId::DocumentFragment(DocumentFragmentTypeId::ShadowRoot)
            },
        }
    }

    fn containing_shadow_host(&self) -> Option<Self> {
        self.containing_shadow().map(|s| s.host())
    }

    #[inline]
    fn is_pseudo_element(&self) -> bool {
        self.implemented_pseudo_element().is_some()
    }

    #[inline]
    fn pseudo_element_originating_element(&self) -> Option<Self> {
        debug_assert!(self.is_pseudo_element());
        debug_assert!(!self.matches_user_and_content_rules());