Skip to content

Commit

Permalink
Merge pull request #1077 from davep/bug/1047/id-case-redux
Browse files Browse the repository at this point in the history
Change DOM queries to be case-sensitive for classes and IDs
  • Loading branch information
willmcgugan authored Oct 31, 2022
2 parents af7cb90 + 4573407 commit 7bf81b7
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Widgets are now closed in reversed DOM order
- Input widget justify hardcoded to left to prevent text-align interference
- 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

Expand Down
8 changes: 3 additions & 5 deletions src/textual/css/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class Selector:
type: SelectorType = SelectorType.TYPE
pseudo_classes: list[str] = field(default_factory=list)
specificity: Specificity3 = field(default_factory=lambda: (0, 0, 0))
_name_lower: str = field(default="", repr=False)
advance: int = 1

@property
Expand All @@ -61,7 +60,6 @@ def css(self) -> str:
return f"#{self.name}{pseudo_suffix}"

def __post_init__(self) -> None:
self._name_lower = self.name.lower()
self._checks = {
SelectorType.UNIVERSAL: self._check_universal,
SelectorType.TYPE: self._check_type,
Expand Down Expand Up @@ -94,21 +92,21 @@ def _check_universal(self, node: DOMNode) -> bool:
return node.has_pseudo_class(*self.pseudo_classes)

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
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
return False
return True

def _check_class(self, node: DOMNode) -> bool:
if not node.has_class(self._name_lower):
if not node.has_class(self.name):
return False
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
return False
return True

def _check_id(self, node: DOMNode) -> bool:
if not node.id == self._name_lower:
if not node.id == self.name:
return False
if self.pseudo_classes and not node.has_pseudo_class(*self.pseudo_classes):
return False
Expand Down
4 changes: 2 additions & 2 deletions src/textual/dom.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class DOMNode(MessagePump):

# True if this node inherits the CSS from the base class.
_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()

def __init__(
Expand Down Expand Up @@ -168,7 +168,7 @@ def __init_subclass__(cls, inherit_css: bool = True) -> None:
cls._inherit_css = inherit_css
css_type_names: set[str] = set()
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)

def get_component_styles(self, name: str) -> RenderStyles:
Expand Down
2 changes: 2 additions & 0 deletions tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ class App(Widget):
assert list(app.query("#main")) == [main_view]
assert list(app.query("View#main")) == [main_view]
assert list(app.query("#widget1")) == [widget1]
assert list(app.query("#Widget1")) == [] # Note case.
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).filter(".float")) == [sidebar, tooltip, helpbar]
Expand Down

0 comments on commit 7bf81b7

Please sign in to comment.