瀏覽代碼

10.9.4 release

Gaudenz Alder 6 年之前
父節點
當前提交
093391d52f

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+11-JUL-2019: 10.9.4
+
+- Adds named styles for CSV import
+
 10-JUL-2019: 10.9.3
 
 - Fixes trailing newline in plain text labels

+ 1 - 1
VERSION

@@ -1 +1 @@
-10.9.3
+10.9.4

+ 1 - 1
src/main/webapp/cache.manifest

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 07/10/2019 10:52 AM
+# 07/11/2019 07:19 AM
 
 app.html
 index.html?offline=1

文件差異過大導致無法顯示
+ 326 - 324
src/main/webapp/js/app.min.js


+ 17 - 11
src/main/webapp/js/diagramly/App.js

@@ -28,8 +28,9 @@ App = function(editor, container, lightbox)
 				var evt = {category: 'DISCARD-FILE-' + file.getHash(),
 					action: ((file.savingFile) ? 'saving' : '') +
 					((file.savingFile && file.savingFileTime != null) ? '_' +
-						Math.round((Date.now() - file.savingFileTime) / 1000) : '') +
+						Math.round((Date.now() - file.savingFileTime.getTime()) / 1000) : '') +
 					((file.autosaveThread != null) ? '-thread' : '') +
+					'-sl_' + ((file.saveLevel != null) ? file.saveLevel : 'x') +
 					((this.editor.autosave) ? '' : '-nosave') +
 					((file.isAutosave()) ? '' : '-noauto') +
 					((file.changeListenerEnabled) ? '' : '-nolisten') +
@@ -42,8 +43,9 @@ App = function(editor, container, lightbox)
 					
 				if (file.constructor == DriveFile && file.desc != null && this.drive != null)
 				{
-					evt.label += ((this.drive.user != null) ? '-user_' + this.drive.user.id : '-nouser') + '-rev_' +
-						file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize();
+					evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' +
+						file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize() +
+						'-mime_' + file.desc.mimeType;
 				}
 
 				EditorUi.logEvent(evt);
@@ -1075,7 +1077,7 @@ App.prototype.init = function()
 		}))
 	}
 	
-	var createFooter = mxUtils.bind(this, function(label, link, className, closeHandler)
+	var createFooter = mxUtils.bind(this, function(label, link, className, closeHandler, helpLink)
 	{
 		var footer = document.createElement('div');
 		footer.style.cssText = 'position:absolute;bottom:0px;max-width:90%;padding:10px;padding-right:26px;' +
@@ -1090,7 +1092,10 @@ App.prototype.init = function()
 		footer.style.whiteSpace = 'nowrap';
 		footer.innerHTML = '<a href="' + link +
 			'" target="_blank" style="display:inline;text-decoration:none;font-weight:700;font-size:13px;opacity:1;">' +
-			icn + label + icn + '</a>';
+			icn + label + icn + '</a>' + ((helpLink != null) ? '<a href="' + helpLink +
+			'" target="_blank" style="display:inline;text-decoration:none;font-weight:700;font-size:13px;opacity:1;margin-right:8px;">Help</a>' : '');
+		
+		console.log('help', helpLink);
 		
 		var img = document.createElement('img');
 		
@@ -1286,7 +1291,7 @@ App.prototype.init = function()
 											mxSettings.settings.closeRealtimeWarning = Date.now();
 											mxSettings.save();
 										}
-									}));
+									}), 'https://desk.draw.io/support/solutions/articles/16000092210');
 
 								document.body.appendChild(footer);
 								
@@ -1507,8 +1512,9 @@ App.prototype.sanityCheck = function()
 		var evt = {category: 'WARN-FILE-' + file.getHash(),
 			action: ((file.savingFile) ? 'saving' : '') +
 			((file.savingFile && file.savingFileTime != null) ? '_' +
-				Math.round((Date.now() - file.savingFileTime) / 1000) : '') +
+				Math.round((Date.now() - file.savingFileTime.getTime()) / 1000) : '') +
 			((file.autosaveThread != null) ? '-thread' : '') +
+			'-sl_' + ((file.saveLevel != null) ? file.saveLevel : 'x') +
 			((this.editor.autosave) ? '' : '-nosave') +
 			((file.isAutosave()) ? '' : '-noauto') +
 			((file.changeListenerEnabled) ? '' : '-nolisten') +
@@ -1521,8 +1527,9 @@ App.prototype.sanityCheck = function()
 			
 		if (file.constructor == DriveFile && file.desc != null && this.drive != null)
 		{
-			evt.label += ((this.drive.user != null) ? '-user_' + this.drive.user.id : '-nouser') + '-rev_' +
-				file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize();
+			evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' +
+				file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize() +
+				'-mime_' + file.desc.mimeType;
 		}
 			
 		EditorUi.logEvent(evt);
@@ -2073,9 +2080,8 @@ App.prototype.getThumbnail = function(width, success)
 	}
 	catch (e)
 	{
-		// ignore and use placeholder
 		// Removes temporary graph from DOM
-  	    if (graph != this.editor.graph && graph.container.parentNode != null)
+  	    if (graph != null && graph != this.editor.graph && graph.container.parentNode != null)
 		{
 			graph.container.parentNode.removeChild(graph.container);
 		}

+ 131 - 109
src/main/webapp/js/diagramly/DriveClient.js

@@ -344,7 +344,7 @@ DriveClient.prototype.executeRequest = function(req, success, error)
 					
 					if (error != null)
 					{
-						error({code: App.ERROR_TIMEOUT, retry: fn});
+						error({code: App.ERROR_TIMEOUT, message: mxResources.get('timeout'), retry: fn});
 					}
 				}), this.ui.timeout);
 				
@@ -1079,72 +1079,77 @@ DriveClient.prototype.getXmlFile = function(resp, success, error, ignoreMime, re
  * @param {number} dy Y-coordinate of the translation.
  */
 DriveClient.prototype.saveFile = function(file, revision, success, errFn, noCheck, unloading, overwrite, properties)
-{
-	var error = mxUtils.bind(this, function(e)
+{	
+	try
 	{
-		if (errFn != null)
-		{
-			errFn(e);
-		}
-		else
-		{
-			throw e;
-		}
+		file.saveLevel = 1;
 		
-		// Logs failed save
-		try
+		var error = mxUtils.bind(this, function(e)
 		{
-			if (!file.isConflict(e))
+			file.saveLevel = null;
+			
+			if (errFn != null)
 			{
-				var err = 'error_' + (file.getErrorMessage(e) || 'unknown');
-
-				if (e != null && e.error != null && e.error.code != null)
+				errFn(e);
+			}
+			else
+			{
+				throw e;
+			}
+			
+			// Logs failed save
+			try
+			{
+				if (!file.isConflict(e))
 				{
-					err += '-code_' + e.error.code;
+					var err = 'error_' + (file.getErrorMessage(e) || 'unknown');
+	
+					if (e != null && e.error != null && e.error.code != null)
+					{
+						err += '-code_' + e.error.code;
+					}
+					
+					EditorUi.logEvent({category: 'ERROR-SAVE-FILE-' + file.getHash() + '-rev_' +
+						file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate +
+							'-size_' + file.getSize() + '-mime_' + file.desc.mimeType +
+						((this.ui.editor.autosave) ? '' : '-nosave') +
+						((file.isAutosave()) ? '' : '-noauto') +
+						((file.changeListenerEnabled) ? '' : '-nolisten') +
+						((file.inConflictState) ? '-conflict' : '') +
+						((file.invalidChecksum) ? '-invalid' : ''),
+						action: err, label: ((this.user != null) ? ('user_' + this.user.id) : 'nouser') +
+						((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync')});
 				}
-				
-				EditorUi.logEvent({category: 'ERROR-SAVE-FILE-' + file.getHash() + '.' +
-					file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize() +
-					((this.ui.editor.autosave) ? '' : '-nosave') +
-					((file.isAutosave()) ? '' : '-noauto') +
-					((file.changeListenerEnabled) ? '' : '-nolisten') +
-					((file.inConflictState) ? '-conflict' : '') +
-					((file.invalidChecksum) ? '-invalid' : ''),
-					action: err, label: ((this.user != null) ? 'user_' + this.user.id : 'unknown') +
-					((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync')});
 			}
-		}
-		catch (ex)
+			catch (ex)
+			{
+				// ignore
+			}
+		});
+		
+		var criticalError = mxUtils.bind(this, function(e)
 		{
-			// ignore
-		}
-	});
+			error(e);
 	
-	var criticalError = mxUtils.bind(this, function(e)
-	{
-		error(e);
+			try
+			{
+				EditorUi.logError(e.message, null, null, e);
+				
+				EditorUi.sendReport('Critical error in DriveClient.saveFile ' +
+					new Date().toISOString() + ':' +
+					'\n\nBrowser=' + navigator.userAgent +
+					'\nFile=' + file.desc.id + '.' + file.desc.headRevisionId +
+					'\nUser=' + ((this.user != null) ? this.user.id : 'nouser') +
+					 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync') +
+					'\nMessage=' + e.message +
+					'\n\nStack:\n' + e.stack);
+			}
+			catch (e)
+			{
+				// ignore
+			}
+		});
 
-		try
-		{
-			EditorUi.logError(e.message, null, null, e);
-			
-			EditorUi.sendReport('Critical error in DriveClient.saveFile ' +
-				new Date().toISOString() + ':' +
-				'\n\nBrowser=' + navigator.userAgent +
-				'\nFile=' + file.desc.id + '.' + file.desc.headRevisionId +
-				'\nUser=' + ((this.user != null) ? this.user.id : 'unknown') +
-				 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync') +
-				'\nMessage=' + e.message +
-				'\n\nStack:\n' + e.stack);
-		}
-		catch (e)
-		{
-			// ignore
-		}
-	});
-	
-	try
-	{
 		if (file.isEditable() && file.desc != null)
 		{
 			var t0 = new Date().getTime();
@@ -1170,6 +1175,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 			{
 				try
 				{
+					file.saveLevel = 3;
 					var prevDesc = null;
 					var pinned = false;
 					var meta =
@@ -1278,7 +1284,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 									EditorUi.sendReport('Critical: Error saving to Google Drive ' +
 										new Date().toISOString() + ':' + '\n\nBrowser=' + navigator.userAgent +
 										'\nFile=' + file.desc.id + ' ' + file.desc.mimeType +
-										'\nUser=' + ((this.user != null) ? this.user.id : 'unknown') +
+										'\nUser=' + ((this.user != null) ? this.user.id : 'nouser') +
 										 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync') +
 										'\nErrors=' + temp + '\nOld=' + head0 + ' ' + mod0 + ' etag-hash=' +
 										this.ui.hashValue(etag0) + '\nNew=' + resp.headRevisionId + ' ' +
@@ -1287,7 +1293,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 										null, 'from-' + head0 + '.' + mod0 + '-' + this.ui.hashValue(etag0) +
 										'-to-' + resp.headRevisionId + '.' + resp.modifiedDate + '-' +
 										this.ui.hashValue(resp.etag) + ((temp.length > 0) ? '-errors-' + temp : ''),
-										'user-' + ((this.user != null) ? this.user.id : 'unknown') +
+										'user-' + ((this.user != null) ? this.user.id : 'nouser') +
 									 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync'));
 								}
 								catch (e)
@@ -1297,6 +1303,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 							}
 							else
 							{
+								file.saveLevel = null;
 						    	success(resp, savedData);
 		
 						    	if (prevDesc != null)
@@ -1325,7 +1332,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 										EditorUi.logEvent({category: file.convertedFrom + '-CONVERT-FILE-' + file.getHash(),
 											action: 'from_' + prevDesc.id + '.' + prevDesc.headRevisionId +
 											'-to_' + file.desc.id + '.' + file.desc.headRevisionId,
-											label: (this.user != null) ? 'user_' + this.user.id : 'unknown' +
+											label: (this.user != null) ? ('user_' + this.user.id) : 'nouser' +
 											((file.sync != null) ? '-client_' + file.sync.clientId : 'nosync')});
 									}
 									catch (e)
@@ -1338,14 +1345,16 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 								try
 								{
 									EditorUi.logEvent({category: 'SUCCESS-SAVE-FILE-' + file.getHash() +
-										'.' + head0 + '-mod_' + mod0, action: 'saved-' + resp.headRevisionId +
+										'-rev0_' + head0 + '-mod0_' + mod0,
+										action: 'rev-' + resp.headRevisionId +
 										'-mod_' + resp.modifiedDate + '-size_' + file.getSize() +
+										'-mime_' + file.desc.mimeType +
 										((this.ui.editor.autosave) ? '' : '-nosave') +
 										((file.isAutosave()) ? '' : '-noauto') +
 										((file.changeListenerEnabled) ? '' : '-nolisten') +
 										((file.inConflictState) ? '-conflict' : '') +
 										((file.invalidChecksum) ? '-invalid' : ''),
-										label: ((this.user != null) ? 'user_' + this.user.id : 'unknown') +
+										label: ((this.user != null) ? ('user_' + this.user.id) : 'nouser') +
 										((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync')});
 								}
 								catch (e)
@@ -1362,6 +1371,8 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 					
 					var doExecuteRequest = mxUtils.bind(this, function(data, binary)
 					{
+						file.saveLevel = 4;
+						
 						try
 						{
 							if (properties != null)
@@ -1377,6 +1388,8 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 							
 							var executeSave = mxUtils.bind(this, function(realOverwrite)
 							{
+								file.saveLevel = 5;
+								
 								try
 								{
 									var unknown = file.desc.mimeType != this.xmlMimeType && file.desc.mimeType != this.mimeType &&
@@ -1387,6 +1400,8 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 										(realOverwrite) ? null : etag, pinned), wrapper,
 										mxUtils.bind(this, function(err)
 									{
+										file.saveLevel = 6;
+											
 										try
 										{
 											if (!file.isConflict(err))
@@ -1401,6 +1416,8 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 													'fields': this.catchupFields, 'supportsTeamDrives': true}), 
 													mxUtils.bind(this, function(resp)
 												{
+													file.saveLevel = 7;
+
 													try
 													{
 														// Stale etag detected, retry with delay
@@ -1422,8 +1439,8 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 																{
 																	EditorUi.logError('Warning: Stale Etag Overwrite ' + file.getHash(),
 																		null, file.desc.id + '.' + file.desc.headRevisionId,
-																		(this.user != null) ? this.user.id : 'unknown' +
-																		'.' + ((file.sync != null) ? file.sync.clientId : 'nosync'));
+																		((this.user != null) ? ('user_' + this.user.id) : 'nouser') +
+																		((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync'));
 																}
 																catch (e)
 																{
@@ -1431,7 +1448,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 																}
 															}
 														}
-														else if (error != null)
+														else
 														{
 															error(err, resp);
 														}
@@ -1442,10 +1459,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 													}
 												}), mxUtils.bind(this, function()
 												{
-													if (error != null)
-													{
-														error(err);
-													}
+													error(err);
 												}));
 											}
 										}
@@ -1464,6 +1478,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 							// Uses saved PNG data for thumbnail
 							if (saveAsPng && thumb == null)
 							{
+								file.saveLevel = 8;
 								var img = new Image();
 								
 								img.onload = mxUtils.bind(this, function()
@@ -1531,53 +1546,64 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 			// (required because generation of thumbnails is asynchronous)
 			var fn = mxUtils.bind(this, function()
 			{
-				// NOTE: getThumbnail is asynchronous and returns false if no thumbnails can be created
-				if (unloading || saveAsPng || file.constructor == DriveLibrary || !this.enableThumbnails || urlParams['thumb'] == '0' ||
-					(file.desc.mimeType != null && file.desc.mimeType.substring(0, 29) != 'application/vnd.jgraph.mxfile') ||
-					!this.ui.getThumbnail(this.thumbnailWidth, mxUtils.bind(this, function(canvas)
-					{
-						// Callback for getThumbnail
-						try
-						{
-							var thumb = null;
+				try
+				{
+					file.saveLevel = 2;
 
+					// NOTE: getThumbnail is asynchronous and returns false if no thumbnails can be created
+					if (unloading || saveAsPng || file.constructor == DriveLibrary || !this.enableThumbnails || urlParams['thumb'] == '0' ||
+						(file.desc.mimeType != null && file.desc.mimeType.substring(0, 29) != 'application/vnd.jgraph.mxfile') ||
+						!this.ui.getThumbnail(this.thumbnailWidth, mxUtils.bind(this, function(canvas)
+						{
+							// Callback for getThumbnail
 							try
 							{
-								if (canvas != null)
-								{
-									// Security errors are possible
-									thumb = canvas.toDataURL('image/png');
-								}
-								
-								// Maximum thumbnail size is 2MB
-								if (thumb != null)
+								file.thumbTime = null;
+								var thumb = null;
+	
+								try
 								{
-									if (thumb.length > this.maxThumbnailSize)
+									if (canvas != null)
 									{
-										thumb = null;
+										// Security errors are possible
+										thumb = canvas.toDataURL('image/png');
 									}
-									else
+									
+									// Maximum thumbnail size is 2MB
+									if (thumb != null)
 									{
-										// Converts base64 data into required format for Drive (base64url with no prefix)
-										thumb = thumb.substring(thumb.indexOf(',') + 1).replace(/\+/g, '-').replace(/\//g, '_');
+										if (thumb.length > this.maxThumbnailSize)
+										{
+											thumb = null;
+										}
+										else
+										{
+											// Converts base64 data into required format for Drive (base64url with no prefix)
+											thumb = thumb.substring(thumb.indexOf(',') + 1).replace(/\+/g, '-').replace(/\//g, '_');
+										}
 									}
 								}
+								catch (e)
+								{
+									thumb = null;
+								}
+								
+								doSave(thumb, 'image/png');
 							}
 							catch (e)
 							{
-								thumb = null;
+								criticalError(e);
 							}
-							
-							doSave(thumb, 'image/png');
-						}
-						catch (e)
-						{
-							criticalError(e);
-						}
-					})))
+						})))
+					{
+						// If-branch
+						file.thumbTime = null;
+						doSave(null, null, file.constructor != DriveLibrary);
+					}
+				}
+				catch (e)
 				{
-					// If-branch
-					doSave(null, null, file.constructor != DriveLibrary);
+					criticalError(e);
 				}
 			});
 			
@@ -1599,11 +1625,7 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 		else
 		{
 			this.ui.editor.graph.reset();
-			
-			if (error != null)
-			{
-				error({message: mxResources.get('readOnly')});
-			}
+			error({message: mxResources.get('readOnly')});
 		}
 	}
 	catch (e)
@@ -2604,10 +2626,10 @@ DriveClient.prototype.convertRealtimeFiles = function()
 					// Logs conversion
 					EditorUi.logEvent({category: 'AUTO-CONVERT',
 						action: 'total_' + total + '-done_' + converted +
-						'-fail_' + '-xml_' + fromXml + '-json_' + fromJson +
+						'-fail_' + failed + '-xml_' + fromXml + '-json_' + fromJson +
 						'-load_' + loadFail + '-save_' + saveFail +
 						'-invalid_' + invalid + '-dt-' + Math.round(dt / 1000),
-						label: (this.user != null) ? 'user_' + this.user.id : '-nouser'});
+						label: (this.user != null) ? ('user_' + this.user.id) : '-nouser'});
 				}
 				catch (e)
 				{

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

@@ -184,8 +184,8 @@ DriveFile.prototype.saveFile = function(title, revision, success, error, unloadi
 					{
 						try
 						{
-							this.isModified = prevModified;
 							this.savingFile = false;
+							this.isModified = prevModified;
 							
 							// Handles special case where resp is false eg
 							// if the old file was converted to realtime

+ 10 - 0
src/main/webapp/js/diagramly/Editor.js

@@ -230,6 +230,16 @@
 		'#\n' +
 		'# parentstyle: swimlane;whiteSpace=wrap;html=1;childLayout=stackLayout;horizontal=1;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;\n' +
 		'#\n' +
+		'## Optional column name that contains a reference to a named style in styles.\n' +
+		'## Default is the current style for nodes.\n' +
+		'#\n' +
+		'# stylename: -\n' +
+		'#\n' +
+		'## JSON for named styles of the form {"name": "style", "name": "style"} where style is a cell style with\n' +
+		'## placeholders that are replaced once.\n' +
+		'#\n' +
+		'# styles: -\n' +
+		'#\n' +
 		'## Uses the given column name as the identity for cells (updates existing cells).\n' +
 		'## Default is no identity (empty value or -).\n' +
 		'#\n' +

+ 129 - 64
src/main/webapp/js/diagramly/EditorUi.js

@@ -6301,36 +6301,46 @@
 			{
 				(mxUtils.bind(this, function(img)
 				{
-					var src = converter.convert(img.getAttribute(srcAttr));
-		        	
-					// Data URIs are pass-through
-					if (src != null && src.substring(0, 5) != 'data:')
+					try
 					{
-						var tmp = cache[src];
-						
-						if (tmp == null)
+						if (img != null)
 						{
-							inc();
-							
-							this.convertImageToDataUri(src, function(uri)
+							var src = converter.convert(img.getAttribute(srcAttr));
+				        	
+							// Data URIs are pass-through
+							if (src != null && src.substring(0, 5) != 'data:')
 							{
-								if (uri != null)
+								var tmp = cache[src];
+								
+								if (tmp == null)
+								{
+									inc();
+									
+									this.convertImageToDataUri(src, function(uri)
+									{
+										if (uri != null)
+										{
+											cache[src] = uri;
+											img.setAttribute(srcAttr, uri);
+										}
+										
+										dec();
+									});
+								}
+								else
 								{
-									cache[src] = uri;
-									img.setAttribute(srcAttr, uri);
+									img.setAttribute(srcAttr, tmp);
 								}
-								
-								dec();
-							});
-						}
-						else
-						{
-							img.setAttribute(srcAttr, tmp);
+							}
+							else if (src != null)
+							{
+								img.setAttribute(srcAttr, src);
+							}
 						}
 					}
-					else if (src != null)
+					catch (e)
 					{
-						img.setAttribute(srcAttr, src);
+						// ignore
 					}
 				}))(images[i]);
 			}
@@ -6442,51 +6452,86 @@
 	 */
 	EditorUi.prototype.convertImageToDataUri = function(url, callback)
 	{
-		if (/(\.svg)$/i.test(url))
+		try
 		{
-			mxUtils.get(url, mxUtils.bind(this, function(req)
-			{
-				callback(this.createSvgDataUri(req.getText()));
-			}),
-			function()
+			var acceptResponse = true;
+			
+			var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
 			{
+				acceptResponse = false;
 				callback(this.svgBrokenImage.src);
-			});
+			}), this.timeout);
+	
+			if (/(\.svg)$/i.test(url))
+			{
+				mxUtils.get(url, mxUtils.bind(this, function(req)
+				{
+			    	window.clearTimeout(timeoutThread);
+					
+					if (acceptResponse)
+					{
+						callback(this.createSvgDataUri(req.getText()));
+					}
+				}),
+				function()
+				{
+			    	window.clearTimeout(timeoutThread);
+					
+					if (acceptResponse)
+					{
+						callback(this.svgBrokenImage.src);
+					}
+				});
+			}
+			else
+			{
+			    var img = new Image();
+			    var self = this;
+			    
+			    if (this.crossOriginImages)
+		    	{
+				    img.crossOrigin = 'anonymous';
+			    }
+			    
+			    img.onload = function()
+			    {
+			    	window.clearTimeout(timeoutThread);
+					
+					if (acceptResponse)
+					{
+				        try
+				        {
+					        var canvas = document.createElement('canvas');
+					        var ctx = canvas.getContext('2d');
+					        canvas.height = img.height;
+					        canvas.width = img.width;
+					        ctx.drawImage(img, 0, 0);
+
+				        	callback(canvas.toDataURL());
+				        }
+				        catch (e)
+				        {
+			        		callback(self.svgBrokenImage.src);
+				        }
+					}
+			    };
+			    
+			    img.onerror = function()
+			    {
+			    	window.clearTimeout(timeoutThread);
+					
+					if (acceptResponse)
+					{
+						callback(self.svgBrokenImage.src);
+					}
+			    };
+			    
+			    img.src = url;
+			}
 		}
-		else
+		catch (e)
 		{
-		    var img = new Image();
-		    var self = this;
-		    
-		    if (this.crossOriginImages)
-	    	{
-			    img.crossOrigin = 'anonymous';
-		    }
-		    
-		    img.onload = function()
-		    {
-		        var canvas = document.createElement('canvas');
-		        var ctx = canvas.getContext('2d');
-		        canvas.height = img.height;
-		        canvas.width = img.width;
-		        ctx.drawImage(img, 0, 0);
-		        
-		        try
-		        {
-	        		callback(canvas.toDataURL());
-		        }
-		        catch (e)
-		        {
-	        		callback(self.svgBrokenImage.src);
-		        }
-		    };
-		    
-		    img.onerror = function()
-		    {
-	    		callback(self.svgBrokenImage.src);
-		    };
-		    
-		    img.src = url;
+			callback(this.svgBrokenImage.src);
 		}
 	};
 
@@ -10883,6 +10928,8 @@
         		
         		// Default values
         		var style = null;
+        		var styles = null;
+        		var stylename = null;
         		var parentstyle = null;
         		var identity = null;
         		var parent = null;
@@ -10975,6 +11022,14 @@
 		    				{
 		    					parentstyle = value;
 		    				}
+		    				else if (key == 'stylename' && value.length > 0 && value != '-')
+		    				{
+		    					stylename = value;
+		    				}
+		    				else if (key == 'styles' && value.length > 0 && value != '-')
+		    				{
+		    					styles = JSON.parse(value);
+		    				}
 		    				else if (key == 'identity' && value.length > 0 && value != '-')
 		    				{
 		    					identity = value;
@@ -11115,7 +11170,17 @@
 					    	{
 								graph.setAttributeForCell(newCell, keys[j], values[j]);
 					    	}
-							
+
+							if (stylename != null && styles != null)
+							{
+								var tempStyle = styles[newCell.getAttribute(stylename)];
+								
+								if (tempStyle != null)
+								{
+									newCell.style = tempStyle;
+								}
+							}
+	
 							graph.setAttributeForCell(newCell, 'placeholders', '1');
 							newCell.style = graph.replacePlaceholders(newCell, newCell.style);
 
@@ -11147,7 +11212,7 @@
 								// Removes attribute
 								graph.setAttributeForCell(cell, link, null);
 							}
-	
+							
 							// Sets the size
 							graph.fireEvent(new mxEventObject('cellsInserted', 'cells', [cell]));
 							var size = this.editor.graph.getPreferredSizeForCell(cell);

文件差異過大導致無法顯示
+ 553 - 552
src/main/webapp/js/viewer.min.js