mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
style: Record attribute dependencies within the selector list of :nth-child(... of <selector list>)
There are separate filters for IDs, classes, attribute local names, and element state. Also, we invalidate siblings of elements matched against the selector list of :nth-child(... of <selector list>) by marking matched elements with NODE_HAS_SLOW_SELECTOR_NTH_OF. The only remaining invalidation case invalidation case is `:nth-child(An+B of :has())` (bug 1818155), which should not block shipping `layout.css.nth-child-of.enabled`, because :has(...) is still being implemented (bug 418039). Depends on D172352 Differential Revision: https://phabricator.services.mozilla.com/D171936
This commit is contained in:
parent
c7f8845665
commit
356e886d26
7 changed files with 261 additions and 28 deletions
|
@ -38,14 +38,24 @@ bitflags! {
|
|||
/// :first-of-type, or :nth-of-type.
|
||||
const HAS_SLOW_SELECTOR_LATER_SIBLINGS = 1 << 1;
|
||||
|
||||
/// When a DOM mutation occurs on a child that might be matched by
|
||||
/// :nth-last-child(.. of <selector list>), earlier children must be
|
||||
/// restyled, and HAS_SLOW_SELECTOR will be set (which normally
|
||||
/// indicates that all children will be restyled).
|
||||
///
|
||||
/// Similarly, when a DOM mutation occurs on a child that might be
|
||||
/// matched by :nth-child(.. of <selector list>), later children must be
|
||||
/// restyled, and HAS_SLOW_SELECTOR_LATER_SIBLINGS will be set.
|
||||
const HAS_SLOW_SELECTOR_NTH_OF = 1 << 2;
|
||||
|
||||
/// When a child is added or removed from the parent, the first and
|
||||
/// last children must be restyled, because they may match :first-child,
|
||||
/// :last-child, or :only-child.
|
||||
const HAS_EDGE_CHILD_SELECTOR = 1 << 2;
|
||||
const HAS_EDGE_CHILD_SELECTOR = 1 << 3;
|
||||
|
||||
/// The element has an empty selector, so when a child is appended we
|
||||
/// might need to restyle the parent completely.
|
||||
const HAS_EMPTY_SELECTOR = 1 << 3;
|
||||
const HAS_EMPTY_SELECTOR = 1 << 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +69,7 @@ impl ElementSelectorFlags {
|
|||
pub fn for_parent(self) -> ElementSelectorFlags {
|
||||
self & (ElementSelectorFlags::HAS_SLOW_SELECTOR |
|
||||
ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS |
|
||||
ElementSelectorFlags::HAS_SLOW_SELECTOR_NTH_OF |
|
||||
ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR)
|
||||
}
|
||||
}
|
||||
|
@ -939,13 +950,17 @@ where
|
|||
let is_edge_child_selector = a == 0 && b == 1 && !is_of_type && selectors.is_empty();
|
||||
|
||||
if context.needs_selector_flags() {
|
||||
element.apply_selector_flags(if is_edge_child_selector {
|
||||
let mut flags = if is_edge_child_selector {
|
||||
ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR
|
||||
} else if is_from_end {
|
||||
ElementSelectorFlags::HAS_SLOW_SELECTOR
|
||||
} else {
|
||||
ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS
|
||||
});
|
||||
};
|
||||
if !selectors.is_empty() {
|
||||
flags |= ElementSelectorFlags::HAS_SLOW_SELECTOR_NTH_OF;
|
||||
}
|
||||
element.apply_selector_flags(flags);
|
||||
}
|
||||
|
||||
if !selectors.is_empty() && !list_matches_complex_selector(selectors, element, context) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue