|
39 | 39 |
|
40 | 40 | from . import Logger, LogGroup, LogVerbosity, actions, events, log, messages |
41 | 41 | from ._animator import DEFAULT_EASING, Animatable, Animator, EasingFunction |
| 42 | +from .await_remove import AwaitRemove |
42 | 43 | from ._ansi_sequences import SYNC_END, SYNC_START |
43 | 44 | from ._callback import invoke |
44 | 45 | from ._context import active_app |
@@ -353,6 +354,7 @@ def __init__( |
353 | 354 | else None |
354 | 355 | ) |
355 | 356 | self._screenshot: str | None = None |
| 357 | + self._dom_lock = asyncio.Lock() |
356 | 358 |
|
357 | 359 | @property |
358 | 360 | def return_value(self) -> ReturnType | None: |
@@ -1936,6 +1938,42 @@ def _walk_children(self, root: Widget) -> Iterable[list[Widget]]: |
1936 | 1938 | for child in widget.children: |
1937 | 1939 | push(child) |
1938 | 1940 |
|
| 1941 | + def _remove_nodes(self, widgets: list[Widget]) -> AwaitRemove: |
| 1942 | + """Remove nodes from DOM, and return an awaitable that awaits cleanup. |
| 1943 | +
|
| 1944 | + Args: |
| 1945 | + widgets (list[Widget]): List of nodes to remvoe. |
| 1946 | +
|
| 1947 | + Returns: |
| 1948 | + AwaitRemove: Awaitable that returns when the nodes have been fully removed. |
| 1949 | + """ |
| 1950 | + |
| 1951 | + async def remove_task( |
| 1952 | + widgets: list[Widget], finished_event: asyncio.Event |
| 1953 | + ) -> None: |
| 1954 | + try: |
| 1955 | + await self._prune_nodes(widgets) |
| 1956 | + finally: |
| 1957 | + finished_event.set() |
| 1958 | + |
| 1959 | + removed_widgets = self._detach_from_dom(widgets) |
| 1960 | + self.refresh(layout=True) |
| 1961 | + |
| 1962 | + finished_event = asyncio.Event() |
| 1963 | + asyncio.create_task(remove_task(removed_widgets, finished_event)) |
| 1964 | + |
| 1965 | + return AwaitRemove(finished_event) |
| 1966 | + |
| 1967 | + async def _prune_nodes(self, widgets: list[Widget]) -> None: |
| 1968 | + """Remove nodes and children. |
| 1969 | +
|
| 1970 | + Args: |
| 1971 | + widgets (Widget): _description_ |
| 1972 | + """ |
| 1973 | + async with self._dom_lock: |
| 1974 | + for widget in widgets: |
| 1975 | + await self._prune_node(widget) |
| 1976 | + |
1939 | 1977 | async def _prune_node(self, root: Widget) -> None: |
1940 | 1978 | """Remove a node and its children. Children are removed before parents. |
1941 | 1979 |
|
|
0 commit comments