diff --git a/src/jinjax/html_attrs.py b/src/jinjax/html_attrs.py index a7f72ed..6fa30a7 100644 --- a/src/jinjax/html_attrs.py +++ b/src/jinjax/html_attrs.py @@ -1,6 +1,5 @@ import re from typing import Any -from xml.sax.saxutils import quoteattr CLASS_KEY = "class" @@ -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]" = {} @@ -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) diff --git a/tests/test_html_attrs.py b/tests/test_html_attrs.py index 2fdcb88..5f15b1f 100644 --- a/tests/test_html_attrs.py +++ b/tests/test_html_attrs.py @@ -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