Commit graph

4 commits

Author SHA1 Message Date
Andreas Kling
c92ea86c30 LibWeb: Invalidate shadow focus-within styles
Match :focus-within by walking flat-tree parents so shadow hosts and
slotted content follow the Selectors definition instead of DOM ancestry.

When focus state changes, also run pseudo-class invalidation in shadow
style scopes that can observe the focused node. This lets shadow-root
rules such as :host(:focus-within)::before and ::slotted(:focus) update
without waiting for an unrelated DOM mutation to restyle the host.

Add focused coverage for host pseudo-elements, shadow descendants, and
slotted controls, and update the style-invalidation counter baseline for
the lower focus-family no-op restyle counts.
2026-05-21 08:56:05 +02:00
Andreas Kling
98a9c36ba7 LibWeb: Make structural-position pseudos targetable when sole feature
When a sheet's rightmost compound carries :first-child, :last-child,
or :only-child but no other class/tag/id/attr feature, the sheet
add/remove path can target the boundary children directly instead of
falling back to a whole-subtree invalidation.

The narrowing in extend_style_sheet_invalidation_set_with_style_rule
deliberately only kicks in when the structural pseudo is the only
feature in the rightmost compound. A selector like `.foo:first-child`
keeps targeting `.foo` rather than every first-child in the
document.

Adds matchers for :first-child / :last-child / :only-child in
InvalidationSetMatcher so the targeted walk can recognize them on
each candidate element.
2026-05-07 19:32:27 +02:00
Andreas Kling
62440c1472 LibWeb: Make :host, :root, and interaction-state pseudos targetable
Stylesheet add/remove previously fell back to a whole-subtree
invalidation whenever a sheet's rightmost compound carried one of
these pseudo-classes. They each match a small, knowable set of
elements at any moment, so the invalidation walk can target them
directly:

- :host matches one element per shadow root and :root matches the
  html element. Mark them targetable.
- :hover, :focus, :focus-visible, :focus-within, :active, and
  :target all match at most a handful of elements at a time. Mark
  them targetable and add matchers in InvalidationSetMatcher that
  consult Document::hovered_node, focused_area, target_element,
  and the element's own focused/active state.
2026-05-07 19:32:27 +02:00
Andreas Kling
4b3abc6958 LibWeb: Move invalidation set matching into a helper
Element.cpp still contained the CSS logic for deciding whether an
invalidation set references features present on an element. Move that
matcher into CSS::Invalidation::InvalidationSetMatcher.

The helper uses Element's public API for classes, id, attributes,
pseudo-class state, and removed-attribute tracking. This keeps Element
focused on DOM state while CSS::Invalidation owns selector feature
matching.
2026-04-29 15:47:23 +02:00