group.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from __future__ import annotations
  2. from typing import List
  3. import justpy as jp
  4. from ..auto_context import get_view_stack
  5. from ..binding import active_links, bindable_properties, bindings
  6. from .element import Element
  7. class Group(Element):
  8. def __enter__(self):
  9. self._child_count_on_enter = len(self.view)
  10. get_view_stack().append(self.view)
  11. return self
  12. def __exit__(self, *_):
  13. get_view_stack().pop()
  14. if self._child_count_on_enter != len(self.view):
  15. self.update()
  16. def tight(self) -> Group:
  17. return self.classes(replace='').style(replace='')
  18. def clear(self):
  19. def collect_components(view: jp.HTMLBaseComponent) -> List[jp.HTMLBaseComponent]:
  20. return getattr(view, 'components', []) + \
  21. [view for child in getattr(view, 'components', []) for view in collect_components(child)]
  22. components = collect_components(self.view)
  23. active_links[:] = [
  24. (source_obj, source_name, target_obj, target_name, transform)
  25. for source_obj, source_name, target_obj, target_name, transform in active_links
  26. if not (
  27. isinstance(source_obj, jp.HTMLBaseComponent) and source_obj in components or
  28. isinstance(target_obj, jp.HTMLBaseComponent) and target_obj in components or
  29. isinstance(source_obj, Element) and source_obj.view in components or
  30. isinstance(target_obj, Element) and target_obj.view in components
  31. )
  32. ]
  33. for key, binding_list in list(bindings.items()):
  34. binding_list[:] = [
  35. (source_obj, target_obj, target_name, transform)
  36. for source_obj, target_obj, target_name, transform in binding_list
  37. if not (
  38. isinstance(source_obj, jp.HTMLBaseComponent) and source_obj in components or
  39. isinstance(target_obj, jp.HTMLBaseComponent) and target_obj in components or
  40. isinstance(source_obj, Element) and source_obj.view in components or
  41. isinstance(target_obj, Element) and target_obj.view in components
  42. )
  43. ]
  44. if not binding_list:
  45. del bindings[key]
  46. for (obj_id, name), obj in list(bindable_properties.items()):
  47. if isinstance(obj, jp.HTMLBaseComponent) and obj in components or \
  48. isinstance(obj, Element) and obj.view in components:
  49. del bindable_properties[(obj_id, name)]
  50. self.view.delete_components()
  51. self.update()