From d8ccf759e4b972e1b0f86f41f892bbd3026e1107 Mon Sep 17 00:00:00 2001 From: ishikawa999 <14245262+ishikawa999@users.noreply.github.com> Date: Thu, 17 Sep 2026 08:59:25 +0900 Subject: [PATCH 2/2] Render code blocks highlighted as mermaid into diagrams Includes 0003-parse-error-to-flash-error-message.patch by Florian Walchshofer from https://www.redmine.org/issues/44425 --- .github/workflows/tests.yml | 3 + app/helpers/application_helper.rb | 10 ++ .../controllers/mermaid_controller.js | 109 +++++++++++++++++ .../wiki_formatting/syntax_highlight.rb | 10 ++ test/helpers/application_helper_test.rb | 5 + test/system/mermaid_rendering_test.rb | 113 ++++++++++++++++++ .../syntax_highlight_scrubber_test.rb | 40 +++++++ .../textile/syntax_highlight_scrubber_test.rb | 80 +++++++++++++ 8 files changed, 370 insertions(+) create mode 100644 app/javascript/controllers/mermaid_controller.js create mode 100644 test/system/mermaid_rendering_test.rb create mode 100644 test/unit/lib/redmine/wiki_formatting/textile/syntax_highlight_scrubber_test.rb diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1af103373..ef4f1f3ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -86,6 +86,9 @@ jobs: - name: Display Chrome version run: google-chrome --version + - name: Install mermaid.js for the mermaid rendering tests + run: bin/rails redmine:mermaid:install + - name: Run system tests run: bin/rails test:system env: diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 308077087..10ea8eb4d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1830,6 +1830,16 @@ module ApplicationHelper 'tribute-5.1.3.min' ) tags << javascript_include_tag('application-legacy', 'responsive') + # mermaid.js is installed by the redmine:mermaid:install task and is + # several MB, so it is not part of every page load. When it is available, + # its URL is exposed here and the mermaid Stimulus controller loads it + # only when a ```mermaid code block is actually present on the page. + if Redmine::Mermaid.available? + tags << + javascript_tag( + "window.MermaidAssetUrl = #{asset_path(Redmine::Mermaid::FILENAME).to_json};" + ) + end unless User.current.pref.warn_on_leaving_unsaved == '0' warn_text = escape_javascript(l(:text_warn_on_leaving_unsaved)) tags << diff --git a/app/javascript/controllers/mermaid_controller.js b/app/javascript/controllers/mermaid_controller.js new file mode 100644 index 000000000..7a4a31a5d --- /dev/null +++ b/app/javascript/controllers/mermaid_controller.js @@ -0,0 +1,109 @@ +/** + * Redmine - project management software + * Copyright (C) 2006- Jean-Philippe Lang + * This code is released under the GNU General Public License. + */ +import { Controller } from "@hotwired/stimulus" + +let mermaidInitialized = false; +let mermaidLoadPromise = null; + +// mermaid.js is not bundled with Redmine; administrators install it with +// `bin/rails redmine:mermaid:install`. When it is available, javascript_heads +// exposes its URL as window.MermaidAssetUrl. It is several MB, so it is only +// fetched (as a classic