style: Add invalidation support for ::slotted().

Bug: 1424607
Reviewed-by: heycam
MozReview-Commit-ID: 8pIVUx27o7x
This commit is contained in:
Emilio Cobos Álvarez 2017-12-17 17:56:15 +01:00
parent 040379208e
commit b26f3280d2
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
7 changed files with 294 additions and 110 deletions

View file

@ -13,7 +13,8 @@ use dom::TElement;
use element_state::ElementState;
use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
use invalidation::element::invalidation_map::*;
use invalidation::element::invalidator::{InvalidationVector, Invalidation, InvalidationProcessor};
use invalidation::element::invalidator::{DescendantInvalidationLists, InvalidationVector};
use invalidation::element::invalidator::{Invalidation, InvalidationProcessor};
use invalidation::element::restyle_hints::RestyleHint;
use selector_map::SelectorMap;
use selector_parser::Snapshot;
@ -47,7 +48,7 @@ where
classes_removed: &'a SmallVec<[Atom; 8]>,
classes_added: &'a SmallVec<[Atom; 8]>,
state_changes: ElementState,
descendant_invalidations: &'a mut InvalidationVector<'selectors>,
descendant_invalidations: &'a mut DescendantInvalidationLists<'selectors>,
sibling_invalidations: &'a mut InvalidationVector<'selectors>,
invalidates_self: bool,
}
@ -109,7 +110,7 @@ where
&mut self,
element: E,
_self_invalidations: &mut InvalidationVector<'a>,
descendant_invalidations: &mut InvalidationVector<'a>,
descendant_invalidations: &mut DescendantInvalidationLists<'a>,
sibling_invalidations: &mut InvalidationVector<'a>,
) -> bool {
debug_assert!(element.has_snapshot(), "Why bothering?");
@ -236,7 +237,10 @@ where
//
// This number is completely made-up, but the page that made us add this
// code generated 1960+ invalidations (bug 1420741).
if descendant_invalidations.len() > 150 {
//
// We don't look at slotted_descendants because those don't propagate
// down more than one level anyway.
if descendant_invalidations.dom_descendants.len() > 150 {
self.data.hint.insert(RestyleHint::RESTYLE_DESCENDANTS);
}
@ -509,36 +513,52 @@ where
}
fn note_dependency(&mut self, dependency: &'selectors Dependency) {
if dependency.affects_self() {
debug_assert!(self.dependency_may_be_relevant(dependency));
let invalidation_kind = dependency.invalidation_kind();
if matches!(invalidation_kind, DependencyInvalidationKind::Element) {
self.invalidates_self = true;
return;
}
if dependency.affects_descendants() {
debug_assert_ne!(dependency.selector_offset, 0);
debug_assert_ne!(dependency.selector_offset, dependency.selector.len());
debug_assert!(!dependency.affects_later_siblings());
self.descendant_invalidations.push(Invalidation::new(
&dependency.selector,
dependency.selector.len() - dependency.selector_offset + 1,
));
} else if dependency.affects_later_siblings() {
debug_assert_ne!(dependency.selector_offset, 0);
debug_assert_ne!(dependency.selector_offset, dependency.selector.len());
self.sibling_invalidations.push(Invalidation::new(
&dependency.selector,
dependency.selector.len() - dependency.selector_offset + 1,
));
debug_assert_ne!(dependency.selector_offset, 0);
debug_assert_ne!(
dependency.selector_offset,
dependency.selector.len()
);
let invalidation = Invalidation::new(
&dependency.selector,
dependency.selector.len() - dependency.selector_offset + 1,
);
match invalidation_kind {
DependencyInvalidationKind::Element => unreachable!(),
DependencyInvalidationKind::ElementAndDescendants => {
self.invalidates_self = true;
self.descendant_invalidations.dom_descendants.push(invalidation);
}
DependencyInvalidationKind::Descendants => {
self.descendant_invalidations.dom_descendants.push(invalidation);
}
DependencyInvalidationKind::Siblings => {
self.sibling_invalidations.push(invalidation);
}
DependencyInvalidationKind::SlottedElements => {
self.descendant_invalidations.slotted_descendants.push(invalidation);
}
}
}
/// Returns whether `dependency` may cause us to invalidate the style of
/// more elements than what we've already invalidated.
fn dependency_may_be_relevant(&self, dependency: &Dependency) -> bool {
if dependency.affects_descendants() || dependency.affects_later_siblings() {
return true;
match dependency.invalidation_kind() {
DependencyInvalidationKind::Element => !self.invalidates_self,
DependencyInvalidationKind::SlottedElements => self.element.is_html_slot_element(),
DependencyInvalidationKind::ElementAndDescendants |
DependencyInvalidationKind::Siblings |
DependencyInvalidationKind::Descendants => true,
}
debug_assert!(dependency.affects_self());
!self.invalidates_self
}
}