mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
style: Implement selector-matching for ::part().
Also fairly straight-forward. This may get more complicated when we do part forwarding, if any. I've opened https://github.com/w3c/csswg-drafts/issues/3841 in what I think would be a cleaner model for forwarding. Differential Revision: https://phabricator.services.mozilla.com/D28063
This commit is contained in:
parent
a23ad3be50
commit
627514b737
4 changed files with 40 additions and 12 deletions
|
@ -183,13 +183,23 @@ impl ElementSnapshot for GeckoElementSnapshot {
|
||||||
snapshot_helpers::get_id(&*self.mAttrs)
|
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]
|
#[inline]
|
||||||
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
||||||
if !self.has_any(Flags::MaybeClass) {
|
if !self.has_any(Flags::MaybeClass) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot_helpers::has_class(name, case_sensitivity, &self.mClass)
|
snapshot_helpers::has_class_or_part(name, case_sensitivity, &self.mClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -29,7 +29,7 @@ unsafe fn ptr<T>(attr: &structs::nsAttrValue) -> *const T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[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));
|
debug_assert!(bindings::Gecko_AssertClassAttrValueIsSane(attr));
|
||||||
let base_type = base_type(attr);
|
let base_type = base_type(attr);
|
||||||
if base_type == structs::nsAttrValue_ValueBaseType_eStringBase {
|
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"))?) })
|
Some(unsafe { get_id_from_attr(find_attr(attrs, &atom!("id"))?) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a class name, a case sensitivity, and an array of attributes, returns
|
/// Given a class or part name, a case sensitivity, and an array of attributes,
|
||||||
/// whether the class has the attribute that name represents.
|
/// returns whether the attribute has that name.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn has_class(
|
pub fn has_class_or_part(
|
||||||
name: &Atom,
|
name: &Atom,
|
||||||
case_sensitivity: CaseSensitivity,
|
case_sensitivity: CaseSensitivity,
|
||||||
attr: &structs::nsAttrValue,
|
attr: &structs::nsAttrValue,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match unsafe { get_class_from_attr(attr) } {
|
match unsafe { get_class_or_part_from_attr(attr) } {
|
||||||
Class::None => false,
|
Class::None => false,
|
||||||
Class::One(atom) => unsafe { case_sensitivity.eq_atom(name, WeakAtom::new(atom)) },
|
Class::One(atom) => unsafe { case_sensitivity.eq_atom(name, WeakAtom::new(atom)) },
|
||||||
Class::More(atoms) => match case_sensitivity {
|
Class::More(atoms) => match case_sensitivity {
|
||||||
|
@ -114,7 +114,7 @@ where
|
||||||
F: FnMut(&Atom),
|
F: FnMut(&Atom),
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
match get_class_from_attr(attr) {
|
match get_class_or_part_from_attr(attr) {
|
||||||
Class::None => {},
|
Class::None => {},
|
||||||
Class::One(atom) => Atom::with(atom, callback),
|
Class::One(atom) => Atom::with(atom, callback),
|
||||||
Class::More(atoms) => {
|
Class::More(atoms) => {
|
||||||
|
|
|
@ -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)]
|
#[inline(always)]
|
||||||
fn get_class_attr(&self) -> Option<&structs::nsAttrValue> {
|
fn get_class_attr(&self) -> Option<&structs::nsAttrValue> {
|
||||||
if !self.may_have_class() {
|
if !self.may_have_class() {
|
||||||
|
@ -2259,8 +2264,14 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
case_sensitivity.eq_atom(element_id, id)
|
case_sensitivity.eq_atom(element_id, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_part(&self, _name: &Atom) -> bool {
|
#[inline]
|
||||||
unimplemented!();
|
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)]
|
#[inline(always)]
|
||||||
|
@ -2270,7 +2281,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
snapshot_helpers::has_class(name, case_sensitivity, attr)
|
snapshot_helpers::has_class_or_part(name, case_sensitivity, attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -58,6 +58,10 @@ pub trait ElementSnapshot: Sized {
|
||||||
/// if `has_attrs()` returns true.
|
/// if `has_attrs()` returns true.
|
||||||
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool;
|
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
|
/// A callback that should be called for each class of the snapshot. Should
|
||||||
/// only be called if `has_attrs()` returns true.
|
/// only be called if `has_attrs()` returns true.
|
||||||
fn each_class<F>(&self, _: F)
|
fn each_class<F>(&self, _: F)
|
||||||
|
@ -340,8 +344,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_part(&self, _name: &Atom) -> bool {
|
fn is_part(&self, name: &Atom) -> bool {
|
||||||
unimplemented!();
|
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 {
|
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue