Skip to content

Fix Mermaid diagrams failing when node labels contain line breaks#37296

Merged
silverwind merged 3 commits intogo-gitea:mainfrom
bircni:fix-37295
Apr 19, 2026
Merged

Fix Mermaid diagrams failing when node labels contain line breaks#37296
silverwind merged 3 commits intogo-gitea:mainfrom
bircni:fix-37295

Conversation

@bircni
Copy link
Copy Markdown
Member

@bircni bircni commented Apr 19, 2026

Mermaid code blocks that use line breaks inside node labels (for example A["line1\nline2"] or labels that resolve to multi-line text) could fail to render in Gitea. This change fixes that by disabling Mermaid’s HTML-based labels so the generated SVG stays well-formed XML for our client-side pipeline.

Root cause

Gitea renders Mermaid in the browser, then parses the returned SVG string with DOMParser using the image/svg+xml type before inserting it into the page. With Mermaid’s default htmlLabels: true, labels with line breaks are often emitted as HTML inside a foreignObject, including tags like <br> that are valid in HTML but not valid in XML. That output can break strict XML parsing of the SVG string (see mermaid-js/mermaid#1766).

What we changed

Set htmlLabels: false in mermaid.initialize() so labels are drawn with SVG text instead of HTML in foreignObject, producing SVG that parses cleanly as image/svg+xml.

Trade-offs

  • Pros: Restores reliable rendering for diagrams with line breaks in labels; aligns with securityLevel: 'strict' (less reliance on HTML inside diagrams).
  • Cons: Node/edge labels are no longer rendered via the HTML/foreignObject path, so rich HTML inside quoted label text may not behave like before; layout/wrapping of long labels may differ slightly.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Apr 19, 2026
@silverwind
Copy link
Copy Markdown
Member

The actual regression looks like it was introduced in #36547 (commit a60201a), which changed how the mermaid SVG string is attached to the iframe.

Before that PR, the SVG was embedded via iframe srcdoc:

iframe.srcdoc = html`<html><body>${htmlRaw(svg)}</body></html>`;

which the browser parsed as HTML, tolerating Mermaid's <br> inside foreignObject.

After the refactor (web_src/js/markup/mermaid.ts:204):

const svgDoc = parseDom(svgText, 'image/svg+xml');

the SVG string is now parsed as strict XML, which chokes on HTML-mode void tags — hence the 1.26 regression.

So htmlLabels: false works, but it's papering over the parser-mode change and sacrifices rich HTML labels in the process. A more targeted alternative would be to either:

  1. Parse the SVG string with text/html and extract the <svg> element, or
  2. Go back to embedding the raw SVG in the iframe srcdoc (HTML-tolerant parsing, restores pre-1.26 behavior including HTML labels).

Either would fix the reported bug without the HTML-labels trade-off.


Comment written by Claude Opus 4.7.

Copy link
Copy Markdown
Member

@silverwind silverwind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the right fix as per above. Also this fix should include regression tests.

@GiteaBot GiteaBot added lgtm/blocked A maintainer has reservations with the PR and thus it cannot be merged and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Apr 19, 2026
@wxiaoguang
Copy link
Copy Markdown
Contributor

Welcome to the one of the most complex parts of Gitea's code base: markup rendering.

@wxiaoguang
Copy link
Copy Markdown
Contributor

wxiaoguang commented Apr 19, 2026

This will fix: bb25bd1

@wxiaoguang wxiaoguang added type/bug backport/v1.26 This PR should be backported to Gitea 1.26 labels Apr 19, 2026
@wxiaoguang wxiaoguang marked this pull request as ready for review April 19, 2026 15:29
@wxiaoguang wxiaoguang requested a review from silverwind April 19, 2026 15:29
@silverwind
Copy link
Copy Markdown
Member

Seems ok but I'm unsure about the table special-casing that createElementFromHTML does and whether that would cause issues in mermaid. Parsing as text/html might be safer.

@wxiaoguang
Copy link
Copy Markdown
Contributor

Seems ok but I'm unsure about the table special-casing that createElementFromHTML does and whether that would cause issues in mermaid.

It won't. The table special-casing is a must for "td" elements, the same as jQuery does.

It doesn't affect other elements (which can be put into a div element)

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/blocked A maintainer has reservations with the PR and thus it cannot be merged labels Apr 19, 2026
@silverwind
Copy link
Copy Markdown
Member

Should merge #37297 first for green CI.

@wxiaoguang
Copy link
Copy Markdown
Contributor

No new issue caused by this change, and I have manually tested.

So, I think we can merge this now and backport ASAP to help users to get a nightly build.

@silverwind silverwind merged commit 284298f into go-gitea:main Apr 19, 2026
25 of 26 checks passed
@GiteaBot GiteaBot added this to the 1.27.0 milestone Apr 19, 2026
@silverwind
Copy link
Copy Markdown
Member

I was able to merge with non-green CI, apparently there is no protection for that configured on the repo, so it's fine.

@bircni bircni deleted the fix-37295 branch April 19, 2026 15:40
@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 19, 2026

I was able to merge with non-green CI, apparently there is no protection for that configured on the repo, so it's fine.

thats not fine thats really bad

@wxiaoguang wxiaoguang added backport/done All backports for this PR have been created backport/manual No power to the bots! Create your backport yourself! labels Apr 19, 2026
@wxiaoguang
Copy link
Copy Markdown
Contributor

Backport Fix Mermaid diagrams failing when node labels contain line breaks #37299

wxiaoguang added a commit that referenced this pull request Apr 19, 2026
silverwind added a commit to silverwind/gitea that referenced this pull request Apr 19, 2026
* 'cast' of github.com:silverwind/gitea:
  Fix Mermaid diagrams failing when node labels contain line breaks (go-gitea#37296)
  Add project column picker to issue and pull request sidebar (go-gitea#37037)
  Fix container auth for public instance (go-gitea#37290)
  Refactor frontend `tw-justify-between` layouts to `flex-left-right` (go-gitea#37291)
  Update Nix flake (go-gitea#37284)
  Workflow Artifact Info Hover (go-gitea#37100)
zjjhot added a commit to zjjhot/gitea that referenced this pull request Apr 20, 2026
* main: (25 commits)
  Add WebKit to e2e test matrix (go-gitea#37298)
  Don't add useless labels which will bother changelog generation (go-gitea#37267)
  Fix Repository transferring page (go-gitea#37277)
  Stabilize issue-project e2e test, increase timeout factor (go-gitea#37297)
  Fix Mermaid diagrams failing when node labels contain line breaks (go-gitea#37296)
  Add project column picker to issue and pull request sidebar (go-gitea#37037)
  Fix container auth for public instance (go-gitea#37290)
  Refactor frontend `tw-justify-between` layouts to `flex-left-right` (go-gitea#37291)
  Update Nix flake (go-gitea#37284)
  Workflow Artifact Info Hover (go-gitea#37100)
  [skip ci] Updated translations via Crowdin
  release notes for 1.26.0 (go-gitea#37282)
  Enhance GetActionWorkflow to support fallback references (go-gitea#37189)
  Refactor LDAP tests (go-gitea#37274)
  Remove `SubmitEvent` polyfill (go-gitea#37276)
  Upgrade go-git to v5.18.0 (go-gitea#37268)
  Avoid top-level await (go-gitea#37272)
  Frontend iframe renderer framework: 3D models, OpenAPI (go-gitea#37233)
  pull: Fix CODEOWNERS absolute path matching. (go-gitea#37244)
  Swift registry metadata: preserve more JSON fields and accept empty metadata (go-gitea#37254)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/done All backports for this PR have been created backport/manual No power to the bots! Create your backport yourself! backport/v1.26 This PR should be backported to Gitea 1.26 lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mermaid diagrams with line breaks in node cause rendering failure

4 participants