Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
752fa30
Explicitly dissallow expanding attributes to be templated until we fi…
ianjosephwilson Jan 10, 2026
fe3c1f4
Update data templated error test and add similar aria test.
ianjosephwilson Jan 10, 2026
4136505
Cleanup parser attr tests.
ianjosephwilson Jan 11, 2026
e83b6fc
Reorganize and expand parser tests.
ianjosephwilson Jan 11, 2026
3e181da
Add helper function for combining multuple TemplateRefs together.
ianjosephwilson Jan 11, 2026
173e7e6
Merge adjacent text nodes during parsing.
ianjosephwilson Jan 11, 2026
1e61146
Expand parser tests to include singleton interpolations and templates.
ianjosephwilson Jan 11, 2026
5abbf3c
Regroup and expand processor tests.
ianjosephwilson Jan 11, 2026
cfb8514
More processor testing cleanup/reduction.
ianjosephwilson Jan 11, 2026
ce30232
Whitelist supported decl.
ianjosephwilson Jan 11, 2026
bbc3f6c
This isn't an accurate s_index, just bring it back correctly when/if …
ianjosephwilson Jan 11, 2026
a150b74
Remove unreachable code.
ianjosephwilson Jan 11, 2026
b779e82
Expand parser test coverage.
ianjosephwilson Jan 11, 2026
f1ce30f
Strictly only allow instances of dict or None for aria and data.
ianjosephwilson Jan 11, 2026
b7d8d99
Only allow None and dict when processing spread attributes.
ianjosephwilson Jan 11, 2026
222dac4
Expand processor test coverage.
ianjosephwilson Jan 11, 2026
f239b74
Expand processor test coverage.
ianjosephwilson Jan 11, 2026
6fc9b23
Add script nested elements check.
ianjosephwilson Jan 11, 2026
a5f3ddd
Formatting.
ianjosephwilson Jan 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 15 additions & 31 deletions tdom/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
TTemplatedAttribute,
TText,
)
from .template_utils import combine_template_refs


type HTMLAttribute = tuple[str, str | None]
type HTMLAttributesDict = dict[str, str | None]
Expand All @@ -38,7 +40,6 @@ class OpenTFragment:

@dataclass
class OpenTComponent:
# TODO: hold on to start_s_index when we start to need it.
start_i_index: int
attrs: tuple[TAttribute, ...]
children: list[TNode] = field(default_factory=list)
Expand All @@ -61,11 +62,6 @@ class SourceTracker:
def interpolations(self) -> tuple[Interpolation, ...]:
return self.template.interpolations

@property
def s_index(self) -> int:
"""The current string index."""
return self.i_index + 1

def advance_interpolation(self) -> int:
"""Call before processing an interpolation to move to the next one."""
self.i_index += 1
Expand All @@ -81,28 +77,10 @@ def get_expression(
ip = self.interpolations[i_index]
return ip.expression if ip.expression else f"{{{fallback_prefix}-{i_index}}}"

def get_interpolation_value(self, i_index: int):
"""Get the runtime value at the given interpolation index."""
return self.interpolations[i_index].value

def format_starttag(self, i_index: int) -> str:
"""Format a component start tag for error messages."""
return self.get_expression(i_index, fallback_prefix="component-starttag")

def format_endtag(self, i_index: int) -> str:
"""Format a component end tag for error messages."""
return self.get_expression(i_index, fallback_prefix="component-endtag")

def format_open_tag(self, open_tag: OpenTag) -> str:
"""Format any open tag for error messages."""
match open_tag:
case OpenTElement(tag=tag):
return tag
case OpenTFragment():
return ""
case OpenTComponent(start_i_index=i_index):
return self.format_starttag(i_index)


class TemplateParser(HTMLParser):
root: OpenTFragment
Expand Down Expand Up @@ -275,8 +253,13 @@ def handle_endtag(self, tag: str) -> None:

def handle_data(self, data: str) -> None:
ref = self.placeholders.remove_placeholders(data)
text = TText(ref)
self.append_child(text)
parent = self.get_parent()
if parent.children and isinstance(parent.children[-1], TText):
parent.children[-1] = TText(
ref=combine_template_refs(parent.children[-1].ref, ref)
)
else:
self.append_child(TText(ref=ref))

def handle_comment(self, data: str) -> None:
ref = self.placeholders.remove_placeholders(data)
Expand All @@ -287,13 +270,14 @@ def handle_decl(self, decl: str) -> None:
ref = self.placeholders.remove_placeholders(decl)
if not ref.is_literal:
raise ValueError("Interpolations are not allowed in declarations.")
if not decl.upper().startswith("DOCTYPE"):
elif decl.upper().startswith("DOCTYPE "):
doctype_content = decl[7:].strip()
doctype = TDocumentType(doctype_content)
self.append_child(doctype)
else:
raise NotImplementedError(
"Only DOCTYPE declarations are currently supported."
"Only well formed DOCTYPE declarations are currently supported."
)
doctype_content = decl[7:].strip()
doctype = TDocumentType(doctype_content)
self.append_child(doctype)

def reset(self):
super().reset()
Expand Down
Loading