mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Move nth-related logic to the NthSelectorData type for reuse
Drive-by, but selector_list_specificity() was also renamed to max_selector_list_specificity(). Differential Revision: https://phabricator.services.mozilla.com/D166263
This commit is contained in:
parent
1c8408e97e
commit
39b056cf70
2 changed files with 50 additions and 42 deletions
|
@ -331,7 +331,7 @@ where
|
|||
// specificity of a regular pseudo-class with that of its
|
||||
// selector argument S.
|
||||
specificity.class_like_selectors += 1;
|
||||
*specificity += selector_list_specificity(nth_of_data.selectors());
|
||||
*specificity += max_selector_list_specificity(nth_of_data.selectors());
|
||||
},
|
||||
Component::Negation(ref list) | Component::Is(ref list) | Component::Has(ref list) => {
|
||||
// https://drafts.csswg.org/selectors/#specificity-rules:
|
||||
|
@ -339,7 +339,7 @@ where
|
|||
// The specificity of an :is(), :not(), or :has() pseudo-class
|
||||
// is replaced by the specificity of the most specific complex
|
||||
// selector in its selector list argument.
|
||||
*specificity += selector_list_specificity(list);
|
||||
*specificity += max_selector_list_specificity(list);
|
||||
},
|
||||
Component::Where(..) |
|
||||
Component::ExplicitUniversalType |
|
||||
|
@ -353,7 +353,7 @@ where
|
|||
}
|
||||
|
||||
/// Finds the maximum specificity of elements in the list and returns it.
|
||||
fn selector_list_specificity<Impl: SelectorImpl>(list: &[Selector<Impl>]) -> Specificity {
|
||||
fn max_selector_list_specificity<Impl: SelectorImpl>(list: &[Selector<Impl>]) -> Specificity {
|
||||
let max = list
|
||||
.iter()
|
||||
.map(|selector| selector.specificity())
|
||||
|
|
|
@ -1124,6 +1124,41 @@ impl NthSelectorData {
|
|||
b: 1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the beginning of the selector.
|
||||
#[inline]
|
||||
fn write_start<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
|
||||
dest.write_str(match self.ty {
|
||||
NthType::Child if self.is_function => ":nth-child(",
|
||||
NthType::Child => ":first-child",
|
||||
NthType::LastChild if self.is_function => ":nth-last-child(",
|
||||
NthType::LastChild => ":last-child",
|
||||
NthType::OfType if self.is_function => ":nth-of-type(",
|
||||
NthType::OfType => ":first-of-type",
|
||||
NthType::LastOfType if self.is_function => ":nth-last-of-type(",
|
||||
NthType::LastOfType => ":last-of-type",
|
||||
NthType::OnlyChild => ":only-child",
|
||||
NthType::OnlyOfType => ":only-of-type",
|
||||
})
|
||||
}
|
||||
|
||||
/// Serialize <an+b> (part of the CSS Syntax spec, but currently only used here).
|
||||
/// <https://drafts.csswg.org/css-syntax-3/#serialize-an-anb-value>
|
||||
#[inline]
|
||||
fn write_affine<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
|
||||
match (self.a, self.b) {
|
||||
(0, 0) => dest.write_char('0'),
|
||||
|
||||
(1, 0) => dest.write_char('n'),
|
||||
(-1, 0) => dest.write_str("-n"),
|
||||
(_, 0) => write!(dest, "{}n", self.a),
|
||||
|
||||
(0, _) => write!(dest, "{}", self.b),
|
||||
(1, _) => write!(dest, "n{:+}", self.b),
|
||||
(-1, _) => write!(dest, "-n{:+}", self.b),
|
||||
(_, _) => write!(dest, "{}n{:+}", self.a, self.b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The properties that comprise an :nth- pseudoclass as of Selectors 4 (e.g.,
|
||||
|
@ -1613,26 +1648,6 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> {
|
|||
{
|
||||
use self::Component::*;
|
||||
|
||||
/// Serialize <an+b> values (part of the CSS Syntax spec, but currently only used here).
|
||||
/// <https://drafts.csswg.org/css-syntax-3/#serialize-an-anb-value>
|
||||
fn write_affine<W>(dest: &mut W, a: i32, b: i32) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
match (a, b) {
|
||||
(0, 0) => dest.write_char('0'),
|
||||
|
||||
(1, 0) => dest.write_char('n'),
|
||||
(-1, 0) => dest.write_str("-n"),
|
||||
(_, 0) => write!(dest, "{}n", a),
|
||||
|
||||
(0, _) => write!(dest, "{}", b),
|
||||
(1, _) => write!(dest, "n{:+}", b),
|
||||
(-1, _) => write!(dest, "-n{:+}", b),
|
||||
(_, _) => write!(dest, "{}n{:+}", a, b),
|
||||
}
|
||||
}
|
||||
|
||||
match *self {
|
||||
Combinator(ref c) => c.to_css(dest),
|
||||
Slotted(ref selector) => {
|
||||
|
@ -1712,32 +1727,25 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> {
|
|||
Ok(())
|
||||
},
|
||||
Nth(ref nth_data) => {
|
||||
dest.write_str(match nth_data.ty {
|
||||
NthType::Child if nth_data.is_function => ":nth-child(",
|
||||
NthType::Child => ":first-child",
|
||||
NthType::LastChild if nth_data.is_function => ":nth-last-child(",
|
||||
NthType::LastChild => ":last-child",
|
||||
NthType::OfType if nth_data.is_function => ":nth-of-type(",
|
||||
NthType::OfType => ":first-of-type",
|
||||
NthType::LastOfType if nth_data.is_function => ":nth-last-of-type(",
|
||||
NthType::LastOfType => ":last-of-type",
|
||||
NthType::OnlyChild => ":only-child",
|
||||
NthType::OnlyOfType => ":only-of-type",
|
||||
})?;
|
||||
nth_data.write_start(dest)?;
|
||||
if nth_data.is_function {
|
||||
write_affine(dest, nth_data.a, nth_data.b)?;
|
||||
nth_data.write_affine(dest)?;
|
||||
dest.write_char(')')?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
NthOf(ref nth_of_data) => {
|
||||
let nth_data = nth_of_data.nth_data();
|
||||
dest.write_str(match nth_data.ty {
|
||||
NthType::Child => ":nth-child(",
|
||||
NthType::LastChild => ":nth-last-child(",
|
||||
_ => unreachable!(),
|
||||
})?;
|
||||
write_affine(dest, nth_data.a, nth_data.b)?;
|
||||
nth_data.write_start(dest)?;
|
||||
debug_assert!(
|
||||
nth_data.is_function,
|
||||
"A selector must be a function to hold An+B notation"
|
||||
);
|
||||
nth_data.write_affine(dest)?;
|
||||
debug_assert!(
|
||||
matches!(nth_data.ty, NthType::Child | NthType::LastChild),
|
||||
"Only :nth-child or :nth-last-child can be of a selector list"
|
||||
);
|
||||
debug_assert!(
|
||||
!nth_of_data.selectors().is_empty(),
|
||||
"The selector list should not be empty"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue