Skip to content

Commit 4ee6c86

Browse files
Update Mermaid.js to v10.9.3 (#124)
* chore: bump Mermaid.js to v10.9.1 - Updated Mermaid to version 10.9.1 - Rewrote ext.mermaid.js to use ESM - Removed jQuery + mw.loader.using wrapper - Used Rollup to create single UMD bundle (mermaid.min.js) - Switched to packageFiles with bundled output * update config options to be the same as in Mermaid.js v10.9.1 * chore: bump Mermaid.js to v10.9.3 * docs: update UPDATEMERMAID.md file * tests (json): add more tests now available from v10.9.3 * prepared 6.0.0 * clean code: remove unnecessary debugger from js * remove sourcemap references for Mermaid.js v10+ Mermaid.js no longer includes .map files in its distribution since v10. Removed unused sourcemap references from packageFiles and build config.
1 parent bcdc1da commit 4ee6c86

File tree

14 files changed

+292
-1654
lines changed

14 files changed

+292
-1654
lines changed

docs/INSTALL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ If you do not have a "composer.local.json" file yet, create one and add the foll
1313
```
1414
{
1515
"require": {
16-
"mediawiki/mermaid": "~5.0.2"
16+
"mediawiki/mermaid": "~6.0.0"
1717
}
1818
}
1919
```
2020

2121
If you already have a "composer.local.json" file add the following line to the end of the "require"
2222
section in your file:
2323

24-
"mediawiki/mermaid": "~5.0.2"
24+
"mediawiki/mermaid": "~6.0.0"
2525

2626
Remember to add a comma to the end of the preceding line in this section.
2727

docs/RELEASE-NOTES.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
This file contains the *release notes* of the **Mermaid** extension. See also the
22
[readme], the [installation and configuration information] and [usage examples].
33

4+
### 6.0.0
5+
6+
Released July 7, 2025.
7+
8+
* Upgraded Mermaid.js to version 10.9.3.
9+
* Updated configMap to align with the official Mermaid.js v10.9.3 configuration.
10+
* Switched from multiple separate script files to a single bundled file using Rollup, improving load performance and simplifying ResourceLoader configuration.
11+
* Refactored initialization code: Mermaid library and extension-specific logic are now bundled together in mermaid.min.js.
12+
* Removed the need for explicit script load ordering by using a single packageFiles entry.
13+
* Dropped usage of global Mermaid variable exposure; now using ES module import internally and UMD bundle output.
14+
* Simplified extension configuration and improved maintainability by consolidating scripts.
15+
* Added more JSONScript test cases.
16+
* Ensured all existing tests pass successfully with the new bundling approach and Mermaid version.
17+
418
### 5.0.2
519

620
Released July 2, 2025.

docs/UPDATEMERMAID.md

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
1-
## Updating `mermaid` Library
2-
Mermaid 4.0.0 introduced a new mechanism to update the MermaidJS library shipped with this extension. Starting from this version, the extension switched from using `yarn` to `npm` for managing and updating MermaidJS. This document explains how to perform the update using npm. It is intended for developers only. Users should simply install the extension version tagged with the desired MermaidJS release.
1+
# Updating `mermaid` Library
32

4-
### How It Works
5-
After running `npm install`, the following happens automatically:
3+
Starting from version 6.0.0, this extension uses a **Rollup-based bundling approach** to include both the `mermaid` library and extension-specific initialization code in a single bundled file (`mermaid.min.js`).
64

7-
1. **Copying Files**
8-
The `copy-files-from-to` tool copies the minified `mermaid` files from `node_modules` to the `resources/mermaid/` directory:
9-
- `mermaid.min.js`
10-
- `mermaid.min.js.map`
5+
This document is intended for **developers only**. Users should simply install a tagged release of the extension that already contains the bundled `mermaid.min.js`.
116

12-
2. **Injecting Comment**
13-
A custom script (`inject-nomin.js`) prepends the line `/*@nomin*/` to `mermaid.min.js`.
14-
This comment prevents MediaWiki's ResourceLoader from re-minifying the file.
7+
8+
## How It Works
9+
10+
After running `npm install`, the following occurs:
11+
12+
1. **Library Installation**
13+
14+
The version of `mermaid` specified in `package.json` is installed into `node_modules`.
15+
16+
2. **Bundling via Rollup `rollup.config.mjs`**
17+
18+
This file includes both the `mermaid` library and extension-specific initialization code to find and render Mermaid diagrams on the page using the global mermaid object.
19+
20+
Rollup is configured to:
21+
22+
- Bundle both mermaid and the extension code into a single output file (`resources/mermaid.min.js`)
23+
- Use the UMD format, so mermaid becomes available globally
24+
- Inline all dependencies (inlineDynamicImports: true)
25+
- Minify the output with terser
26+
27+
This approach ensures that ResourceLoader can treat the final file as a single script without requiring multiple scripts or worrying about load order.
1528

1629
### To Update `mermaid`
1730

1831
1. Open `package.json` and change the version under `"mermaid"`
19-
(e.g., `"mermaid": "latest"` or a specific version like `"8.14.0"`).
32+
(e.g., `"mermaid": "latest"` or a specific version like `"10.9.3"`).
2033

2134
2. Run:
2235

extension.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Mermaid",
3-
"version": "5.0.2",
3+
"version": "6.0.0",
44
"author": [
55
"James Hong Kong",
66
"Tyler Gibson"
@@ -29,16 +29,15 @@
2929
},
3030
"ResourceModules": {
3131
"ext.mermaid": {
32-
"scripts": [
33-
"resources/ext.mermaid.js",
32+
"packageFiles": [
3433
"resources/mermaid.min.js"
3534
],
36-
"dependencies": [
37-
"mediawiki.api"
38-
],
3935
"styles": [
4036
"resources/styles/ext.mermaid.css"
4137
],
38+
"dependencies": [
39+
"mediawiki.api"
40+
],
4241
"messages": [
4342
"mermaid-desc"
4443
],
@@ -50,8 +49,9 @@
5049
},
5150
"ResourceFileModulePaths": {
5251
"localBasePath": "",
53-
"remoteExtPath": "Mermaid"
52+
"remoteExtPath": "Mermaid/resources"
5453
},
54+
5555
"ServiceWiringFiles": [
5656
"src/ServiceWiring.php"
5757
],

package.json

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
2+
"type": "module",
23
"name": "mediawiki-mermaid",
3-
"version": "9.4.3",
4+
"version": "10.9.3",
45
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
56
"main": "lib/mermaid.core.js",
67
"keywords": [
@@ -13,7 +14,8 @@
1314
"git graph"
1415
],
1516
"scripts": {
16-
"postinstall": "copy-files-from-to && node resources/utility/inject-nomin.js"
17+
"build": "rollup -c",
18+
"postinstall": "npm run build && node resources/utility/inject-nomin.cjs"
1719
},
1820
"repository": {
1921
"type": "git",
@@ -27,27 +29,21 @@
2729
]
2830
},
2931
"dependencies": {
30-
"mermaid": "9.4.3"
32+
"mermaid": "10.9.3"
3133
},
3234
"files": [
3335
"lib",
3436
"resources"
3537
],
36-
"copyFiles": [
37-
{
38-
"from": "node_modules/mermaid/dist/mermaid.min.js",
39-
"to": "resources/mermaid.min.js"
40-
},
41-
{
42-
"from": "node_modules/mermaid/dist/mermaid.min.js.map",
43-
"to": "resources/mermaid.min.js.map"
44-
}
45-
],
4638
"copyFilesSettings": {
4739
"whenFileExists": "overwrite"
4840
},
4941
"devDependencies": {
42+
"@rollup/plugin-commonjs": "^28.0.6",
43+
"@rollup/plugin-node-resolve": "^16.0.1",
44+
"@rollup/plugin-terser": "^0.4.4",
5045
"copy-files-from-to": "^3.12.1",
51-
"insert-line": "^1.1.0"
46+
"insert-line": "^1.1.0",
47+
"rollup": "^4.0.0"
5248
}
5349
}

resources/ext.mermaid.js

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,68 @@
66
* @author mwjames
77
*/
88

9-
/*global jQuery, mediaWiki, smw */
9+
/*global mediaWiki, mermaid */
1010
/*jslint white: true */
1111

12-
( function( $, mw ) {
12+
import mermaid from 'mermaid';
13+
window.mermaid = mermaid;
1314

14-
'use strict';
15+
const generateString = (length) =>
16+
Array(length)
17+
.fill("")
18+
.map(() => Math.random().toString(36).charAt(2))
19+
.join("");
1520

16-
var config = mw.config.get( 'mermaid' );
17-
mw.loader.using( [ 'mediawiki.api', 'ext.mermaid' ] ).then( function () {
21+
function decodeHtmlEntities(str) {
22+
const textarea = document.createElement('textarea');
23+
textarea.innerHTML = str;
24+
return textarea.value;
25+
}
1826

19-
$( document ).ready( function() {
20-
// Fallback: ensure mermaid is globally available (for newer builds)
21-
if ( typeof mermaid === 'undefined' && typeof window.mermaid !== 'undefined' ) {
22-
window.mermaid = window.mermaid;
23-
} else if ( typeof mermaid === 'undefined' ) {
24-
console.error( '[Mermaid] Global "mermaid" object not found.' );
25-
return;
26-
}
27+
async function initMermaid() {
28+
if (typeof mermaid === 'undefined') {
29+
console.error('[Mermaid] Global "mermaid" object not found.');
30+
return;
31+
}
2732

28-
$( '.ext-mermaid' ).each( function() {
33+
const items = document.querySelectorAll('.ext-mermaid');
34+
await Promise.all(Array.from(items).map(async (item, index) => {
35+
const id = 'ext-mermaid-' + generateString(8) + '-' + index;
2936

30-
var that = $( this );
31-
var id = 'ext-mermaid-' + ( new Date().getTime() );
32-
var data = that.data( 'mermaid' );
37+
let data;
38+
try {
39+
data = typeof item.dataset.mermaid === 'string'
40+
? JSON.parse(item.dataset.mermaid)
41+
: {};
42+
} catch (e) {
43+
console.error('[Mermaid] Failed to parse data-mermaid:', e);
44+
return;
45+
}
3346

34-
that.find( '.mermaid-dots' ).hide();
35-
that.append( '<div id="' + id + '"> ' + data.content + ' </div>' );
47+
if (!data.content || typeof data.content !== 'string') {
48+
console.error('[Mermaid] No diagram content provided.');
49+
return;
50+
}
3651

37-
try {
38-
mermaid.initialize( data.config || {} );
39-
mermaid.init( undefined, $( "#" + id )[0] );
40-
} catch (e) {
41-
console.error( '[Mermaid] Failed to render diagram:', e );
42-
}
43-
} );
44-
} );
45-
} );
52+
// Hide loading animation (dots)
53+
const dots = item.children[0];
54+
if (dots) dots.style.display = 'none';
4655

47-
}( jQuery, mediaWiki ) );
56+
try {
57+
mermaid.initialize({
58+
securityLevel: 'loose',
59+
...data.config
60+
});
61+
const { svg, bindFunctions } = await mermaid.render(id + '-svg', decodeHtmlEntities(data.content));
62+
const graph = document.createElement('div');
63+
graph.id = id;
64+
graph.innerHTML = svg;
65+
item.appendChild(graph);
66+
bindFunctions?.(graph);
67+
} catch (e) {
68+
console.error(`[Mermaid] Failed to render diagram with id=${id}:`, e);
69+
}
70+
}));
71+
}
72+
73+
initMermaid();

resources/mermaid.min.js

Lines changed: 27 additions & 1580 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/mermaid.min.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

resources/utility/inject-nomin.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
const targetFile = path.resolve(__dirname, '../../resources/mermaid.min.js');
5+
const comment = '/*@nomin*/\n';
6+
7+
const content = fs.readFileSync(targetFile, 'utf8');
8+
fs.writeFileSync(targetFile, comment + content, 'utf8');
9+
10+
console.log('Prepended /*@nomin*/ to mermaid.min.js');

resources/utility/inject-nomin.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)