style: Allow to export a shadow part under multiple names.

Other browsers allow this and the spec doesn't really disallow it, so fix it,
add a test and carry on.

Differential Revision: https://phabricator.services.mozilla.com/D65107
This commit is contained in:
Emilio Cobos Álvarez 2020-03-09 13:04:21 +00:00
parent 614d3e746f
commit 635f5fbf1b
8 changed files with 46 additions and 46 deletions

View file

@ -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: &<Self::Impl as SelectorImpl>::PartName,
) -> Option<<Self::Impl as SelectorImpl>::PartName>;
/// Returns the mapping from the `exportparts` attribute in the reverse
/// direction, that is, in an outer-tree -> inner-tree direction.
fn imported_part(

View file

@ -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<F>(&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

View file

@ -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<Atom> {
snapshot_helpers::exported_part(&*self.mAttrs, name)
}
#[inline]
fn imported_part(&self, name: &Atom) -> Option<Atom> {
snapshot_helpers::imported_part(&*self.mAttrs, name)

View file

@ -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<Atom> {
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)]

View file

@ -1281,6 +1281,14 @@ impl<'le> TElement for GeckoElement<'le> {
snapshot_helpers::each_class_or_part(attr, callback)
}
#[inline]
fn each_exported_part<F>(&self, name: &Atom, callback: F)
where
F: FnMut(&Atom),
{
snapshot_helpers::each_exported_part(self.attrs(), name, callback)
}
fn each_part<F>(&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<Atom> {
snapshot_helpers::exported_part(self.attrs(), name)
}
#[inline]
fn imported_part(&self, name: &Atom) -> Option<Atom> {
snapshot_helpers::imported_part(self.attrs(), name)

View file

@ -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<Atom>;
/// See Element::imported_part.
fn imported_part(&self, name: &Atom) -> Option<Atom>;
@ -371,13 +368,6 @@ where
}
}
fn exported_part(&self, name: &Atom) -> Option<Atom> {
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<Atom> {
match self.snapshot() {
Some(snapshot) if snapshot.has_attrs() => snapshot.imported_part(name),

View file

@ -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;
}
}

View file

@ -709,10 +709,6 @@ impl ElementSnapshot for ServoElementSnapshot {
false
}
fn exported_part(&self, _: &Atom) -> Option<Atom> {
None
}
fn imported_part(&self, _: &Atom) -> Option<Atom> {
None
}