diff --git a/packages/mermaid/src/diagrams/class/classDb.ts b/packages/mermaid/src/diagrams/class/classDb.ts index 851353477..18e218244 100644 --- a/packages/mermaid/src/diagrams/class/classDb.ts +++ b/packages/mermaid/src/diagrams/class/classDb.ts @@ -14,7 +14,14 @@ import { setDiagramTitle, getDiagramTitle, } from '../../commonDb'; -import { ClassRelation, ClassNode, ClassNote, ClassMap } from './classTypes'; +import { + ClassRelation, + ClassNode, + ClassNote, + ClassMap, + NamespaceMap, + NamespaceNode, +} from './classTypes'; const MERMAID_DOM_ID_PREFIX = 'classId-'; @@ -22,6 +29,8 @@ let relations: ClassRelation[] = []; let classes: ClassMap = {}; let notes: ClassNote[] = []; let classCounter = 0; +let namespaces: NamespaceMap = {}; +let namespaceCounter = 0; let functions: any[] = []; @@ -100,6 +109,8 @@ export const clear = function () { notes = []; functions = []; functions.push(setupToolTips); + namespaces = {}; + namespaceCounter = 0; commonClear(); }; @@ -393,14 +404,28 @@ const setDirection = (dir: string) => { }; /** - * Function called by parser when a namespace keyword has been found. + * Function called by parser when a namespace definition has been found. * * @param id - Id of the namespace to add * @public */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export const addNamespace = function (id: string) { - // TODO: Implement here +export const addNamespace = function (name: string) { + namespaces[name] = { + id: name, + domId: MERMAID_DOM_ID_PREFIX + name + '-' + namespaceCounter, + classes: {}, + children: {}, + }; + + namespaceCounter++; +}; + +const getNamespace = function (name: string): NamespaceNode { + return namespaces[name]; +}; + +const getNamespaces = function (): NamespaceMap { + return namespaces; }; /** @@ -410,9 +435,14 @@ export const addNamespace = function (id: string) { * @param classNames - Ids of the class to add * @public */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars export const addClassesToNamespace = function (id: string, classNames: string[]) { - // TODO: Implement here + if (namespaces[id] !== undefined) { + classNames.map((className) => { + namespaces[id].classes[className] = classes[className]; + delete classes[className]; + classCounter--; + }); + } }; export default { @@ -450,4 +480,6 @@ export default { setClassLabel, addNamespace, addClassesToNamespace, + getNamespace, + getNamespaces, }; diff --git a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts index 11b556179..48d7ca64d 100644 --- a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts +++ b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts @@ -1008,6 +1008,25 @@ foo() expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall'); expect(classDb.setTooltip).toHaveBeenCalledWith('Class1', 'A tooltip'); }); + + it('should add classes namespaces', function () { + const str = `classDiagram +namespace Namespace1 { +class Class1 { +int : test +string : foo +test() +foo() +} +class Class2 +}`; + parser.parse(str); + + const testNamespace = parser.yy.getNamespace('Namespace1'); + expect(Object.keys(testNamespace.classes).length).toBe(2); + expect(Object.keys(testNamespace.children).length).toBe(0); + expect(testNamespace.classes['Class1'].id).toBe('Class1'); + }); }); describe('when parsing classDiagram with text labels', () => { diff --git a/packages/mermaid/src/diagrams/class/classTypes.ts b/packages/mermaid/src/diagrams/class/classTypes.ts index 4cacad3db..cf6f20f0b 100644 --- a/packages/mermaid/src/diagrams/class/classTypes.ts +++ b/packages/mermaid/src/diagrams/class/classTypes.ts @@ -52,4 +52,13 @@ export type ClassRelation = { lineType: number; }; }; + +export interface NamespaceNode { + id: string; + domId: string; + classes: ClassMap; + children: NamespaceMap; +} + export type ClassMap = Record; +export type NamespaceMap = Record;