diff --git a/components/selectors/tree.rs b/components/selectors/tree.rs index d6198c5a5f5..ac90fa1f00c 100644 --- a/components/selectors/tree.rs +++ b/components/selectors/tree.rs @@ -117,13 +117,6 @@ pub trait Element: Sized + Clone + Debug { case_sensitivity: CaseSensitivity, ) -> bool; - /// Returns the mapping from the `exportparts` attribute in the regular - /// direction, that is, inner-tree -> outer-tree. - fn exported_part( - &self, - name: &::PartName, - ) -> Option<::PartName>; - /// Returns the mapping from the `exportparts` attribute in the reverse /// direction, that is, in an outer-tree -> inner-tree direction. fn imported_part( diff --git a/components/style/dom.rs b/components/style/dom.rs index d07cac998ae..c1c1f74ef68 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -522,6 +522,14 @@ pub trait TElement: { } + /// Internal iterator for the part names that this element exports for a + /// given part name. + fn each_exported_part(&self, _name: &Atom, _callback: F) + where + F: FnMut(&Atom), + { + } + /// Whether a given element may generate a pseudo-element. /// /// This is useful to avoid computing, for example, pseudo styles for diff --git a/components/style/gecko/snapshot.rs b/components/style/gecko/snapshot.rs index fa9914f6222..b2a66f709e2 100644 --- a/components/style/gecko/snapshot.rs +++ b/components/style/gecko/snapshot.rs @@ -193,11 +193,6 @@ impl ElementSnapshot for GeckoElementSnapshot { snapshot_helpers::has_class_or_part(name, CaseSensitivity::CaseSensitive, attr) } - #[inline] - fn exported_part(&self, name: &Atom) -> Option { - snapshot_helpers::exported_part(&*self.mAttrs, name) - } - #[inline] fn imported_part(&self, name: &Atom) -> Option { snapshot_helpers::imported_part(&*self.mAttrs, name) diff --git a/components/style/gecko/snapshot_helpers.rs b/components/style/gecko/snapshot_helpers.rs index cb3056e7bd5..f65fe55d8ff 100644 --- a/components/style/gecko/snapshot_helpers.rs +++ b/components/style/gecko/snapshot_helpers.rs @@ -83,16 +83,32 @@ pub fn get_id(attrs: &[structs::AttrArray_InternalAttr]) -> Option<&WeakAtom> { } #[inline(always)] -pub(super) fn exported_part( +pub(super) fn each_exported_part( attrs: &[structs::AttrArray_InternalAttr], name: &Atom, -) -> Option { - let attr = find_attr(attrs, &atom!("exportparts"))?; - let atom = unsafe { bindings::Gecko_Element_ExportedPart(attr, name.as_ptr()) }; - if atom.is_null() { - return None; + mut callback: impl FnMut(&Atom), +) { + let attr = match find_attr(attrs, &atom!("exportparts")) { + Some(attr) => attr, + None => return, + }; + let mut length = 0; + let atoms = unsafe { + bindings::Gecko_Element_ExportedParts( + attr, + name.as_ptr(), + &mut length, + ) + }; + if atoms.is_null() { + return; + } + + unsafe { + for atom in std::slice::from_raw_parts(atoms, length) { + Atom::with(*atom, &mut callback) + } } - Some(unsafe { Atom::from_raw(atom) }) } #[inline(always)] diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 7071c818579..337e6999fa7 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1281,6 +1281,14 @@ impl<'le> TElement for GeckoElement<'le> { snapshot_helpers::each_class_or_part(attr, callback) } + #[inline] + fn each_exported_part(&self, name: &Atom, callback: F) + where + F: FnMut(&Atom), + { + snapshot_helpers::each_exported_part(self.attrs(), name, callback) + } + fn each_part(&self, callback: F) where F: FnMut(&Atom), @@ -2226,11 +2234,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { snapshot_helpers::has_class_or_part(name, CaseSensitivity::CaseSensitive, attr) } - #[inline] - fn exported_part(&self, name: &Atom) -> Option { - snapshot_helpers::exported_part(self.attrs(), name) - } - #[inline] fn imported_part(&self, name: &Atom) -> Option { snapshot_helpers::imported_part(self.attrs(), name) diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index bc74527bf16..1154c136165 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -62,9 +62,6 @@ pub trait ElementSnapshot: Sized { /// called if `has_attrs()` returns true. fn is_part(&self, name: &Atom) -> bool; - /// See Element::exported_part. - fn exported_part(&self, name: &Atom) -> Option; - /// See Element::imported_part. fn imported_part(&self, name: &Atom) -> Option; @@ -371,13 +368,6 @@ where } } - fn exported_part(&self, name: &Atom) -> Option { - match self.snapshot() { - Some(snapshot) if snapshot.has_attrs() => snapshot.exported_part(name), - _ => self.element.exported_part(name), - } - } - fn imported_part(&self, name: &Atom) -> Option { match self.snapshot() { Some(snapshot) if snapshot.has_attrs() => snapshot.imported_part(name), diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs index 9841eb9e70f..7b7b0b48787 100644 --- a/components/style/rule_collector.rs +++ b/components/style/rule_collector.rs @@ -393,14 +393,13 @@ where None => break, // Nowhere to export to. }; - parts.retain(|part| { - let exported_part = match inner_shadow_host.exported_part(part) { - Some(part) => part, - None => return false, - }; - std::mem::replace(part, exported_part); - true - }); + let mut new_parts = SmallVec::new(); + for part in &parts { + inner_shadow_host.each_exported_part(part, |exported_part| { + new_parts.push(exported_part.clone()); + }); + } + parts = new_parts; } } diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 599b603f4ff..2537cae9f83 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -709,10 +709,6 @@ impl ElementSnapshot for ServoElementSnapshot { false } - fn exported_part(&self, _: &Atom) -> Option { - None - } - fn imported_part(&self, _: &Atom) -> Option { None }