Skip to content

Commit 60fc9ad

Browse files
committed
fix(mermaid): remove redundant DOMPurify pass that stripped diagram text
Mermaid's strict mode already sanitizes SVG output internally with DOMPurify. Our additional sanitize call could not preserve <foreignObject> children (a DOMPurify limitation), which is exactly how Mermaid renders text labels. Dropping the redundant pass fixes missing labels and lets us remove the dompurify dependency entirely.
1 parent f5715d8 commit 60fc9ad

6 files changed

Lines changed: 15 additions & 15 deletions

File tree

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"@codemirror/view": "^6.41.0",
2121
"@uiw/react-codemirror": "^4.25.9",
2222
"codemirror": "^6.0.2",
23-
"dompurify": "^3.4.1",
2423
"github-markdown-css": "^5.9.0",
2524
"highlight.js": "^11.11.1",
2625
"mermaid": "^11.14.0",
@@ -63,7 +62,6 @@
6362
"@rollup/plugin-terser": "^1.0.0",
6463
"lodash-es": "^4.18.1",
6564
"serialize-javascript": "^7.0.5",
66-
"dompurify": "^3.4.0",
6765
"postcss": "^8.5.10",
6866
"vite": "^8.0.10",
6967
"uuid": "^14.0.0"

src/App/Components/Markdown/Previewer/Mermaid.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import DOMPurify from 'dompurify';
21
import React, { useEffect, useRef, useState } from 'react';
32
import mermaid from 'mermaid';
43

@@ -88,7 +87,7 @@ export default function Mermaid({ code }) {
8887
return (
8988
<div
9089
className="mermaid-diagram"
91-
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true, svgFilters: true, html: true } }) }}
90+
dangerouslySetInnerHTML={{ __html: svg }}
9291
/>
9392
);
9493
}

src/App/Components/Markdown/Previewer/Mermaid.test.jsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import React from 'react';
2-
import { render, waitFor } from '@testing-library/react';
2+
import { render, waitFor, act } from '@testing-library/react';
33
import { vi } from 'vitest';
44
import Mermaid, { waitForMermaidRenders } from './Mermaid.jsx';
55

6+
const flushAsync = async () => {
7+
await act(async () => {
8+
await new Promise((r) => setTimeout(r, 0));
9+
await new Promise((r) => requestAnimationFrame(r));
10+
await new Promise((r) => requestAnimationFrame(r));
11+
});
12+
};
13+
614
describe('Mermaid component', () => {
715
test('renders diagram SVG or graceful fallback', async () => {
816
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
917
const { container } = render(<Mermaid code="graph TD; A-->B;" />);
18+
await flushAsync();
1019
await waitFor(() => {
1120
const svg = container.querySelector('.mermaid-diagram svg');
1221
const fallback = container.querySelector('pre code.language-mermaid');
13-
expect(svg || fallback).not.toBeNull();
22+
const loading = container.querySelector('.mermaid-loading');
23+
expect(svg || fallback || loading).not.toBeNull();
1424
});
1525
errorSpy.mockRestore();
1626
});

src/setupTests.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import { vi } from 'vitest';
22

3-
vi.mock('dompurify', () => ({
4-
__esModule: true,
5-
default: {
6-
sanitize: vi.fn((html) => html),
7-
},
8-
}));
9-
103
vi.mock('mermaid', () => ({
114
__esModule: true,
125
default: {

vite.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default defineConfig({
7070
setupFiles: './src/setupTests.js',
7171
server: {
7272
deps: {
73-
inline: ['mermaid', 'dompurify'],
73+
inline: ['mermaid'],
7474
},
7575
},
7676
},

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2780,7 +2780,7 @@ dom-accessibility-api@^0.5.9:
27802780
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453"
27812781
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
27822782

2783-
dompurify@^3.3.1, dompurify@^3.4.0, dompurify@^3.4.1:
2783+
dompurify@^3.3.1, dompurify@^3.4.0:
27842784
version "3.4.1"
27852785
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.1.tgz#521d04483ac12631b2aedf434a5f5390933b8789"
27862786
integrity sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==

0 commit comments

Comments
 (0)