mermaid-js / mermaid

Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
https://mermaid.js.org
MIT License
72.68k stars 6.62k forks source link

Bug: namespace prefix xlink for href on image is not defined #4092

Open Mister-Hope opened 1 year ago

Mister-Hope commented 1 year ago

Description

mermaid 9.4 failed to provide namespace for xlink, so svg will not be rendered correctly:

image

A render result of c4 demo in official docs.

C4Context
    title System Context diagram for Internet Banking System

    Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
    Person(customerB, "Banking Customer B")
    Person_Ext(customerC, "Banking Customer C")
    System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

    Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")

    Enterprise_Boundary(b1, "BankBoundary") {

      SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

      System_Boundary(b2, "BankBoundary2") {
        System(SystemA, "Banking System A")
        System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
      }

      System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
      SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")

      Boundary(b3, "BankBoundary3", "boundary") {
        SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
        SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
      }
    }

    BiRel(customerA, SystemAA, "Uses")
    BiRel(SystemAA, SystemE, "Uses")
    Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
    Rel(SystemC, customerA, "Sends e-mails to")

Anything will be fine by adding xlink namespace:

- <svg aria-labelledby="chart-title-mermaid-62" aria-roledescription="c4" role="graphics-document document" viewBox="0 -70 1871 1652" style="max-width: 1871px;"
  xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid-62">
+ <svg aria-labelledby="chart-title-mermaid-62" aria-roledescription="c4" role="graphics-document document" viewBox="0 -70 1871 1652" style="max-width: 1871px;"
  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" id="mermaid-62">
image
Mister-Hope commented 1 year ago

Updated: It seems that older versions of mermaid does not provide xmlns="http://www.w3.org/2000/svg", removing that fix this and fix another issue with innerHTML.

With xmlns="http://www.w3.org/2000/svg", inserting svg by innerHTML will fail, see https://stackoverflow.com/questions/59936358/trying-to-add-svg-data-with-innerhtml

sidharthv96 commented 1 year ago

This change was done more than 4 months back. By older versions, did you mean 9.3 or even older?

Mister-Hope commented 1 year ago

I do think that everything is working before upgrading, and before its 9.3.0.

At least current render results are wrong, as xmlns is added , then xlink namespace is required if there is any xlink attribute.

For rendering svg to dom, I will copy the way that mermaid docs are doing, so this is leaving to you. Using innerHTML to insert SVG string with xmlns to dom has no effect, see stackoverflow above. This is not a bug with mermaid behavior at least.

Mister-Hope commented 1 year ago

Updated: if you are sure that xmlns="http://www.w3.org/2000/svg" exisits in 9.3.0, maybe the changes is caused by Chrome, as Chrome is automatically upgrading through time on my laptop and now it's 110

Charts are working well at https://theme-hope.vuejs.press/guide/markdown/mermaid.html#a-complex-example (mermaid 9.3) with chrome 110, and 9.4 is not, so the change should belong to mermaid

sidharthv96 commented 1 year ago

I'm unable to replicate the issue. When does the SVG not render?
Both live editor, and downloaded version renders for me in chrome & ff.

image
sidharthv96 commented 1 year ago

Live editor with 9.4 https://deploy-preview-1147--mermaidjs.netlify.app/edit

Mister-Hope commented 1 year ago

Step 1: open https://deploy-preview-1147--mermaidjs.netlify.app/edit

Step 2: paste the following:

C4Context
    title System Context diagram for Internet Banking System

    Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
    Person(customerB, "Banking Customer B")
    Person_Ext(customerC, "Banking Customer C")
    System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

    Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")

    Enterprise_Boundary(b1, "BankBoundary") {

      SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

      System_Boundary(b2, "BankBoundary2") {
        System(SystemA, "Banking System A")
        System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
      }

      System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
      SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")

      Boundary(b3, "BankBoundary3", "boundary") {
        SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
        SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
      }
    }

    BiRel(customerA, SystemAA, "Uses")
    BiRel(SystemAA, SystemE, "Uses")
    Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
    Rel(SystemC, customerA, "Sends e-mails to")

Step 3: copy the svg rendered in live editor and paste to an empty file named test.svg

Step 4: open that svg in brower:

image

The svg is not actually valid, you can check more at w3c or mdn.

2 solutions:

  1. In this demo, all image src are data urls, so replacing xlink:href with src solves:
image
  1. Add xmlns:xlink="http://www.w3.org/1999/xlink": image

Is this reproduction clear enough for you?

Mister-Hope commented 1 year ago

I did not check the source code of live editor, and I am not sure how it "adds" svg strings to dom, but doing element.innerHTML = SVG_STRING is not working with the result above

sidharthv96 commented 1 year ago
              container.innerHTML = svgCode;

This is how live editor adds the SVG to the DOM. https://github.com/mermaid-js/mermaid-live-editor/blob/308aec158063e9f775aab467ecbe2c14540f1f25/src/lib/components/View.svelte#L89-L90

In step 3, how are you copying the SVG? Using Inspect element > copy ?

I've added a log statement with the raw svg code. Can you try copying that from the console?

Mister-Hope commented 1 year ago

Same content bro:

image
asos-robbell commented 1 year ago

A simpler way to recreate this if you're struggling:

  1. Go to https://kroki.io and paste the following into their editor:
    C4Context
    Person(client, "API client", "A client of our API")
  2. That will appear to render correctly in the page, but will generate the following GET example: https://kroki.io/mermaid/svg/eNpzNnHOzytJrSjhCkgtKs7P00jOyUzNK9FRUHIM8FSAcJRAPChbIT9NIb-0SAEoq6QJAHdFE4w=

    Which results in the following response when followed: image