David Benson [draw.io] 4 gadi atpakaļ
vecāks
revīzija
0a442de57f

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+20-OCT-2020: 13.8.1
+
+- Lucidchart import improvements
+- Gliffy import improvements
+- Uses mxGraph 4.2.1 beta 21
+
 14-OCT-2020: 13.8.0
 
 - App Engine configuration changes

+ 1 - 1
VERSION

@@ -1 +1 @@
-13.8.0
+13.8.1

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19 - 18
etc/mxgraph/mxClient.js


+ 3 - 0
src/main/webapp/WEB-INF/appengine-web.xml

@@ -21,4 +21,7 @@
   </static-files>
 
   <instance-class>F1</instance-class>
+  <automatic-scaling>
+    <max-idle-instances>1</max-idle-instances>
+  </automatic-scaling>
 </appengine-web-app>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1456 - 1454
src/main/webapp/js/app.min.js


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

@@ -4075,7 +4075,7 @@ App.prototype.saveFile = function(forceDialog, success)
 			}
 		});
 		
-		if (!forceDialog && file.getTitle() != null && this.mode != null)
+		if (!forceDialog && file.getTitle() != null && file.invalidFileHandle == null && this.mode != null)
 		{
 			this.save(file.getTitle(), done);
 		}
@@ -4083,6 +4083,7 @@ App.prototype.saveFile = function(forceDialog, success)
 		{
 			this.chooseFileSystemEntries(mxUtils.bind(this, function(fileHandle, desc)
 			{
+				file.invalidFileHandle = null;
 				file.fileHandle = fileHandle;
 				file.title = desc.name;
 				file.desc = desc;

+ 111 - 100
src/main/webapp/js/diagramly/DriveClient.js

@@ -1043,141 +1043,152 @@ DriveClient.prototype.getXmlFile = function(resp, success, error, ignoreMime, re
 		var headers = {'Authorization': 'Bearer ' + this.token};
 		var url = resp.downloadUrl;
 		
-		// Loads XML to initialize realtime document if realtime is empty
-		this.ui.editor.loadUrl(url, mxUtils.bind(this, function(data)
+		// Download URL is null if no option to download for viewers
+		if (url == null)
 		{
-			try
+			if (error != null)
 			{
-				if (data == null)
-				{
-					// TODO: Optional redirect to legacy if link is for old file
-					error({message: mxResources.get('invalidOrMissingFile')});
-				}
-				else if (resp.mimeType == this.libraryMimeType || readLibrary)
+				error({message: mxResources.get('exportOptionsDisabledDetails')});
+			}
+		}
+		else
+		{
+			// Loads XML to initialize realtime document if realtime is empty
+			this.ui.editor.loadUrl(url, mxUtils.bind(this, function(data)
+			{
+				try
 				{
-					if (resp.mimeType == this.libraryMimeType && !readLibrary)
+					if (data == null)
 					{
-						error({message: mxResources.get('notADiagramFile')});
+						// TODO: Optional redirect to legacy if link is for old file
+						error({message: mxResources.get('invalidOrMissingFile')});
 					}
-					else
+					else if (resp.mimeType == this.libraryMimeType || readLibrary)
 					{
-						success(new DriveLibrary(this.ui, data, resp));
+						if (resp.mimeType == this.libraryMimeType && !readLibrary)
+						{
+							error({message: mxResources.get('notADiagramFile')});
+						}
+						else
+						{
+							success(new DriveLibrary(this.ui, data, resp));
+						}
 					}
-				}
-				else
-				{
-					var importFile = false;
-					
-					if (/\.png$/i.test(resp.title))
+					else
 					{
-						var index = data.lastIndexOf(',');
+						var importFile = false;
 						
-						if (index > 0)
+						if (/\.png$/i.test(resp.title))
 						{
-							var xml = this.ui.extractGraphModelFromPng(data.substring(index + 1));
+							var index = data.lastIndexOf(',');
 							
-							if (xml != null && xml.length > 0)
-							{
-								data = xml;
-							}
-							else
+							if (index > 0)
 							{
-								// Checks if the file contains XML data which can happen when we insert
-								// the file and then don't post-process it when loaded into the UI which
-								// is required for creating the images for .PNG and .SVG files.
-								try
+								var xml = this.ui.extractGraphModelFromPng(data.substring(index + 1));
+								
+								if (xml != null && xml.length > 0)
 								{
-									var xml = data.substring(index + 1);
-									var temp = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ?
-										atob(xml) : Base64.decode(xml);
-									var node = this.ui.editor.extractGraphModel(
-										mxUtils.parseXml(temp).documentElement, true);
-									
-									if (node == null || node.getElementsByTagName('parsererror').length > 0)
+									data = xml;
+								}
+								else
+								{
+									// Checks if the file contains XML data which can happen when we insert
+									// the file and then don't post-process it when loaded into the UI which
+									// is required for creating the images for .PNG and .SVG files.
+									try
 									{
-										importFile = true;
+										var xml = data.substring(index + 1);
+										var temp = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ?
+											atob(xml) : Base64.decode(xml);
+										var node = this.ui.editor.extractGraphModel(
+											mxUtils.parseXml(temp).documentElement, true);
+										
+										if (node == null || node.getElementsByTagName('parsererror').length > 0)
+										{
+											importFile = true;
+										}
+										else
+										{
+											data = temp;
+										}
 									}
-									else
+									catch (e)
 									{
-										data = temp;
+										importFile = true;
 									}
 								}
-								catch (e)
-								{
-									importFile = true;
-								}
 							}
 						}
-					}
-					else if (/\.pdf$/i.test(resp.title))
-					{
-						var xml = Editor.extractGraphModelFromPdf(data);
-						
-						if (xml != null && xml.length > 0)
+						else if (/\.pdf$/i.test(resp.title))
 						{
-							importFile = true;
-							data = xml;
+							var xml = Editor.extractGraphModelFromPdf(data);
+							
+							if (xml != null && xml.length > 0)
+							{
+								importFile = true;
+								data = xml;
+							}
 						}
-					}
-					// Checks for base64 encoded mxfile
-					else if (data.substring(0, 32) == 'data:image/png;base64,PG14ZmlsZS')
-					{
-						var temp = data.substring(22);
-						data = (window.atob && !mxClient.IS_SF) ? atob(temp) : Base64.decode(temp);
-					}
-					
-					if (Graph.fileSupport && new XMLHttpRequest().upload && this.ui.isRemoteFileFormat(data, url))
-					{
-						this.ui.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
+						// Checks for base64 encoded mxfile
+						else if (data.substring(0, 32) == 'data:image/png;base64,PG14ZmlsZS')
 						{
-							try
+							var temp = data.substring(22);
+							data = (window.atob && !mxClient.IS_SF) ? atob(temp) : Base64.decode(temp);
+						}
+						
+						if (Graph.fileSupport && new XMLHttpRequest().upload && this.ui.isRemoteFileFormat(data, url))
+						{
+							this.ui.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
 							{
-								if (xhr.readyState == 4)
+								try
 								{
-									if (xhr.status >= 200 && xhr.status <= 299)
+									if (xhr.readyState == 4)
 									{
-										success(new LocalFile(this.ui, xhr.responseText, resp.title + this.extension, true));
-									}
-									else if (error != null)
-									{
-										error({message: mxResources.get('errorLoadingFile')});
+										if (xhr.status >= 200 && xhr.status <= 299)
+										{
+											success(new LocalFile(this.ui, xhr.responseText, resp.title + this.extension, true));
+										}
+										else if (error != null)
+										{
+											error({message: mxResources.get('errorLoadingFile')});
+										}
 									}
 								}
-							}
-							catch (e)
-							{
-								if (error != null)
-								{
-									error(e);
-								}
-								else
+								catch (e)
 								{
-									throw e;
+									if (error != null)
+									{
+										error(e);
+									}
+									else
+									{
+										throw e;
+									}
 								}
-							}
-						}), resp.title);
+							}), resp.title);
+						}
+						else
+						{
+							success((importFile) ? new LocalFile(this.ui, data, resp.title, true) : new DriveFile(this.ui, data, resp));
+						}
+					}
+				}
+				catch (e)
+				{
+					if (error != null)
+					{
+						error(e);
 					}
 					else
 					{
-						success((importFile) ? new LocalFile(this.ui, data, resp.title, true) : new DriveFile(this.ui, data, resp));
+						throw e;
 					}
 				}
-			}
-			catch (e)
-			{
-				if (error != null)
-				{
-					error(e);
-				}
-				else
-				{
-					throw e;
-				}
-			}
-		}), error, ((resp.mimeType != null && resp.mimeType.substring(0, 6) == 'image/' &&
-			resp.mimeType.substring(0, 9) != 'image/svg')) || /\.png$/i.test(resp.title) ||
-			/\.jpe?g$/i.test(resp.title) || /\.pdf$/i.test(resp.title),
-			null, null, null, headers);
+			}), error, ((resp.mimeType != null && resp.mimeType.substring(0, 6) == 'image/' &&
+				resp.mimeType.substring(0, 9) != 'image/svg')) || /\.png$/i.test(resp.title) ||
+				/\.jpe?g$/i.test(resp.title) || /\.pdf$/i.test(resp.title),
+				null, null, null, headers);
+		}
 	}
 	catch (e)
 	{

+ 11 - 2
src/main/webapp/js/diagramly/EditorUi.js

@@ -1550,10 +1550,13 @@
 		if (forceSvg || (!forceXml && file != null && /(\.svg)$/i.test(file.getTitle())))
 		{
 			uncompressed = false;
+			var darkTheme = graph.themes != null && graph.defaultThemeName == 'darkTheme';
 			
 			// Exports SVG for first page while other page is visible by creating a graph
 			// LATER: Add caching for the graph or SVG while not on first page
-			if (this.pages != null && this.currentPage != this.pages[0])
+			// Dark mode requires a refresh that would destroy all handlers
+			// LATER: Use dark theme here to bypass refresh
+			if (darkTheme || (this.pages != null && this.currentPage != this.pages[0]))
 			{
 				var graphGetGlobalVariable = graph.getGlobalVariable;
 				graph = this.createTemporaryGraph(graph.getStylesheet());
@@ -5965,6 +5968,7 @@
 	EditorUi.prototype.createEmbedImage = function(fit, shadow, retina, lightbox, edit, layers, fn, err)
 	{
 		var bounds = this.editor.graph.getGraphBounds();
+		var page = this.getSelectedPageIndex();
 		
 		function doUpdate(dataUri)
 		{
@@ -5977,6 +5981,7 @@
 				// KNOWN: Message passing does not seem to work in IE11
 				onclick = " onclick=\"(function(img){if(img.wnd!=null&&!img.wnd.closed){img.wnd.focus();}else{var r=function(evt){if(evt.data=='ready'&&evt.source==img.wnd){img.wnd.postMessage(decodeURIComponent(" +
 					"img.getAttribute('src')),'*');window.removeEventListener('message',r);}};window.addEventListener('message',r);img.wnd=window.open('" + EditorUi.lightboxHost + "/?client=1" +
+					((page != null) ? ("&page=" + page) : "") +
 					((edit) ? "&edit=_blank" : "") +
 					((layers) ? '&layers=1' : '') + "');}})(this);\"";
 				css += 'cursor:pointer;';
@@ -6121,6 +6126,8 @@
 			// Adds double click handling
 			if (lightbox)
 			{
+				var page = this.getSelectedPageIndex();
+				
 				// KNOWN: Message passing does not seem to work in IE11
 				var js = "(function(svg){var src=window.event.target||window.event.srcElement;" +
 					// Ignores link events
@@ -6133,6 +6140,7 @@
 					"window.addEventListener('message',r);" +
 					// Opens lightbox window
 					"svg.wnd=window.open('" + EditorUi.lightboxHost + "/?client=1" +
+					((page != null) ? ("&page=" + page) : "") +
 					((edit) ? "&edit=_blank" : "") + ((layers) ? '&layers=1' : '') + "');}}})(this);";
 				svgRoot.setAttribute('onclick', js);
 				css += 'cursor:pointer;';
@@ -10614,7 +10622,8 @@
 			}
 			else
 			{
-				this.fileLoaded(new LocalFile(this, data, name || this.defaultFilename, temp, fileHandle, desc));
+				this.fileLoaded(new LocalFile(this, data, name ||
+					this.defaultFilename, temp, fileHandle, desc));
 			}
 		});
 

+ 9 - 3
src/main/webapp/js/diagramly/LocalFile.js

@@ -29,7 +29,7 @@ mxUtils.extend(LocalFile, DrawioFile);
  */
 LocalFile.prototype.isAutosave = function()
 {
-	return this.fileHandle != null && DrawioFile.prototype.isAutosave.apply(this, arguments);
+	return this.fileHandle != null && !this.invalidFileHandle && DrawioFile.prototype.isAutosave.apply(this, arguments);
 };
 
 /**
@@ -71,7 +71,7 @@ LocalFile.prototype.getTitle = function()
  */
 LocalFile.prototype.isRenamable = function()
 {
-	return this.fileHandle == null;
+	return true;
 };
 
 /**
@@ -203,6 +203,8 @@ LocalFile.prototype.saveFile = function(title, revision, success, error, useCurr
 				{
 					this.fileHandle.getFile().then(mxUtils.bind(this, function(newDesc)
 					{
+						this.invalidFileHandle = null;
+						
 						if (this.desc.lastModified == newDesc.lastModified)
 						{
 							writable.write((binary) ? this.ui.base64ToBlob(data, 'image/png') : data).then(mxUtils.bind(this, function()
@@ -223,7 +225,11 @@ LocalFile.prototype.saveFile = function(title, revision, success, error, useCurr
 							this.inConflictState = true;
 							errorWrapper();
 						}
-					}), errorWrapper);
+					}), mxUtils.bind(this, function(e)
+					{
+						this.invalidFileHandle = true;
+						errorWrapper(e);
+					}));
 				}), errorWrapper);
 			}
 		}

+ 41 - 27
src/main/webapp/js/diagramly/Menus.js

@@ -2307,37 +2307,51 @@
 			
 			if (file != null)
 			{
-				var filename = (file.getTitle() != null) ? file.getTitle() : this.editorUi.defaultFilename;
-				
-				var dlg = new FilenameDialog(this.editorUi, filename, mxResources.get('rename'), mxUtils.bind(this, function(title)
+				if (file.constructor == LocalFile && file.fileHandle != null)
 				{
-					if (title != null && title.length > 0 && file != null && title != file.getTitle() &&
-						this.editorUi.spinner.spin(document.body, mxResources.get('renaming')))
+					editorUi.chooseFileSystemEntries(mxUtils.bind(editorUi, function(fileHandle, desc)
 					{
-						// Delete old file, save new file in dropbox if autosize is enabled
-						file.rename(title, mxUtils.bind(this, function(resp)
-						{
-							this.editorUi.spinner.stop();
-						}),
-						mxUtils.bind(this, function(resp)
-						{
-							this.editorUi.handleError(resp, (resp != null) ? mxResources.get('errorRenamingFile') : null);
-						}));
-					}
-				}), (file.constructor == DriveFile || file.constructor == StorageFile) ?
-					mxResources.get('diagramName') : null, function(name)
+						file.invalidFileHandle = null;
+						file.fileHandle = fileHandle;
+						file.title = desc.name;
+						file.desc = desc;
+						editorUi.save(desc.name);
+					}), null, editorUi.createFileSystemOptions(file.getTitle()));
+				}
+				else
 				{
-					if (name != null && name.length > 0)
-					{
-						return true;
-					}
-					
-					editorUi.showError(mxResources.get('error'), mxResources.get('invalidName'), mxResources.get('ok'));
+					var filename = (file.getTitle() != null) ? file.getTitle() : this.editorUi.defaultFilename;
 					
-					return false;
-				}, null, null, null, null, editorUi.editor.fileExtensions);
-				this.editorUi.showDialog(dlg.container, 340, 90, true, true);
-				dlg.init();
+					var dlg = new FilenameDialog(this.editorUi, filename, mxResources.get('rename'), mxUtils.bind(this, function(title)
+					{
+						if (title != null && title.length > 0 && file != null && title != file.getTitle() &&
+							this.editorUi.spinner.spin(document.body, mxResources.get('renaming')))
+						{
+							// Delete old file, save new file in dropbox if autosize is enabled
+							file.rename(title, mxUtils.bind(this, function(resp)
+							{
+								this.editorUi.spinner.stop();
+							}),
+							mxUtils.bind(this, function(resp)
+							{
+								this.editorUi.handleError(resp, (resp != null) ? mxResources.get('errorRenamingFile') : null);
+							}));
+						}
+					}), (file.constructor == DriveFile || file.constructor == StorageFile) ?
+						mxResources.get('diagramName') : null, function(name)
+					{
+						if (name != null && name.length > 0)
+						{
+							return true;
+						}
+						
+						editorUi.showError(mxResources.get('error'), mxResources.get('invalidName'), mxResources.get('ok'));
+						
+						return false;
+					}, null, null, null, null, editorUi.editor.fileExtensions);
+					this.editorUi.showDialog(dlg.container, 340, 90, true, true);
+					dlg.init();
+				}
 			}
 		}));
 		

+ 22 - 4
src/main/webapp/js/diagramly/mxRuler.js

@@ -200,13 +200,31 @@ function mxRuler(editorUi, unit, isVertical, isSecondery)
 	        
 	        if (isVertical)
 	    	{
-	        	ctx.fillRect(0, RULER_THICKNESS, RULER_THICKNESS, rStart - RULER_THICKNESS);
-		        ctx.fillRect(0, rEnd, RULER_THICKNESS, canvas.height);
+				var oh = rStart - RULER_THICKNESS;
+				
+				if (oh > 0)
+				{
+					ctx.fillRect(0, RULER_THICKNESS, RULER_THICKNESS, oh);
+				}
+
+				if (rEnd < canvas.height)
+				{
+					ctx.fillRect(0, rEnd, RULER_THICKNESS, canvas.height);
+				}
 	    	}
 	        else
 	        {
-		        ctx.fillRect(RULER_THICKNESS, 0, rStart - RULER_THICKNESS, RULER_THICKNESS);
-		        ctx.fillRect(rEnd, 0, canvas.width, RULER_THICKNESS);
+				var ow = rStart - RULER_THICKNESS;
+		        
+				if (ow > 0)
+				{
+					ctx.fillRect(RULER_THICKNESS, 0, ow, RULER_THICKNESS);	
+				}
+		        
+				if (rEnd < canvas.width)
+				{
+					ctx.fillRect(rEnd, 0, canvas.width, RULER_THICKNESS);
+				}
 	        }
         }
         

+ 42 - 9
src/main/webapp/js/mxgraph/Actions.js

@@ -309,18 +309,28 @@ Actions.prototype.init = function()
 	this.addAction('toBack', function() { graph.orderCells(true); }, null, null, Editor.ctrlKey + '+Shift+B');
 	this.addAction('group', function()
 	{
-		if (graph.getSelectionCount() == 1)
-		{
-			graph.setCellStyles('container', '1');
-		}
-		else
+		if (graph.isEnabled())
 		{
-			graph.setSelectionCell(graph.groupCells(null, 0));
+			var cells = mxUtils.sortCells(graph.getSelectionCells(), true);
+
+			if (cells.length == 1 && !graph.isTable(cells[0]) && !graph.isTableRow(cells[0]))
+			{
+				graph.setCellStyles('container', '1');
+			}
+			else
+			{
+				cells = graph.getCellsForGroup(cells);
+				
+				if (cells.length > 1)
+				{
+					graph.setSelectionCell(graph.groupCells(null, 0, cells));
+				}
+			}
 		}
 	}, null, null, Editor.ctrlKey + '+G');
 	this.addAction('ungroup', function()
 	{
-		if (graph.isEnabled() && !graph.isSelectionEmpty())
+		if (graph.isEnabled())
 		{
 			var cells = graph.getSelectionCells();
 			
@@ -329,7 +339,7 @@ Actions.prototype.init = function()
 			{
 				var temp = graph.ungroupCells();
 				
-				// Unsets container flag for remaining cells
+				// Clears container flag for remaining cells
 				if (cells != null)
 				{
 					for (var i = 0; i < cells.length; i++)
@@ -355,7 +365,30 @@ Actions.prototype.init = function()
 			graph.setSelectionCells(temp);
 		}
 	}, null, null, Editor.ctrlKey + '+Shift+U');
-	this.addAction('removeFromGroup', function() { graph.removeCellsFromParent(); });
+	this.addAction('removeFromGroup', function()
+	{
+		if (graph.isEnabled())
+		{
+			var cells = graph.getSelectionCells();
+			
+			// Removes table rows and cells
+			if (cells != null)
+			{
+				var temp = [];
+				
+				for (var i = 0; i < cells.length; i++)
+		    	{
+					if (!graph.isTableRow(cells[i]) &&
+						!graph.isTableCell(cells[i]))
+					{
+						temp.push(cells[i]);
+					}
+		    	}
+				
+				graph.removeCellsFromParent(temp);
+			}
+		}
+	});
 	// Adds action
 	this.addAction('edit', function()
 	{

+ 1 - 1
src/main/webapp/js/mxgraph/EditorUi.js

@@ -516,7 +516,7 @@ EditorUi = function(editor, container, lightbox)
 	
 		// Keys that should be ignored if the cell has a value (known: new default for all cells is html=1 so
 	    // for the html key this effecticely only works for edges inserted via the connection handler)
-		var valueStyles = ['fontFamily', 'fontSize', 'fontColor'];
+		var valueStyles = ['fontFamily', 'fontSource', 'fontSize', 'fontColor'];
 		
 		// Keys that always update the current edge style regardless of selection
 		var alwaysEdgeStyles = ['edgeStyle', 'startArrow', 'startFill', 'startSize', 'endArrow',

+ 48 - 7
src/main/webapp/js/mxgraph/Graph.js

@@ -1195,7 +1195,7 @@ Graph.foreignObjectWarningLink = 'https://desk.draw.io/support/solutions/article
 /**
  * Minimum height for table rows.
  */
-Graph.pasteStyles = ['rounded', 'shadow', 'dashed', 'dashPattern', 'fontFamily', 'fontSize', 'fontColor', 'fontStyle',
+Graph.pasteStyles = ['rounded', 'shadow', 'dashed', 'dashPattern', 'fontFamily', 'fontSource', 'fontSize', 'fontColor', 'fontStyle',
 					'align', 'verticalAlign', 'strokeColor', 'strokeWidth', 'fillColor', 'gradientColor', 'swimlaneFillColor',
 					'textOpacity', 'gradientDirection', 'glass', 'labelBackgroundColor', 'labelBorderColor', 'opacity',
 					'spacing', 'spacingTop', 'spacingLeft', 'spacingBottom', 'spacingRight', 'endFill', 'endArrow',
@@ -1957,8 +1957,6 @@ Graph.prototype.init = function(container)
 	};
 	
 	/**
-	 * Function: viewStateChanged
-	 * 
 	 * Overrides to bypass full cell tree validation.
 	 * TODO: Check if this improves performance
 	 */
@@ -1977,8 +1975,6 @@ Graph.prototype.init = function(container)
 	};
 
 	/**
-	 * Function: validate
-	 * 
 	 * Overrides validate to normalize validation view state and pass
 	 * current state to CSS transform.
 	 */
@@ -2008,6 +2004,51 @@ Graph.prototype.init = function(container)
 		}
 	};
 
+	/**
+	 * Overrides function to exclude table cells and rows from groups.
+	 */
+	var graphGetCellsForGroup = mxGraph.prototype.getCellsForGroup;
+	Graph.prototype.getCellsForGroup = function(cells)
+	{
+		cells = graphGetCellsForGroup.apply(this, arguments);
+		var result = [];
+		
+		// Filters selection cells with the same parent
+		for (var i = 0; i < cells.length; i++)
+		{
+			if (!this.isTableRow(cells[i]) &&
+				!this.isTableCell(cells[i]))
+			{
+				result.push(cells[i]);
+			}
+		}
+		
+		return result;
+	};
+	
+	/**
+	 * Overrides function to exclude tables, rows and cells from ungrouping.
+	 */
+	var graphGetCellsForUngroup = mxGraph.prototype.getCellsForUngroup;
+	Graph.prototype.getCellsForUngroup = function(cells)
+	{
+		cells = graphGetCellsForGroup.apply(this, arguments);
+		var result = [];
+		
+		// Filters selection cells with the same parent
+		for (var i = 0; i < cells.length; i++)
+		{
+			if (!this.isTable(cells[i]) &&
+				!this.isTableRow(cells[i]) &&
+				!this.isTableCell(cells[i]))
+			{
+				result.push(cells[i]);
+			}
+		}
+		
+		return result;
+	};
+
 	/**
 	 * Function: updateCssTransform
 	 * 
@@ -6147,7 +6188,7 @@ if (typeof mxVertexHandler != 'undefined')
 		var mxConnectionHandlerCreateTarget = mxConnectionHandler.prototype.isCreateTarget;
 		mxConnectionHandler.prototype.isCreateTarget = function(evt)
 		{
-			return mxEvent.isControlDown(evt) || mxConnectionHandlerCreateTarget.apply(this, arguments);
+			return this.graph.isCloneEvent(evt) || mxConnectionHandlerCreateTarget.apply(this, arguments);
 		};
 
 		// Overrides highlight shape for connection points
@@ -7151,7 +7192,7 @@ if (typeof mxVertexHandler != 'undefined')
 						{
 							// Rotates the size and position in the geometry
 							if (!this.isTable(cell) && !this.isTableRow(cell) &&
-								!this.isTableCell(cell))
+								!this.isTableCell(cell) && !this.isSwimlane(cell))
 							{
 								geo = geo.clone();
 								geo.x += geo.width / 2 - geo.height / 2;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 633 - 631
src/main/webapp/js/viewer-static.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 633 - 631
src/main/webapp/js/viewer.min.js


+ 1 - 1
src/main/webapp/service-worker.js

@@ -6,7 +6,7 @@ if (workbox)
 	workbox.precaching.precacheAndRoute([
   {
     "url": "js/app.min.js",
-    "revision": "9d3b09ac48cbc9d81cfff11d3ce9861d"
+    "revision": "5f5f114e28603c9ea325bd6839db869a"
   },
   {
     "url": "js/extensions.min.js",