Bug 1449089 part 1 - Make :-moz-native-anonymous and :-moz-use-shadow-tree-root matches in Rust code. r?emilio
:-moz-native-anonymous can just use is_in_native_anonymous_subtree()
which is an existing function duplicating IsInNativeAnonymousSubtree().
IsRootOfUseElementShadowTree() in C++ code only has a single reference
from nsCSSPseudoClasses::MatchesElement() so we can just move it to the
Rust side. And actually Rust code has existing duplicate logic for
blocks_ancestor_combinators().
MozReview-Commit-ID: 8M1hHrYJT6Y
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -241,24 +241,16 @@ public:
NS_ASSERTION(!IsInNativeAnonymousSubtree() || GetBindingParent() ||
(!IsInUncomposedDoc() &&
static_cast<nsIContent*>(SubtreeRoot())->IsInNativeAnonymousSubtree()),
"Must have binding parent when in native anonymous subtree which is in document.\n"
"Native anonymous subtree which is not in document must have native anonymous root.");
return IsInNativeAnonymousSubtree() || (!IsInShadowTree() && GetBindingParent() != nullptr);
}
- /*
- * Return true if this node is the shadow root of an use-element shadow tree.
- */
- bool IsRootOfUseElementShadowTree() const {
- return GetParent() && GetParent()->IsSVGElement(nsGkAtoms::use) &&
- IsRootOfAnonymousSubtree();
- }
-
/**
* Return true iff this node is in an HTML document (in the HTML5 sense of
* the term, i.e. not in an XHTML/XML document).
*/
inline bool IsInHTMLDocument() const;
/**
--- a/layout/style/nsCSSPseudoClasses.cpp
+++ b/layout/style/nsCSSPseudoClasses.cpp
@@ -290,20 +290,16 @@ nsCSSPseudoClasses::StringPseudoMatches(
}
return true;
}
/* static */ Maybe<bool>
nsCSSPseudoClasses::MatchesElement(Type aType, const dom::Element* aElement)
{
switch (aType) {
- case CSSPseudoClassType::mozNativeAnonymous:
- return Some(aElement->IsInNativeAnonymousSubtree());
- case CSSPseudoClassType::mozUseShadowTreeRoot:
- return Some(aElement->IsRootOfUseElementShadowTree());
case CSSPseudoClassType::mozTableBorderNonzero: {
if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
return Some(false);
}
const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
return Some(val && (val->Type() != nsAttrValue::eInteger ||
val->GetIntegerValue() != 0));
}
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -809,16 +809,31 @@ impl<'le> GeckoElement<'le> {
/// This logic is duplicated in Gecko's nsIContent::IsInAnonymousSubtree.
#[inline]
fn is_in_anonymous_subtree(&self) -> bool {
self.is_in_native_anonymous_subtree() ||
(!self.as_node().is_in_shadow_tree() && self.has_xbl_binding_parent())
}
+ /// Returns true if this node is the shadow root of an use-element shadow tree.
+ #[inline]
+ fn is_root_of_use_element_shadow_tree(&self) -> bool {
+ if !self.is_root_of_anonymous_subtree() {
+ return false
+ }
+ match self.parent_element() {
+ Some(e) => {
+ e.local_name() == &*local_name!("use") &&
+ e.namespace() == &*ns!("http://www.w3.org/2000/svg")
+ },
+ None => false,
+ }
+ }
+
fn css_transitions_info(&self) -> FnvHashMap<LonghandId, Arc<AnimationValue>> {
use gecko_bindings::bindings::Gecko_ElementTransitions_EndValueAt;
use gecko_bindings::bindings::Gecko_ElementTransitions_Length;
let collection_length =
unsafe { Gecko_ElementTransitions_Length(self.0) } as usize;
let mut map = FnvHashMap::with_capacity_and_hasher(
collection_length,
@@ -2098,20 +2113,24 @@ impl<'le> ::selectors::Element for Gecko
}
NonTSPseudoClass::MozOnlyWhitespace => {
flags_setter(self, ElementSelectorFlags::HAS_EMPTY_SELECTOR);
if self.as_node().dom_children().any(|c| c.contains_non_whitespace_content()) {
return false
}
true
}
+ NonTSPseudoClass::MozNativeAnonymous => {
+ self.is_in_native_anonymous_subtree()
+ }
+ NonTSPseudoClass::MozUseShadowTreeRoot => {
+ self.is_root_of_use_element_shadow_tree()
+ }
NonTSPseudoClass::MozTableBorderNonzero |
- NonTSPseudoClass::MozBrowserFrame |
- NonTSPseudoClass::MozNativeAnonymous |
- NonTSPseudoClass::MozUseShadowTreeRoot => unsafe {
+ NonTSPseudoClass::MozBrowserFrame => unsafe {
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
},
NonTSPseudoClass::MozIsHTML => {
self.is_html_element_in_html_document()
}
NonTSPseudoClass::MozLWTheme => {
self.document_theme() != DocumentTheme::Doc_Theme_None
}
@@ -2230,30 +2249,20 @@ impl<'le> ::selectors::Element for Gecko
#[inline]
fn ignores_nth_child_selectors(&self) -> bool {
self.is_root_of_anonymous_subtree()
}
#[inline]
fn blocks_ancestor_combinators(&self) -> bool {
- if !self.is_root_of_anonymous_subtree() {
- return false
- }
-
- match self.parent_element() {
- Some(e) => {
- // If this element is the shadow root of an use-element shadow
- // tree, according to the spec, we should not match rules
- // cross the shadow DOM boundary.
- e.local_name() == &*local_name!("use") &&
- e.namespace() == &*ns!("http://www.w3.org/2000/svg")
- },
- None => false,
- }
+ // If this element is the shadow root of an use-element shadow tree,
+ // according to the spec, we should not match rules cross the shadow
+ // DOM boundary.
+ self.is_root_of_use_element_shadow_tree()
}
}
/// A few helpers to help with attribute selectors and snapshotting.
pub trait NamespaceConstraintHelpers {
/// Returns the namespace of the selector, or null otherwise.
fn atom_or_null(&self) -> *mut nsAtom;
}