add some stuff

This commit is contained in:
Rowan 2025-10-08 11:40:26 -04:00
parent 4210f500c4
commit 3deafd4d97
7 changed files with 99 additions and 40 deletions

View file

@ -2,7 +2,7 @@
from argparse import ArgumentParser
from puppygirl import Puppygirl
from puppygirl.elements.domme import PuppygirlDomme
from puppygirl.elements.host import PuppygirlHost, PuppygirlPart
from puppygirl.elements import Node
from puppygirl.renderer import ClientSideRenderer, ServerSideRenderer
@ -24,7 +24,7 @@ def main():
case _:
renderer = ServerSideRenderer()
pg = Puppygirl(renderer=renderer, elements=[PuppygirlDomme])
pg = Puppygirl(renderer=renderer, elements=[PuppygirlHost, PuppygirlPart])
html = pg.parse(Node.from_path(args.input))
if args.pretty:

View file

@ -1,4 +1,4 @@
class PuppygirlDomme extends HTMLElement {
class PuppygirlHost extends HTMLElement {
constructor() {
super()
}
@ -14,4 +14,4 @@ class PuppygirlDomme extends HTMLElement {
}
customElements.define("puppygirl-domme", PuppygirlDomme)
customElements.define("pg-host", PuppygirlDomme)

View file

@ -1,3 +1,3 @@
from .constants import *
from .domme import *
from .host import *
from .shadow_root import *

View file

@ -1,31 +0,0 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING
from .constants import TemplateAttr
from .shadow_root import ShadowRootMode
from ..renderer import Renderable
if TYPE_CHECKING:
from .. import Puppygirl
from .shadow_root import Node
from ..puppytype import RenderableElement, Templates
@dataclass
class PuppygirlDomme(Renderable):
puppygirl: "Puppygirl"
@property
def name(self):
return "puppygirl-domme"
def render(self, node: "Node", templates: "Templates") -> "RenderableElement":
if not node.has_attr(TemplateAttr):
return node
template = templates[node[TemplateAttr]]
shadow_root = node.attach_shadow(ShadowRootMode.Open)
shadow_root.append_child(template.clone())
return node

View file

@ -0,0 +1,67 @@
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 []

View file

@ -80,6 +80,10 @@ class SingleNode(Node):
def value(self):
return self._value
@property
def parent(self):
return self._value.parent
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,

View file

@ -1,6 +1,8 @@
from dataclasses import InitVar, dataclass, field
from importlib import resources
from typing import TYPE_CHECKING, Iterable, Protocol, runtime_checkable
from typing import TYPE_CHECKING, Any, Iterable, Protocol, Self, runtime_checkable
from bs4 import Tag
from puppygirl.elements import IdAttr, TemplateName
from puppygirl.elements.shadow_root import Node, SingleNode
@ -10,10 +12,24 @@ if TYPE_CHECKING:
from bs4 import BeautifulSoup
from puppygirl import Puppygirl
class Query:
_args: Iterable[Any]
_kwargs: dict[str, Any]
def __init__(self, *args, **kwargs):
self._args = args
self._kwargs = kwargs
def query(self, tree: "BeautifulSoup") -> Iterable[Tag]:
return tree.find_all(*self._args, **self._kwargs)
@runtime_checkable
class Renderable(Protocol):
def query(self) -> Query:
return Query()
def render(self, tree: "BeautifulSoup") -> "BeautifulSoup":
pass
return tree
class Renderer(Protocol):
def render(self, puppygirl: "Puppygirl", tree: "BeautifulSoup") -> "BeautifulSoup":
@ -35,6 +51,7 @@ class ClientSideRenderer(Renderer):
head.append(script)
return tree
class ServerSideRenderer(Renderer):
def _find_local_templates(puppygirl: "Puppygirl", tree: "BeautifulSoup") -> "Templates":
templates = tree.find_all(TemplateName)
@ -46,11 +63,13 @@ class ServerSideRenderer(Renderer):
for element in puppygirl.elements:
if hasattr(element, "name"):
tags = tree.find_all(element.name)
query = element.query()
tags = query.query(tree)
tags.reverse()
for tag in tags:
new_tag = element.render(
SingleNode(tag).clone(),
SingleNode(tag),
# SingleNode(tag).clone(),
templates
)