Auto merge of #17541 - heycam:is-needed, r=emilio

style: Make GeckoElement::traversal_children faster.

From https://bugzilla.mozilla.org/show_bug.cgi?id=1372061.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17541)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-06-28 11:59:31 -07:00 committed by GitHub
commit a40e5353b3
7 changed files with 4663 additions and 4139 deletions

View file

@ -187,12 +187,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
self.children()
}
fn children_and_traversal_children_might_differ(&self) -> bool {
// Servo doesn't have to worry about nodes being rearranged in the
// flattened tree like Gecko does (for XBL and Shadow DOM). Yet.
false
}
fn opaque(&self) -> OpaqueNode {
unsafe { self.get_jsmanaged().opaque() }
}

View file

@ -127,10 +127,6 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo {
/// Get this node's children from the perspective of a restyle traversal.
fn traversal_children(&self) -> LayoutIterator<Self::ConcreteChildrenIterator>;
/// Returns whether `children()` and `traversal_children()` might return
/// iterators over different nodes.
fn children_and_traversal_children_might_differ(&self) -> bool;
/// Converts self into an `OpaqueNode`.
fn opaque(&self) -> OpaqueNode;

View file

@ -986,6 +986,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4HARDE"]
pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms8haspopupE"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms11hasSameNodeE"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4hboxE"]
@ -1562,6 +1564,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms10oncheckingE"]
pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms21onCheckboxStateChangeE"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms7onclickE"]
pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms16onclirmodechangeE"]
@ -1898,6 +1902,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18onradiostatechangeE"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18onRadioStateChangeE"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms13onrdsdisabledE"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms12onrdsenabledE"]
@ -4208,6 +4214,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms14pseudoPropertyE"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms17manualNACPropertyE"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms8JapaneseE"]
pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms7ChineseE"]
@ -6099,6 +6107,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "?HARD@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "?haspopup@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "?hasSameNode@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "?hbox@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -6675,6 +6685,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "?onchecking@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "?onCheckboxStateChange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "?onclick@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "?onclirmodechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -7011,6 +7023,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "?onradiostatechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "?onRadioStateChange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "?onrdsdisabled@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "?onrdsenabled@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -9321,6 +9335,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "?pseudoProperty@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "?manualNACProperty@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "?Japanese@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "?Chinese@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -11212,6 +11228,8 @@ cfg_if! {
pub static nsGkAtoms_handlers: *mut nsIAtom;
#[link_name = "\x01?HARD@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_HARD: *mut nsIAtom;
#[link_name = "\x01?haspopup@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_haspopup: *mut nsIAtom;
#[link_name = "\x01?hasSameNode@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_hasSameNode: *mut nsIAtom;
#[link_name = "\x01?hbox@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -11788,6 +11806,8 @@ cfg_if! {
pub static nsGkAtoms_onchargingtimechange: *mut nsIAtom;
#[link_name = "\x01?onchecking@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onchecking: *mut nsIAtom;
#[link_name = "\x01?onCheckboxStateChange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onCheckboxStateChange: *mut nsIAtom;
#[link_name = "\x01?onclick@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onclick: *mut nsIAtom;
#[link_name = "\x01?onclirmodechange@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -12124,6 +12144,8 @@ cfg_if! {
pub static nsGkAtoms_onptychange: *mut nsIAtom;
#[link_name = "\x01?onradiostatechange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onradiostatechange: *mut nsIAtom;
#[link_name = "\x01?onRadioStateChange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onRadioStateChange: *mut nsIAtom;
#[link_name = "\x01?onrdsdisabled@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onrdsdisabled: *mut nsIAtom;
#[link_name = "\x01?onrdsenabled@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -14434,6 +14456,8 @@ cfg_if! {
pub static nsGkAtoms_paintRequestTime: *mut nsIAtom;
#[link_name = "\x01?pseudoProperty@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_pseudoProperty: *mut nsIAtom;
#[link_name = "\x01?manualNACProperty@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_manualNACProperty: *mut nsIAtom;
#[link_name = "\x01?Japanese@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_Japanese: *mut nsIAtom;
#[link_name = "\x01?Chinese@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -16328,6 +16352,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_handlers as *mut _) } };
("HARD") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_HARD as *mut _) } };
("haspopup") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_haspopup as *mut _) } };
("has-same-node") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_hasSameNode as *mut _) } };
("hbox") =>
@ -16904,6 +16930,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchargingtimechange as *mut _) } };
("onchecking") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onchecking as *mut _) } };
("onCheckboxStateChange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onCheckboxStateChange as *mut _) } };
("onclick") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onclick as *mut _) } };
("onclirmodechange") =>
@ -17240,6 +17268,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onptychange as *mut _) } };
("onradiostatechange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onradiostatechange as *mut _) } };
("onRadioStateChange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onRadioStateChange as *mut _) } };
("onrdsdisabled") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onrdsdisabled as *mut _) } };
("onrdsenabled") =>
@ -19550,6 +19580,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_paintRequestTime as *mut _) } };
("PseudoProperty") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_pseudoProperty as *mut _) } };
("ManualNACProperty") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_manualNACProperty as *mut _) } };
("ja") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_Japanese as *mut _) } };
("zh-CN") =>

View file

@ -29,6 +29,7 @@ use gecko_bindings::structs::RawServoStyleRule;
use gecko_bindings::structs::RawGeckoPresContext;
use gecko_bindings::structs::RawGeckoPresContextOwned;
use gecko_bindings::structs::RawGeckoStyleAnimationList;
use gecko_bindings::structs::RawGeckoStyleChildrenIteratorBorrowedMut;
use gecko_bindings::structs::RawGeckoServoStyleRuleList;
use gecko_bindings::structs::RawGeckoURLExtraData;
use gecko_bindings::structs::RawGeckoXBLBinding;
@ -227,14 +228,6 @@ pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet;
pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>;
enum RawServoStyleSetVoid { }
pub struct RawServoStyleSet(RawServoStyleSetVoid);
pub type StyleChildrenIteratorOwned = ::gecko_bindings::sugar::ownership::Owned<StyleChildrenIterator>;
pub type StyleChildrenIteratorOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<StyleChildrenIterator>;
pub type StyleChildrenIteratorBorrowed<'a> = &'a StyleChildrenIterator;
pub type StyleChildrenIteratorBorrowedOrNull<'a> = Option<&'a StyleChildrenIterator>;
pub type StyleChildrenIteratorBorrowedMut<'a> = &'a mut StyleChildrenIterator;
pub type StyleChildrenIteratorBorrowedMutOrNull<'a> = Option<&'a mut StyleChildrenIterator>;
enum StyleChildrenIteratorVoid { }
pub struct StyleChildrenIterator(StyleChildrenIteratorVoid);
pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned<ServoElementSnapshot>;
pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<ServoElementSnapshot>;
pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot;
@ -532,14 +525,18 @@ extern "C" {
*mut nsTArray<*mut nsIContent>);
}
extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed)
-> StyleChildrenIteratorOwnedOrNull;
pub fn Gecko_ConstructStyleChildrenIterator(aElement:
RawGeckoElementBorrowed,
aIterator:
RawGeckoStyleChildrenIteratorBorrowedMut);
}
extern "C" {
pub fn Gecko_DropStyleChildrenIterator(it: StyleChildrenIteratorOwned);
pub fn Gecko_DestroyStyleChildrenIterator(aIterator:
RawGeckoStyleChildrenIteratorBorrowedMut);
}
extern "C" {
pub fn Gecko_GetNextStyleChild(it: StyleChildrenIteratorBorrowedMut)
pub fn Gecko_GetNextStyleChild(it:
RawGeckoStyleChildrenIteratorBorrowedMut)
-> RawGeckoNodeBorrowedOrNull;
}
extern "C" {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ use gecko::global_style_data::GLOBAL_STYLE_DATA;
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
use gecko::snapshot_helpers;
use gecko_bindings::bindings;
use gecko_bindings::bindings::{Gecko_DropStyleChildrenIterator, Gecko_MaybeCreateStyleChildrenIterator};
use gecko_bindings::bindings::{Gecko_ConstructStyleChildrenIterator, Gecko_DestroyStyleChildrenIterator};
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_Namespace};
@ -227,6 +227,21 @@ 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)
}
/// This logic is duplicated in Gecko's nsIContent::IsInAnonymousSubtree.
#[inline]
fn is_in_anonymous_subtree(&self) -> bool {
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use gecko_bindings::structs::NODE_IS_IN_SHADOW_TREE;
self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) != 0 ||
((self.flags() & (NODE_IS_IN_SHADOW_TREE as u32) == 0) &&
self.as_element().map_or(false, |e| e.has_xbl_binding_parent()))
}
}
impl<'ln> NodeInfo for GeckoNode<'ln> {
@ -267,19 +282,23 @@ impl<'ln> TNode for GeckoNode<'ln> {
}
fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'ln>> {
let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) };
if let Some(iter) = maybe_iter.into_owned_opt() {
LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter))
} else {
LayoutIterator(self.dom_children())
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 self.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));
}
}
}
}
fn children_and_traversal_children_might_differ(&self) -> bool {
match self.as_element() {
Some(e) => e.xbl_binding_anonymous_content().is_some(),
None => false,
}
LayoutIterator(self.dom_children())
}
fn opaque(&self) -> OpaqueNode {
@ -343,14 +362,14 @@ pub enum GeckoChildrenIterator<'a> {
/// replaces it with the next sibling when requested.
Current(Option<GeckoNode<'a>>),
/// A Gecko-implemented iterator we need to drop appropriately.
GeckoIterator(bindings::StyleChildrenIteratorOwned),
GeckoIterator(structs::StyleChildrenIterator),
}
impl<'a> Drop for GeckoChildrenIterator<'a> {
fn drop(&mut self) {
if let GeckoChildrenIterator::GeckoIterator(ref it) = *self {
if let GeckoChildrenIterator::GeckoIterator(ref mut it) = *self {
unsafe {
Gecko_DropStyleChildrenIterator(ptr::read(it as *const _));
Gecko_DestroyStyleChildrenIterator(it);
}
}
}
@ -373,10 +392,11 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> {
}
/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer.
#[derive(Clone, Copy)]
pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding);
impl<'lb> GeckoXBLBinding<'lb> {
fn base_binding(&self) -> Option<GeckoXBLBinding> {
fn base_binding(&self) -> Option<Self> {
unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) }
}
@ -388,6 +408,21 @@ impl<'lb> GeckoXBLBinding<'lb> {
unsafe { bindings::Gecko_XBLBinding_InheritsStyle(self.0) }
}
// This duplicates the logic in Gecko's
// nsBindingManager::GetBindingWithContent.
fn get_binding_with_content(&self) -> Option<Self> {
let mut binding = *self;
loop {
if !binding.anon_content().is_null() {
return Some(binding);
}
binding = match binding.base_binding() {
Some(b) => b,
None => return None,
};
}
}
// Implements Gecko's nsXBLBinding::WalkRules().
fn get_declarations_for<E, V>(&self,
element: &E,
@ -480,12 +515,71 @@ impl<'le> GeckoElement<'le> {
unsafe { slots.as_ref() }
}
#[inline]
fn get_xbl_binding(&self) -> Option<GeckoXBLBinding> {
if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 {
return None;
}
unsafe { bindings::Gecko_GetXBLBinding(self.0).map(GeckoXBLBinding) }
}
#[inline]
fn get_xbl_binding_with_content(&self) -> Option<GeckoXBLBinding> {
self.get_xbl_binding().and_then(|b| b.get_binding_with_content())
}
#[inline]
fn has_xbl_binding_with_content(&self) -> bool {
!self.get_xbl_binding_with_content().is_none()
}
/// This and has_xbl_binding_parent duplicate the logic in Gecko's virtual
/// nsINode::GetBindingParent function, which only has two implementations:
/// one for XUL elements, and one for other elements. We just hard code in
/// our knowledge of those two implementations here.
fn get_xbl_binding_parent(&self) -> Option<Self> {
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) }
if self.is_xul_element() {
// FIXME(heycam): Having trouble with bindgen on nsXULElement,
// where the binding parent is stored in a member variable
// rather than in slots. So just get it through FFI for now.
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) }
} else {
let binding_parent =
unsafe { self.get_non_xul_xbl_binding_parent_raw_content().as_ref() }
.map(GeckoNode::from_content)
.and_then(|n| n.as_element());
debug_assert!(binding_parent ==
unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) });
binding_parent
}
}
fn get_non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
debug_assert!(!self.is_xul_element());
match self.get_dom_slots() {
Some(slots) => unsafe { *slots.__bindgen_anon_1.mBindingParent.as_ref() },
None => ptr::null_mut(),
}
}
fn has_xbl_binding_parent(&self) -> bool {
if self.is_xul_element() {
// FIXME(heycam): Having trouble with bindgen on nsXULElement,
// where the binding parent is stored in a member variable
// rather than in slots. So just get it through FFI for now.
unsafe { bindings::Gecko_GetBindingParent(self.0).is_some() }
} else {
!self.get_non_xul_xbl_binding_parent_raw_content().is_null()
}
}
fn namespace_id(&self) -> i32 {
self.as_node().node_info().mInner.mNamespaceID
}
fn is_xul_element(&self) -> bool {
self.namespace_id() == (structs::root::kNameSpaceID_XUL as i32)
}
/// Clear the element data for a given element.
@ -1061,16 +1155,9 @@ impl<'le> TElement for GeckoElement<'le> {
}
fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> {
if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 {
return None;
}
let anon_content = match self.get_xbl_binding() {
Some(binding) => binding.anon_content(),
None => return None,
};
unsafe { anon_content.as_ref().map(GeckoNode::from_content) }
self.get_xbl_binding_with_content()
.map(|b| unsafe { b.anon_content().as_ref() }.unwrap())
.map(GeckoNode::from_content)
}
fn get_css_transitions_info(&self)