mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	fix(mermaid): <br> breaking diagram rendering (closes #1345)
This commit is contained in:
		
							parent
							
								
									e795caa2f3
								
							
						
					
					
						commit
						a162fbfe42
					
				| @ -11,7 +11,7 @@ import FNote from "../entities/fnote.js"; | |||||||
| import FAttachment from "../entities/fattachment.js"; | import FAttachment from "../entities/fattachment.js"; | ||||||
| import imageContextMenuService from "../menus/image_context_menu.js"; | import imageContextMenuService from "../menus/image_context_menu.js"; | ||||||
| import { applySingleBlockSyntaxHighlight, applySyntaxHighlight } from "./syntax_highlight.js"; | import { applySingleBlockSyntaxHighlight, applySyntaxHighlight } from "./syntax_highlight.js"; | ||||||
| import { loadElkIfNeeded } from "./mermaid.js"; | import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js"; | ||||||
| import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js"; | import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js"; | ||||||
| 
 | 
 | ||||||
| let idCounter = 1; | let idCounter = 1; | ||||||
| @ -226,7 +226,7 @@ async function renderMermaid(note: FNote | FAttachment, $renderedContent: JQuery | |||||||
|         await loadElkIfNeeded(content); |         await loadElkIfNeeded(content); | ||||||
|         const { svg } = await mermaid.mermaidAPI.render("in-mermaid-graph-" + idCounter++, content); |         const { svg } = await mermaid.mermaidAPI.render("in-mermaid-graph-" + idCounter++, content); | ||||||
| 
 | 
 | ||||||
|         $renderedContent.append($(svg)); |         $renderedContent.append($(postprocessMermaidSvg(svg))); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         const $error = $("<p>The diagram could not displayed.</p>"); |         const $error = $("<p>The diagram could not displayed.</p>"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								src/public/app/services/mermaid.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/public/app/services/mermaid.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | import { describe, expect, it } from "vitest"; | ||||||
|  | import { postprocessMermaidSvg } from "./mermaid.js"; | ||||||
|  | import { trimIndentation } from "../../../../spec/support/utils.js"; | ||||||
|  | 
 | ||||||
|  | describe("Mermaid", () => { | ||||||
|  |     it("converts <br> properly", () => { | ||||||
|  |         const before = trimIndentation`\ | ||||||
|  |             <g transform="translate(-55.71875, -24)" style="color:black !important" class="label"> | ||||||
|  |             <rect></rect> | ||||||
|  |             <foreignObject height="48" width="111.4375"> | ||||||
|  |                 <div xmlns="http://www.w3.org/1999/xhtml" | ||||||
|  |                 style="color: black !important; display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"> | ||||||
|  |                 <span class="nodeLabel" style="color:black !important"> | ||||||
|  |                     <p>Verify Output<br>Against<BR > Criteria</p> | ||||||
|  |                 </span> | ||||||
|  |                 </div> | ||||||
|  |             </foreignObject> | ||||||
|  |             </g> | ||||||
|  |         `;
 | ||||||
|  |         const after = trimIndentation`\ | ||||||
|  |             <g transform="translate(-55.71875, -24)" style="color:black !important" class="label"> | ||||||
|  |             <rect></rect> | ||||||
|  |             <foreignObject height="48" width="111.4375"> | ||||||
|  |                 <div xmlns="http://www.w3.org/1999/xhtml" | ||||||
|  |                 style="color: black !important; display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"> | ||||||
|  |                 <span class="nodeLabel" style="color:black !important"> | ||||||
|  |                     <p>Verify Output<br/>Against<br/> Criteria</p> | ||||||
|  |                 </span> | ||||||
|  |                 </div> | ||||||
|  |             </foreignObject> | ||||||
|  |             </g> | ||||||
|  |         `;
 | ||||||
|  |         expect(postprocessMermaidSvg(before)).toBe(after); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
| @ -23,3 +23,16 @@ export async function loadElkIfNeeded(mermaidContent: string) { | |||||||
|         mermaid.registerLayoutLoaders((await import("@mermaid-js/layout-elk")).default); |         mermaid.registerLayoutLoaders((await import("@mermaid-js/layout-elk")).default); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Processes the output of a Mermaid SVG render before it should be delivered to the user. | ||||||
|  |  * | ||||||
|  |  * <p> | ||||||
|  |  * Currently this fixes <br> to <br/> which would otherwise cause an invalid XML. | ||||||
|  |  * | ||||||
|  |  * @param svg the Mermaid SVG to process. | ||||||
|  |  * @returns the processed SVG. | ||||||
|  |  */ | ||||||
|  | export function postprocessMermaidSvg(svg: string) { | ||||||
|  |     return svg.replaceAll(/<br\s*>/ig, "<br/>"); | ||||||
|  | } | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import libraryLoader from "../services/library_loader.js"; | |||||||
| import NoteContextAwareWidget from "./note_context_aware_widget.js"; | import NoteContextAwareWidget from "./note_context_aware_widget.js"; | ||||||
| import server from "../services/server.js"; | import server from "../services/server.js"; | ||||||
| import utils from "../services/utils.js"; | import utils from "../services/utils.js"; | ||||||
| import { loadElkIfNeeded } from "../services/mermaid.js"; | import { loadElkIfNeeded, postprocessMermaidSvg } from "../services/mermaid.js"; | ||||||
| import type FNote from "../entities/fnote.js"; | import type FNote from "../entities/fnote.js"; | ||||||
| import type { EventData } from "../components/app_context.js"; | import type { EventData } from "../components/app_context.js"; | ||||||
| 
 | 
 | ||||||
| @ -122,7 +122,7 @@ export default class MermaidWidget extends NoteContextAwareWidget { | |||||||
| 
 | 
 | ||||||
|         await loadElkIfNeeded(content); |         await loadElkIfNeeded(content); | ||||||
|         const { svg } = await mermaid.mermaidAPI.render(`mermaid-graph-${idCounter}`, content); |         const { svg } = await mermaid.mermaidAPI.render(`mermaid-graph-${idCounter}`, content); | ||||||
|         return svg; |         return postprocessMermaidSvg(svg); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { |     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran