mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Properly handle invalidation of eager pseudo-elements.
Bug: 1368240 MozReview-Commit-ID: EkzDVhC3GPH
This commit is contained in:
parent
cb06375fe2
commit
14bb57c08f
1 changed files with 48 additions and 12 deletions
|
@ -420,30 +420,66 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
|
||||||
let mut invalidated_self = false;
|
let mut invalidated_self = false;
|
||||||
match matching_result {
|
match matching_result {
|
||||||
CompoundSelectorMatchingResult::Matched { next_combinator_offset: 0 } => {
|
CompoundSelectorMatchingResult::Matched { next_combinator_offset: 0 } => {
|
||||||
if let Some(ref mut data) = self.data {
|
debug!(" > Invalidation matched completely");
|
||||||
data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
|
invalidated_self = true;
|
||||||
invalidated_self = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CompoundSelectorMatchingResult::Matched { next_combinator_offset } => {
|
CompoundSelectorMatchingResult::Matched { next_combinator_offset } => {
|
||||||
let next_combinator =
|
let next_combinator =
|
||||||
invalidation.selector.combinator_at(next_combinator_offset);
|
invalidation.selector.combinator_at(next_combinator_offset);
|
||||||
|
|
||||||
|
if matches!(next_combinator, Combinator::PseudoElement) {
|
||||||
|
let pseudo_selector =
|
||||||
|
invalidation.selector
|
||||||
|
.iter_raw_rev_from(next_combinator_offset - 1)
|
||||||
|
.next()
|
||||||
|
.unwrap();
|
||||||
|
let pseudo = match *pseudo_selector {
|
||||||
|
Component::PseudoElement(ref pseudo) => pseudo,
|
||||||
|
_ => unreachable!("Someone seriously messed up selector parsing"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME(emilio): This is not ideal, and could not be
|
||||||
|
// accurate if we ever have stateful element-backed eager
|
||||||
|
// pseudos.
|
||||||
|
//
|
||||||
|
// Ideally, we'd just remove element-backed eager pseudos
|
||||||
|
// altogether, given they work fine without it. Only gotcha
|
||||||
|
// is that we wouldn't style them in parallel, which may or
|
||||||
|
// may not be an issue.
|
||||||
|
//
|
||||||
|
// Also, this could be more fine grained now (perhaps a
|
||||||
|
// RESTYLE_PSEUDOS hint?).
|
||||||
|
//
|
||||||
|
// Note that we'll also restyle the pseudo-element because
|
||||||
|
// it would match this invalidation.
|
||||||
|
if pseudo.is_eager() {
|
||||||
|
invalidated_self = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let next_invalidation = Invalidation {
|
||||||
|
selector: invalidation.selector.clone(),
|
||||||
|
offset: next_combinator_offset,
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!(" > Invalidation matched, next: {:?}, ({:?})",
|
||||||
|
next_invalidation, next_combinator);
|
||||||
if next_combinator.is_ancestor() {
|
if next_combinator.is_ancestor() {
|
||||||
descendant_invalidations.push(Invalidation {
|
descendant_invalidations.push(next_invalidation);
|
||||||
selector: invalidation.selector.clone(),
|
|
||||||
offset: next_combinator_offset,
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
sibling_invalidations.push(Invalidation {
|
sibling_invalidations.push(next_invalidation);
|
||||||
selector: invalidation.selector.clone(),
|
|
||||||
offset: next_combinator_offset,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CompoundSelectorMatchingResult::NotMatched => {}
|
CompoundSelectorMatchingResult::NotMatched => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if invalidated_self {
|
||||||
|
if let Some(ref mut data) = self.data {
|
||||||
|
data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(emilio): For pseudo-elements this should be mostly false, except
|
// TODO(emilio): For pseudo-elements this should be mostly false, except
|
||||||
// for the weird pseudos in <input type="number">.
|
// for the weird pseudos in <input type="number">.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue