Bug 265894 - Part 6. (Stylo) Fix counterpart of Part 2 and Part 4 in stylo draft
authorcku <cku@mozilla.com>
Tue, 13 Jun 2017 16:19:39 +0800
changeset 593196 95a78ac8a5c45a748ae4761f4fccd2d34ad692bc
parent 593195 20c2da279ab4334fc2a9bcaeba87b1fee6bb77a7
child 633047 3690365c7dcfb95384f79497cbff0086d6a3b984
push id63626
push userbmo:cku@mozilla.com
push dateTue, 13 Jun 2017 09:27:54 +0000
bugs265894
milestone55.0a1
Bug 265894 - Part 6. (Stylo) Fix counterpart of Part 2 and Part 4 in stylo MozReview-Commit-ID: Jg2r5Zwcijo
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
servo/components/selectors/matching.rs
servo/components/selectors/tree.rs
servo/components/style/gecko/wrapper.rs
servo/components/style/restyle_hints.rs
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -180,17 +180,17 @@ Gecko_GetLastChild(RawGeckoNodeBorrowed 
   return aNode->GetLastChild();
 }
 
 RawGeckoNodeBorrowedOrNull
 Gecko_GetPrevSibling(RawGeckoNodeBorrowed aNode)
 {
   return aNode->GetPreviousSibling();
 }
-
+  
 RawGeckoNodeBorrowedOrNull
 Gecko_GetNextSibling(RawGeckoNodeBorrowed aNode)
 {
   return aNode->GetNextSibling();
 }
 
 RawGeckoElementBorrowedOrNull
 Gecko_GetParentElement(RawGeckoElementBorrowed aElement)
@@ -774,16 +774,41 @@ Gecko_GetXMLLangValue(RawGeckoElementBor
 {
   nsString string;
   if (aElement->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang, string)) {
     return NS_Atomize(string).take();
   }
   return nullptr;
 }
 
+nsIAtom* Gecko_GetTagName(RawGeckoElementBorrowed aElement)
+{
+  return aElement->GetTagNameAtom();
+}
+
+RawGeckoElementBorrowedOrNull
+Gecko_GetParentInsideUseElementShadowTree(RawGeckoNodeBorrowed aNode)
+{
+    if (!aNode->IsElement()) {
+    return nullptr;
+  }
+
+  nsIContent* parent = aNode->AsElement()->GetParentInsideUseElementShadowTree();
+  return parent ? parent->AsElement() : nullptr;
+}
+
+bool Gecko_IsAnonymousContentInSVGUseSubtree(RawGeckoNodeBorrowed aNode)
+{
+  if (!aNode->IsInAnonymousSubtree()) {
+    return false;
+  }
+
+  return aNode->IsAnonymousContentInSVGUseSubtree();
+}
+
 template <typename Implementor>
 static nsIAtom*
 AtomAttrValue(Implementor* aElement, nsIAtom* aName)
 {
   const nsAttrValue* attr = aElement->GetParsedAttr(aName);
   return attr ? attr->GetAtomValue() : nullptr;
 }
 
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -158,17 +158,19 @@ uint64_t Gecko_ElementState(RawGeckoElem
 bool Gecko_IsTextNode(RawGeckoNodeBorrowed node);
 bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
 bool Gecko_MatchesElement(mozilla::CSSPseudoClassType type, RawGeckoElementBorrowed element);
 nsIAtom* Gecko_LocalName(RawGeckoElementBorrowed element);
 nsIAtom* Gecko_Namespace(RawGeckoElementBorrowed element);
 nsIAtom* Gecko_GetElementId(RawGeckoElementBorrowed element);
 
 nsIAtom* Gecko_GetXMLLangValue(RawGeckoElementBorrowed element);
-
+nsIAtom* Gecko_GetTagName(RawGeckoElementBorrowed element);
+bool Gecko_IsAnonymousContentInSVGUseSubtree(RawGeckoNodeBorrowed node);
+RawGeckoElementBorrowedOrNull Gecko_GetParentInsideUseElementShadowTree(RawGeckoNodeBorrowed node);
 // Attributes.
 #define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_)  \
   nsIAtom* prefix_##AtomAttrValue(implementor_ element, nsIAtom* attribute);  \
   bool prefix_##HasAttr(implementor_ element, nsIAtom* ns, nsIAtom* name);    \
   bool prefix_##AttrEquals(implementor_ element, nsIAtom* ns, nsIAtom* name,  \
                            nsIAtom* str, bool ignoreCase);                    \
   bool prefix_##AttrDashEquals(implementor_ element, nsIAtom* ns,             \
                                nsIAtom* name, nsIAtom* str);                  \
--- a/servo/components/selectors/matching.rs
+++ b/servo/components/selectors/matching.rs
@@ -435,18 +435,23 @@ fn matches_complex_selector_internal<E, 
                 Combinator::NextSibling | Combinator::LaterSibling => {
                     // Only ancestor combinators are allowed while looking for
                     // relevant links, so switch to not looking.
                     relevant_link = RelevantLinkStatus::NotLooking;
                     (element.prev_sibling_element(),
                      SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant)
                 }
                 Combinator::Child | Combinator::Descendant => {
-                    (element.parent_element(),
-                     SelectorMatchingResult::NotMatchedGlobally)
+                    if element.is_in_use_element_shadow_tree() {
+                        (element.parent_element_in_use_element_tree(),
+                         SelectorMatchingResult::NotMatchedGlobally)
+                    } else {
+                        (element.parent_element(),
+                         SelectorMatchingResult::NotMatchedGlobally)
+                    }
                 }
                 Combinator::PseudoElement => {
                     (element.pseudo_element_originating_element(),
                      SelectorMatchingResult::NotMatchedGlobally)
                 }
             };
 
             loop {
@@ -484,17 +489,21 @@ fn matches_complex_selector_internal<E, 
                     // or the Combinator::LaterSibling combinator and the status is
                     // NotMatchedAndRestartFromClosestDescendant
                     // can continue to matching on the next candidate element.
                     _ => {},
                 }
                 next_element = if siblings {
                     element.prev_sibling_element()
                 } else {
-                    element.parent_element()
+                    if element.is_in_use_element_shadow_tree() {
+                        element.parent_element_in_use_element_tree()
+                    } else {
+                        element.parent_element()
+                    }
                 };
             }
         }
     }
 }
 
 /// Determines whether the given element matches the given single selector.
 #[inline]
--- a/servo/components/selectors/tree.rs
+++ b/servo/components/selectors/tree.rs
@@ -9,16 +9,23 @@ use attr::{AttrSelectorOperation, Namesp
 use matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus};
 use parser::SelectorImpl;
 
 pub trait Element: Sized {
     type Impl: SelectorImpl;
 
     fn parent_element(&self) -> Option<Self>;
 
+    /// Whether this element in inside of an use-element shadow tree.
+    fn is_in_use_element_shadow_tree(&self) -> bool;
+
+    /// Get parent of this element inside an use-element shadow tree.
+    /// Can/should be used only if is_in_use_element_shadow_tree return true.
+    fn parent_element_in_use_element_tree(&self) -> Option<Self>;
+
     /// The parent of a given pseudo-element, after matching a pseudo-element
     /// selector.
     ///
     /// This is guaranteed to be called in a pseudo-element.
     fn pseudo_element_originating_element(&self) -> Option<Self> {
         self.parent_element()
     }
 
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -24,17 +24,17 @@ use element_state::ElementState;
 use error_reporting::RustLogReporter;
 use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
 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_ElementState, Gecko_GetLastChild, Gecko_GetNextStyleChild};
-use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_Namespace};
+use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement, Gecko_Namespace, Gecko_GetTagName, Gecko_IsAnonymousContentInSVGUseSubtree, Gecko_GetParentInsideUseElementShadowTree};
 use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
 use gecko_bindings::bindings::Gecko_ClassOrClassList;
 use gecko_bindings::bindings::Gecko_ElementHasAnimations;
 use gecko_bindings::bindings::Gecko_ElementHasCSSAnimations;
 use gecko_bindings::bindings::Gecko_ElementHasCSSTransitions;
 use gecko_bindings::bindings::Gecko_GetAnimationRule;
 use gecko_bindings::bindings::Gecko_GetExtraContentStyleDeclarations;
 use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
@@ -1127,16 +1127,33 @@ impl<'le> PresentationalHintsSynthesizer
 impl<'le> ::selectors::Element for GeckoElement<'le> {
     type Impl = SelectorImpl;
 
     fn parent_element(&self) -> Option<Self> {
         let parent_node = self.as_node().parent_node();
         parent_node.and_then(|n| n.as_element())
     }
 
+    fn is_in_use_element_shadow_tree(&self) -> bool {
+        unsafe {
+            Gecko_IsAnonymousContentInSVGUseSubtree(self.as_node().0)
+        }
+    }
+
+    fn parent_element_in_use_element_tree(&self) -> Option<Self> {
+        debug_assert!(self.is_in_use_element_shadow_tree());
+
+        unsafe {
+            match Gecko_GetParentInsideUseElementShadowTree(self.as_node().0) {
+                Some(parent) => Some(GeckoElement(parent)),
+                None => None
+            }
+        }
+    }
+
     fn pseudo_element_originating_element(&self) -> Option<Self> {
         debug_assert!(self.implemented_pseudo_element().is_some());
         self.closest_non_native_anonymous_ancestor()
     }
 
     fn first_child_element(&self) -> Option<Self> {
         let mut child = self.as_node().first_child();
         while let Some(child_node) = child {
@@ -1252,17 +1269,17 @@ impl<'le> ::selectors::Element for Gecko
     fn is_empty(&self) -> bool {
         !self.as_node().dom_children().any(|child| unsafe {
             Gecko_IsSignificantChild(child.0, true, true)
         })
     }
 
     fn get_local_name(&self) -> &WeakAtom {
         unsafe {
-            WeakAtom::new(self.as_node().node_info().mInner.mName.raw::<nsIAtom>())
+            WeakAtom::new(Gecko_GetTagName(self.0))
         }
     }
 
     fn get_namespace(&self) -> &WeakNamespace {
         unsafe {
             WeakNamespace::new(Gecko_Namespace(self.0))
         }
     }
--- a/servo/components/style/restyle_hints.rs
+++ b/servo/components/style/restyle_hints.rs
@@ -709,17 +709,22 @@ impl<'a, E> Element for ElementWrapper<'
                                        &RelevantLinkStatus::default(),
                                        &mut |_, _| {})
     }
 
     fn parent_element(&self) -> Option<Self> {
         self.element.parent_element()
             .map(|e| ElementWrapper::new(e, self.snapshot_map))
     }
-
+    fn is_in_use_element_shadow_tree(&self) -> bool {
+        false
+    }
+    fn parent_element_in_use_element_tree(&self) -> Option<Self> {
+        self.parent_element()
+    }
     fn first_child_element(&self) -> Option<Self> {
         self.element.first_child_element()
             .map(|e| ElementWrapper::new(e, self.snapshot_map))
     }
 
     fn last_child_element(&self) -> Option<Self> {
         self.element.last_child_element()
             .map(|e| ElementWrapper::new(e, self.snapshot_map))