aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBobby Holley <bobbyholley@gmail.com>2017-06-01 17:03:35 -0700
committerBobby Holley <bobbyholley@gmail.com>2017-06-05 19:44:02 -0700
commit992059c8560fddd92bb49d709f606ef72f0d71f0 (patch)
treeb8bb72fad489b0051e3a090739c0316836be7e3e
parent1281fd935358aa5d85d46176734a3e4055091059 (diff)
downloadservo-992059c8560fddd92bb49d709f606ef72f0d71f0.tar.gz
servo-992059c8560fddd92bb49d709f606ef72f0d71f0.zip
Move around specificity computation so that we know it by the time we mint the Selector.
This is important to make the selector immutable, which needs to happen when we stick it in an Arc. MozReview-Commit-ID: BaMbOEbYC3D
-rw-r--r--components/selectors/parser.rs38
1 files changed, 19 insertions, 19 deletions
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<Specificity> for u32 {
}
}
-fn specificity<Impl>(complex_selector: &Selector<Impl>) -> u32
+fn specificity<Impl>(iter: SelectorIter<Impl>) -> u32
where Impl: SelectorImpl
{
- complex_selector_specificity(complex_selector).into()
+ complex_selector_specificity(iter).into()
}
-fn complex_selector_specificity<Impl>(selector: &Selector<Impl>)
+fn complex_selector_specificity<Impl>(mut iter: SelectorIter<Impl>)
-> Specificity
where Impl: SelectorImpl
{
@@ -896,9 +896,7 @@ fn complex_selector_specificity<Impl>(selector: &Selector<Impl>)
}
}
-
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<Impl>(selector: &Selector<Impl>)
fn parse_selector<P, Impl>(parser: &P, input: &mut CssParser) -> Result<Selector<Impl>, ()>
where P: Parser<Impl=Impl>, 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<Impl> = SmallVec<[Component<Impl>; 8]>;
fn parse_complex_selector<P, Impl>(
parser: &P,
input: &mut CssParser)
- -> Result<(Selector<Impl>, bool), ()>
+ -> Result<Selector<Impl>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl
{
let mut sequence = ParseVec::new();
@@ -992,21 +985,28 @@ fn parse_complex_selector<P, Impl>(
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<Impl: SelectorImpl> Selector<Impl> {
- /// Parse a complex selector, without any pseudo-element.
+ /// Parse a selector, without any pseudo-element.
pub fn parse<P>(parser: &P, input: &mut CssParser) -> Result<Self, ()>
where P: Parser<Impl=Impl>
{
- 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)
}
}