diff --git a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md index fa100744e..c388a4f26 100644 --- a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md +++ b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md @@ -19,4 +19,4 @@ The `parseError` function will not be called. #### Defined in -[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64) +[mermaidAPI.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L65) diff --git a/docs/config/setup/interfaces/mermaidAPI.ParseResult.md b/docs/config/setup/interfaces/mermaidAPI.ParseResult.md index 9f912cc8c..376f29346 100644 --- a/docs/config/setup/interfaces/mermaidAPI.ParseResult.md +++ b/docs/config/setup/interfaces/mermaidAPI.ParseResult.md @@ -18,4 +18,4 @@ The diagram type, e.g. 'flowchart', 'sequence', etc. #### Defined in -[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71) +[mermaidAPI.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L72) diff --git a/docs/config/setup/interfaces/mermaidAPI.RenderResult.md b/docs/config/setup/interfaces/mermaidAPI.RenderResult.md index b5cc48038..52ef3ec0c 100644 --- a/docs/config/setup/interfaces/mermaidAPI.RenderResult.md +++ b/docs/config/setup/interfaces/mermaidAPI.RenderResult.md @@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present. #### Defined in -[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94) +[mermaidAPI.ts:95](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L95) --- @@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc. #### Defined in -[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84) +[mermaidAPI.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L85) --- @@ -63,4 +63,4 @@ The svg code for the rendered graph. #### Defined in -[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80) +[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81) diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index d17533a03..d7bfe68ef 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -26,7 +26,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) #### Defined in -[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74) +[mermaidAPI.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L75) ## Variables @@ -155,7 +155,7 @@ the cleaned up svgCode #### Defined in -[mermaidAPI.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L222) +[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223) --- @@ -180,7 +180,7 @@ the string with all the user styles #### Defined in -[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153) +[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154) --- @@ -203,7 +203,7 @@ the string with all the user styles #### Defined in -[mermaidAPI.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L199) +[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200) --- @@ -230,7 +230,7 @@ with an enclosing block that has each of the cssClasses followed by !important; #### Defined in -[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138) +[mermaidAPI.ts:139](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L139) --- @@ -252,7 +252,6 @@ Put the svgCode into an iFrame. Return the iFrame code `string` - the code with the iFrame that now contains the svgCode - TODO replace btoa(). Replace with buf.toString('base64')? #### Defined in diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts index aa5c7a7fb..1134f8635 100644 --- a/packages/mermaid/src/mermaidAPI.spec.ts +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -69,6 +69,7 @@ vi.mock('stylis', () => { import { compile, serialize } from 'stylis'; import { decodeEntities, encodeEntities } from './utils.js'; import { Diagram } from './Diagram.js'; +import { toBase64 } from './utils/base64.js'; /** * @see https://vitest.dev/guide/mocking.html Mock part of a module @@ -176,7 +177,7 @@ describe('mermaidAPI', () => { }); describe('putIntoIFrame', () => { - const inputSvgCode = 'this is the SVG code'; + const inputSvgCode = 'this is the SVG code ⛵'; it('uses the default SVG iFrame height is used if no svgElement given', () => { const result = putIntoIFrame(inputSvgCode); @@ -199,11 +200,10 @@ describe('mermaidAPI', () => { }); it('sets src to base64 version of svgCode', () => { - const base64encodedSrc = btoa('' + inputSvgCode + ''); - const expectedRegExp = new RegExp('src="data:text/html;base64,' + base64encodedSrc + '"'); - + const base64encodedSrc = toBase64(`${inputSvgCode}`); + const expectedSrc = `src="data:text/html;charset=UTF-8;base64,${base64encodedSrc}"`; const result = putIntoIFrame(inputSvgCode); - expect(result).toMatch(expectedRegExp); + expect(result).toContain(expectedSrc); }); it('uses the height and appends px from the svgElement given', () => { diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 365467dbd..ee6696af9 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -31,6 +31,7 @@ import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility. import type { DiagramMetadata, DiagramStyleClassDef } from './diagram-api/types.js'; import { preprocessDiagram } from './preprocess.js'; import { decodeEntities } from './utils.js'; +import { toBase64 } from './utils/base64.js'; const MAX_TEXTLENGTH = 50_000; const MAX_TEXTLENGTH_EXCEEDED_MSG = @@ -248,14 +249,13 @@ export const cleanUpSvgCode = ( * @param svgCode - the svg code to put inside the iFrame * @param svgElement - the d3 node that has the current svgElement so we can get the height from it * @returns - the code with the iFrame that now contains the svgCode - * TODO replace btoa(). Replace with buf.toString('base64')? */ export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => { const height = svgElement?.viewBox?.baseVal?.height ? svgElement.viewBox.baseVal.height + 'px' : IFRAME_HEIGHT; - const base64encodedSrc = btoa('' + svgCode + ''); - return ``; }; diff --git a/packages/mermaid/src/utils/base64.ts b/packages/mermaid/src/utils/base64.ts new file mode 100644 index 000000000..4a0f5b295 --- /dev/null +++ b/packages/mermaid/src/utils/base64.ts @@ -0,0 +1,6 @@ +export function toBase64(str: string) { + // ref: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem + const utf8Bytes = new TextEncoder().encode(str); + const utf8Str = Array.from(utf8Bytes, (byte) => String.fromCodePoint(byte)).join(''); + return btoa(utf8Str); +}