Project

General

Profile

Defect #44664 » fix-mermaid-duplicate-svg-ids_r25293.patch

Takenori TAKAKI, 2026-10-23 03:41

View differences:

app/javascript/controllers/mermaid_controller.js
13 13

  
14 14
let mermaidInitialized = false;
15 15
let mermaidLoadPromise = null;
16
let renderCount = 0;
16 17

  
17 18
// Mermaid.js is not bundled with Redmine; administrators install it with
18 19
// `bin/rails redmine:mermaid:install`. When it is available, javascript_heads
......
91 92

  
92 93
    const container = document.createElement('div');
93 94
    container.className = 'mermaid';
94
    container.textContent = this.element.textContent.trim();
95
    const source = this.element.textContent.trim();
96
    container.textContent = source;
95 97
    // Keep the source text in the container from flashing until Mermaid.js
96 98
    // replaces it with the diagram. Mermaid.js measures the diagram inside
97 99
    // the container, so it is made invisible rather than display: none, and
......
104 106

  
105 107
    // On failure, show a Redmine flash message while keeping the source block
106 108
    // visible, so that the invalid diagram can be inspected and copied.
107
    mermaid.run({ nodes: [container], suppressErrors: false }).then(() => {
109
    mermaid.render(`redmine-mermaid-${++renderCount}`, source, container).then(({ svg, bindFunctions }) => {
110
      container.innerHTML = svg;
111
      bindFunctions?.(container);
108 112
      pre.style.display = 'none';
109 113
      container.style.visibility = container.style.position = container.style.insetInline = '';
110 114
      if (this.container === container) this.addDownloadLink(pre, container);
test/system/mermaid_rendering_test.rb
56 56
    end
57 57
  end
58 58

  
59
  def test_should_render_multiple_mermaid_diagrams_with_unique_ids
60
    skip unless mermaid_installed?
61

  
62
    issue = Issue.find(1)
63
    issue.update_column(
64
      :description,
65
      [
66
        "graph TD;\nA-->B;", "graph TD;\nC-->D;",
67
        "sequenceDiagram\nAlice->>Bob: Hi", "sequenceDiagram\nBob->>Alice: Hello",
68
        "pie\n\"X\" : 1\n\"Y\" : 2", "classDiagram\nclass Foo"
69
      ].map {|source| "```mermaid\n#{source}\n```"}.join("\n\n")
70
    )
71

  
72
    log_user('jsmith', 'jsmith')
73
    visit "/issues/#{issue.id}"
74

  
75
    within('div.description') do
76
      assert_selector 'div.mermaid svg', count: 6
77
      assert_no_selector 'svg .error-icon'
78
    end
79
    ids = page.evaluate_script("Array.from(document.querySelectorAll('div.mermaid svg')).map(svg => svg.id)")
80
    assert_equal ids.uniq, ids
81
  end
82

  
59 83
  def test_should_show_flash_message_for_invalid_mermaid_diagram
60 84
    skip unless mermaid_installed?
61 85

  
(3-3/3)