Skip to content

Commit

Permalink
Do not escape & in html attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsca committed Feb 6, 2023
1 parent 6413cac commit 5b15af7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
14 changes: 12 additions & 2 deletions src/jinjax/html_attrs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import re
from typing import Any
from xml.sax.saxutils import quoteattr


CLASS_KEY = "class"
Expand All @@ -12,6 +11,17 @@ def split(ssl: str) -> "list[str]":
return re.split(r"\s+", ssl.strip())


def quote(text: str) -> str:
if '"' in text:
if "'" in text:
text = text.replace('"', """)
return f'"{text}"'
else:
return f"'{text}'"

return f'"{text}"'


class HTMLAttrs:
def __init__(self, attrs) -> None:
attributes: "dict[str, str]" = {}
Expand Down Expand Up @@ -147,7 +157,7 @@ def render(self, **kw) -> str:
properties = sorted(list(self.__properties))

html_attrs = [
f"{name}={quoteattr(str(value))}"
f"{name}={quote(str(value))}"
for name, value in attributes.items()
]
html_attrs.extend(properties)
Expand Down
27 changes: 26 additions & 1 deletion tests/test_html_attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,34 @@ def test_as_dict_no_classes():
def test_render_attrs_lik_set():
attrs = HTMLAttrs({"class": "lorem"})
expected = 'class="ipsum lorem" data-position="top" title="hi" open'
assert expected == attrs.render(
result = attrs.render(
title="hi",
data_position="top",
classes="ipsum",
open=True,
)
print(result)
assert expected == result


def test_do_not_escape_tailwind_syntax():
attrs = HTMLAttrs({"class": "lorem [&_a]:flex"})
expected = 'class="[&_a]:flex ipsum lorem" title="Hi&Stuff"'
result = attrs.render(**{
"title": "Hi&Stuff",
"class": "ipsum",
})
print(result)
assert expected == result


def test_do_escape_quotes_inside_attrs():
attrs = HTMLAttrs({
"class": "lorem text-['red']",
"title": 'I say "hey"',
"open": True,
})
expected = """class="lorem text-['red']" title='I say "hey"' open"""
result = attrs.render()
print(result)
assert expected == result

0 comments on commit 5b15af7

Please sign in to comment.