style: Move functions related to anonymous element to GeckoElement (
Bug 1390773)
MozReview-Commit-ID: 6LqAPM86MQC
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -57,18 +57,16 @@ use gecko_bindings::structs;
use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding};
use gecko_bindings::structs::{nsIAtom, nsIContent, nsINode_BooleanFlag, nsStyleContext};
use gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT;
use gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT;
use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
use gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES;
-use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
-use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme;
use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::{ComputedValues, parse_style_attribute};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
@@ -216,39 +214,24 @@ impl<'ln> GeckoNode<'ln> {
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_GetFlattenedTreeParentNode(self.0).map(GeckoNode) }
}
}
- /// This logic is duplicated in Gecko's nsIContent::IsRootOfNativeAnonymousSubtree.
- fn is_root_of_native_anonymous_subtree(&self) -> bool {
- use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS_ROOT;
- return self.flags() & (NODE_IS_NATIVE_ANONYMOUS_ROOT as u32) != 0
- }
-
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_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> {
#[inline]
fn is_element(&self) -> bool {
self.get_bool_flag(nsINode_BooleanFlag::NodeIsElement)
}
@@ -284,17 +267,17 @@ impl<'ln> TNode for GeckoNode<'ln> {
}
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 self.is_in_anonymous_subtree() ||
+ 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));
}
}
@@ -726,20 +709,49 @@ impl<'le> GeckoElement<'le> {
restyle_data.hint.insert(restyle_hint.into());
restyle_data.damage |= damage;
} else {
debug!("(Element not styled, discarding hints)");
}
}
/// This logic is duplicated in Gecko's nsIContent::IsRootOfAnonymousSubtree.
+ #[inline]
fn is_root_of_anonymous_subtree(&self) -> bool {
use gecko_bindings::structs::NODE_IS_ANONYMOUS_ROOT;
self.flags() & (NODE_IS_ANONYMOUS_ROOT as u32) != 0
}
+
+ /// This logic is duplicated in Gecko's nsIContent::IsRootOfNativeAnonymousSubtree.
+ #[inline]
+ fn is_root_of_native_anonymous_subtree(&self) -> bool {
+ use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS_ROOT;
+ return self.flags() & (NODE_IS_NATIVE_ANONYMOUS_ROOT as u32) != 0
+ }
+
+ /// This logic is duplicated in Gecko's nsINode::IsInNativeAnonymousSubtree.
+ #[inline]
+ fn is_in_native_anonymous_subtree(&self) -> bool {
+ use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
+ self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) != 0
+ }
+
+ /// This logic is duplicate in Gecko's nsIContent::IsInShadowTree().
+ #[inline]
+ fn is_in_shadow_tree(&self) -> bool {
+ use gecko_bindings::structs::NODE_IS_IN_SHADOW_TREE;
+ self.flags() & (NODE_IS_IN_SHADOW_TREE as u32) != 0
+ }
+
+ /// This logic is duplicated in Gecko's nsIContent::IsInAnonymousSubtree.
+ #[inline]
+ fn is_in_anonymous_subtree(&self) -> bool {
+ self.is_in_native_anonymous_subtree() ||
+ (!self.is_in_shadow_tree() && self.has_xbl_binding_parent())
+ }
}
/// Converts flags from the layout used by rust-selectors to the layout used
/// by Gecko. We could align these and then do this without conditionals, but
/// it's probably not worth the trouble.
fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 {
use gecko_bindings::structs::*;
use selectors::matching::*;
@@ -1066,16 +1078,17 @@ impl<'le> TElement for GeckoElement<'le>
}
fn is_visited_link(&self) -> bool {
use element_state::IN_VISITED_STATE;
self.get_state().intersects(IN_VISITED_STATE)
}
fn is_native_anonymous(&self) -> bool {
+ use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
self.flags() & (NODE_IS_NATIVE_ANONYMOUS as u32) != 0
}
fn implemented_pseudo_element(&self) -> Option<PseudoElement> {
if !self.is_native_anonymous() {
return None;
}
@@ -1239,17 +1252,17 @@ impl<'le> TElement for GeckoElement<'le>
if !binding.inherits_style() {
// Go no further; we're not inheriting style from
// anything above here.
break;
}
}
}
- if element.as_node().is_root_of_native_anonymous_subtree() {
+ if element.is_root_of_native_anonymous_subtree() {
// Deliberately cut off style inheritance here.
break;
}
current = element.get_xbl_binding_parent();
}
// If current has something, this means we cut off inheritance at some
@@ -2011,11 +2024,11 @@ impl<'a> NamespaceConstraintHelpers for
NamespaceConstraint::Specific(ref ns) => ns.0.as_ptr(),
}
}
}
impl<'le> ElementExt for GeckoElement<'le> {
#[inline]
fn matches_user_and_author_rules(&self) -> bool {
- self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) == 0
+ !self.is_in_native_anonymous_subtree()
}
}