@@ -180,6 +180,9 @@ class DOMNode(MessagePump):
180180 # Names of potential computed reactives
181181 _computes : ClassVar [frozenset [str ]]
182182
183+ _PSEUDO_CLASSES : ClassVar [dict [str , Callable [[object ], bool ]]] = {}
184+ """Pseudo class checks."""
185+
183186 def __init__ (
184187 self ,
185188 * ,
@@ -217,6 +220,8 @@ def __init__(
217220 )
218221 self ._has_hover_style : bool = False
219222 self ._has_focus_within : bool = False
223+ self ._has_order_style : bool = False
224+ """The node has an ordered dependent pseudo-style (`:odd`, `:even`, `:first-of-type`, `:last-of-type`)"""
220225 self ._reactive_connect : (
221226 dict [str , tuple [MessagePump , Reactive [object ] | object ]] | None
222227 ) = None
@@ -1228,13 +1233,18 @@ def on_dark_change(old_value:bool, new_value:bool) -> None:
12281233 """
12291234 _watch (self , obj , attribute_name , callback , init = init )
12301235
1231- def get_pseudo_classes (self ) -> Iterable [str ]:
1232- """Get any pseudo classes applicable to this Node, e.g. hover, focus .
1236+ def get_pseudo_classes (self ) -> set [str ]:
1237+ """Pseudo classes for a widget .
12331238
12341239 Returns:
1235- Iterable of strings, such as a generator .
1240+ Names of the pseudo classes .
12361241 """
1237- return ()
1242+
1243+ return {
1244+ name
1245+ for name , check_class in self ._PSEUDO_CLASSES .items ()
1246+ if check_class (self )
1247+ }
12381248
12391249 def reset_styles (self ) -> None :
12401250 """Reset styles back to their initial state."""
@@ -1658,7 +1668,10 @@ def has_pseudo_class(self, class_name: str) -> bool:
16581668 Returns:
16591669 `True` if the DOM node has the pseudo class, `False` if not.
16601670 """
1661- return class_name in self .get_pseudo_classes ()
1671+ try :
1672+ return self ._PSEUDO_CLASSES [class_name ](self )
1673+ except KeyError :
1674+ return False
16621675
16631676 def has_pseudo_classes (self , class_names : set [str ]) -> bool :
16641677 """Check the node has all the given pseudo classes.
@@ -1669,7 +1682,16 @@ def has_pseudo_classes(self, class_names: set[str]) -> bool:
16691682 Returns:
16701683 `True` if all pseudo class names are present.
16711684 """
1672- return class_names .issubset (self .get_pseudo_classes ())
1685+ PSEUDO_CLASSES = self ._PSEUDO_CLASSES
1686+ try :
1687+ return all (PSEUDO_CLASSES [name ](self ) for name in class_names )
1688+ except KeyError :
1689+ return False
1690+
1691+ @property
1692+ def _pseudo_classes_cache_key (self ) -> tuple [int , ...]:
1693+ """A cache key used when updating a number of nodes from the stylesheet."""
1694+ return ()
16731695
16741696 def refresh (
16751697 self , * , repaint : bool = True , layout : bool = False , recompose : bool = False
0 commit comments