from dataclasses import dataclass from typing import TYPE_CHECKING from .constants import TemplateAttr from .shadow_root import ShadowRootMode from ..renderer import Query, Renderable if TYPE_CHECKING: from .. import Puppygirl from .shadow_root import Node from ..puppytype import RenderableElement, Templates @dataclass class PuppygirlHost(Renderable): puppygirl: "Puppygirl" @property def name(self): return "pg-host" def query(self) -> Query: return Query(self.name, attrs={ "template": True }) def render(self, node: "Node", templates: "Templates") -> "RenderableElement": template = templates[node[TemplateAttr]] shadow_root = node.attach_shadow(ShadowRootMode.Open) shadow_root.append_child(template.clone()) return node @dataclass class PuppygirlPart(Renderable): puppygirl: "Puppygirl" @property def name(self): return "pg-part" def query(self) -> Query: return Query(self.name, attrs={ "for": True }) def render(self, node: "Node", templates: "Templates") -> "RenderableElement": template = node.parent.find("template", recursive=False) if template is None: return node part_name = node["for"] parts = template.find_all(attrs={ "part": part_name }) attrs = { attr: value for attr, value in node.value.attrs.items() if attr != "for" } for attr, value in attrs.items(): for part in parts: part[attr] = value return []