diff --git a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts index aa5e514e0..489b4703b 100644 --- a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts +++ b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts @@ -88,6 +88,50 @@ describe('given a basic class diagram, ', function () { expect(relations[0].title).toBe('generates'); }); + it('should handle link statements within namespaces', function () { + spyOn(classDb, 'setLink'); + const str = `classDiagram + namespace MyNamespace { + class UserService { + +createUser() + +deleteUser() + } + + class PaymentService { + +processPayment() + +refund() + } + + link UserService "https://example.com/user-service" + link PaymentService "https://example.com/payment-service" "Payment Service Documentation" + }`; + + parser.parse(str); + + // Verify setLink was called for both classes + expect(classDb.setLink).toHaveBeenCalledWith( + 'UserService', + 'https://example.com/user-service' + ); + expect(classDb.setLink).toHaveBeenCalledWith( + 'PaymentService', + 'https://example.com/payment-service' + ); + + // Verify the classes have the correct links and are in the namespace + const userService = classDb.getClass('UserService'); + const paymentService = classDb.getClass('PaymentService'); + + expect(userService.parent).toBe('MyNamespace'); + expect(userService.link).toBe('https://example.com/user-service'); + expect(userService.cssClasses).toBe('default clickable'); + + expect(paymentService.parent).toBe('MyNamespace'); + expect(paymentService.link).toBe('https://example.com/payment-service'); + expect(paymentService.tooltip).toBe('Payment Service Documentation'); + expect(paymentService.cssClasses).toBe('default clickable'); + }); + it('should handle accTitle and accDescr', function () { const str = `classDiagram accTitle: My Title diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison index 9a1f991a7..041dc3704 100644 --- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison +++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison @@ -275,14 +275,25 @@ statement ; namespaceStatement - : namespaceIdentifier STRUCT_START classStatements STRUCT_STOP { yy.addClassesToNamespace($1, $3); } - | namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP { yy.addClassesToNamespace($1, $4); } + : namespaceIdentifier STRUCT_START namespaceBodyStatements STRUCT_STOP { yy.addClassesToNamespace($1, $3); } + | namespaceIdentifier STRUCT_START NEWLINE namespaceBodyStatements STRUCT_STOP { yy.addClassesToNamespace($1, $4); } ; namespaceIdentifier : NAMESPACE namespaceName { $$=$2; yy.addNamespace($2); } ; +namespaceBodyStatements + : namespaceBodyStatement { $$=[$1].filter(s => s !== null); } + | namespaceBodyStatement NEWLINE { $$=[$1].filter(s => s !== null); } + | namespaceBodyStatement NEWLINE namespaceBodyStatements { var filtered = [$1].filter(s => s !== null); $3.unshift(...filtered); $$=$3; } + ; + +namespaceBodyStatement + : classStatement { $$=$1; } + | clickStatement { $$=null; /* clickStatements don't return class names, but are processed for side effects */ } + ; + classStatements : classStatement {$$=[$1]} | classStatement NEWLINE {$$=[$1]} diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md index 7ef81b96f..12bd9d3c8 100644 --- a/packages/mermaid/src/docs/syntax/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -452,6 +452,7 @@ classDiagram It is possible to bind a click event to a node. The click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. You would define these actions on a separate line after all classes have been declared. +If you have classes defined within a namespace, you can also add interaction definitions within the namespace definition, after the class(es) is defined ``` action className "reference" "tooltip"