Browse Source

20.8.4 release

David Benson 2 years ago
parent
commit
217caf2960

+ 21 - 0
ChangeLog

@@ -1,3 +1,24 @@
+11-JAN-2023: 20.8.4
+
+- Fixes evt is not defined in selectSiblings action
+- Adds sharp, rounded, curved option for wire shapes
+- Fixes drawing of markers and shadows in wire shape
+- Fixes sidebar triggers autosave, scale for preview
+- Fixed OneDrive share link [3273]
+- Fixes clientId in checksum error fallback logging
+- Fixes preview graph state, drag preview background
+- Shift+Click on About menu item shows console
+- [conf cloud] Adds viewerCanExceedPageWidth settings to allow increasing the viewer size above the allowed width [DID-7094]
+- Adds fallback for missing translations to show key
+- Fixes specificity for gePrimaryBtn dark mode style
+- Fixes possible NPE for missing resource in confirm
+- Saves file to Google Drive if sharing unavailable
+- Fixes draft dialog shape background for dark mode
+- Adds merge/unmerge to context menu for table cells
+- Fixes reset of view state after initial file save
+- Fixes change stroke color for table cells and rows
+- Removes span with cell styles after paste of text
+
 06-JAN-2023: 20.8.3
 
 - Adds logging for merge fallback success or failure

+ 1 - 1
VERSION

@@ -1 +1 @@
-20.8.3
+20.8.4

File diff suppressed because it is too large
+ 1826 - 1832
src/main/webapp/js/app.min.js


+ 23 - 14
src/main/webapp/js/diagramly/App.js

@@ -4580,10 +4580,19 @@ App.prototype.saveFile = function(forceDialog, success)
 						{
 							this.pickFolder(mode, mxUtils.bind(this, function(folderId)
 							{
+								var graph = this.editor.graph;
+								var selection = graph.getSelectionCells();
+								var viewState = graph.getViewState();
+								var page = this.currentPage;
+								
 								this.createFile(name, this.getFileData(/(\.xml)$/i.test(name) ||
 									name.indexOf('.') < 0 || /(\.drawio)$/i.test(name),
-									/(\.svg)$/i.test(name), /(\.html)$/i.test(name)),
-									null, mode, done, this.mode == null, folderId);
+									/(\.svg)$/i.test(name), /(\.html)$/i.test(name)), null,
+									mode, done, this.mode == null, folderId, null, null,
+									mxUtils.bind(this, function()
+									{
+										this.restoreViewState(page, viewState, selection);
+									}));
 							}));
 						}
 						else if (mode != null)
@@ -4744,7 +4753,7 @@ App.prototype.getPeerForMode = function(mode)
  * @param {number} dx X-coordinate of the translation.
  * @param {number} dy Y-coordinate of the translation.
  */
-App.prototype.createFile = function(title, data, libs, mode, done, replace, folderId, tempFile, clibs)
+App.prototype.createFile = function(title, data, libs, mode, done, replace, folderId, tempFile, clibs, success)
 {
 	mode = (tempFile) ? null : ((mode != null) ? mode : this.mode);
 
@@ -4783,7 +4792,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.drive.insertFile(title, data, folderId, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error);
 			}
 			else if (mode == App.MODE_GITHUB && this.gitHub != null)
@@ -4791,7 +4800,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.gitHub.insertFile(title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error, false, folderId);
 			}
 			else if (mode == App.MODE_GITLAB && this.gitLab != null)
@@ -4799,7 +4808,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.gitLab.insertFile(title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error, false, folderId);
 			}
 			else if (mode == App.MODE_TRELLO && this.trello != null)
@@ -4807,7 +4816,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.trello.insertFile(title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error, false, folderId);
 			}
 			else if (mode == App.MODE_DROPBOX && this.dropbox != null)
@@ -4815,7 +4824,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.dropbox.insertFile(title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error);
 			}
 			else if (mode == App.MODE_ONEDRIVE && this.oneDrive != null)
@@ -4823,7 +4832,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				this.oneDrive.insertFile(title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error, false, folderId);
 			}
 			else if (mode == App.MODE_BROWSER)
@@ -4831,7 +4840,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 				StorageFile.insertFile(this, title, data, mxUtils.bind(this, function(file)
 				{
 					complete();
-					this.fileCreated(file, libs, replace, done, clibs);
+					this.fileCreated(file, libs, replace, done, clibs, success);
 				}), error);
 			}
 			else if (!tempFile && mode == App.MODE_DEVICE && EditorUi.nativeFileSupport)
@@ -4844,7 +4853,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 					
 					file.saveFile(desc.name, false, mxUtils.bind(this, function()
 					{
-						this.fileCreated(file, libs, replace, done, clibs);
+						this.fileCreated(file, libs, replace, done, clibs, success);
 					}), error, true);
 				}), mxUtils.bind(this, function(e)
 				{
@@ -4857,7 +4866,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 			else
 			{
 				complete();
-				this.fileCreated(new LocalFile(this, data, title, mode == null), libs, replace, done, clibs);
+				this.fileCreated(new LocalFile(this, data, title, mode == null), libs, replace, done, clibs, success);
 			}
 		}
 		catch (e)
@@ -4874,7 +4883,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
  * @param {number} dx X-coordinate of the translation.
  * @param {number} dy Y-coordinate of the translation.
  */
-App.prototype.fileCreated = function(file, libs, replace, done, clibs)
+App.prototype.fileCreated = function(file, libs, replace, done, clibs, success)
 {
 	var url = window.location.pathname;
 	
@@ -4941,7 +4950,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
 			var fn3 = mxUtils.bind(this, function()
 			{
 				window.openFile = null;
-				this.fileLoaded(file);
+				this.fileLoaded(file, null, success);
 				
 				if (replace)
 				{

+ 6 - 3
src/main/webapp/js/diagramly/Dialogs.js

@@ -2231,18 +2231,20 @@ var ParseDialog = function(editorUi, title, defaultType)
 					var rowCell = new mxCell('', new mxGeometry(0, 0, 160, 30),
 						'shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;' +
 						'collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;' +
-						'top=0;left=0;right=0;bottom=' + (pk ? '1' : '0') + ';');
+						'strokeColor=inherit;top=0;left=0;right=0;bottom=' + (pk ? '1' : '0') + ';');
 					rowCell.vertex = true;
 					
 					var left = new mxCell(pk ? 'PK' : '', new mxGeometry(0, 0, 30, 30),
 						'shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;' +
-						'top=0;left=0;bottom=0;right=0;' + (pk ? 'fontStyle=1;' : ''));
+						'strokeColor=inherit;top=0;left=0;bottom=0;right=0;' +
+						(pk ? 'fontStyle=1;' : ''));
 					left.vertex = true;
 					rowCell.insert(left);
 					
 					var right = new mxCell(name, new mxGeometry(30, 0, 130, 30),
 						'shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;align=left;' +
-						'top=0;left=0;bottom=0;right=0;spacingLeft=6;' + (pk ? 'fontStyle=5;' : ''));
+						'strokeColor=inherit;top=0;left=0;bottom=0;right=0;spacingLeft=6;' +
+						(pk ? 'fontStyle=5;' : ''));
 					right.vertex = true;
 					rowCell.insert(right);
 					
@@ -6666,6 +6668,7 @@ var DraftDialog = function(editorUi, title, xml, editFn, discardFn, editLabel, d
 	var graph = new Graph(container);
 	graph.setEnabled(false);
 	graph.setPanning(true);
+	graph.shapeBackgroundColor = (Editor.isDarkMode() ? '#2a252f' : '#ffffff');
 	graph.panningHandler.ignoreCell = true;
 	graph.panningHandler.useLeftButtonForPanning = true;
 	graph.minFitScale = null;

+ 26 - 1
src/main/webapp/js/diagramly/DrawioFile.js

@@ -1247,7 +1247,32 @@ DrawioFile.prototype.move = function(folderId, success, error) { };
  */
 DrawioFile.prototype.share = function()
 {
-	this.ui.alert(mxResources.get('sharingAvailable'), null, 380);
+	if (this.ui.drive != null)
+	{
+		this.ui.confirm(mxResources.get('saveItToGoogleDriveToCollaborate', [this.getTitle()]),
+			mxUtils.bind(this, function()
+		{
+			this.ui.pickFolder(App.MODE_GOOGLE, mxUtils.bind(this, function(folderId)
+			{
+				var graph = this.ui.editor.graph;
+				var selection = graph.getSelectionCells();
+				var viewState = graph.getViewState();
+				var page = this.ui.currentPage;
+				
+				this.ui.createFile(this.getTitle(), this.ui.getFileData(null, null, null, null, null,
+					null, null, null, this), null, App.MODE_GOOGLE, null, true, folderId, null, null,
+					mxUtils.bind(this, function()
+					{
+						this.ui.restoreViewState(page, viewState, selection);
+						this.ui.actions.get('share').funct();
+					}));
+			}));
+		}), null, mxResources.get('saveToGoogleDrive', null, 'Save to Google Drive'), mxResources.get('cancel'));
+	}
+	else
+	{
+		this.ui.alert(mxResources.get('sharingAvailable'), null, 380);
+	}
 };
 
 /**

+ 1 - 2
src/main/webapp/js/diagramly/DrawioFileSync.js

@@ -1230,8 +1230,7 @@ DrawioFileSync.prototype.merge = function(patches, checksum, desc, success, erro
 						EditorUi.logError('Merge checksum fallback ' + (failed ?
 							'failed' : 'success') + ' ' + id, null,
 							this.file.getMode() + '.' + this.file.getId(),
-							'user_' + uid + ((this.sync != null) ?
-							'-client_' + this.clientId : '-nosync') +
+							'user_' + uid + '-client_' + this.clientId +
 							'-bytes_' + bytes + '-patches_' + patches.length +
 							'-size_' + this.file.getSize() +
 							((checksum != null) ? ('-expected_' + checksum) : '') +

+ 10 - 7
src/main/webapp/js/diagramly/DriveClient.js

@@ -2354,14 +2354,17 @@ DriveClient.prototype.pickFolder = function(fn, force)
 	}
 	else
 	{
-		this.ui.confirm(mxResources.get('useRootFolder'), mxUtils.bind(this, function()
-		{
-			this.folderPickerCallback({action: google.picker.Action.PICKED,
-				docs: [{type: 'folder', id: 'root'}]});
-		}), mxUtils.bind(this, function()
+		this.execute(mxUtils.bind(this, function()
 		{
-			showPicker();
-		}), mxResources.get('yes'), mxResources.get('noPickFolder') + '...', true);
+			this.ui.confirm(mxResources.get('useRootFolder'), mxUtils.bind(this, function()
+			{
+				this.folderPickerCallback({action: google.picker.Action.PICKED,
+					docs: [{type: 'folder', id: 'root'}]});
+			}), mxUtils.bind(this, function()
+			{
+				showPicker();
+			}), mxResources.get('yes'), mxResources.get('noPickFolder') + '...', true);
+		}));
 	}
 };
 

+ 36 - 14
src/main/webapp/js/diagramly/EditorUi.js

@@ -2657,7 +2657,7 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.fileLoaded = function(file, noDialogs)
+	EditorUi.prototype.fileLoaded = function(file, noDialogs, success)
 	{
 		var oldFile = this.getCurrentFile();
 		this.fileLoadedError = null;
@@ -2785,6 +2785,11 @@
 				{
 					this.chromelessResize();
 				}
+
+				if (success != null)
+				{
+					success();
+				}
 				
 				this.editor.fireEvent(new mxEventObject('fileLoaded'));
 				result = true;
@@ -4248,8 +4253,9 @@
 	 */
 	EditorUi.prototype.confirm = function(msg, okFn, cancelFn, okLabel, cancelLabel, closable)
 	{
+		msg = (msg != null) ? msg : '';
 		var resume = (this.spinner != null && this.spinner.pause != null) ? this.spinner.pause() : function() {};
-		var height = Math.min(200, Math.ceil(msg.length / 50) * 28);
+		var height = Math.min(220, Math.ceil(Math.max(1, msg.length) / 50) * 28);
 		
 		var dlg = new ConfirmDialog(this, msg, function()
 		{
@@ -9852,24 +9858,40 @@
 					}
 
 					this.addMenuItems(menu, ['lockUnlock', '-'], null, evt);
-					
-					if (!this.isShowStyleItems() && graph.getSelectionCount() == 1 &&
-						!graph.isCellLocked(cell) && graph.isCellEditable(cell))
-					{
-						this.addSubmenu('editCell', menu, null, mxResources.get('edit'));
 
-						// Show line submenu for edges
-						if (graph.getModel().isEdge(cell))
+					if (!this.isShowStyleItems())
+					{
+						if (graph.getSelectionCount() == 1 && !graph.isCellLocked(cell) &&
+							graph.isCellEditable(cell))
 						{
-							this.addSubmenu('line', menu);
-
-							var geo = graph.getModel().getGeometry(cell);
+							this.addSubmenu('editCell', menu, null, mxResources.get('edit'));
+							menu.addSeparator();
 
-							if (geo != null && geo.points != null && geo.points.length > 0)
+							// Shows line submenu for edges
+							if (graph.getModel().isEdge(cell))
 							{
-								this.addMenuItems(menu, ['clearWaypoints'], null, evt);
+								this.addSubmenu('line', menu);
+
+								var geo = graph.getModel().getGeometry(cell);
+
+								if (geo != null && geo.points != null && geo.points.length > 0)
+								{
+									this.addMenuItems(menu, ['clearWaypoints'], null, evt);
+								}
 							}
 						}
+
+						// Shows table cell options
+						var ss = ui.getSelectionState();
+
+						if (ss.mergeCell != null)
+						{
+							var item = this.addMenuItem(menu, 'mergeCells');
+						}
+						else if (ss.style['colspan'] > 1 || ss.style['rowspan'] > 1)
+						{
+							var item = this.addMenuItem(menu, 'unmergeCells');
+						}
 					}
 				}
 			};

+ 0 - 18
src/main/webapp/js/diagramly/LocalFile.js

@@ -123,24 +123,6 @@ LocalFile.prototype.setDescriptor = function(desc)
 	this.desc = desc;
 };
 
-/**
- * Translates this point by the given vector.
- * 
- * @param {number} dx X-coordinate of the translation.
- * @param {number} dy Y-coordinate of the translation.
- */
-LocalFile.prototype.share = function()
-{
-	if (this.mode == null)
-	{
-		this.ui.actions.get('save').funct(false);
-	}
-	else
-	{
-		DrawioFile.prototype.share.apply(this, arguments);
-	}
-};
-
 /**
  * Translates this point by the given vector.
  * 

+ 6 - 2
src/main/webapp/js/diagramly/Menus.js

@@ -918,9 +918,13 @@
 		action.setToggleAction(true);
 		action.setSelectedCallback(function() { return graph.shadowVisible; });
 
-		editorUi.actions.put('about', new Action(mxResources.get('about') + ' ' + EditorUi.VERSION + '...', function()
+		editorUi.actions.put('about', new Action(mxResources.get('about') + ' ' + EditorUi.VERSION + '...', function(arg1, evt)
 		{
-			if (editorUi.isOffline() || mxClient.IS_CHROMEAPP || EditorUi.isElectronApp)
+			if (evt != null && mxEvent.isShiftDown(evt))
+			{
+				mxLog.show();
+			}
+			else if (editorUi.isOffline() || mxClient.IS_CHROMEAPP || EditorUi.isElectronApp)
 			{
 				editorUi.alert(editorUi.editor.appName + ' ' + EditorUi.VERSION);
 			}

+ 1 - 1
src/main/webapp/js/diagramly/OneDriveFile.js

@@ -49,7 +49,7 @@ OneDriveFile.prototype.getFileUrl = function()
 				path = path.substring(path.indexOf('/root:') + 6);
 				
 				var id = this.meta.webUrl;
-				var url = id.substring(0, id.length - path.length - this.meta.name.length - ((path.length > 0) ? 1 : 0)); 
+				var url = id.substring(0, id.length - path.length - encodeURIComponent(this.meta.name).length - 1); 
 				id = id.substring(id.indexOf('/', 8));
 				
 				url = url + '/Forms/AllItems.aspx?id=' + id + '&parent=' + id.substring(0, id.lastIndexOf('/'));

+ 1 - 1
src/main/webapp/js/diagramly/Trees.js

@@ -323,7 +323,7 @@
 		}, null, null, 'Alt+Shift+P');
 		
 		// Adds actions
-		ui.actions.addAction('selectSiblings', function()
+		ui.actions.addAction('selectSiblings', function(evt)
 		{
 			if (graph.isEnabled() && graph.getSelectionCount() == 1)
 			{

File diff suppressed because it is too large
+ 2 - 1
src/main/webapp/js/diagramly/sidebar/Sidebar-BPMN.js


File diff suppressed because it is too large
+ 3 - 31
src/main/webapp/js/diagramly/sidebar/Sidebar-C4.js


File diff suppressed because it is too large
+ 4 - 117
src/main/webapp/js/diagramly/sidebar/Sidebar-ThreatModeling.js


+ 29 - 4
src/main/webapp/js/grapheditor/Format.js

@@ -934,6 +934,8 @@ BaseFormatPanel.prototype.createCellOption = function(label, key, defaultValue,
 BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setColorFn,
 	defaultColor, listener, callbackFn, hideCheckbox, defaultColorValue)
 {
+	var graph = this.editorUi.editor.graph;
+
 	var div = document.createElement('div');
 	div.style.padding = '3px 0px 3px 0px';
 	div.style.whiteSpace = 'nowrap';
@@ -1030,8 +1032,9 @@ BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setCol
 					btn.setAttribute('title', name);
 				}
 			}
-			
-			if (color != null && color != mxConstants.NONE)
+
+			if (color != null && color != mxConstants.NONE &&
+				!graph.isSpecialColor(color))
 			{
 				cb.setAttribute('checked', 'checked');
 				cb.defaultChecked = true;
@@ -1167,7 +1170,7 @@ BaseFormatPanel.prototype.createCellColorOption = function(label, colorKey, defa
 		}
 		
 		return null;
-	}, function(color, realValue)
+	}, function(color)
 	{
 		graph.getModel().beginUpdate();
 		try
@@ -4913,6 +4916,26 @@ StyleFormatPanel.prototype.addStroke = function(container)
 	var lineColor = this.createCellColorOption(label, strokeKey, 'default', null, mxUtils.bind(this, function(color)
 	{
 		graph.setCellStyles(strokeKey, color, ss.cells);
+
+		// Sets strokeColor to inherit for rows and cells in tables
+		if (color == null || color == mxConstants.NONE)
+		{
+			var tableCells = [];
+
+			for (var i = 0; i < ss.cells.length; i++)
+			{
+				if (graph.isTableCell(ss.cells[i]) ||
+					graph.isTableRow(ss.cells[i]))
+				{
+					tableCells.push(ss.cells[i]);
+				}
+			}
+
+			if (tableCells.length > 0)
+			{
+				graph.setCellStyles(strokeKey, 'inherit', tableCells);
+			}
+		}
 	}), graph.shapeForegroundColor);
 	
 	lineColor.appendChild(styleSelect);
@@ -5355,7 +5378,9 @@ StyleFormatPanel.prototype.addStroke = function(container)
 			altInput.value = (isNaN(tmp)) ? '' : tmp + ' pt';
 		}
 		
-		styleSelect.style.visibility = (ss.style.shape == 'connector' || ss.style.shape == 'filledEdge') ? '' : 'hidden';
+		styleSelect.style.visibility = (ss.style.shape == 'connector' ||
+			ss.style.shape == 'filledEdge' || ss.style.shape == 'wire') ?
+			'' : 'hidden';
 		
 		if (mxUtils.getValue(ss.style, mxConstants.STYLE_CURVED, null) == '1')
 		{

+ 25 - 9
src/main/webapp/js/grapheditor/Graph.js

@@ -145,7 +145,6 @@ if (!Uint8Array.from) {
   }());
 }
 
-// Changes default colors
 /**
  * Measurements Units
  */
@@ -207,7 +206,7 @@ mxGraphView.prototype.defaultGridColor = '#d0d0d0';
 mxGraphView.prototype.defaultDarkGridColor = '#424242';
 mxGraphView.prototype.gridColor = mxGraphView.prototype.defaultGridColor;
 
-//Units
+// Units
 mxGraphView.prototype.unit = mxConstants.POINTS;
 
 mxGraphView.prototype.setUnit = function(unit) 
@@ -229,7 +228,7 @@ mxShape.prototype.getConstraints = function(style, w, h)
 	return null;
 };
 
-// Override for clipSvg style.
+// Override for clipSvg style
 mxImageShape.prototype.getImageDataUri = function()
 {
 	var src = this.image;
@@ -249,6 +248,23 @@ mxImageShape.prototype.getImageDataUri = function()
 	return src;
 };
 
+// Override to use key as fallback
+(function()
+{
+	var mxResourcesGet = mxResources.get;
+
+	mxResources.get = function(key, params, defaultValue)
+	{
+		if (defaultValue == null)
+		{
+			defaultValue = key;
+		}
+
+		return mxResourcesGet.apply(this, [key, params, defaultValue]);
+	};
+
+})();
+
 /**
  * Constructs a new graph instance. Note that the constructor does not take a
  * container because the graph instance is needed for creating the UI, which
@@ -2342,7 +2358,7 @@ Graph.prototype.init = function(container)
 	 */
 	Graph.prototype.isStrokeState = function(state)
 	{
-		return !this.isSpecialColor(state.style[mxConstants.STYLE_STROKECOLOR]);
+		return true;
 	};
 	
 	/**
@@ -6346,9 +6362,9 @@ Graph.prototype.createTable = function(rowCount, colCount, w, h, title, startSiz
 	startSize = (startSize != null) ? startSize : 30;
 	tableStyle = (tableStyle != null) ? tableStyle : 'shape=table;startSize=' +
 		((title != null) ? startSize : '0') + ';container=1;collapsible=0;childLayout=tableLayout;';
-	rowStyle = (rowStyle != null) ? rowStyle : 'shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;' +
+	rowStyle = (rowStyle != null) ? rowStyle : 'shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;strokeColor=inherit;' +
     	'top=0;left=0;bottom=0;right=0;collapsible=0;dropTarget=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;';
-	cellStyle = (cellStyle != null) ? cellStyle : 'shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;' +
+	cellStyle = (cellStyle != null) ? cellStyle : 'shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;strokeColor=inherit;' +
 		'overflow=hidden;fillColor=none;top=0;left=0;bottom=0;right=0;pointerEvents=1;';
 	
 	return this.createParent(this.createVertex(null, null, (title != null) ? title : '',
@@ -6400,11 +6416,11 @@ Graph.prototype.createCrossFunctionalSwimlane = function(rowCount, colCount, w,
 	var s = 'collapsible=0;recursiveResize=0;expand=0;';
 	tableStyle = (tableStyle != null) ? tableStyle : 'shape=table;childLayout=tableLayout;' +
 		((title == null) ? 'startSize=0;fillColor=none;' : 'startSize=40;') + s;
-	rowStyle = (rowStyle != null) ? rowStyle : 'shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;' +
+	rowStyle = (rowStyle != null) ? rowStyle : 'shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;' +
 		'bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;startSize=40;' + s;
-	firstCellStyle = (firstCellStyle != null) ? firstCellStyle : 'swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;' +
+	firstCellStyle = (firstCellStyle != null) ? firstCellStyle : 'swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;' +
 		'connectable=0;fillColor=none;startSize=40;' + s;
-	cellStyle = (cellStyle != null) ? cellStyle : 'swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;connectable=0;' +
+	cellStyle = (cellStyle != null) ? cellStyle : 'swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;connectable=0;strokeColor=inherit;' +
 		'fillColor=none;startSize=0;' + s;
 	
 	var table = this.createVertex(null, null, (title != null) ? title : '', 0, 0,

+ 33 - 4
src/main/webapp/js/grapheditor/Shapes.js

@@ -458,12 +458,41 @@
 
 	WireShape.prototype.paintEdgeShape = function(c, pts)
 	{
-		c.save();
+		// The indirection via functions for markers is needed in
+		// order to apply the offsets before painting the line and
+		// paint the markers after painting the line.
+		var sourceMarker = this.createMarker(c, pts, true);
+		var targetMarker = this.createMarker(c, pts, false);
+
+		// Paints base line without dash pattern
 		c.setDashed(false);
-		mxConnector.prototype.paintEdgeShape.apply(this, [c, pts]);
-		c.restore();
+		mxPolyline.prototype.paintEdgeShape.apply(this, arguments);
+		
+		// Paints dashed line with dash pattern and fill color
+		if (this.isDashed != null)
+		{
+			c.setDashed(this.isDashed, (this.style != null) ?
+				mxUtils.getValue(this.style, mxConstants.STYLE_FIX_DASH, false) == 1 : false);
+		}
+
+		c.setShadow(false);
 		c.setStrokeColor(this.fill);
-		mxPolyline.prototype.paintEdgeShape.apply(this, [c, pts]);
+		mxPolyline.prototype.paintEdgeShape.apply(this, arguments);
+
+		// Paints markers with stroke color
+		c.setStrokeColor(this.stroke);
+		c.setFillColor(this.stroke);
+		c.setDashed(false);
+		
+		if (sourceMarker != null)
+		{
+			sourceMarker();
+		}
+		
+		if (targetMarker != null)
+		{
+			targetMarker();
+		}
 	};
 
 	mxCellRenderer.registerShape('wire', WireShape);

File diff suppressed because it is too large
+ 17 - 13
src/main/webapp/js/grapheditor/Sidebar.js


File diff suppressed because it is too large
+ 1491 - 1497
src/main/webapp/js/integrate.min.js


File diff suppressed because it is too large
+ 741 - 738
src/main/webapp/js/viewer-static.min.js


File diff suppressed because it is too large
+ 741 - 738
src/main/webapp/js/viewer.min.js


File diff suppressed because it is too large
+ 4 - 3
src/main/webapp/mxgraph/mxClient.js


File diff suppressed because it is too large
+ 1 - 1
src/main/webapp/service-worker.js


File diff suppressed because it is too large
+ 1 - 1
src/main/webapp/service-worker.js.map


File diff suppressed because it is too large
+ 1 - 1
src/main/webapp/shortcuts.svg


+ 2 - 2
src/main/webapp/styles/dark.css

@@ -91,8 +91,8 @@ html body .geSidebarContainer div.geDropTarget {
 	color:#767676;
 	border-color:#767676;
 }
-html body.geEditor button.gePrimaryBtn, html body.geEditor div.gePrimaryBtn,
-html body.geEditor .geBigButton {
+html body.geEditor .gePrimaryBtn:not([disabled]),
+html body.geEditor .geBigButton:not([disabled]) {
 	background:var(--header-color);
 }
 html body.geEditor .geBtn, html body.geEditor button,