diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ff8ab6cc..d1641b1a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed visibility not affecting children https://github.com/Textualize/textual/issues/1313 - Fixed issue with auto width/height and relative children https://github.com/Textualize/textual/issues/1319 - Fixed issue with offset applied to containers https://github.com/Textualize/textual/issues/1256 +- Fixed default CSS retrieval for widgets with no `DEFAULT_CSS` that inherited from widgets with `DEFAULT_CSS` https://github.com/Textualize/textual/issues/1335 ## [0.5.0] - 2022-11-20 diff --git a/src/textual/app.py b/src/textual/app.py index 19e7b4c10..ef1260032 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1996,9 +1996,9 @@ class App(Generic[ReturnType], DOMNode): await self._prune_nodes(widgets) finally: finished_event.set() + self.refresh(layout=True) removed_widgets = self._detach_from_dom(widgets) - self.refresh(layout=True) finished_event = asyncio.Event() asyncio.create_task(prune_widgets_task(removed_widgets, finished_event)) diff --git a/src/textual/dom.py b/src/textual/dom.py index bc1d52ee5..49057b67d 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -266,7 +266,7 @@ class DOMNode(MessagePump): return f"{base.__name__}" for tie_breaker, base in enumerate(self._node_bases): - css = base.DEFAULT_CSS.strip() + css = base.__dict__.get("DEFAULT_CSS", "").strip() if css: css_stack.append((get_path(base), css, -tie_breaker)) diff --git a/tests/test_dom.py b/tests/test_dom.py index 6037abdd0..c1b5221c0 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -78,6 +78,43 @@ def test_inherited_bindings(): assert list(e._bindings.keys.keys()) == ["e"] +def test_get_default_css(): + class A(DOMNode): + pass + class B(A): + pass + class C(B): + DEFAULT_CSS = "C" + class D(C): + pass + class E(D): + DEFAULT_CSS = "E" + node = DOMNode() + node_css = node.get_default_css() + a = A() + a_css = a.get_default_css() + b = B() + b_css = b.get_default_css() + c = C() + c_css = c.get_default_css() + d = D() + d_css = d.get_default_css() + e = E() + e_css = e.get_default_css() + + # Descendants that don't assign to DEFAULT_CSS don't add new CSS to the stack. + assert len(node_css) == len(a_css) == len(b_css) == 0 + assert len(c_css) == len(d_css) == 1 + assert len(e_css) == 2 + + # Descendants do push the priority of the ancestors' rules down. + assert c_css[0][2] == d_css[0][2] + 1 == 0 + + # The CSS on the stack is the correct one. + assert e_css[0][1:] == ("E", 0) + assert e_css[1][1:] == ("C", -2) + + @pytest.fixture def search(): """