commit 25f525fca85324e9c9b29e59de16a6ce81df9118
parent a426a924811ad96d8bc101d6c4d91ed894c4d0cf
Author: Diego Escalante <descalante@mozilla.com>
Date: Tue, 14 Oct 2025 12:36:14 +0000
Bug 1986741 - Implement correct datapath for scope element in invalidation collector and processor. r=dshin,firefox-style-system-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D267684
Diffstat:
2 files changed, 37 insertions(+), 44 deletions(-)
diff --git a/servo/components/style/invalidation/element/invalidator.rs b/servo/components/style/invalidation/element/invalidator.rs
@@ -927,7 +927,6 @@ where
&mut self,
invalidation: &Invalidation<'b>,
descendant_invalidations: &mut DescendantInvalidationLists<'b>,
- sibling_invalidations: &mut InvalidationVector<'b>,
) -> (ProcessInvalidationResult, SmallVec<[Invalidation<'b>; 1]>) {
debug!(" > Invalidation matched completely");
// We matched completely. If we're an inner selector now we need
@@ -946,17 +945,14 @@ where
if dependency.invalidation_kind()
== DependencyInvalidationKind::Scope(ScopeDependencyInvalidationKind::ScopeEnd)
{
- let invalidations =
- note_scope_dependency_force_at_subject(dependency, invalidation.host);
- for (invalidation, override_type) in invalidations {
- match override_type {
- InvalidationAddOverride::Descendant => {
- descendant_invalidations.dom_descendants.push(invalidation)
- },
- InvalidationAddOverride::Sibling => {
- sibling_invalidations.push(invalidation)
- },
- }
+ let invalidations = note_scope_dependency_force_at_subject(
+ dependency,
+ invalidation.host,
+ invalidation.scope,
+ false,
+ );
+ for invalidation in invalidations{
+ descendant_invalidations.dom_descendants.push(invalidation);
}
continue;
}
@@ -1073,7 +1069,6 @@ where
CompoundSelectorMatchingResult::FullyMatched => self.handle_fully_matched(
invalidation,
descendant_invalidations,
- sibling_invalidations,
),
CompoundSelectorMatchingResult::Matched {
next_combinator_offset,
@@ -1245,30 +1240,34 @@ where
pub fn note_scope_dependency_force_at_subject<'selectors>(
dependency: &'selectors Dependency,
current_host: Option<OpaqueElement>,
-) -> Vec<(Invalidation<'selectors>, InvalidationAddOverride)> {
- let mut invalidations_and_override_types: Vec<(Invalidation, InvalidationAddOverride)> =
+ scope: Option<OpaqueElement>,
+ traversed_non_subject: bool,
+) -> Vec<Invalidation<'selectors>> {
+ let mut invalidations: Vec<Invalidation> =
Vec::new();
if let Some(next) = dependency.next.as_ref() {
for dep in next.slice() {
- if dep.selector_offset == 0 {
+ if dep.selector_offset == 0 && !traversed_non_subject {
continue;
}
- let invalidation = Invalidation::new_subject_invalidation(dep, current_host, None);
-
- let combinator = dep
- .selector
- .combinator_at_match_order(dep.selector_offset - 1);
-
- let invalidation_override = match combinator.is_sibling() {
- true => InvalidationAddOverride::Sibling,
- false => InvalidationAddOverride::Descendant,
- };
+ if dep.next.is_some() {
+ invalidations
+ .extend(
+ note_scope_dependency_force_at_subject(
+ dep,
+ current_host,
+ scope,
+ true,
+ )
+ );
+ } else {
+ let invalidation =
+ Invalidation::new_subject_invalidation(dep, current_host, scope);
- invalidations_and_override_types.push((invalidation, invalidation_override));
- invalidations_and_override_types
- .extend(note_scope_dependency_force_at_subject(dep, current_host));
+ invalidations.push(invalidation);
+ }
}
}
- invalidations_and_override_types
+ invalidations
}
diff --git a/servo/components/style/invalidation/element/state_and_attributes.rs b/servo/components/style/invalidation/element/state_and_attributes.rs
@@ -11,7 +11,7 @@ use crate::dom::{TElement, TNode};
use crate::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
use crate::invalidation::element::invalidation_map::*;
use crate::invalidation::element::invalidator::{
- note_scope_dependency_force_at_subject, DescendantInvalidationLists, InvalidationAddOverride,
+ note_scope_dependency_force_at_subject, DescendantInvalidationLists,
InvalidationVector, SiblingTraversalMap,
};
use crate::invalidation::element::invalidator::{Invalidation, InvalidationProcessor};
@@ -569,11 +569,11 @@ where
DependencyInvalidationKind::Scope(_)
)
{
- return self.note_dependency(dependency);
+ return self.note_dependency(dependency, set_scope);
}
}
- fn note_dependency(&mut self, dependency: &'selectors Dependency) {
+ fn note_dependency(&mut self, dependency: &'selectors Dependency, set_scope: bool) {
debug_assert!(self.dependency_may_be_relevant(dependency));
let invalidation_kind = dependency.invalidation_kind();
if matches!(
@@ -583,7 +583,7 @@ where
if let Some(ref next) = dependency.next {
// We know something changed in the inner selector, go outwards
// now.
- self.scan_dependency(&next.as_ref().slice()[0], false);
+ self.scan_dependency(&next.as_ref().slice()[0], set_scope);
} else {
self.invalidates_self = true;
}
@@ -596,17 +596,11 @@ where
let invalidations = note_scope_dependency_force_at_subject(
dependency,
self.matching_context.current_host.clone(),
+ self.matching_context.scope_element,
+ false,
);
- for (invalidation, override_type) in invalidations {
- match override_type {
- InvalidationAddOverride::Descendant => self
- .descendant_invalidations
- .dom_descendants
- .push(invalidation),
- InvalidationAddOverride::Sibling => {
- self.sibling_invalidations.push(invalidation)
- },
- }
+ for invalidation in invalidations {
+ self.descendant_invalidations.dom_descendants.push(invalidation);
}
self.invalidates_self = true;
} else if let Some(ref next) = dependency.next {