diff --git a/.changeset/fair-swans-allow.md b/.changeset/fair-swans-allow.md new file mode 100644 index 00000000000..e02d07e9d49 --- /dev/null +++ b/.changeset/fair-swans-allow.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: Prevent browser hang when using multiline accDescr in XY charts diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison index 33575b9466b..023c5abdbc4 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison @@ -26,7 +26,7 @@ "accDescr"\s*":"\s* { this.pushState("acc_descr");return 'acc_descr'; } (?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; } "accDescr"\s*"{"\s* { this.pushState("acc_descr_multiline");} -"{" { this.popState(); } +"}" { this.popState(); } [^\}]* { return "acc_descr_multiline_value"; } "xychart-beta" {return 'XYCHART';} diff --git a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts index 40997282854..693175ae6fb 100644 --- a/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts +++ b/packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts @@ -19,6 +19,8 @@ const mockDB: Record> = { setYAxisRangeData: vi.fn(), setLineData: vi.fn(), setBarData: vi.fn(), + setAccTitle: vi.fn(), + setAccDescription: vi.fn(), }; function clearMocks() { @@ -440,4 +442,43 @@ describe('Testing xychart jison file', () => { [45, 99, 12] ); }); + + describe('accessibility', () => { + it('should handle accTitle', () => { + const str = 'xychart\naccTitle: Accessible Title\nx-axis [Q1, Q2]\nline [1, 2]'; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setAccTitle).toHaveBeenCalledWith('Accessible Title'); + }); + + it('should handle single-line accDescr', () => { + const str = 'xychart\naccDescr: This is a description\nx-axis [Q1, Q2]\nline [1, 2]'; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setAccDescription).toHaveBeenCalledWith('This is a description'); + }); + + it('should handle multiline accDescr', () => { + const str = `xychart +accDescr { + This is a multiline + description +} +x-axis [Q1, Q2] +line [1, 2]`; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setAccDescription).toHaveBeenCalledWith('This is a multiline\n description'); + }); + + it('should handle both accTitle and accDescr', () => { + const str = `xychart +accTitle: Sales Overview +accDescr: Revenue report for Q1-Q4 +title "Revenue Report" +x-axis [Q1, Q2, Q3, Q4] +line [45, 67, 89, 55]`; + expect(parserFnConstructor(str)).not.toThrow(); + expect(mockDB.setAccTitle).toHaveBeenCalledWith('Sales Overview'); + expect(mockDB.setAccDescription).toHaveBeenCalledWith('Revenue report for Q1-Q4'); + expect(mockDB.setDiagramTitle).toHaveBeenCalledWith('Revenue Report'); + }); + }); });