from copy import copy from dataclasses import dataclass from enum import StrEnum from typing import TYPE_CHECKING, Optional, Self from bs4 import Tag from ..clonable import Clonable if TYPE_CHECKING: from ..puppytype import ElementLike TemplateName = "template" class ShadowRootMode(StrEnum): Open = "open" Closed = "closed" @dataclass class Node(Clonable): _value: Tag @property def value(self): return self._value def attach_shadow(self, shadow_root_mode: ShadowRootMode, clonable: Optional[bool] = None, delegates_focus: Optional[bool] = None, serializable: Optional[bool] = None): return ShadowRoot( host=self, mode=shadow_root_mode, clonable=clonable, delegates_focus=delegates_focus, serializable=serializable ) def from_element(element: "ElementLike") -> Self: if isinstance(element, Node): return element return Node(element) def clone(self) -> "Self": return Node(copy(self.value)) def __getattr__(self, name): if name == '_value': raise AttributeError() return getattr(self._value, name) def __getitem__(self, index): return self._value[index] @dataclass class Template(Clonable): _value: Node @property def value(self): return self._value @property def shadow_root_mode(self) -> ShadowRootMode | None: return self._value.get("shadowrootmode") @shadow_root_mode.setter def shadow_root_mode(self, mode: ShadowRootMode): self._value["shadowrootmode"] = mode.value @property def delegates_focus(self) -> Optional[bool]: return self._value.get("delegatesfocus") @delegates_focus.setter def delegates_focus(self, value: bool): self._value["delegatesfocus"] = value @property def clonable(self) -> Optional[bool]: return self._value.get("clonable") @clonable.setter def clonable(self, value: bool): self._value["clonable"] = value @property def serializable(self) -> Optional[bool]: return self._value.get("serializable") @serializable.setter def serializable(self, value: bool): self._value["serializable"] = value def from_element(element: "ElementLike") -> Self: if isinstance(element, Template): return element return Template(element) def clone(self) -> Self: return Template(copy(self._value)) def __getattr__(self, name): if name == '_value': raise AttributeError() return getattr(self._value, name) def __getitem__(self, index): return self._value[index] def __setitem__(self, index, value): self._value[index] = value @dataclass class ShadowRoot(Clonable): host: "Node" mode: ShadowRootMode clonable: Optional[bool] = None delegates_focus: Optional[bool] = None serializable: Optional[bool] = None def append_child(self, template: Template): template.shadow_root_mode = self.mode if self.clonable is not None: template.clonable = self.clonable if self.delegates_focus is not None: template.delegates_focus = self.delegates_focus if self.serializable is not None: template.serializable = self.serializable self.host.value.insert(0, template.value)