Skip to content

Commit a749366

Browse files
committedOct 24, 2023
Bug 1853258: Part 3 - Optimize invalidating relative selectors on DOM mutation. r=emilio
There are cases where we can run a selector match to realize that some DOM mutations will not make a difference in the relative selector match state, which avoids O(n^2) behaviour under some circumstances. Differential Revision: https://phabricator.services.mozilla.com/D191307
1 parent 88edb6d commit a749366

File tree

5 files changed

+307
-31
lines changed

5 files changed

+307
-31
lines changed
 

‎servo/components/selectors/matching.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1098,11 +1098,8 @@ where
10981098
},
10991099
Component::RelativeSelectorAnchor => {
11001100
let anchor = context.shared.relative_selector_anchor();
1101-
debug_assert!(
1102-
anchor.is_some(),
1103-
"Relative selector outside of relative selector matching?"
1104-
);
1105-
anchor.map_or(false, |a| a == element.opaque())
1101+
// We may match inner relative selectors, in which case we want to always match.
1102+
anchor.map_or(true, |a| a == element.opaque())
11061103
},
11071104
Component::Invalid(..) => false,
11081105
}

‎servo/components/selectors/parser.rs

+24
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,30 @@ impl<Impl: SelectorImpl> Component<Impl> {
20962096

20972097
true
20982098
}
2099+
2100+
// Returns true if this has any selector that requires an index calculation. e.g.
2101+
// :nth-child, :first-child, etc. For nested selectors, return true only if the
2102+
// indexed selector is in its subject compound.
2103+
pub fn has_indexed_selector_in_subject(&self) -> bool {
2104+
match *self {
2105+
Component::NthOf(..) | Component::Nth(..) => return true,
2106+
Component::Is(ref selectors) |
2107+
Component::Where(ref selectors) |
2108+
Component::Negation(ref selectors) => {
2109+
// Check the subject compound.
2110+
for selector in selectors.slice() {
2111+
let mut iter = selector.iter();
2112+
while let Some(c) = iter.next() {
2113+
if c.has_indexed_selector_in_subject() {
2114+
return true;
2115+
}
2116+
}
2117+
}
2118+
}
2119+
_ => (),
2120+
};
2121+
false
2122+
}
20992123
}
21002124

21012125
#[derive(Clone, Eq, PartialEq, ToShmem)]

0 commit comments

Comments
 (0)
Failed to load comments.