mirror of
https://github.com/servo/servo.git
synced 2025-07-08 16:03:40 +01:00
Bug 1335863 - Inline common case parent access. r=emilio
This commit is contained in:
parent
e78f2404e1
commit
001f258322
1 changed files with 50 additions and 2 deletions
|
@ -83,6 +83,10 @@ impl<'ln> GeckoNode<'ln> {
|
|||
GeckoNode(&content._base)
|
||||
}
|
||||
|
||||
fn flags(&self) -> u32 {
|
||||
(self.0)._base._base_1.mFlags
|
||||
}
|
||||
|
||||
fn node_info(&self) -> &structs::NodeInfo {
|
||||
debug_assert!(!self.0.mNodeInfo.mRawPtr.is_null());
|
||||
unsafe { &*self.0.mNodeInfo.mRawPtr }
|
||||
|
@ -108,6 +112,32 @@ impl<'ln> GeckoNode<'ln> {
|
|||
fn next_sibling(&self) -> Option<GeckoNode<'ln>> {
|
||||
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
use ::gecko_bindings::structs::*;
|
||||
let flags = self.flags();
|
||||
if flags & (NODE_MAY_BE_IN_BINDING_MNGR as u32 |
|
||||
NODE_IS_IN_SHADOW_TREE as u32) != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let parent = unsafe { self.0.mParent.as_ref() }.map(GeckoNode);
|
||||
let parent_el = parent.and_then(|p| p.as_element());
|
||||
if flags & (NODE_IS_NATIVE_ANONYMOUS_ROOT as u32) != 0 &&
|
||||
parent_el.map_or(false, |el| el.is_root())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if parent_el.map_or(false, |el| el.has_shadow_root()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'ln> NodeInfo for GeckoNode<'ln> {
|
||||
|
@ -173,7 +203,13 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
|||
}
|
||||
|
||||
fn parent_node(&self) -> Option<Self> {
|
||||
unsafe { bindings::Gecko_GetParentNode(self.0).map(GeckoNode) }
|
||||
let fast_path = self.flattened_tree_parent_is_parent();
|
||||
debug_assert!(fast_path == unsafe { bindings::Gecko_FlattenedTreeParentIsParent(self.0) });
|
||||
if fast_path {
|
||||
unsafe { self.0.mParent.as_ref().map(GeckoNode) }
|
||||
} else {
|
||||
unsafe { bindings::Gecko_GetParentNode(self.0).map(GeckoNode) }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_in_doc(&self) -> bool {
|
||||
|
@ -283,6 +319,17 @@ impl<'le> GeckoElement<'le> {
|
|||
unsafe { Gecko_UnsetNodeFlags(self.as_node().0, flags) }
|
||||
}
|
||||
|
||||
/// Returns true if this element has a shadow root.
|
||||
fn has_shadow_root(&self) -> bool {
|
||||
self.get_dom_slots().map_or(false, |slots| !slots.mShadowRoot.mRawPtr.is_null())
|
||||
}
|
||||
|
||||
/// Returns a reference to the DOM slots for this Element, if they exist.
|
||||
fn get_dom_slots(&self) -> Option<&structs::FragmentOrElement_nsDOMSlots> {
|
||||
let slots = self.as_node().0.mSlots as *const structs::FragmentOrElement_nsDOMSlots;
|
||||
unsafe { slots.as_ref() }
|
||||
}
|
||||
|
||||
/// Clear the element data for a given element.
|
||||
pub fn clear_data(&self) {
|
||||
let ptr = self.0.mServoData.get();
|
||||
|
@ -445,7 +492,8 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
|
|||
|
||||
impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||
fn parent_element(&self) -> Option<Self> {
|
||||
unsafe { bindings::Gecko_GetParentElement(self.0).map(GeckoElement) }
|
||||
let parent_node = self.as_node().parent_node();
|
||||
parent_node.and_then(|n| n.as_element())
|
||||
}
|
||||
|
||||
fn first_child_element(&self) -> Option<Self> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue