diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 4c40ab54bb4..0049c4e5286 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -841,13 +841,13 @@ impl From for u32 { } } -fn specificity(complex_selector: &Selector) -> u32 +fn specificity(iter: SelectorIter) -> u32 where Impl: SelectorImpl { - complex_selector_specificity(complex_selector).into() + complex_selector_specificity(iter).into() } -fn complex_selector_specificity(selector: &Selector) +fn complex_selector_specificity(mut iter: SelectorIter) -> Specificity where Impl: SelectorImpl { @@ -896,9 +896,7 @@ fn complex_selector_specificity(selector: &Selector) } } - let mut specificity = Default::default(); - let mut iter = selector.iter(); loop { for simple_selector in &mut iter { simple_selector_specificity(&simple_selector, &mut specificity); @@ -917,12 +915,7 @@ fn complex_selector_specificity(selector: &Selector) fn parse_selector(parser: &P, input: &mut CssParser) -> Result, ()> where P: Parser, Impl: SelectorImpl { - let (mut selector, has_pseudo_element) = parse_complex_selector(parser, input)?; - let mut specificity = specificity(&selector); - if has_pseudo_element { - specificity |= HAS_PSEUDO_BIT; - } - selector.1 = specificity; + let selector = parse_complex_selector(parser, input)?; Ok(selector) } @@ -944,7 +937,7 @@ type ParseVec = SmallVec<[Component; 8]>; fn parse_complex_selector( parser: &P, input: &mut CssParser) - -> Result<(Selector, bool), ()> + -> Result, ()> where P: Parser, Impl: SelectorImpl { let mut sequence = ParseVec::new(); @@ -992,21 +985,28 @@ fn parse_complex_selector( sequence.push(Component::Combinator(combinator)); } - let complex = Selector(ArcSlice::new(sequence.into_vec().into_boxed_slice()), 0); - Ok((complex, parsed_pseudo_element)) + let mut specificity = specificity(SelectorIter { + iter: sequence.iter().rev(), + next_combinator: None, + }); + if parsed_pseudo_element { + specificity |= HAS_PSEUDO_BIT; + } + + let complex = Selector(ArcSlice::new(sequence.into_vec().into_boxed_slice()), specificity); + Ok(complex) } impl Selector { - /// Parse a complex selector, without any pseudo-element. + /// Parse a selector, without any pseudo-element. pub fn parse

(parser: &P, input: &mut CssParser) -> Result where P: Parser { - let (complex, has_pseudo_element) = - parse_complex_selector(parser, input)?; - if has_pseudo_element { + let selector = parse_complex_selector(parser, input)?; + if selector.has_pseudo_element() { return Err(()) } - Ok(complex) + Ok(selector) } }