diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt index 5f72ea22130..8b44cbb9c68 100644 --- a/.cspell/code-terms.txt +++ b/.cspell/code-terms.txt @@ -89,6 +89,7 @@ MULT NODIR NSTR outdir +parsererror Qcontrolx QSTR reinit diff --git a/.gitignore b/.gitignore index 7eb55d5cbab..7931d1ed618 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ coverage/ dist v8-compile-cache-0 +node-compile-cache/ yarn-error.log .npmrc diff --git a/demos/sandboxBaseUrl-test.html b/demos/sandboxBaseUrl-test.html new file mode 100644 index 00000000000..3bec452da2b --- /dev/null +++ b/demos/sandboxBaseUrl-test.html @@ -0,0 +1,294 @@ + + + + + + sandboxBaseUrl Feature Test + + + +

🧪 sandboxBaseUrl Feature Test

+ +
+ What this tests: The sandboxBaseUrl config option enables + relative URLs in diagram links to work correctly when using + securityLevel: 'sandbox'. +
+ +
+ Before testing: You need to build mermaid first. Run from the repo root: +
pnpm install && pnpm build
+
+ + +
+

Test 1: With sandboxBaseUrl (should work)

+
+ Expected: Clicking "Details Page" should navigate to the resolved URL + (shown in browser console). Clicking "GitHub" should open GitHub. +
+
+
+flowchart TD
+    A[Home Page] --> B[Details Page]
+    A --> C[GitHub]
+
+    click A "./" "Go to current directory"
+    click B "./details.html" "View details page"
+    click C "https://github.com/mermaid-js/mermaid" "View GitHub"
+      
+
+
+ + +
+

Test 2: Without sandboxBaseUrl (relative links won't work)

+
+ Expected: Clicking "Details Page" will fail (navigate to + about:blank#blocked). Clicking "GitHub" should still work (absolute URL). +
+
+
+flowchart TD
+    A[Home Page] --> B[Details Page]
+    A --> C[GitHub]
+
+    click A "./" "Go to current directory"
+    click B "./details.html" "View details page"
+    click C "https://github.com/mermaid-js/mermaid" "View GitHub"
+      
+
+
+ + +
+

Test 3: Various URL Types with sandboxBaseUrl

+
+ Tests different URL patterns: relative (./, ../), absolute (/), hash (#), and external + (https://) +
+
+
+flowchart LR
+    A[Relative ./] --> B[Parent ../]
+    B --> C[Absolute /]
+    C --> D[Hash #section]
+    D --> E[External URL]
+
+    click A "./page.html" "Relative path"
+    click B "../parent.html" "Parent directory"
+    click C "/root.html" "Absolute path"
+    click D "#test-section" "Hash link"
+    click E "https://mermaid.js.org" "External site"
+      
+
+
+ + +
+

Test 4: Strict Mode (non-sandbox) - Links Disabled

+
+ In strict mode, click functionality is disabled entirely (this is expected + behavior). +
+
+
+flowchart TD
+    A[Click me] --> B[Won't work]
+    click A "https://github.com" "This link is disabled in strict mode"
+      
+
+
+ +
+

Console Output

+
+ Check the browser console (F12) for resolved URLs and any errors. +
+
+ Waiting for mermaid to load... +
+
+ + + + + + + diff --git a/docs/config/setup/mermaid/interfaces/MermaidConfig.md b/docs/config/setup/mermaid/interfaces/MermaidConfig.md index f4c5b0b2b5e..36aa63a05fe 100644 --- a/docs/config/setup/mermaid/interfaces/MermaidConfig.md +++ b/docs/config/setup/mermaid/interfaces/MermaidConfig.md @@ -26,7 +26,7 @@ Defined in: [packages/mermaid/src/config.type.ts:132](https://github.com/mermaid > `optional` **architecture**: `ArchitectureDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204) +Defined in: [packages/mermaid/src/config.type.ts:219](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L219) --- @@ -34,7 +34,7 @@ Defined in: [packages/mermaid/src/config.type.ts:204](https://github.com/mermaid > `optional` **arrowMarkerAbsolute**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:151](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L151) +Defined in: [packages/mermaid/src/config.type.ts:166](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L166) Controls whether or arrow markers in html code are absolute paths or anchors. This matters if you are using base tag settings. @@ -45,7 +45,7 @@ This matters if you are using base tag settings. > `optional` **block**: `BlockDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L211) +Defined in: [packages/mermaid/src/config.type.ts:226](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L226) --- @@ -53,7 +53,7 @@ Defined in: [packages/mermaid/src/config.type.ts:211](https://github.com/mermaid > `optional` **c4**: `C4DiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:208](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L208) +Defined in: [packages/mermaid/src/config.type.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L223) --- @@ -61,7 +61,7 @@ Defined in: [packages/mermaid/src/config.type.ts:208](https://github.com/mermaid > `optional` **class**: `ClassDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197) +Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212) --- @@ -77,7 +77,7 @@ Defined in: [packages/mermaid/src/config.type.ts:123](https://github.com/mermaid > `optional` **deterministicIds**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L184) +Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199) This option controls if the generated ids of nodes in the SVG are generated randomly or based on a seed. @@ -93,7 +93,7 @@ should not change unless content is changed. > `optional` **deterministicIDSeed**: `string` -Defined in: [packages/mermaid/src/config.type.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L191) +Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206) This option is the optional seed for deterministic ids. If set to `undefined` but deterministicIds is `true`, a simple number iterator is used. @@ -105,7 +105,7 @@ You can set this attribute to base the seed on a static string. > `optional` **dompurifyConfig**: `Config` -Defined in: [packages/mermaid/src/config.type.ts:213](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L213) +Defined in: [packages/mermaid/src/config.type.ts:228](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L228) --- @@ -151,7 +151,7 @@ Elk specific option affecting how nodes are placed. > `optional` **er**: `ErDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199) +Defined in: [packages/mermaid/src/config.type.ts:214](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L214) --- @@ -159,7 +159,7 @@ Defined in: [packages/mermaid/src/config.type.ts:199](https://github.com/mermaid > `optional` **flowchart**: `FlowchartDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L192) +Defined in: [packages/mermaid/src/config.type.ts:207](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L207) --- @@ -179,7 +179,7 @@ See > `optional` **fontSize**: `number` -Defined in: [packages/mermaid/src/config.type.ts:215](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L215) +Defined in: [packages/mermaid/src/config.type.ts:230](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L230) --- @@ -187,7 +187,7 @@ Defined in: [packages/mermaid/src/config.type.ts:215](https://github.com/mermaid > `optional` **forceLegacyMathML**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:173](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L173) +Defined in: [packages/mermaid/src/config.type.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L188) This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS fonts and browser's MathML implementation, this option is recommended if consistent rendering is important. @@ -199,7 +199,7 @@ If set to true, ignores legacyMathML. > `optional` **gantt**: `GanttDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L194) +Defined in: [packages/mermaid/src/config.type.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L209) --- @@ -207,7 +207,7 @@ Defined in: [packages/mermaid/src/config.type.ts:194](https://github.com/mermaid > `optional` **gitGraph**: `GitGraphDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:207](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L207) +Defined in: [packages/mermaid/src/config.type.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L222) --- @@ -233,7 +233,7 @@ Defined in: [packages/mermaid/src/config.type.ts:124](https://github.com/mermaid > `optional` **journey**: `JourneyDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L195) +Defined in: [packages/mermaid/src/config.type.ts:210](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L210) --- @@ -241,7 +241,7 @@ Defined in: [packages/mermaid/src/config.type.ts:195](https://github.com/mermaid > `optional` **kanban**: `KanbanDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:206](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L206) +Defined in: [packages/mermaid/src/config.type.ts:221](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L221) --- @@ -259,7 +259,7 @@ Defines which layout algorithm to use for rendering the diagram. > `optional` **legacyMathML**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:166](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L166) +Defined in: [packages/mermaid/src/config.type.ts:181](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L181) This option specifies if Mermaid can expect the dependent to include KaTeX stylesheets for browsers without their own MathML implementation. If this option is disabled and MathML is not supported, the math @@ -292,7 +292,7 @@ Defines which main look to use for the diagram. > `optional` **markdownAutoWrap**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:216](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L216) +Defined in: [packages/mermaid/src/config.type.ts:231](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L231) --- @@ -320,7 +320,7 @@ The maximum allowed size of the users text diagram > `optional` **mindmap**: `MindmapDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205) +Defined in: [packages/mermaid/src/config.type.ts:220](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L220) --- @@ -328,7 +328,7 @@ Defined in: [packages/mermaid/src/config.type.ts:205](https://github.com/mermaid > `optional` **packet**: `PacketDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:210](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L210) +Defined in: [packages/mermaid/src/config.type.ts:225](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L225) --- @@ -336,7 +336,7 @@ Defined in: [packages/mermaid/src/config.type.ts:210](https://github.com/mermaid > `optional` **pie**: `PieDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200) +Defined in: [packages/mermaid/src/config.type.ts:215](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L215) --- @@ -344,7 +344,7 @@ Defined in: [packages/mermaid/src/config.type.ts:200](https://github.com/mermaid > `optional` **quadrantChart**: `QuadrantChartConfig` -Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201) +Defined in: [packages/mermaid/src/config.type.ts:216](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L216) --- @@ -352,7 +352,7 @@ Defined in: [packages/mermaid/src/config.type.ts:201](https://github.com/mermaid > `optional` **radar**: `RadarDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L212) +Defined in: [packages/mermaid/src/config.type.ts:227](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L227) --- @@ -360,7 +360,27 @@ Defined in: [packages/mermaid/src/config.type.ts:212](https://github.com/mermaid > `optional` **requirement**: `RequirementDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203) +Defined in: [packages/mermaid/src/config.type.ts:218](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L218) + +--- + +### sandboxBaseUrl? + +> `optional` **sandboxBaseUrl**: `string` + +Defined in: [packages/mermaid/src/config.type.ts:156](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L156) + +Base URL for resolving relative links in sandbox mode. + +When securityLevel is 'sandbox', relative URLs in diagram links cannot be resolved +because data: URIs have no base URL context. Providing sandboxBaseUrl enables Mermaid +to pre-resolve all relative URLs to absolute URLs before embedding in the sandbox iframe. + +This option only applies when securityLevel is 'sandbox'. + +Example: If your page is at , +set sandboxBaseUrl to '' to enable relative links +like './details.html' to work correctly. --- @@ -368,7 +388,7 @@ Defined in: [packages/mermaid/src/config.type.ts:203](https://github.com/mermaid > `optional` **sankey**: `SankeyDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L209) +Defined in: [packages/mermaid/src/config.type.ts:224](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L224) --- @@ -376,7 +396,7 @@ Defined in: [packages/mermaid/src/config.type.ts:209](https://github.com/mermaid > `optional` **secure**: `string`\[] -Defined in: [packages/mermaid/src/config.type.ts:158](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L158) +Defined in: [packages/mermaid/src/config.type.ts:173](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L173) This option controls which `currentConfig` keys are considered secure and can only be changed via call to `mermaid.initialize`. @@ -398,7 +418,7 @@ Level of trust for parsed diagram > `optional` **sequence**: `SequenceDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L193) +Defined in: [packages/mermaid/src/config.type.ts:208](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L208) --- @@ -406,7 +426,7 @@ Defined in: [packages/mermaid/src/config.type.ts:193](https://github.com/mermaid > `optional` **startOnLoad**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L145) +Defined in: [packages/mermaid/src/config.type.ts:160](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L160) Dictates whether mermaid starts on Page load @@ -416,7 +436,7 @@ Dictates whether mermaid starts on Page load > `optional` **state**: `StateDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198) +Defined in: [packages/mermaid/src/config.type.ts:213](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L213) --- @@ -424,7 +444,7 @@ Defined in: [packages/mermaid/src/config.type.ts:198](https://github.com/mermaid > `optional` **suppressErrorRendering**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L222) +Defined in: [packages/mermaid/src/config.type.ts:237](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L237) Suppresses inserting 'Syntax error' diagram in the DOM. This is useful when you want to control how to handle syntax errors in your application. @@ -462,7 +482,7 @@ Defined in: [packages/mermaid/src/config.type.ts:65](https://github.com/mermaid- > `optional` **timeline**: `TimelineDiagramConfig` -Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196) +Defined in: [packages/mermaid/src/config.type.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L211) --- @@ -470,7 +490,7 @@ Defined in: [packages/mermaid/src/config.type.ts:196](https://github.com/mermaid > `optional` **wrap**: `boolean` -Defined in: [packages/mermaid/src/config.type.ts:214](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L214) +Defined in: [packages/mermaid/src/config.type.ts:229](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L229) --- @@ -478,4 +498,4 @@ Defined in: [packages/mermaid/src/config.type.ts:214](https://github.com/mermaid > `optional` **xyChart**: `XYChartConfig` -Defined in: [packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202) +Defined in: [packages/mermaid/src/config.type.ts:217](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L217) diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 79fadd19531..66eec8f65a3 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -139,6 +139,21 @@ export interface MermaidConfig { * Level of trust for parsed diagram */ securityLevel?: 'strict' | 'loose' | 'antiscript' | 'sandbox'; + /** + * Base URL for resolving relative links in sandbox mode. + * + * When securityLevel is 'sandbox', relative URLs in diagram links cannot be resolved + * because data: URIs have no base URL context. Providing sandboxBaseUrl enables Mermaid + * to pre-resolve all relative URLs to absolute URLs before embedding in the sandbox iframe. + * + * This option only applies when securityLevel is 'sandbox'. + * + * Example: If your page is at https://example.com/docs/diagrams/arch.html, + * set sandboxBaseUrl to 'https://example.com/docs/diagrams/' to enable relative links + * like './details.html' to work correctly. + * + */ + sandboxBaseUrl?: string; /** * Dictates whether mermaid starts on Page load */ diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 80deda740fc..2544b0ac8a2 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -24,6 +24,7 @@ import theme from './themes/index.js'; import type { D3Element, ParseOptions, ParseResult, RenderResult } from './types.js'; import { decodeEntities } from './utils.js'; import { toBase64 } from './utils/base64.js'; +import { resolveRelativeUrlsInElement } from './utils/sandboxUrl.js'; const MAX_TEXTLENGTH = 50_000; const MAX_TEXTLENGTH_EXCEEDED_MSG = @@ -212,6 +213,7 @@ export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => { const height = svgElement?.viewBox?.baseVal?.height ? svgElement.viewBox.baseVal.height + 'px' : IFRAME_HEIGHT; + const base64encodedSrc = toBase64(`${svgCode}`); return `