group.py 2.5 KB

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