diff --git a/components/style/gecko/snapshot.rs b/components/style/gecko/snapshot.rs index 6ac4003fa25..d294939baeb 100644 --- a/components/style/gecko/snapshot.rs +++ b/components/style/gecko/snapshot.rs @@ -183,13 +183,23 @@ impl ElementSnapshot for GeckoElementSnapshot { snapshot_helpers::get_id(&*self.mAttrs) } + #[inline] + fn is_part(&self, name: &Atom) -> bool { + let attr = match snapshot_helpers::find_attr(&*self.mAttrs, &atom!("part")) { + Some(attr) => attr, + None => return false, + }; + + snapshot_helpers::has_class_or_part(name, CaseSensitivity::CaseSensitive, attr) + } + #[inline] fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { if !self.has_any(Flags::MaybeClass) { return false; } - snapshot_helpers::has_class(name, case_sensitivity, &self.mClass) + snapshot_helpers::has_class_or_part(name, case_sensitivity, &self.mClass) } #[inline] diff --git a/components/style/gecko/snapshot_helpers.rs b/components/style/gecko/snapshot_helpers.rs index 0eb84830546..aaa2254dbd7 100644 --- a/components/style/gecko/snapshot_helpers.rs +++ b/components/style/gecko/snapshot_helpers.rs @@ -29,7 +29,7 @@ unsafe fn ptr(attr: &structs::nsAttrValue) -> *const T { } #[inline(always)] -unsafe fn get_class_from_attr(attr: &structs::nsAttrValue) -> Class { +unsafe fn get_class_or_part_from_attr(attr: &structs::nsAttrValue) -> Class { debug_assert!(bindings::Gecko_AssertClassAttrValueIsSane(attr)); let base_type = base_type(attr); if base_type == structs::nsAttrValue_ValueBaseType_eStringBase { @@ -82,15 +82,15 @@ pub fn get_id(attrs: &[structs::AttrArray_InternalAttr]) -> Option<&WeakAtom> { Some(unsafe { get_id_from_attr(find_attr(attrs, &atom!("id"))?) }) } -/// Given a class name, a case sensitivity, and an array of attributes, returns -/// whether the class has the attribute that name represents. +/// Given a class or part name, a case sensitivity, and an array of attributes, +/// returns whether the attribute has that name. #[inline(always)] -pub fn has_class( +pub fn has_class_or_part( name: &Atom, case_sensitivity: CaseSensitivity, attr: &structs::nsAttrValue, ) -> bool { - match unsafe { get_class_from_attr(attr) } { + match unsafe { get_class_or_part_from_attr(attr) } { Class::None => false, Class::One(atom) => unsafe { case_sensitivity.eq_atom(name, WeakAtom::new(atom)) }, Class::More(atoms) => match case_sensitivity { @@ -114,7 +114,7 @@ where F: FnMut(&Atom), { unsafe { - match get_class_from_attr(attr) { + match get_class_or_part_from_attr(attr) { Class::None => {}, Class::One(atom) => Atom::with(atom, callback), Class::More(atoms) => { diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index f88e30ab777..9d987c56308 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -573,6 +573,11 @@ impl<'le> GeckoElement<'le> { } } + #[inline(always)] + fn get_part_attr(&self) -> Option<&structs::nsAttrValue> { + snapshot_helpers::find_attr(self.attrs(), &atom!("part")) + } + #[inline(always)] fn get_class_attr(&self) -> Option<&structs::nsAttrValue> { if !self.may_have_class() { @@ -2259,8 +2264,14 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { case_sensitivity.eq_atom(element_id, id) } - fn is_part(&self, _name: &Atom) -> bool { - unimplemented!(); + #[inline] + fn is_part(&self, name: &Atom) -> bool { + let attr = match self.get_part_attr() { + Some(c) => c, + None => return false, + }; + + snapshot_helpers::has_class_or_part(name, CaseSensitivity::CaseSensitive, attr) } #[inline(always)] @@ -2270,7 +2281,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { None => return false, }; - snapshot_helpers::has_class(name, case_sensitivity, attr) + snapshot_helpers::has_class_or_part(name, case_sensitivity, attr) } #[inline] diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index 114cdc9cd8a..6e8e504c226 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -58,6 +58,10 @@ pub trait ElementSnapshot: Sized { /// if `has_attrs()` returns true. fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool; + /// Whether this snapshot represents the part named `name`. Should only be + /// called if `has_attrs()` returns true. + fn is_part(&self, name: &Atom) -> bool; + /// A callback that should be called for each class of the snapshot. Should /// only be called if `has_attrs()` returns true. fn each_class(&self, _: F) @@ -340,8 +344,11 @@ where } } - fn is_part(&self, _name: &Atom) -> bool { - unimplemented!(); + fn is_part(&self, name: &Atom) -> bool { + match self.snapshot() { + Some(snapshot) if snapshot.has_attrs() => snapshot.is_part(name), + _ => self.element.is_part(name), + } } fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {