mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge branch 'main' into bump0.3.0
This commit is contained in:
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- Widgets are now closed in reversed DOM order
|
- Widgets are now closed in reversed DOM order
|
||||||
- Input widget justify hardcoded to left to prevent text-align interference
|
- Input widget justify hardcoded to left to prevent text-align interference
|
||||||
- Changed `textual run` so that it patches `argv` in more situations
|
- Changed `textual run` so that it patches `argv` in more situations
|
||||||
|
- DOM classes and IDs are now always treated fully case-sensitive https://github.com/Textualize/textual/issues/1047
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class Selector:
|
|||||||
type: SelectorType = SelectorType.TYPE
|
type: SelectorType = SelectorType.TYPE
|
||||||
pseudo_classes: list[str] = field(default_factory=list)
|
pseudo_classes: list[str] = field(default_factory=list)
|
||||||
specificity: Specificity3 = field(default_factory=lambda: (0, 0, 0))
|
specificity: Specificity3 = field(default_factory=lambda: (0, 0, 0))
|
||||||
_name_lower: str = field(default="", repr=False)
|
|
||||||
advance: int = 1
|
advance: int = 1
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -61,7 +60,6 @@ class Selector:
|
|||||||
return f"#{self.name}{pseudo_suffix}"
|
return f"#{self.name}{pseudo_suffix}"
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
self._name_lower = self.name.lower()
|
|
||||||
self._checks = {
|
self._checks = {
|
||||||
SelectorType.UNIVERSAL: self._check_universal,
|
SelectorType.UNIVERSAL: self._check_universal,
|
||||||
SelectorType.TYPE: self._check_type,
|
SelectorType.TYPE: self._check_type,
|
||||||
@@ -94,21 +92,21 @@ class Selector:
|
|||||||
return node.has_pseudo_class(*self.pseudo_classes)
|
return node.has_pseudo_class(*self.pseudo_classes)
|
||||||
|
|
||||||
def _check_type(self, node: DOMNode) -> bool:
|
def _check_type(self, node: DOMNode) -> bool:
|
||||||
if self._name_lower not in node._css_type_names:
|
if self.name not in node._css_type_names:
|
||||||
return False
|
return False
|
||||||
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _check_class(self, node: DOMNode) -> bool:
|
def _check_class(self, node: DOMNode) -> bool:
|
||||||
if not node.has_class(self._name_lower):
|
if not node.has_class(self.name):
|
||||||
return False
|
return False
|
||||||
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _check_id(self, node: DOMNode) -> bool:
|
def _check_id(self, node: DOMNode) -> bool:
|
||||||
if not node.id == self._name_lower:
|
if not node.id == self.name:
|
||||||
return False
|
return False
|
||||||
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class DOMNode(MessagePump):
|
|||||||
|
|
||||||
# True if this node inherits the CSS from the base class.
|
# True if this node inherits the CSS from the base class.
|
||||||
_inherit_css: ClassVar[bool] = True
|
_inherit_css: ClassVar[bool] = True
|
||||||
# List of names of base class (lower cased) that inherit CSS
|
# List of names of base classes that inherit CSS
|
||||||
_css_type_names: ClassVar[frozenset[str]] = frozenset()
|
_css_type_names: ClassVar[frozenset[str]] = frozenset()
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -168,7 +168,7 @@ class DOMNode(MessagePump):
|
|||||||
cls._inherit_css = inherit_css
|
cls._inherit_css = inherit_css
|
||||||
css_type_names: set[str] = set()
|
css_type_names: set[str] = set()
|
||||||
for base in cls._css_bases(cls):
|
for base in cls._css_bases(cls):
|
||||||
css_type_names.add(base.__name__.lower())
|
css_type_names.add(base.__name__)
|
||||||
cls._css_type_names = frozenset(css_type_names)
|
cls._css_type_names = frozenset(css_type_names)
|
||||||
|
|
||||||
def get_component_styles(self, name: str) -> RenderStyles:
|
def get_component_styles(self, name: str) -> RenderStyles:
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ def test_query():
|
|||||||
assert list(app.query("#main")) == [main_view]
|
assert list(app.query("#main")) == [main_view]
|
||||||
assert list(app.query("View#main")) == [main_view]
|
assert list(app.query("View#main")) == [main_view]
|
||||||
assert list(app.query("#widget1")) == [widget1]
|
assert list(app.query("#widget1")) == [widget1]
|
||||||
|
assert list(app.query("#Widget1")) == [] # Note case.
|
||||||
assert list(app.query("#widget2")) == [widget2]
|
assert list(app.query("#widget2")) == [widget2]
|
||||||
|
assert list(app.query("#Widget2")) == [] # Note case.
|
||||||
|
|
||||||
assert list(app.query("Widget.float")) == [sidebar, tooltip, helpbar]
|
assert list(app.query("Widget.float")) == [sidebar, tooltip, helpbar]
|
||||||
assert list(app.query(Widget).filter(".float")) == [sidebar, tooltip, helpbar]
|
assert list(app.query(Widget).filter(".float")) == [sidebar, tooltip, helpbar]
|
||||||
|
|||||||
Reference in New Issue
Block a user