Bug 1425755: Implement GeckoElement::assigned_slot. r?heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sun, 17 Dec 2017 14:44:53 +0100
changeset 712564 9bbfbd5126023e1cf530a20a38e7a4b227a5ed62
parent 712557 85feedb9054af0ddefa5cc3e3eac5a254da79c52
child 712565 91b47f0a6fb572937add318ef14a578643226ce4
child 712566 3676ad0f8f6a5382e8015c7a19be03a4528d214b
push id93366
push userbmo:emilio@crisal.io
push dateSun, 17 Dec 2017 17:03:14 +0000
reviewersheycam
bugs1425755
milestone59.0a1
Bug 1425755: Implement GeckoElement::assigned_slot. r?heycam This allows to selector-match ::slotted. MozReview-Commit-ID: ItELHkf2PMl
layout/style/ServoBindings.toml
servo/components/style/gecko/wrapper.rs
servo/components/style/invalidation/element/element_wrapper.rs
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -51,16 +51,17 @@ headers = [
     "nsStyleStruct.h",
     "mozilla/ServoPropPrefList.h",
     "mozilla/StyleAnimationValue.h",
     "gfxFontConstants.h",
     "gfxFontFeatures.h",
     "nsThemeConstants.h",
     "mozilla/css/Loader.h",
     "mozilla/dom/AnimationEffectReadOnlyBinding.h",
+    "mozilla/dom/HTMLSlotElement.h",
     "mozilla/dom/KeyframeEffectBinding.h",
     "mozilla/AnimationPropertySegment.h",
     "mozilla/ComputedTiming.h",
     "mozilla/ComputedTimingFunction.h",
     "mozilla/Keyframe.h",
     "mozilla/ServoElementSnapshot.h",
     "mozilla/ServoElementSnapshotTable.h",
     "mozilla/css/ErrorReporter.h",
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -1791,22 +1791,32 @@ impl<'le> ::selectors::Element for Gecko
     #[inline]
     fn parent_element(&self) -> Option<Self> {
         // FIXME(emilio): This will need to jump across if the parent node is a
         // shadow root to get the shadow host.
         let parent_node = self.as_node().parent_node();
         parent_node.and_then(|n| n.as_element())
     }
 
+    #[inline]
     fn pseudo_element_originating_element(&self) -> Option<Self> {
         debug_assert!(self.implemented_pseudo_element().is_some());
         self.closest_non_native_anonymous_ancestor()
     }
 
     #[inline]
+    fn assigned_slot(&self) -> Option<Self> {
+        let slot = self.get_extended_slots()?.mAssignedSlot.mRawPtr;
+
+        unsafe {
+            Some(GeckoElement(&slot.as_ref()?._base._base._base._base))
+        }
+    }
+
+    #[inline]
     fn first_child_element(&self) -> Option<Self> {
         let mut child = self.as_node().first_child();
         while let Some(child_node) = child {
             if let Some(el) = child_node.as_element() {
                 return Some(el)
             }
             child = child_node.next_sibling();
         }
--- a/servo/components/style/invalidation/element/element_wrapper.rs
+++ b/servo/components/style/invalidation/element/element_wrapper.rs
@@ -346,12 +346,17 @@ impl<'a, E> Element for ElementWrapper<'
         self.element.is_root()
     }
 
     fn pseudo_element_originating_element(&self) -> Option<Self> {
         self.element.pseudo_element_originating_element()
             .map(|e| ElementWrapper::new(e, self.snapshot_map))
     }
 
+    fn assigned_slot(&self) -> Option<Self> {
+        self.element.assigned_slot()
+            .map(|e| ElementWrapper::new(e, self.snapshot_map))
+    }
+
     fn blocks_ancestor_combinators(&self) -> bool {
         self.element.blocks_ancestor_combinators()
     }
 }