yeahyeahyeaheyaehehahwrggvdf

This commit is contained in:
Rowan 2025-10-08 05:51:52 -04:00
parent 4ff8c37160
commit afa0170041
3 changed files with 71 additions and 35 deletions

View file

@ -1,7 +1,7 @@
from copy import copy
from dataclasses import dataclass
from enum import StrEnum
from typing import TYPE_CHECKING, Optional, Self
from typing import TYPE_CHECKING, Iterable, Optional, Self
from bs4 import BeautifulSoup, Tag
from ..clonable import Clonable
@ -15,10 +15,67 @@ class ShadowRootMode(StrEnum):
Open = "open"
Closed = "closed"
@dataclass
class Node(Clonable):
_value: Tag
@property
def value(self): pass
def from_path(path: str) -> Self:
with open(path, "r") as f:
soup = BeautifulSoup(f.read(), 'html.parser')
nodes = soup.find_all()
match len(nodes):
case 0: return EmptyNode()
case 1: return SingleNode(nodes[0])
case _: return NodeCollection(soup)
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.value,
mode=shadow_root_mode,
clonable=clonable,
delegates_focus=delegates_focus,
serializable=serializable
)
def find(self, *args, **kwargs):
return self.value.find(*args, **kwargs)
def find_all(self, *args, **kwargs):
return self.value.find_all(*args, **kwargs)
def append(self, *args, **kwargs):
return self.value.append(*args, **kwargs)
def insert(self, *args, **kwargs):
return self.value.insert(*args, **kwargs)
def has_attr(self, attr: str) -> bool:
return self.value.has_attr(attr)
def prettify(self) -> str:
return self.value.prettify()
class EmptyNode(Node):
@property
def value(self):
return None
@dataclass
class NodeCollection(Node):
nodes: Iterable[Tag]
@property
def value(self):
return self.nodes
def clone(self) -> Self:
return NodeCollection(copy(self.value))
@dataclass
class SingleNode(Node):
_value: Tag
@property
def value(self):
return self._value
@ -32,26 +89,12 @@ class Node(Clonable):
serializable=serializable
)
def from_path(path: str) -> Self:
with open(path, "r") as f:
return Node(BeautifulSoup(f.read(), 'html.parser').find())
def from_element(element: "Parsable") -> 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]
def clone(self) -> Self:
return SingleNode(copy(self.value))
@dataclass
class Template(Clonable):
_value: Node
@ -60,6 +103,10 @@ class Template(Clonable):
def value(self):
return self._value
@property
def id(self):
return self._value["id"]
@property
def shadow_root_mode(self) -> ShadowRootMode | None:
return self._value.get("shadowrootmode")
@ -104,20 +151,9 @@ class Template(Clonable):
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"
host: Node
mode: ShadowRootMode
clonable: Optional[bool] = None

View file

@ -22,7 +22,7 @@ class Puppygirl[R: Renderer]:
def _create_template_dict(templates: Iterable[Parsable]) -> Templates:
templates = [Template.from_element(t) for t in templates]
return {t[IdAttr]: t for t in templates}
return {t.id: t for t in templates}
def add_template(self, template: Parsable):
template = Template.from_element(template)

View file

@ -3,7 +3,7 @@ from importlib import resources
from typing import TYPE_CHECKING, Iterable, Protocol, runtime_checkable
from puppygirl.elements import IdAttr, TemplateName
from puppygirl.elements.shadow_root import Node
from puppygirl.elements.shadow_root import Node, SingleNode
from puppygirl.puppytype import Templates
if TYPE_CHECKING:
@ -47,7 +47,7 @@ class ServerSideRenderer(Renderer):
for element in puppygirl.elements:
if hasattr(element, "name"):
for tag in tree.find_all(element.name):
new_tag = element.render(Node(tag).clone(), templates)
new_tag = element.render(SingleNode(tag).clone(), templates)
if isinstance(new_tag, Iterable):
tag.extend(new_tag)