Просмотр исходного кода

fix: add PlantUmlViewer support and improve MermaidViewer rendering logic

Yuki Takei 4 дней назад
Родитель
Сommit
cd5e4a9c2e

+ 6 - 0
apps/app/src/client/services/renderer/renderer.tsx

@@ -95,6 +95,7 @@ export const generateViewOptions = (
             presentation.sanitizeOption,
             drawio.sanitizeOption,
             mermaidSanitizeOption,
+            plantuml.sanitizeOption,
             callout.sanitizeOption,
             attachment.sanitizeOption,
             lsxGrowiDirective.sanitizeOption,
@@ -132,6 +133,7 @@ export const generateViewOptions = (
     components.refsimg = refsGrowiDirective.RefsImg;
     components.gallery = refsGrowiDirective.Gallery;
     components.drawio = DrawioViewerWithEditButton;
+    components.plantuml = plantuml.PlantUmlViewer;
     components.table = TableWithEditButton;
     components.mermaid = MermaidViewer;
     components.callout = callout.CalloutViewer;
@@ -220,6 +222,7 @@ export const generateSimpleViewOptions = (
             presentation.sanitizeOption,
             drawio.sanitizeOption,
             mermaidSanitizeOption,
+            plantuml.sanitizeOption,
             callout.sanitizeOption,
             attachment.sanitizeOption,
             lsxGrowiDirective.sanitizeOption,
@@ -250,6 +253,7 @@ export const generateSimpleViewOptions = (
     components.refsimg = refsGrowiDirective.RefsImgImmutable;
     components.gallery = refsGrowiDirective.GalleryImmutable;
     components.drawio = drawio.DrawioViewer;
+    components.plantuml = plantuml.PlantUmlViewer;
     components.mermaid = MermaidViewer;
     components.callout = callout.CalloutViewer;
     components.attachment = RichAttachment;
@@ -321,6 +325,7 @@ export const generatePreviewOptions = (
             getCommonSanitizeOption(config),
             drawio.sanitizeOption,
             mermaidSanitizeOption,
+            plantuml.sanitizeOption,
             callout.sanitizeOption,
             attachment.sanitizeOption,
             lsxGrowiDirective.sanitizeOption,
@@ -352,6 +357,7 @@ export const generatePreviewOptions = (
     components.refsimg = refsGrowiDirective.RefsImgImmutable;
     components.gallery = refsGrowiDirective.GalleryImmutable;
     components.drawio = drawio.DrawioViewer;
+    components.plantuml = plantuml.PlantUmlViewer;
     components.mermaid = MermaidViewer;
     components.callout = callout.CalloutViewer;
     components.attachment = RichAttachment;

+ 16 - 1
apps/app/src/features/mermaid/components/MermaidViewer.tsx

@@ -21,6 +21,8 @@ export const MermaidViewer = React.memo(
     const ref = useRef<HTMLDivElement>(null);
 
     useEffect(() => {
+      let rafId: number | undefined;
+
       (async () => {
         if (ref.current != null && value != null) {
           mermaid.initialize({
@@ -35,13 +37,26 @@ export const MermaidViewer = React.memo(
             const id = `mermaid-${uuidV7()}`;
             const { svg } = await mermaid.render(id, value, ref.current);
             ref.current.innerHTML = svg;
-            ref.current.setAttribute(GROWI_IS_CONTENT_RENDERING_ATTR, 'false');
+            // Delay the "done" signal to the next animation frame so the browser has a chance
+            // to compute the SVG layout before the auto-scroll system re-scrolls.
+            rafId = requestAnimationFrame(() => {
+              ref.current?.setAttribute(
+                GROWI_IS_CONTENT_RENDERING_ATTR,
+                'false',
+              );
+            });
           } catch (err) {
             logger.error(err);
             ref.current?.setAttribute(GROWI_IS_CONTENT_RENDERING_ATTR, 'false');
           }
         }
       })();
+
+      return () => {
+        if (rafId != null) {
+          cancelAnimationFrame(rafId);
+        }
+      };
     }, [isDarkMode, value]);
 
     return value ? (