Skip to content

Commit

Permalink
introduce ui.get().not_within(...)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodja committed Nov 1, 2023
1 parent f1f5a33 commit 84fbd51
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
24 changes: 20 additions & 4 deletions nicegui/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ def __init__(self, *,
self._texts = [text] if isinstance(text, str) else text
self._within_types: list[Element] = []
self._within_keys: list[str] = []
self._not_within_types: list[Element] = []
self._not_within_keys: list[str] = []
self._exclude_types: list[Element] = []
self._exclude_keys: list[str] = []
self.exclude_texts: list[str] = []
self._exclude_texts: list[str] = []

def __iter__(self) -> Iterator[T]:
client = context.get_client()
Expand All @@ -43,9 +45,11 @@ def iterate(self, parent: Element, *, visited: List[Element] = []) -> Iterator[T
(not self._texts or hasattr(element, 'text') and all(text in element.text for text in self._texts)) and \
(not self._exclude_types or not any(isinstance(element, type) for type in self._exclude_types)) and \
(not self._exclude_keys or not any(key in element._keys for key in self._exclude_keys)) and \
(not self.exclude_texts or ((hasattr(element, 'text') and not any(text in element.text for text in self.exclude_texts)))):
(not self._exclude_texts or ((hasattr(element, 'text') and not any(text in element.text for text in self._exclude_texts)))):
if (not self._within_types or any(isinstance(element, type) for type in self._within_types for element in visited)) and \
(not self._within_keys or any(key in element._keys for key in self._within_keys for element in visited)):
(not self._within_keys or any(key in element._keys for key in self._within_keys for element in visited)) and \
(not self._not_within_types or not any(isinstance(element, type) for type in self._not_within_types for element in visited)) and \
(not self._not_within_keys or not any(key in element._keys for key in self._not_within_keys for element in visited)):
yield element
yield from self.iterate(element, visited=visited + [element])

Expand All @@ -69,13 +73,25 @@ def within(self, *, type: Optional[Element] = None, key: str = None) -> Self:
return self

def exclude(self, *, type: Optional[Element] = None, key: Optional[str] = None, text: Optional[str] = None) -> Self:
"""Exclude elements with specific type, key or text."""

if type is not None:
assert issubclass(type, Element)
self._exclude_types.append(type)
if key is not None:
self._exclude_keys.append(key)
if text is not None:
self.exclude_texts.append(text)
self._exclude_texts.append(text)
return self

def not_within(self, *, type: Optional[Element] = None, key: str = None) -> Self:
"""Exclude elements which have a parent of a specific type or key."""

if type is not None:
assert issubclass(type, Element)
self._not_within_types.append(type)
if key is not None:
self._not_within_keys.append(key)
return self

def classes(self, add: Optional[str] = None, *, remove: Optional[str] = None, replace: Optional[str] = None) -> Self:
Expand Down
28 changes: 28 additions & 0 deletions tests/test_get_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,31 @@ def test_get_with_excluding_text(screen: Screen):
screen.open('/')
assert len(result) == 1
assert result[0].text == 'button B'


def test_get_not_within_type(screen: Screen):
ui.button('button A')
ui.label('label A')
with ui.row():
ui.button('button B')
ui.label('label B')

result = [e for e in ui.get(type=ui.button).not_within(type=ui.row)]

screen.open('/')
assert len(result) == 1
assert result[0].text == 'button A'


def test_get_not_within_key(screen: Screen):
ui.button('button A')
ui.label('label A')
with ui.row().keys('horizontal'):
ui.button('button B')
ui.label('label B')

result = [e for e in ui.get(type=ui.button).not_within(key='horizontal')]

screen.open('/')
assert len(result) == 1
assert result[0].text == 'button A'

0 comments on commit 84fbd51

Please sign in to comment.