diff --git a/packages/mermaid/src/diagrams/c4/svgDraw.js b/packages/mermaid/src/diagrams/c4/svgDraw.js
index 5ca2f55f81..9ec7422613 100644
--- a/packages/mermaid/src/diagrams/c4/svgDraw.js
+++ b/packages/mermaid/src/diagrams/c4/svgDraw.js
@@ -1,5 +1,5 @@
import common from '../common/common.js';
-import * as svgDrawCommon from '../common/svgDrawCommon';
+import * as svgDrawCommon from '../common/svgDrawCommon.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
export const drawRect = function (elem, rectData) {
diff --git a/packages/mermaid/src/diagrams/common/common.spec.js b/packages/mermaid/src/diagrams/common/common.spec.ts
similarity index 76%
rename from packages/mermaid/src/diagrams/common/common.spec.js
rename to packages/mermaid/src/diagrams/common/common.spec.ts
index d1c68e8926..cfef5d58d3 100644
--- a/packages/mermaid/src/diagrams/common/common.spec.js
+++ b/packages/mermaid/src/diagrams/common/common.spec.ts
@@ -1,15 +1,15 @@
import { sanitizeText, removeScript, parseGenericTypes } from './common.js';
-describe('when securityLevel is antiscript, all script must be removed', function () {
+describe('when securityLevel is antiscript, all script must be removed', () => {
/**
- * @param {string} original The original text
- * @param {string} result The expected sanitized text
+ * @param original - The original text
+ * @param result - The expected sanitized text
*/
- function compareRemoveScript(original, result) {
+ function compareRemoveScript(original: string, result: string) {
expect(removeScript(original).trim()).toEqual(result);
}
- it('should remove all script block, script inline.', function () {
+ it('should remove all script block, script inline.', () => {
const labelString = `1
Act1: Hello 11
Act2:
@@ -25,7 +25,7 @@ describe('when securityLevel is antiscript, all script must be removed', functio
compareRemoveScript(labelString, exactlyString);
});
- it('should remove all javascript urls', function () {
+ it('should remove all javascript urls', () => {
compareRemoveScript(
`This is a clean link + clean link
and me too`,
@@ -34,11 +34,11 @@ describe('when securityLevel is antiscript, all script must be removed', functio
);
});
- it('should detect malicious images', function () {
+ it('should detect malicious images', () => {
compareRemoveScript(``, ``);
});
- it('should detect iframes', function () {
+ it('should detect iframes', () => {
compareRemoveScript(
`
`,
@@ -47,8 +47,8 @@ describe('when securityLevel is antiscript, all script must be removed', functio
});
});
-describe('Sanitize text', function () {
- it('should remove script tag', function () {
+describe('Sanitize text', () => {
+ it('should remove script tag', () => {
const maliciousStr = 'javajavascript:script:alert(1)';
const result = sanitizeText(maliciousStr, {
securityLevel: 'strict',
@@ -58,8 +58,8 @@ describe('Sanitize text', function () {
});
});
-describe('generic parser', function () {
- it('should parse generic types', function () {
+describe('generic parser', () => {
+ it('should parse generic types', () => {
expect(parseGenericTypes('test~T~')).toEqual('test');
expect(parseGenericTypes('test~Array~Array~string~~~')).toEqual('test>>');
expect(parseGenericTypes('test~Array~Array~string[]~~~')).toEqual(
diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts
index 243c0cbf25..24591642b2 100644
--- a/packages/mermaid/src/diagrams/common/common.ts
+++ b/packages/mermaid/src/diagrams/common/common.ts
@@ -1,6 +1,7 @@
import DOMPurify from 'dompurify';
import { MermaidConfig } from '../../config.type.js';
+// Remove and ignore br:s
export const lineBreakRegex = /
/gi;
/**
diff --git a/packages/mermaid/src/diagrams/common/commonTypes.ts b/packages/mermaid/src/diagrams/common/commonTypes.ts
new file mode 100644
index 0000000000..84c26db6e1
--- /dev/null
+++ b/packages/mermaid/src/diagrams/common/commonTypes.ts
@@ -0,0 +1,58 @@
+export interface RectData {
+ x: number;
+ y: number;
+ fill: string;
+ width: number;
+ height: number;
+ stroke: string;
+ class?: string;
+ color?: string;
+ rx?: number;
+ ry?: number;
+ attrs?: Record;
+ anchor?: string;
+}
+
+export interface Bound {
+ startx: number;
+ stopx: number;
+ starty: number;
+ stopy: number;
+ fill: string;
+ stroke: string;
+}
+
+export interface TextData {
+ x: number;
+ y: number;
+ anchor: string;
+ text: string;
+ textMargin: number;
+ class?: string;
+}
+
+export interface TextObject {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+ fill?: string;
+ anchor?: string;
+ 'text-anchor': string;
+ style: string;
+ textMargin: number;
+ rx: number;
+ ry: number;
+ tspan: boolean;
+ valign?: string;
+}
+
+export type D3RectElement = d3.Selection;
+
+export type D3UseElement = d3.Selection;
+
+export type D3ImageElement = d3.Selection;
+
+export type D3TextElement = d3.Selection;
+
+export type D3TSpanElement = d3.Selection;
diff --git a/packages/mermaid/src/diagrams/common/svgDrawCommon.js b/packages/mermaid/src/diagrams/common/svgDrawCommon.js
deleted file mode 100644
index 9a4ce8aa2b..0000000000
--- a/packages/mermaid/src/diagrams/common/svgDrawCommon.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import { sanitizeUrl } from '@braintree/sanitize-url';
-
-export const drawRect = function (elem, rectData) {
- const rectElem = elem.append('rect');
- rectElem.attr('x', rectData.x);
- rectElem.attr('y', rectData.y);
- rectElem.attr('fill', rectData.fill);
- rectElem.attr('stroke', rectData.stroke);
- rectElem.attr('width', rectData.width);
- rectElem.attr('height', rectData.height);
- rectElem.attr('rx', rectData.rx);
- rectElem.attr('ry', rectData.ry);
-
- if (rectData.attrs !== 'undefined' && rectData.attrs !== null) {
- for (let attrKey in rectData.attrs) {
- rectElem.attr(attrKey, rectData.attrs[attrKey]);
- }
- }
-
- if (rectData.class !== 'undefined') {
- rectElem.attr('class', rectData.class);
- }
-
- return rectElem;
-};
-
-/**
- * Draws a background rectangle
- *
- * @param {any} elem Diagram (reference for bounds)
- * @param {any} bounds Shape of the rectangle
- */
-export const drawBackgroundRect = function (elem, bounds) {
- const rectElem = drawRect(elem, {
- x: bounds.startx,
- y: bounds.starty,
- width: bounds.stopx - bounds.startx,
- height: bounds.stopy - bounds.starty,
- fill: bounds.fill,
- stroke: bounds.stroke,
- class: 'rect',
- });
- rectElem.lower();
-};
-
-export const drawText = function (elem, textData) {
- // Remove and ignore br:s
- const nText = textData.text.replace(/
/gi, ' ');
-
- const textElem = elem.append('text');
- textElem.attr('x', textData.x);
- textElem.attr('y', textData.y);
- textElem.attr('class', 'legend');
-
- textElem.style('text-anchor', textData.anchor);
-
- if (textData.class !== undefined) {
- textElem.attr('class', textData.class);
- }
-
- const span = textElem.append('tspan');
- span.attr('x', textData.x + textData.textMargin * 2);
- span.text(nText);
-
- return textElem;
-};
-
-export const drawImage = function (elem, x, y, link) {
- const imageElem = elem.append('image');
- imageElem.attr('x', x);
- imageElem.attr('y', y);
- var sanitizedLink = sanitizeUrl(link);
- imageElem.attr('xlink:href', sanitizedLink);
-};
-
-export const drawEmbeddedImage = function (elem, x, y, link) {
- const imageElem = elem.append('use');
- imageElem.attr('x', x);
- imageElem.attr('y', y);
- const sanitizedLink = sanitizeUrl(link);
- imageElem.attr('xlink:href', '#' + sanitizedLink);
-};
-
-export const getNoteRect = function () {
- return {
- x: 0,
- y: 0,
- width: 100,
- height: 100,
- fill: '#EDF2AE',
- stroke: '#666',
- anchor: 'start',
- rx: 0,
- ry: 0,
- };
-};
-
-export const getTextObj = function () {
- return {
- x: 0,
- y: 0,
- width: 100,
- height: 100,
- fill: undefined,
- anchor: undefined,
- 'text-anchor': 'start',
- style: '#666',
- textMargin: 0,
- rx: 0,
- ry: 0,
- tspan: true,
- valign: undefined,
- };
-};
diff --git a/packages/mermaid/src/diagrams/common/svgDrawCommon.ts b/packages/mermaid/src/diagrams/common/svgDrawCommon.ts
new file mode 100644
index 0000000000..706d43ab9d
--- /dev/null
+++ b/packages/mermaid/src/diagrams/common/svgDrawCommon.ts
@@ -0,0 +1,126 @@
+import { sanitizeUrl } from '@braintree/sanitize-url';
+import type { Group, SVG } from '../../diagram-api/types.js';
+import type {
+ Bound,
+ D3ImageElement,
+ D3RectElement,
+ D3TSpanElement,
+ D3TextElement,
+ D3UseElement,
+ RectData,
+ TextData,
+ TextObject,
+} from './commonTypes.js';
+import { lineBreakRegex } from './common.js';
+
+export const drawRect = (element: SVG | Group, rectData: RectData): D3RectElement => {
+ const rectElement: D3RectElement = element.append('rect');
+ rectElement.attr('x', rectData.x);
+ rectElement.attr('y', rectData.y);
+ rectElement.attr('fill', rectData.fill);
+ rectElement.attr('stroke', rectData.stroke);
+ rectElement.attr('width', rectData.width);
+ rectElement.attr('height', rectData.height);
+ rectData.rx !== undefined && rectElement.attr('rx', rectData.rx);
+ rectData.ry !== undefined && rectElement.attr('ry', rectData.ry);
+
+ if (rectData.attrs !== undefined) {
+ for (const attrKey in rectData.attrs) {
+ rectElement.attr(attrKey, rectData.attrs[attrKey]);
+ }
+ }
+
+ rectData.class !== undefined && rectElement.attr('class', rectData.class);
+
+ return rectElement;
+};
+
+/**
+ * Draws a background rectangle
+ *
+ * @param element - Diagram (reference for bounds)
+ * @param bounds - Shape of the rectangle
+ */
+export const drawBackgroundRect = (element: SVG | Group, bounds: Bound): void => {
+ const rectData: RectData = {
+ x: bounds.startx,
+ y: bounds.starty,
+ width: bounds.stopx - bounds.startx,
+ height: bounds.stopy - bounds.starty,
+ fill: bounds.fill,
+ stroke: bounds.stroke,
+ class: 'rect',
+ };
+ const rectElement: D3RectElement = drawRect(element, rectData);
+ rectElement.lower();
+};
+
+export const drawText = (element: SVG | Group, textData: TextData): D3TextElement => {
+ const nText: string = textData.text.replace(lineBreakRegex, ' ');
+
+ const textElem: D3TextElement = element.append('text');
+ textElem.attr('x', textData.x);
+ textElem.attr('y', textData.y);
+ textElem.attr('class', 'legend');
+
+ textElem.style('text-anchor', textData.anchor);
+ textData.class !== undefined && textElem.attr('class', textData.class);
+
+ const tspan: D3TSpanElement = textElem.append('tspan');
+ tspan.attr('x', textData.x + textData.textMargin * 2);
+ tspan.text(nText);
+
+ return textElem;
+};
+
+export const drawImage = (elem: SVG | Group, x: number, y: number, link: string): void => {
+ const imageElement: D3ImageElement = elem.append('image');
+ imageElement.attr('x', x);
+ imageElement.attr('y', y);
+ const sanitizedLink: string = sanitizeUrl(link);
+ imageElement.attr('xlink:href', sanitizedLink);
+};
+
+export const drawEmbeddedImage = (
+ element: SVG | Group,
+ x: number,
+ y: number,
+ link: string
+): void => {
+ const imageElement: D3UseElement = element.append('use');
+ imageElement.attr('x', x);
+ imageElement.attr('y', y);
+ const sanitizedLink: string = sanitizeUrl(link);
+ imageElement.attr('xlink:href', `#${sanitizedLink}`);
+};
+
+export const getNoteRect = (): RectData => {
+ const noteRectData: RectData = {
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 100,
+ fill: '#EDF2AE',
+ stroke: '#666',
+ anchor: 'start',
+ rx: 0,
+ ry: 0,
+ };
+ return noteRectData;
+};
+
+export const getTextObj = (): TextObject => {
+ const testObject: TextObject = {
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 100,
+ 'text-anchor': 'start',
+ style: '#666',
+ textMargin: 0,
+ rx: 0,
+ ry: 0,
+ tspan: true,
+ };
+ return testObject;
+};
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
index f6fde5001d..feee7157f7 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
+++ b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
@@ -3,7 +3,7 @@ import { select, selectAll } from 'd3';
import svgDraw, { ACTOR_TYPE_WIDTH, drawText, fixLifeLineHeights } from './svgDraw.js';
import { log } from '../../logger.js';
import common from '../common/common.js';
-import * as svgDrawCommon from '../common/svgDrawCommon';
+import * as svgDrawCommon from '../common/svgDrawCommon.js';
import * as configApi from '../../config.js';
import assignWithDepth from '../../assignWithDepth.js';
import utils from '../../utils.js';
diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js
index 0c7bc64213..e0aaa1eb93 100644
--- a/packages/mermaid/src/diagrams/sequence/svgDraw.js
+++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js
@@ -1,5 +1,5 @@
import common from '../common/common.js';
-import * as svgDrawCommon from '../common/svgDrawCommon';
+import * as svgDrawCommon from '../common/svgDrawCommon.js';
import { addFunction } from '../../interactionDb.js';
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
diff --git a/packages/mermaid/src/diagrams/user-journey/svgDraw.js b/packages/mermaid/src/diagrams/user-journey/svgDraw.js
index 108f4b2f96..7a8f791fac 100644
--- a/packages/mermaid/src/diagrams/user-journey/svgDraw.js
+++ b/packages/mermaid/src/diagrams/user-journey/svgDraw.js
@@ -1,5 +1,5 @@
import { arc as d3arc } from 'd3';
-import * as svgDrawCommon from '../common/svgDrawCommon';
+import * as svgDrawCommon from '../common/svgDrawCommon.js';
export const drawRect = function (elem, rectData) {
return svgDrawCommon.drawRect(elem, rectData);