فهرست منبع

fixed mermaid by adapting "register_vue_component"

Rodja Trappe 1 سال پیش
والد
کامیت
1b2de8663f
4فایلهای تغییر یافته به همراه57 افزوده شده و 38 حذف شده
  1. 42 30
      nicegui/dependencies.py
  2. 1 1
      nicegui/elements/mermaid.js
  3. 5 2
      nicegui/elements/mermaid.py
  4. 9 5
      nicegui/nicegui.py

+ 42 - 30
nicegui/dependencies.py

@@ -1,4 +1,5 @@
 import json
+import logging
 from pathlib import Path
 from typing import Any, Dict, List, Set, Tuple
 
@@ -12,14 +13,22 @@ js_components: Dict[str, Any] = {}
 libraries: Dict[str, Any] = {}
 
 
-def register_vue_component(name: str, path: Path) -> None:
+def register_vue_component(location: Path,
+                           base_path: Path = Path(__file__).parent / 'elements', *, expose: bool = False
+                           ) -> str:
     """Register a .vue or .js Vue component.
 
-    :param name: unique machine-name (used in element's `use_library`): no space, no special characters
-    :param path: local path
+    :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier and must therefore be url-safe.
+    :param base_path: the base path where your libraries are located
+    :return: the resource identifier library name to be used in element's `use_component`        
     """
-    suffix = path.suffix.lower()
+    if isinstance(location, str):
+        logging.warning('register_vue_component: location is a string, did you mean to use register_library?')
+        return
+    suffix = location.suffix.lower()
     assert suffix in {'.vue', '.js', '.mjs'}, 'Only VUE and JS components are supported.'
+    name = location.stem
+    path = base_path / location
     if suffix == '.vue':
         assert name not in vue_components, f'Duplicate VUE component name {name}'
         # The component (in case of .vue) is built right away to:
@@ -28,14 +37,16 @@ def register_vue_component(name: str, path: Path) -> None:
         vue_components[name] = vbuild.VBuild(name, path.read_text())
     elif suffix == '.js':
         assert name not in js_components, f'Duplicate JS component name {name}'
-        js_components[name] = {'name': name, 'path': path}
+        js_components[str(location)] = {'name': name, 'path': path}
+    return str(location)
 
 
-def register_library(
-        location: Path,  base_path: Path = Path(__file__).parent / 'elements' / 'lib', *, expose: bool = False) -> str:
+def register_library(location: Path,
+                     base_path: Path = Path(__file__).parent / 'elements' / 'lib', *, expose: bool = False
+                     ) -> str:
     """Register a new external library.
 
-    :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier (used in element's `use_library`) and must therefore be url-safe.
+    :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier and must therefore be url-safe.
     :param base_path: the base path where your libraries are located
     :param expose: if True, this will be exposed as an ESM module but NOT imported
     :return: the resource identifier library name to be used in element's `use_library`
@@ -44,6 +55,7 @@ def register_library(
         return
     assert location.suffix == '.js' or location.suffix == '.mjs', 'Only JS dependencies are supported.'
     name = str(location)
+    assert name not in libraries, f'Duplicate js library name {name}'
     libraries[name] = {'name': name, 'path': base_path / location,  'expose': expose}
     return name
 
@@ -58,33 +70,33 @@ def generate_resources(prefix: str, elements: List[Element]) -> Tuple[str, str,
     import_maps = {'imports': {}}
 
     # Build the importmap structure for exposed libraries.
-    for key in libraries:
-        if key not in done_libraries and libraries[key]['expose']:
-            name = libraries[key]['name']
-            import_maps['imports'][name] = f'{prefix}/_nicegui/{__version__}/library/{key}'
-            done_libraries.add(key)
+    for resource in libraries:
+        if resource not in done_libraries and libraries[resource]['expose']:
+            name = libraries[resource]['name']
+            import_maps['imports'][name] = f'{prefix}/_nicegui/{__version__}/library/{resource}'
+            done_libraries.add(resource)
     # Build the none optimized component (ie, the vue component).
-    for key in vue_components:
-        if key not in done_components:
-            vue_html += f'{vue_components[key].html}\n'
-            vue_scripts += f'{vue_components[key].script.replace("Vue.component", "app.component", 1)}\n'
-            vue_styles += f'{vue_components[key].style}\n'
-            done_components.add(key)
+    for resource in vue_components:
+        if resource not in done_components:
+            vue_html += f'{vue_components[resource].html}\n'
+            vue_scripts += f'{vue_components[resource].script.replace("Vue.component", "app.component", 1)}\n'
+            vue_styles += f'{vue_components[resource].style}\n'
+            done_components.add(resource)
 
     # Build the resources associated with the elements.
     for element in elements:
-        for key in element.libraries:
-            if key in libraries and key not in done_libraries:
-                if not libraries[key]['expose']:
-                    js_imports += f'import "{prefix}/_nicegui/{__version__}/library/{key}";\n'
-                done_libraries.add(key)
-        for key in element.components:
-            if key in js_components and key not in done_components:
-                name = js_components[key]['name']
-                var = key.replace('-', '_')
-                js_imports += f'import {{ default as {var} }} from "{prefix}/_nicegui/{__version__}/components/{key}";\n'
+        for resource in element.libraries:
+            if resource in libraries and resource not in done_libraries:
+                if not libraries[resource]['expose']:
+                    js_imports += f'import "{prefix}/_nicegui/{__version__}/library/{resource}";\n'
+                done_libraries.add(resource)
+        for resource in element.components:
+            if resource in js_components and resource not in done_components:
+                name = js_components[resource]['name']
+                var = name.replace('-', '_')
+                js_imports += f'import {{ default as {var} }} from "{prefix}/_nicegui/{__version__}/components/{resource}";\n'
                 js_imports += f'app.component("{name}", {var});\n'
-                done_components.add(key)
+                done_components.add(resource)
     vue_styles = f'<style>{vue_styles}</style>'
     import_maps = f'<script type="importmap">{json.dumps(import_maps)}</script>'
     return vue_html, vue_styles, vue_scripts, import_maps, js_imports

+ 1 - 1
nicegui/elements/mermaid.js

@@ -1,4 +1,4 @@
-import mermaid from "mermaid";
+import mermaid from "mermaid/mermaid.esm.min.mjs";
 export default {
   template: `<div></div>`,
   mounted() {

+ 5 - 2
nicegui/elements/mermaid.py

@@ -3,8 +3,11 @@ from pathlib import Path
 from ..dependencies import register_library, register_vue_component
 from .mixins.content_element import ContentElement
 
-register_vue_component('mermaid', Path(__file__).parent / 'mermaid.js')
+component_name = register_vue_component(Path('mermaid.js'))
 library_name = register_library(Path('mermaid') / 'mermaid.esm.min.mjs', expose=True)
+extras_path = Path(__file__).parent / 'lib' / 'mermaid'
+for path in extras_path.glob('*.js'):
+    register_library(path.relative_to(extras_path.parent))
 
 
 class Mermaid(ContentElement):
@@ -19,7 +22,7 @@ class Mermaid(ContentElement):
         :param content: the Mermaid content to be displayed
         '''
         super().__init__(tag='mermaid', content=content)
-        self.use_component('mermaid')
+        self.use_component(component_name)
         self.use_library(library_name)
 
     def on_content_change(self, content: str) -> None:

+ 9 - 5
nicegui/nicegui.py

@@ -55,11 +55,15 @@ def get_dependencies(name: str):
     raise HTTPException(status_code=404, detail=f'dependency "{name}" not found')
 
 
-@app.get(f'/_nicegui/{__version__}' + '/components/{name}')
-def get_components(name: str):
-    if name in js_components and js_components[name]['path'].exists():
-        return FileResponse(js_components[name]['path'], media_type='text/javascript')
-    raise HTTPException(status_code=404, detail=f'library "{name}" not found')
+@app.get(f'/_nicegui/{__version__}' + '/components/{resource:path}')
+def get_components(resource: str):
+    if resource in js_components and js_components[resource]['path'].exists():
+        return FileResponse(
+            js_components[resource]['path'],
+            media_type='text/javascript',
+            headers={'Cache-Control': 'public, max-age=3600'},
+        )
+    raise HTTPException(status_code=404, detail=f'library "{resource}" not found')
 
 
 @app.on_event('startup')