mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Make note_selector more efficient.
My measurements are inconclusive as to whether this really moves the needle, but it seems like the right way to do it in any case. MozReview-Commit-ID: 7OuCc2aQ7jH
This commit is contained in:
parent
b4a2e2f17c
commit
a6ef89a7fe
1 changed files with 43 additions and 36 deletions
|
@ -525,56 +525,63 @@ impl DependencySet {
|
|||
|
||||
/// Adds a selector to this `DependencySet`.
|
||||
pub fn note_selector(&mut self, selector: &Selector<SelectorImpl>) {
|
||||
let mut is_pseudo_element = selector.pseudo_element.is_some();
|
||||
|
||||
let mut next = Some(selector.inner.complex.clone());
|
||||
let mut combinator = None;
|
||||
let mut iter = selector.inner.complex.iter();
|
||||
let mut index = 0;
|
||||
|
||||
while let Some(current) = next.take() {
|
||||
// Set up our visitor.
|
||||
loop {
|
||||
let sequence_start = index;
|
||||
let mut visitor = SensitivitiesVisitor {
|
||||
sensitivities: Sensitivities::new()
|
||||
};
|
||||
let mut hint = combinator_to_restyle_hint(combinator);
|
||||
|
||||
if is_pseudo_element {
|
||||
// TODO(emilio): use more fancy restyle hints to avoid restyling
|
||||
// the whole subtree when pseudos change.
|
||||
//
|
||||
// We currently need is_pseudo_element to handle eager pseudos
|
||||
// (so the style the parent stores doesn't become stale), and
|
||||
// restyle_descendants to handle all of them (::before and
|
||||
// ::after, because we find them in the subtree, and other lazy
|
||||
// pseudos for the same reason).
|
||||
hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS;
|
||||
is_pseudo_element = false;
|
||||
// Visit all the simple selectors in this sequence.
|
||||
//
|
||||
// Note that this works because we can't have combinators nested
|
||||
// inside simple selectors (i.e. in :not() or :-moz-any()). If we
|
||||
// ever support that we'll need to visit complex selectors as well.
|
||||
for ss in &mut iter {
|
||||
ss.visit(&mut visitor);
|
||||
index += 1; // Account for the simple selector.
|
||||
}
|
||||
|
||||
{
|
||||
// Visit all the simple selectors.
|
||||
let mut iter = current.iter();
|
||||
let mut index = 0usize;
|
||||
for ss in &mut iter {
|
||||
ss.visit(&mut visitor);
|
||||
index += 1;
|
||||
}
|
||||
|
||||
// Prepare the next sequence of simple selectors.
|
||||
if let Some(next_combinator) = iter.next_sequence() {
|
||||
next = Some(current.slice_from(index + 1));
|
||||
combinator = Some(next_combinator);
|
||||
}
|
||||
}
|
||||
|
||||
// Note what we found.
|
||||
// If we found a sensitivity, add an entry in the dependency set.
|
||||
if !visitor.sensitivities.is_empty() {
|
||||
let mut hint = combinator_to_restyle_hint(combinator);
|
||||
let dep_selector;
|
||||
if sequence_start == 0 {
|
||||
if selector.pseudo_element.is_some() {
|
||||
// TODO(emilio): use more fancy restyle hints to avoid
|
||||
// restyling the whole subtree when pseudos change.
|
||||
//
|
||||
// We currently need is_pseudo_element to handle eager
|
||||
// pseudos (so the style the parent stores doesn't
|
||||
// become stale), and restyle_descendants to handle all
|
||||
// of them (::before and ::after, because we find them
|
||||
// in the subtree, and other lazy pseudos for the same
|
||||
// reason).
|
||||
hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS;
|
||||
}
|
||||
|
||||
// Reuse the bloom hashes if this is the base selector.
|
||||
dep_selector = selector.inner.clone();
|
||||
} else {
|
||||
dep_selector = SelectorInner::new(selector.inner.complex.slice_from(sequence_start));
|
||||
}
|
||||
|
||||
self.add_dependency(Dependency {
|
||||
sensitivities: visitor.sensitivities,
|
||||
hint: hint,
|
||||
selector: SelectorInner::new(current),
|
||||
})
|
||||
selector: dep_selector,
|
||||
});
|
||||
}
|
||||
|
||||
combinator = iter.next_sequence();
|
||||
if combinator.is_none() {
|
||||
break;
|
||||
}
|
||||
|
||||
index += 1; // Account for the combinator.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue