Selaa lähdekoodia

Merge branch 'zauberzeug:main' into main

Hannes Römer 2 vuotta sitten
vanhempi
säilyke
15f414d126
4 muutettua tiedostoa jossa 51 lisäystä ja 42 poistoa
  1. 2 1
      api_docs_and_examples.py
  2. 2 2
      main.py
  3. 6 12
      nicegui/elements/html.py
  4. 41 27
      nicegui/elements/markdown.py

+ 2 - 1
api_docs_and_examples.py

@@ -7,6 +7,7 @@ import docutils.core
 
 from nicegui import ui
 from nicegui.auto_context import Context
+from nicegui.elements.markdown import apply_tailwind
 from nicegui.task_logger import create_task
 
 REGEX_H4 = re.compile(r'<h4.*?>(.*?)</h4>')
@@ -46,7 +47,7 @@ def example(content: Union[Callable, type, str], tight: bool = False) -> None:
             html = docutils.core.publish_parts(doc, writer_name='html')['html_body']
             html = html.replace('<p>', '<h4>', 1)
             html = html.replace('</p>', '</h4>', 1)
-            html = ui.markdown.apply_tailwind(html)
+            html = apply_tailwind(html)
             add_html_anchor(ui.html(html).classes(markdown_classes))
 
         try:

+ 2 - 2
main.py

@@ -6,14 +6,14 @@ import markdown2
 import api_docs_and_examples
 import traffic_tracking
 from nicegui import ui
-from nicegui.elements.markdown import Markdown
+from nicegui.elements.markdown import apply_tailwind
 
 with open('README.md') as f:
     content = f.read()
     content = re.sub(r'(?m)^\<img.*\n?', '', content)
     # change absolute link on GitHub to relative link
     content = content.replace('(https://nicegui.io/reference)', '(reference)')
-    README = Markdown.apply_tailwind(markdown2.markdown(content, extras=['fenced-code-blocks']))
+    README = apply_tailwind(markdown2.markdown(content, extras=['fenced-code-blocks']))
 
 
 async def go_to_anchor() -> None:

+ 6 - 12
nicegui/elements/html.py

@@ -1,12 +1,13 @@
 from typing import Any
 
 import justpy as jp
-from nicegui.binding import BindContentMixin
 
+from ..binding import BindableProperty, BindContentMixin
 from .element import Element
 
 
 class Html(Element, BindContentMixin):
+    content = BindableProperty()
 
     def __init__(self, content: str = ''):
         """HTML Element
@@ -19,19 +20,12 @@ class Html(Element, BindContentMixin):
         """
         view = jp.QDiv(temp=False)
         super().__init__(view)
-        self.content = content
-
-    @property
-    def content(self) -> str:
-        return self.view.inner_html
 
-    @content.setter
-    def content(self, content: str) -> None:
-        self.set_content(content)
+        self.content = content
+        self.bind_content_to(self.view, 'inner_html')
 
     def set_content(self, content: str) -> None:
         if '</script>' in content:
+            # TODO: should also be checked if content is set directly
             raise ValueError('HTML elements must not contain <script> tags. Use ui.add_body_html() instead.')
-        if self.view.inner_html != content:
-            self.view.inner_html = content
-            self.update()
+        self.content = content

+ 41 - 27
nicegui/elements/markdown.py

@@ -1,12 +1,42 @@
+from __future__ import annotations
+
 import re
 from typing import List
 
+import justpy as jp
 import markdown2
 
-from .html import Html
+from ..binding import BindableProperty, BindContentMixin
+from .element import Element
+
+
+def apply_tailwind(html: str) -> str:
+    rep = {
+        '<h1': '<h1 class="text-5xl mb-4 mt-6"',
+        '<h2': '<h2 class="text-4xl mb-3 mt-5"',
+        '<h3': '<h3 class="text-3xl mb-2 mt-4"',
+        '<h4': '<h4 class="text-2xl mb-1 mt-3"',
+        '<h5': '<h5 class="text-1xl mb-0.5 mt-2"',
+        '<a': '<a class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600"',
+        '<ul': '<ul class="list-disc ml-6"',
+        '<p>': '<p class="mb-2">',
+        '<div\ class="codehilite">': '<div class=" codehilite mb-2 p-2" style="overflow: scroll">',
+        '<code': '<code style="background-color: #f8f8f8"',
+    }
+    pattern = re.compile('|'.join(rep.keys()))
+    return pattern.sub(lambda m: rep[re.escape(m.group(0))], html)
+
 
+def _handle_content_change(sender: Markdown, content: str) -> None:
+    html = markdown2.markdown(content, extras=sender.extras)
+    html = apply_tailwind(html)  # we need explicit markdown styling because tailwind CSS removes all default styles
+    if sender.view.inner_html != html:
+        sender.view.inner_html = html
+        sender.update()
 
-class Markdown(Html):
+
+class Markdown(Element, BindContentMixin):
+    content = BindableProperty(on_change=_handle_content_change)
 
     def __init__(self, content: str = '', *, extras: List[str] = ['fenced-code-blocks', 'tables']):
         """Markdown Element
@@ -17,28 +47,12 @@ class Markdown(Html):
         :param extras: list of `markdown2 extensions <https://github.com/trentm/python-markdown2/wiki/Extras#implemented-extras>`_ (default: `['fenced-code-blocks', 'tables']`)
         """
         self.extras = extras
-        super().__init__(content)
-
-    def set_content(self, content: str):
-        html = markdown2.markdown(content, extras=self.extras)
-        # we need explicit markdown styling because tailwind css removes all default styles
-        html = Markdown.apply_tailwind(html)
-        super().set_content(html)
-        self.update()
-
-    @staticmethod
-    def apply_tailwind(html: str):
-        rep = {
-            '<h1': '<h1 class="text-5xl mb-4 mt-6"',
-            '<h2': '<h2 class="text-4xl mb-3 mt-5"',
-            '<h3': '<h3 class="text-3xl mb-2 mt-4"',
-            '<h4': '<h4 class="text-2xl mb-1 mt-3"',
-            '<h5': '<h5 class="text-1xl mb-0.5 mt-2"',
-            '<a': '<a class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600"',
-            '<ul': '<ul class="list-disc ml-6"',
-            '<p>': '<p class="mb-2">',
-            '<div\ class="codehilite">': '<div class=" codehilite mb-2 p-2" style="overflow: scroll">',
-            '<code': '<code style="background-color: #f8f8f8"',
-        }
-        pattern = re.compile("|".join(rep.keys()))
-        return pattern.sub(lambda m: rep[re.escape(m.group(0))], html)
+
+        view = jp.QDiv(temp=False)
+        super().__init__(view)
+
+        self.content = content
+        _handle_content_change(self, content)
+
+    def set_content(self, content: str) -> None:
+        self.content = content