mirror of
https://github.com/servo/servo.git
synced 2025-07-09 00:13:41 +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)
|
GeckoNode(&content._base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn flags(&self) -> u32 {
|
||||||
|
(self.0)._base._base_1.mFlags
|
||||||
|
}
|
||||||
|
|
||||||
fn node_info(&self) -> &structs::NodeInfo {
|
fn node_info(&self) -> &structs::NodeInfo {
|
||||||
debug_assert!(!self.0.mNodeInfo.mRawPtr.is_null());
|
debug_assert!(!self.0.mNodeInfo.mRawPtr.is_null());
|
||||||
unsafe { &*self.0.mNodeInfo.mRawPtr }
|
unsafe { &*self.0.mNodeInfo.mRawPtr }
|
||||||
|
@ -108,6 +112,32 @@ impl<'ln> GeckoNode<'ln> {
|
||||||
fn next_sibling(&self) -> Option<GeckoNode<'ln>> {
|
fn next_sibling(&self) -> Option<GeckoNode<'ln>> {
|
||||||
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
|
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> {
|
impl<'ln> NodeInfo for GeckoNode<'ln> {
|
||||||
|
@ -173,8 +203,14 @@ impl<'ln> TNode for GeckoNode<'ln> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_node(&self) -> Option<Self> {
|
fn parent_node(&self) -> Option<Self> {
|
||||||
|
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) }
|
unsafe { bindings::Gecko_GetParentNode(self.0).map(GeckoNode) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_in_doc(&self) -> bool {
|
fn is_in_doc(&self) -> bool {
|
||||||
unsafe { bindings::Gecko_IsInDocument(self.0) }
|
unsafe { bindings::Gecko_IsInDocument(self.0) }
|
||||||
|
@ -283,6 +319,17 @@ impl<'le> GeckoElement<'le> {
|
||||||
unsafe { Gecko_UnsetNodeFlags(self.as_node().0, flags) }
|
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.
|
/// Clear the element data for a given element.
|
||||||
pub fn clear_data(&self) {
|
pub fn clear_data(&self) {
|
||||||
let ptr = self.0.mServoData.get();
|
let ptr = self.0.mServoData.get();
|
||||||
|
@ -445,7 +492,8 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
|
||||||
|
|
||||||
impl<'le> ::selectors::Element for GeckoElement<'le> {
|
impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
fn parent_element(&self) -> Option<Self> {
|
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> {
|
fn first_child_element(&self) -> Option<Self> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue