public sealed class StyleInvalidatorWorks out which elements a change can possibly have restyled.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
The premise is that recomputing is not an option. A DataGrid restyles when a row is selected, and if selecting a row cost a pass over ten thousand cells the grid would be unusable — so the question is not "what changed" but "what could a rule have noticed".
Answering it is a static property of the stylesheet. For every name a rule mentions, where does it appear: against the element itself, as an ancestor, before a sibling combinator? And when it appears as an ancestor, what does the far end of that rule test? That last question is the one worth asking — it turns "restyle the subtree" into "restyle the .cells in the subtree".
⚠ This used to say that nothing needs to look upward, and :has() is what changed it. The old reasoning was sound and its premise expired: a selector could only reach downward and rightward because Vixen refused :has() — doc 09's P2 decision, and invalidation was the second thing that refusal bought after match cost. It is supported now, so a name that appears inside a :has() argument carries ReachesAncestors and a change to it walks up. :focus-within remains the apparent exception that is not one: it is stored as element state and set explicitly, so it arrives as a change like any other.
⚠ The upward direction is narrowed by name but not by depth, and that asymmetry is deliberate. A downward reach can be cut at the changed element's subtree; an upward one cannot, because the :has() may sit on the document root and every rule hanging off it reaches back down. So a change to a :has()-mentioned name walks to the top and then collects by feature from there — which is a pass over the document with a set-membership test per element, on the changes that touch such a name and no others. That is the cost doc 09 named, made explicit rather than hidden: see HasInvalidationTests, which measures it as elements resolved.
Fields and properties (4)
public bool StateReachesDescendantsWhether an element's own state change can be narrowed at all, or whether every rule has to be reconsidered.
public bool StateReachesSiblingsWhether a state change can reach later siblings.
public bool StateReachesEverythingWhether what a state change reaches cannot be narrowed by name.
public bool StateReachesAncestorsWhether a state change can be noticed by a :has() above it.
Methods (3)
public StyleInvalidator(SelectorTable table)Creates an invalidator over a rule set.
public void Read(StyleRuleSet rules)Reads every rule that has been added since the last time.
public void Collect(StyleTree tree, StyleNodeId element, ReadOnlySpan<int> changed, bool stateChanged, List<StyleNodeId> roots)Collects the elements a change to an element could have restyled.
Used by (1)
- StyleUpdaterVixen.Ui.Styling