Explorar o código

10.9.5 release

Former-commit-id: ad89de6aa2f1f1fbcf26661c1ba0bb18fa14e1c6
David Benson [draw.io] %!s(int64=6) %!d(string=hai) anos
pai
achega
681338b662

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+11-JUL-2019: 10.9.5
+
+- Fixes desktop startup
+
 11-JUL-2019: 10.9.4
 
 - Adds named styles for CSV import

+ 1 - 1
VERSION

@@ -1 +1 @@
-10.9.4
+10.9.5

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

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

+ 45 - 37
src/main/webapp/electron.js

@@ -191,42 +191,50 @@ app.on('ready', e =>
 	{
 	  return val.split('..').map(Number);
 	}
-
-	program
-        .version(app.getVersion())
-        .usage('[options] [input file/folder]')
-        .allowUnknownOption()
-        .option('-c, --create', 'creates a new empty file if no file is passed')
-        .option('-x, --export', 'export the input file/folder based on the given options')
-        .option('-r, --recursive', 'for a folder input, recursively convert all files in sub-folders also')
-        .option('-o, --output <output file/folder>', 'specify the output file/folder. If omitted, the input file name is used for output with the specified format as extension')
-        .option('-f, --format <format>',
-		    'if output file name extension is specified, this option is ignored (file type is determined from output extension)',
-		    validFormatRegExp, 'pdf')
-		.option('-q, --quality <quality>',
-			'output image quality for JPEG (default: 90)', parseInt)
-		.option('-t, --transparent',
-			'set transparent background for PNG')
-		.option('-e, --embed-diagram',
-			'includes a copy of the diagram (for PNG format only)')
-		.option('-b, --border <border>',
-			'sets the border width around the diagram (default: 0)', parseInt)
-		.option('-s, --scale <scale>',
-			'scales the diagram size', parseFloat)
-		.option('--width <width>',
-			'fits the generated image/pdf into the specified width, preserves aspect ratio.', parseInt)
-		.option('--height <height>',
-			'fits the generated image/pdf into the specified height, preserves aspect ratio.', parseInt)
-		.option('--crop',
-			'crops PDF to diagram size')
-		.option('-a, --all-pages',
-			'export all pages (for PDF format only)')
-		.option('-p, --page-index <pageIndex>',
-			'selects a specific page, if not specified and the format is an image, the first page is selected', parseInt)
-		.option('-g, --page-range <from>..<to>',
-			'selects a page range (for PDF format only)', argsRange)
-        .parse(argv)
-
+	
+	try
+	{
+		program
+	        .version(app.getVersion())
+	        .usage('[options] [input file/folder]')
+	        .allowUnknownOption() //-h and --help are considered unknown!!
+	        .option('-c, --create', 'creates a new empty file if no file is passed')
+	        .option('-x, --export', 'export the input file/folder based on the given options')
+	        .option('-r, --recursive', 'for a folder input, recursively convert all files in sub-folders also')
+	        .option('-o, --output <output file/folder>', 'specify the output file/folder. If omitted, the input file name is used for output with the specified format as extension')
+	        .option('-f, --format <format>',
+			    'if output file name extension is specified, this option is ignored (file type is determined from output extension)',
+			    validFormatRegExp, 'pdf')
+			.option('-q, --quality <quality>',
+				'output image quality for JPEG (default: 90)', parseInt)
+			.option('-t, --transparent',
+				'set transparent background for PNG')
+			.option('-e, --embed-diagram',
+				'includes a copy of the diagram (for PNG format only)')
+			.option('-b, --border <border>',
+				'sets the border width around the diagram (default: 0)', parseInt)
+			.option('-s, --scale <scale>',
+				'scales the diagram size', parseFloat)
+			.option('--width <width>',
+				'fits the generated image/pdf into the specified width, preserves aspect ratio.', parseInt)
+			.option('--height <height>',
+				'fits the generated image/pdf into the specified height, preserves aspect ratio.', parseInt)
+			.option('--crop',
+				'crops PDF to diagram size')
+			.option('-a, --all-pages',
+				'export all pages (for PDF format only)')
+			.option('-p, --page-index <pageIndex>',
+				'selects a specific page, if not specified and the format is an image, the first page is selected', parseInt)
+			.option('-g, --page-range <from>..<to>',
+				'selects a page range (for PDF format only)', argsRange)
+	        .parse(argv)
+	}
+	catch(e)
+	{
+		//On parse error, return [exit and commander will show the error message]
+		return;
+	}
+	
     //Start export mode?
     if (program.export)
 	{
@@ -473,7 +481,7 @@ app.on('ready', e =>
     	
     	return;
 	}
-    else if (program.help)
+    else if (program.rawArgs.indexOf('-h') > -1 || program.rawArgs.indexOf('--help') > -1) //To prevent execution when help arg is used
 	{
     	return;
 	}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 105 - 105
src/main/webapp/js/app.min.js


+ 15 - 15
src/main/webapp/js/diagramly/App.js

@@ -29,16 +29,13 @@ App = function(editor, container, lightbox)
 					action: ((file.savingFile) ? 'saving' : '') +
 					((file.savingFile && file.savingFileTime != null) ? '_' +
 						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') +
-					((file.inConflictState) ? '-conflict' : '') +
-					((file.invalidChecksum) ? '-invalid' : '') +
 					'-open_' + ((file.opened != null) ? Math.round((Date.now() - file.opened.getTime()) / 1000) : 'x') +
-					'-save_' + ((file.lastSaved != null) ?  Math.round((Date.now() - file.lastSaved.getTime()) / 1000) : 'x') +
-					'-change_' + ((file.lastChanged != null) ?  Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x'),
+					'-save_' + ((file.lastSaved != null) ? Math.round((Date.now() - file.lastSaved.getTime()) / 1000) : 'x') +
+					'-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x') +
+					'-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000),
 					label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'};
 					
 				if (file.constructor == DriveFile && file.desc != null && this.drive != null)
@@ -282,6 +279,13 @@ App.PUSHER_URL = 'https://js.pusher.com/4.3/pusher.min.js';
  */
 App.GOOGLE_APIS = 'client,drive-share'; 
 
+/**
+ * Function: authorize
+ * 
+ * Authorizes the client, gets the userId and calls <open>.
+ */
+App.startTime = new Date();
+
 /**
  * Defines plugin IDs for loading via p URL parameter. Update the table at
  * https://desk.draw.io/solution/articles/16000042546
@@ -1505,24 +1509,20 @@ App.prototype.sanityCheck = function()
 {
 	var file = this.getCurrentFile();
 
-	if (file != null && file.isModified() && file.isAutosave() &&
-		(Date.now() - ((file.lastSaved != null) ? file.lastSaved.getTime() :
-		file.opened.getTime())) >= this.warnInterval)
+	if (file != null && file.isModified() && file.isAutosave() && file.isOverdue())
 	{
 		var evt = {category: 'WARN-FILE-' + file.getHash(),
 			action: ((file.savingFile) ? 'saving' : '') +
 			((file.savingFile && file.savingFileTime != null) ? '_' +
 				Math.round((Date.now() - file.savingFileTime.getTime()) / 1000) : '') +
-			((file.autosaveThread != null) ? '-thread' : '') +
+			'-age_' + ((file.ageStart != null) ? Math.round((Date.now() - file.ageStart.getTime()) / 1000) : 'x') +
 			'-sl_' + ((file.saveLevel != null) ? file.saveLevel : 'x') +
 			((this.editor.autosave) ? '' : '-nosave') +
 			((file.isAutosave()) ? '' : '-noauto') +
-			((file.changeListenerEnabled) ? '' : '-nolisten') +
-			((file.inConflictState) ? '-conflict' : '') +
-			((file.invalidChecksum) ? '-invalid' : '') +
 			'-open_' + ((file.opened != null) ? Math.round((Date.now() - file.opened.getTime()) / 1000) : 'x') +
-			'-save_' + ((file.lastSaved != null) ?  Math.round((Date.now() - file.lastSaved.getTime()) / 1000) : 'x') +
-			'-change_' + ((file.lastChanged != null) ?  Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x'),
+			'-save_' + ((file.lastSaved != null) ? Math.round((Date.now() - file.lastSaved.getTime()) / 1000) : 'x') +
+			'-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x')+
+			'-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000),
 			label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'};
 			
 		if (file.constructor == DriveFile && file.desc != null && this.drive != null)

+ 29 - 3
src/main/webapp/js/diagramly/DrawioFile.js

@@ -160,6 +160,11 @@ DrawioFile.prototype.errorReportsEnabled = false;
  */
 DrawioFile.prototype.reportEnabled = true;
 
+/**
+ * Specifies if stats should be sent.
+ */
+DrawioFile.prototype.ageStart = null;
+
 /**
  * Specifies if notify events should be ignored.
  */
@@ -1684,6 +1689,14 @@ DrawioFile.prototype.getErrorMessage = function(err)
 	return (err != null) ? ((err.error != null) ? err.error.message : err.message) : null
 };
 
+/**
+ * Returns true if the oldest unsaved change is older than <EditorUi.warnInterval>.
+ */
+DrawioFile.prototype.isOverdue = function()
+{
+	return this.ageStart != null && (Date.now() - this.ageStart.getTime()) >= this.ui.warnInterval;
+};
+
 /**
  * Adds the listener for automatically saving the diagram for local changes.
  */
@@ -1697,6 +1710,11 @@ DrawioFile.prototype.fileChanged = function()
 		this.addAllSavedStatus(mxUtils.htmlEntities(mxResources.get('saving')) + '...');
 		this.ui.scheduleSanityCheck();
 		
+		if (this.ageStart == null)
+		{
+			this.ageStart = new Date();
+		}
+		
 		this.autosave(this.autosaveDelay, this.maxAutosaveDelay, mxUtils.bind(this, function(resp)
 		{
 			this.ui.stopSanityCheck();
@@ -1705,20 +1723,27 @@ DrawioFile.prototype.fileChanged = function()
 			if (this.autosaveThread == null)
 			{
 				this.handleFileSuccess(true);
+				this.ageStart = null;
 			}
 			else if (this.isModified())
 			{
 				this.ui.scheduleSanityCheck();
+				this.ageStart = this.lastChanged;
 			}
 		}), mxUtils.bind(this, function(err)
 		{
 			this.handleFileError(err);
 		}));
 	}
-	else if ((!this.isAutosaveOptional() || !this.ui.editor.autosave) &&
-		!this.inConflictState)
+	else
 	{
-		this.addUnsavedStatus();
+		this.ageStart = null;
+		
+		if ((!this.isAutosaveOptional() || !this.ui.editor.autosave) &&
+			!this.inConflictState)
+		{
+			this.addUnsavedStatus();
+		}
 	}
 };
 
@@ -1728,6 +1753,7 @@ DrawioFile.prototype.fileChanged = function()
 DrawioFile.prototype.fileSaved = function(savedData, lastDesc, success, error)
 {
 	this.lastSaved = new Date();
+	this.ageStart = null;
 	
 	try
 	{

+ 73 - 53
src/main/webapp/js/diagramly/DriveClient.js

@@ -1079,7 +1079,7 @@ 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)
-{	
+{
 	try
 	{
 		file.saveLevel = 1;
@@ -1394,78 +1394,98 @@ DriveClient.prototype.saveFile = function(file, revision, success, errFn, noChec
 								{
 									var unknown = file.desc.mimeType != this.xmlMimeType && file.desc.mimeType != this.mimeType &&
 										file.desc.mimeType != this.libraryMimeType;
+									var acceptResponse = true;
+									
+									// Allow for re-auth flow with 4x timeout
+									var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
+									{
+										acceptResponse = false;
+										error({code: App.ERROR_TIMEOUT, message: mxResources.get('timeout')});
+									}), 4 * this.ui.timeout);
 									
 									this.executeRequest(this.createUploadRequest(file.getId(), meta,
 										data, revision || realOverwrite || unknown, binary,
-										(realOverwrite) ? null : etag, pinned), wrapper,
-										mxUtils.bind(this, function(err)
+										(realOverwrite) ? null : etag, pinned), mxUtils.bind(this, function(resp)
 									{
-										file.saveLevel = 6;
-											
-										try
+										window.clearTimeout(timeoutThread);
+										
+										if (acceptResponse)
 										{
-											if (!file.isConflict(err))
-											{
-												error(err);
-											}
-											else
+											wrapper(resp);
+										}
+									}), mxUtils.bind(this, function(err)
+									{
+										window.clearTimeout(timeoutThread);
+										
+										if (acceptResponse)
+										{
+											file.saveLevel = 6;
+												
+											try
 											{
-												// Check for stale etag which can happen if a file is being saved or if
-												// the etag simply isn't change but system still returns a 412 error (stale)
-												this.executeRequest(gapi.client.drive.files.get({'fileId': file.getId(),
-													'fields': this.catchupFields, 'supportsTeamDrives': true}), 
-													mxUtils.bind(this, function(resp)
+												if (!file.isConflict(err))
 												{
-													file.saveLevel = 7;
-
-													try
+													error(err);
+												}
+												else
+												{
+													// Check for stale etag which can happen if a file is being saved or if
+													// the etag simply isn't change but system still returns a 412 error (stale)
+													this.executeRequest(gapi.client.drive.files.get({'fileId': file.getId(),
+														'fields': this.catchupFields, 'supportsTeamDrives': true}), 
+														mxUtils.bind(this, function(resp)
 													{
-														// Stale etag detected, retry with delay
-														if (resp != null && resp.etag == etag)
+														file.saveLevel = 7;
+	
+														try
 														{
-															if (retryCount < this.maxRetries)
+															// Stale etag detected, retry with delay
+															if (resp != null && resp.etag == etag)
 															{
-																retryCount++;
-																var jitter = 1 + 0.1 * (Math.random() - 0.5);
-																var delay = retryCount * 2 * this.coolOff * jitter;
-																window.setTimeout(executeSave, delay);
-															}
-															else
-															{
-																executeSave(true);
-																
-																// Logs overwrite
-																try
+																if (retryCount < this.maxRetries)
 																{
-																	EditorUi.logError('Warning: Stale Etag Overwrite ' + file.getHash(),
-																		null, file.desc.id + '.' + file.desc.headRevisionId,
-																		((this.user != null) ? ('user_' + this.user.id) : 'nouser') +
-																		((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync'));
+																	retryCount++;
+																	var jitter = 1 + 0.1 * (Math.random() - 0.5);
+																	var delay = retryCount * 2 * this.coolOff * jitter;
+																	window.setTimeout(executeSave, delay);
 																}
-																catch (e)
+																else
 																{
-																	// ignore
+																	executeSave(true);
+																	
+																	// Logs overwrite
+																	try
+																	{
+																		EditorUi.logError('Warning: Stale Etag Overwrite ' + file.getHash(),
+																			null, file.desc.id + '.' + file.desc.headRevisionId,
+																			((this.user != null) ? ('user_' + this.user.id) : 'nouser') +
+																			((file.sync != null) ? ('-client_' + file.sync.clientId) : '-nosync'));
+																	}
+																	catch (e)
+																	{
+																		// ignore
+																	}
 																}
 															}
+															else
+															{
+																error(err, resp);
+															}
 														}
-														else
+														catch (e)
 														{
-															error(err, resp);
+															criticalError(e);
 														}
-													}
-													catch (e)
+													}), mxUtils.bind(this, function()
 													{
-														criticalError(e);
-													}
-												}), mxUtils.bind(this, function()
-												{
-													error(err);
-												}));
+														error(err);
+													}));
+												}
+											}
+											catch (e)
+											{
+												criticalError(e);
 											}
-										}
-										catch (e)
-										{
-											criticalError(e);
 										}
 									}));
 								}

+ 73 - 66
src/main/webapp/js/diagramly/OneDriveClient.js

@@ -801,78 +801,85 @@ OneDriveClient.prototype.checkExists = function(parentId, filename, askReplace,
  */
 OneDriveClient.prototype.saveFile = function(file, success, error, etag)
 {
-	var savedData = file.getData();
-	
-	var fn = mxUtils.bind(this, function(data)
+	try
 	{
-		var url = this.getItemURL(file.getId());
-
-		this.writeFile(url + '/content/', data, 'PUT', null, mxUtils.bind(this, function(resp)
+		var savedData = file.getData();
+		
+		var fn = mxUtils.bind(this, function(data)
 		{
-			// Checks for truncated files in OneDrive by comparing expected and actual file size
-			// Apparently in some cases the file is not truncated but the expected and actual
-			// file size do still defer and cases with truncated files have not been detected
-			// ie. there were no cases where the file size was significantly off.
-//			try
-//			{
-//				if (typeof window.Blob !== 'undefined')
-//				{
-//
-//					// Returns string length in bytes instead of chars to check returned file size
-//					function byteCount(str)
-//					{
-//						try
-//						{
-//							return new Blob([str]).size
-//						}
-//						catch (e)
-//						{
-//							// ignore
-//						}
-//						
-//						return null;
-//					};
-//					
-//					var exp = (typeof data === 'string') ? byteCount(data) : data.size;
-//					
-//					if (resp != null && exp != null && resp.size != exp)
-//					{
-//						// Logs failed save
-//						var user = this.getUser();
-//						
-//						EditorUi.sendReport('Critical: Truncated OneDrive File ' +
-//							new Date().toISOString() + ':' + '\n\nBrowser=' + navigator.userAgent +
-//							'\nFile=' + file.getId() + '\nMime=' + file.meta.file.mimeType +
-//							'\nUser=' + ((user != null) ? user.id : 'unknown') +
-//							 	'-client_' + ((file.sync != null) ? file.sync.clientId : 'nosync') +
-//							'\nExpected=' + exp + ' Actual=' + resp.size)
-//						EditorUi.logError('Critical: Truncated OneDrive File ' + file.getId(),
-//							null, 'expected_' + exp + '-actual_' + resp.size +
-//							'-mime_' + file.meta.file.mimeType,
-//							'user-' + ((user != null) ? user.id : 'unknown') +
-//						 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync'));
-//					}
-//				}
-//			}
-//			catch (e)
-//			{
-//				// ignore
-//			}
-			
-			success(resp, savedData);
-		}), error, etag);
-	});
+			var url = this.getItemURL(file.getId());
 	
-	if (this.ui.useCanvasForExport && /(\.png)$/i.test(file.meta.name))
-	{
-		this.ui.getEmbeddedPng(mxUtils.bind(this, function(data)
+			this.writeFile(url + '/content/', data, 'PUT', null, mxUtils.bind(this, function(resp)
+			{
+				// Checks for truncated files in OneDrive by comparing expected and actual file size
+				// Apparently in some cases the file is not truncated but the expected and actual
+				// file size do still defer and cases with truncated files have not been detected
+				// ie. there were no cases where the file size was significantly off.
+	//			try
+	//			{
+	//				if (typeof window.Blob !== 'undefined')
+	//				{
+	//
+	//					// Returns string length in bytes instead of chars to check returned file size
+	//					function byteCount(str)
+	//					{
+	//						try
+	//						{
+	//							return new Blob([str]).size
+	//						}
+	//						catch (e)
+	//						{
+	//							// ignore
+	//						}
+	//						
+	//						return null;
+	//					};
+	//					
+	//					var exp = (typeof data === 'string') ? byteCount(data) : data.size;
+	//					
+	//					if (resp != null && exp != null && resp.size != exp)
+	//					{
+	//						// Logs failed save
+	//						var user = this.getUser();
+	//						
+	//						EditorUi.sendReport('Critical: Truncated OneDrive File ' +
+	//							new Date().toISOString() + ':' + '\n\nBrowser=' + navigator.userAgent +
+	//							'\nFile=' + file.getId() + '\nMime=' + file.meta.file.mimeType +
+	//							'\nUser=' + ((user != null) ? user.id : 'unknown') +
+	//							 	'-client_' + ((file.sync != null) ? file.sync.clientId : 'nosync') +
+	//							'\nExpected=' + exp + ' Actual=' + resp.size)
+	//						EditorUi.logError('Critical: Truncated OneDrive File ' + file.getId(),
+	//							null, 'expected_' + exp + '-actual_' + resp.size +
+	//							'-mime_' + file.meta.file.mimeType,
+	//							'user-' + ((user != null) ? user.id : 'unknown') +
+	//						 	((file.sync != null) ? '-client_' + file.sync.clientId : '-nosync'));
+	//					}
+	//				}
+	//			}
+	//			catch (e)
+	//			{
+	//				// ignore
+	//			}
+				
+				success(resp, savedData);
+			}), error, etag);
+		});
+		
+		if (this.ui.useCanvasForExport && /(\.png)$/i.test(file.meta.name))
+		{
+			this.ui.getEmbeddedPng(mxUtils.bind(this, function(data)
+			{
+				fn(this.ui.base64ToBlob(data, 'image/png'));
+			}), error, (this.ui.getCurrentFile() != file) ? savedData : null);
+		}
+		else
 		{
-			fn(this.ui.base64ToBlob(data, 'image/png'));
-		}), error, (this.ui.getCurrentFile() != file) ? savedData : null);
+			fn(savedData);
+		}
 	}
-	else
+	catch (e)
 	{
-		fn(savedData);
+		error(e);
 	}
 };
 

+ 5 - 3
src/main/webapp/js/mxgraph/Format.js

@@ -2838,7 +2838,8 @@ TextFormatPanel.prototype.addFont = function(container)
 
 			function updateSize(elt, ignoreContains)
 			{
-				if (elt != graph.cellEditor.textarea && graph.cellEditor.textarea.contains(elt) &&
+				if (graph.cellEditor.textarea != null && elt != graph.cellEditor.textarea &&
+					graph.cellEditor.textarea.contains(elt) &&
 					(ignoreContains || selection.containsNode(elt, true)))
 				{
 					if (elt.nodeName == 'FONT')
@@ -3213,7 +3214,8 @@ TextFormatPanel.prototype.addFont = function(container)
 				node = graph.cellEditor.textarea.firstChild;
 			}
 			
-			if (node != null && node != graph.cellEditor.textarea && graph.cellEditor.textarea.contains(node))
+			if (node != null && graph.cellEditor.textarea != null && node != graph.cellEditor.textarea &&
+				graph.cellEditor.textarea.contains(node))
 			{
 				node.style.lineHeight = value + '%';
 			}
@@ -3692,7 +3694,7 @@ TextFormatPanel.prototype.addFont = function(container)
 							{
 								var lineHeight = css.lineHeight
 								
-								if (elt.style.lineHeight.substring(elt.style.lineHeight.length - 1) == '%')
+								if (elt.style.lineHeight != null && elt.style.lineHeight.substring(elt.style.lineHeight.length - 1) == '%')
 								{
 									return parseInt(elt.style.lineHeight) / 100;
 								}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 6
src/main/webapp/js/viewer.min.js