Bug 1449089 part 1 - Make :-moz-native-anonymous and :-moz-use-shadow-tree-root matches in Rust code. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Tue, 27 Mar 2018 18:50:44 +1100
changeset 773117 6765099c053e2b5a13643520b55c2bbca565d2f6
parent 773102 d9ae6153f8221920c65414ed1f99f00848630a7b
child 773118 3d7d778124385df0f01b27ca58146c35ba03b800
push id104128
push userxquan@mozilla.com
push dateTue, 27 Mar 2018 11:22:14 +0000
reviewersemilio
bugs1449089
milestone61.0a1
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
dom/base/nsIContent.h
layout/style/nsCSSPseudoClasses.cpp
servo/components/style/gecko/wrapper.rs
--- 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;
 }