Skip to content

Commit 0f3317f

Browse files
committed
29.2.2 release
1 parent e159fbf commit 0f3317f

21 files changed

Lines changed: 9650 additions & 9526 deletions

ChangeLog

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
01-DEC-2025: 29.2.2
2+
3+
- AI and licensing tuning
4+
5+
27-NOV-2025: 29.2.1
6+
7+
- Fixes possible NPE
8+
9+
27-NOV-2025: 29.2.0
10+
11+
- Enhances pagecount and pagenumber placeholders [jgraph/drawio#3378]
12+
- Adds support for CSV in create hash property [jgraph/drawio#5273]
13+
- Replaces smart template section with generate window
14+
15+
21-NOV-2025: 29.1.1
16+
17+
- [conf connect] License tuning
18+
19+
19-NOV-2025: 29.1.0
20+
21+
- Makes attribute encoding deterministic [jgraph/drawio#1556]
22+
123
15-NOV-2025: 29.0.3
224

325
- Math base path and CSP corrections

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
29.0.3
1+
29.2.2

src/main/webapp/js/app.min.js

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

src/main/webapp/js/diagramly/App.js

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,12 +3360,6 @@ App.prototype.start = function()
33603360
null, null, null, null, null, true);
33613361
Editor.useLocalStorage = prev;
33623362
}
3363-
else if (urlParams['smart-template'] != null)
3364-
{
3365-
this.createFile(this.defaultFilename, null,
3366-
null, null, null, null, null, true);
3367-
this.actions.get('insertTemplate').funct();
3368-
}
33693363
else
33703364
{
33713365
var waiting = false;
@@ -3439,6 +3433,14 @@ App.prototype.start = function()
34393433
value = decodeURIComponent(window.location.hash.substring(8));
34403434
}
34413435

3436+
if (urlParams['smart-template'] != null && (window.location.hash == null ||
3437+
window.location.hash.length <= 1))
3438+
{
3439+
value = JSON.stringify({
3440+
type: 'generate', data: decodeURIComponent(urlParams['smart-template'])
3441+
});
3442+
}
3443+
34423444
if ((window.location.hash == null || window.location.hash.length <= 1 ||
34433445
window.location.hash.substring(0, 8) == '#create=') &&
34443446
value.length > 0 && this.spinner.spin(document.body, mxResources.get('loading')))
@@ -3523,11 +3525,12 @@ App.prototype.start = function()
35233525
this.spinner.stop();
35243526
value = JSON.parse(value);
35253527

3526-
var createDiagram = mxUtils.bind(this, function(data)
3528+
var createDiagram = mxUtils.bind(this, function(xml)
35273529
{
3528-
this.createFile((data.filename != null) ?
3529-
data.filename : this.defaultFilename,
3530-
data, null, null, mxUtils.bind(this, function()
3530+
this.spinner.stop();
3531+
this.createFile((value.filename != null) ?
3532+
value.filename : this.defaultFilename,
3533+
xml, null, null, mxUtils.bind(this, function()
35313534
{
35323535
if (!this.editor.chromeless || this.editor.editable)
35333536
{
@@ -3537,7 +3540,7 @@ App.prototype.start = function()
35373540
window.history.replaceState(null, null,
35383541
window.location.pathname +
35393542
this.getSearch(['create']));
3540-
window.location.hash = 'R' + Graph.compress(data);
3543+
window.location.hash = 'R' + Graph.compress(xml);
35413544
}), true, null, true);
35423545
});
35433546

@@ -3547,35 +3550,19 @@ App.prototype.start = function()
35473550
{
35483551
data = Graph.decompress(data);
35493552
}
3550-
3551-
if (value.type == 'mermaid')
3553+
3554+
if (value.type == 'mermaid' && this.spinner.spin(
3555+
document.body, mxResources.get('loading')))
35523556
{
35533557
if (window.isMermaidEnabled)
35543558
{
3555-
mxMermaidToDrawio.addListener(mxUtils.bind(this, function(data)
3556-
{
3557-
if (data != this.emptyDiagramXml)
3558-
{
3559-
createDiagram(data);
3560-
}
3561-
}));
3562-
3563-
this.generateMermaidImage(data, null, function()
3559+
this.parseMermaidDiagram(data, null, mxUtils.bind(this, function(xml)
35643560
{
3565-
// callback implemented above
3566-
}, mxUtils.bind(this, function(e)
3561+
createDiagram(xml);
3562+
}), mxUtils.bind(this, function(e)
35673563
{
3568-
// Removes div in document with an ID that starts with dgeMermaidOutput
3569-
var divs = document.querySelectorAll('div[id^="dgeMermaidOutput"]');
3570-
3571-
for (var i = 0; i < divs.length; i++)
3572-
{
3573-
divs[i].parentNode.removeChild(divs[i]);
3574-
}
3575-
3576-
mxMermaidToDrawio.resetListeners();
35773564
this.handleError(e);
3578-
}));
3565+
}), null, true);
35793566
}
35803567
else
35813568
{
@@ -3588,14 +3575,30 @@ App.prototype.start = function()
35883575
document.body, mxResources.get('generate') +
35893576
' \''+ data + '\''))
35903577
{
3591-
this.generateDiagram(data, mxUtils.bind(this, function(xml)
3578+
this.generateOpenAiMermaidDiagram(data, function(xml)
35923579
{
3593-
this.spinner.stop();
35943580
createDiagram(xml);
3595-
}), mxUtils.bind(this, function(e)
3581+
}, mxUtils.bind(this, function(e)
35963582
{
35973583
this.handleError(e, mxResources.get('errorLoadingFile'));
3598-
}));
3584+
}), true, {complexity: 'high'});
3585+
}
3586+
else if (value.type == 'csv')
3587+
{
3588+
var graph = this.createTemporaryGraph(this.editor.graph.getStylesheet());
3589+
3590+
this.importCsv(data, mxUtils.bind(this, function()
3591+
{
3592+
var codec = new mxCodec();
3593+
createDiagram(mxUtils.getXml(
3594+
codec.encode(graph.getModel())));
3595+
}), graph);
3596+
}
3597+
else
3598+
{
3599+
this.handleError(
3600+
{message: mxResources.get('invalidCallFnNotFound', [value.type])},
3601+
mxResources.get('errorLoadingFile'));
35993602
}
36003603
}
36013604
else
@@ -3693,6 +3696,36 @@ App.prototype.start = function()
36933696
}
36943697
};
36953698

3699+
/**
3700+
*
3701+
*/
3702+
App.prototype.openGenerateDialog = function(prompt)
3703+
{
3704+
if (this.chatWindow == null)
3705+
{
3706+
this.chatWindow = new ChatWindow(this, 224, 104, 280, 320);
3707+
this.chatWindow.window.addListener('show', mxUtils.bind(this, function()
3708+
{
3709+
this.fireEvent(new mxEventObject('chat'));
3710+
}));
3711+
this.chatWindow.window.addListener('hide', function()
3712+
{
3713+
this.fireEvent(new mxEventObject('chat'));
3714+
});
3715+
this.chatWindow.window.setVisible(true);
3716+
this.fireEvent(new mxEventObject('chat'));
3717+
}
3718+
else
3719+
{
3720+
this.chatWindow.window.setVisible(true);
3721+
}
3722+
3723+
if (prompt != null)
3724+
{
3725+
this.chatWindow.generate(prompt);
3726+
}
3727+
};
3728+
36963729
/**
36973730
* Generate a diagram for the given description.
36983731
*/
@@ -3727,42 +3760,6 @@ App.prototype.openTemplateDialog = function(generatePrompt)
37273760
}
37283761
};
37293762

3730-
/**
3731-
* Generate a diagram for the given description.
3732-
*/
3733-
App.prototype.generateDiagram = function(desc, success, error)
3734-
{
3735-
var listenerTriggered = false;
3736-
var xmlResult = null;
3737-
3738-
var prompt = 'Write a detailed and complex MermaidJS declaration for ' +
3739-
'"' + (desc != '' ? desc : 'something random') + '" ' +
3740-
'using correct MermaidJS syntax and do not ' +
3741-
'provide additional text in your response.';
3742-
3743-
if (typeof mxMermaidToDrawio !== 'undefined')
3744-
{
3745-
mxMermaidToDrawio.addListener(mxUtils.bind(this, function(modelXml)
3746-
{
3747-
if (modelXml != this.emptyDiagramXml)
3748-
{
3749-
listenerTriggered = true;
3750-
xmlResult = modelXml;
3751-
}
3752-
}));
3753-
}
3754-
3755-
this.generateOpenAiMermaidDiagram(prompt,
3756-
function(mermaidData, imageData, w, h)
3757-
{
3758-
xmlResult = (listenerTriggered) ? xmlResult :
3759-
this.createMermaidXml(mermaidData,
3760-
EditorUi.defaultMermaidConfig,
3761-
imageData, w, h, desc);
3762-
success(xmlResult, imageData);
3763-
}, error);
3764-
};
3765-
37663763
/**
37673764
* Checks for orphaned drafts.
37683765
*/

src/main/webapp/js/diagramly/Devel.js

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,8 @@ if (!mxIsElectron)
1111
(function()
1212
{
1313
var hashes = 'default-src \'self\'; ' +
14-
'script-src %script-src% \'self\' https://viewer.diagrams.net https://apis.google.com https://*.pusher.com ' +
15-
// Below are the SHAs of the two script blocks in index.html.
16-
// These must be updated here and in the CDN after changes.
17-
// Note: Desktop app uses only the newest hashes (replace it in electron.js [The one in index.html needs to be changed only if the second script block changes])
18-
//----------------------------------------------------------//
19-
//------------- Bootstrap script in index.html -------------//
20-
//----------------------------------------------------------//
21-
// Version 24.4.4
22-
'\'sha256-f6cHSTUnCvbQqwa6rKcbWIpgN9dLl0ROfpEKTQUQPr8=\' ' +
23-
//---------------------------------------------------------//
24-
//------------- App.main script in index.html -------------//
25-
//---------------------------------------------------------//
26-
// Version 13.8.2
27-
'\'sha256-vS/MxlVD7nbY7AnV+0t1Ap338uF7vrcs7y23KjERhKc=\' ' +
28-
//---------------------------------------------------------//
29-
'; ';
14+
'script-src %script-src% \'self\' https://viewer.diagrams.net https://apis.google.com https://*.pusher.com; ';
3015

31-
var styleHashes = '\'sha256-pVoUz0B9cDvBP/6KP+5uOMqPh1c14hF0KFqSELqeyNQ=\' ' + // index.html
32-
'\'sha256-D9Gy46rimBnLRtBqv9U464kXQ5oT5JvkurboVMjtN0Q=\' ' + // MinimalCss/Light
33-
'\'sha256-C9BzsAi3ukZpBZzbdTpUNpxHfPR/+KJbeueKj1U6QGY=\' ' + // MinimalCss/Dark
34-
'\'sha256-7kY8ozVqKLIIBwZ24dhdmZkM26PsOlZmEi72RhmZKoM=\' ' + // mxTooltipHandler.js
35-
'\'sha256-kuk5TvxZ/Kwuobo4g6uasb1xRQwr1+nfa1A3YGePO7U=\' ' + // MathJax
36-
'\'sha256-ByOXYIXIkfNC3flUR/HoxR4Ak0pjOEF1q8XmtuIa6po=\' ' + // purify.min.js
37-
'\'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\' ' + // spin.min.js
38-
'\'sha256-nzHi23DROym7G011m6y0DyDd9mvQL2hSJ0Gy3g2T/5Q=\' ' + // dropins.js
39-
'\'sha256-xjAW8oXqJlP0CWqxT9s80kgOtOjvENMmfnnfulL6p1A=\' ' + // gapi
40-
'\'unsafe-hashes\'; '; // Required for hashes for style attribute
41-
4216
var directives = 'connect-src %connect-src% \'self\' https://*.draw.io https://*.diagrams.net ' +
4317
'https://*.googleapis.com wss://app.diagrams.net wss://*.pusher.com https://*.pusher.com ' +
4418
'https://api.github.com https://raw.githubusercontent.com https://gitlab.com ' +
@@ -49,11 +23,9 @@ if (!mxIsElectron)
4923
// www.draw.io required for browser data migration to app.diagrams.net and
5024
// viewer.diagrams.net required for iframe embed preview
5125
'frame-src %frame-src% \'self\' https://viewer.diagrams.net https://www.draw.io https://*.google.com; ' +
52-
'style-src %style-src% \'self\' https://fonts.googleapis.com ' +
53-
// Replaces unsafe-inline style-src with hashes with safe-style-src URL parameter
54-
((urlParams['safe-style-src'] == '1') ? styleHashes : '\'unsafe-inline\'; ') +
55-
'base-uri \'none\';' +
56-
'child-src \'self\';' +
26+
'style-src %style-src% \'self\' https://fonts.googleapis.com \'unsafe-inline\'; ' +
27+
'base-uri \'none\'; ' +
28+
'child-src \'self\'; ' +
5729
'object-src \'none\';';
5830

5931
var csp = hashes + directives;
@@ -85,8 +57,8 @@ if (!mxIsElectron)
8557
'media-src * data:; ' +
8658
'font-src * data:; ' +
8759
'style-src \'self\' https://fonts.googleapis.com \'unsafe-inline\'; ' +
88-
'base-uri \'none\';' +
89-
'object-src \'none\';' +
60+
'base-uri \'none\'; ' +
61+
'object-src \'none\'; ' +
9062
'worker-src https://viewer.diagrams.net/service-worker.js;'
9163
console.log('viewer.diagrams.net:', viewer_diagrams_net);
9264

0 commit comments

Comments
 (0)