Browse Source

6.3.2 release

Gaudenz Alder 8 years ago
parent
commit
690cb7b4ec

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+14-MAR-2017: 6.3.2
+
+- Updates AWS icons
+- Added update plugin
+- Fixes update of thumbnail if page not visible
+
 12-MAR-2017: 6.3.1
 
 - Sorts properties in metadata dialog

+ 1 - 1
VERSION

@@ -1 +1 @@
-6.3.1
+6.3.2

+ 1 - 0
etc/build/build.xml

@@ -83,6 +83,7 @@
 				<file name="Sidebar-ArchiMate3.js" />
 				<file name="Sidebar-Arrows2.js" />
 				<file name="Sidebar-AWS.js" />
+				<file name="Sidebar-AWS3.js" />
 				<file name="Sidebar-AWS3D.js" />
 				<file name="Sidebar-Azure.js" />
 				<file name="Sidebar-Basic.js" />

+ 2 - 2
etc/sandstorm/ssindex.html

@@ -452,10 +452,10 @@
 
 		request.send(mxUtils.bind(this, function(req)
 		{
-			this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 		}), mxUtils.bind(this, function()
 		{
-			this.ui.editor.setStatus(mxResources.get('unsavedChanges'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('unsavedChanges')));
 		}));
 		
 		this.contentChanged();

+ 1 - 1
war/cache.manifest

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 03/12/2017 03:02 PM
+# 03/14/2017 06:13 PM
 
 app.html
 index.html?offline=1

BIN
war/images/sidebar-aws3.png


File diff suppressed because it is too large
+ 1026 - 794
war/js/app.min.js


File diff suppressed because it is too large
+ 87 - 86
war/js/atlas-viewer.min.js


File diff suppressed because it is too large
+ 363 - 132
war/js/atlas.min.js


+ 55 - 21
war/js/diagramly/App.js

@@ -168,7 +168,7 @@ App.pluginRegistry = {'4xAKTrabTpTzahoLthkwPNUn': '/plugins/explore.js',
 	'doors': '/plugins/doors.js', 'electron': 'plugins/electron.js',
 	'number': '/plugins/number.js', 'sql': '/plugins/sql.js',
 	'props': '/plugins/props.js', 'text': '/plugins/text.js',
-	'anim': '/plugins/animation.js'};
+	'anim': '/plugins/animation.js', 'update': '/plugins/update.js'};
 
 /**
  * Function: authorize
@@ -1523,24 +1523,57 @@ App.prototype.getThumbnail = function(width, success)
 		{
 			this.thumbImageCache = new Object();
 		}
-
+		
+		var graph = this.editor.graph;
+		
+		// Exports PNG 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])
+		{
+			graph = this.createTemporaryGraph(graph.getStylesheet());
+			var graphGetGlobalVariable = graph.getGlobalVariable;
+			var page = this.pages[0];
+	
+			graph.getGlobalVariable = function(name)
+			{
+				if (name == 'page')
+				{
+					return page.getName();
+				}
+				else if (name == 'pagenumber')
+				{
+					return 1;
+				}
+				
+				return graphGetGlobalVariable.apply(this, arguments);
+			};
+	
+			document.body.appendChild(graph.container);
+			graph.model.setRoot(page.root);
+		}
+		
 		// Uses client-side canvas export
-		if (this.isExportToCanvas())
+		if (mxClient.IS_CHROMEAPP || (!graph.mathEnabled && this.useCanvasForExport))
 		{
 		   	this.exportToCanvas(mxUtils.bind(this, function(canvas)
 		   	{
+		   		// Removes temporary graph from DOM
+   	   	    	if (graph != this.editor.graph)
+				{
+					graph.container.parentNode.removeChild(graph.container);
+				}
+		   		
 		   		success(canvas);
 		   	}), width, this.thumbImageCache, '#ffffff', function()
 		   	{
 		   		// Continues with null in error case
 		   		success();
-		   	});
+		   	}, null, null, null, null, null, null, graph);
 		   	
 		   	result = true;
 		}
 		else if (this.canvasSupported && this.getCurrentFile() != null)
 		{
-			var graph = this.editor.graph;
 			var canvas = document.createElement('canvas');
 			var bounds = graph.getGraphBounds();
 			var scale = width / bounds.width;
@@ -1607,11 +1640,18 @@ App.prototype.getThumbnail = function(width, success)
 	
 			imgExport.drawState(graph.getView().getState(graph.model.root), asynCanvas);
 	
-			asynCanvas.finish(function()
+			asynCanvas.finish(mxUtils.bind(this, function()
 			{
 				imgExport.drawState(graph.getView().getState(graph.model.root), htmlCanvas);
+				
+		   		// Removes temporary graph from DOM
+   	   	    	if (graph != this.editor.graph)
+				{
+					graph.container.parentNode.removeChild(graph.container);
+				}
+				
 				success(canvas);
-			});
+			}));
 			
 			result = true;
 		}
@@ -1619,6 +1659,11 @@ 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.removeChild(graph.container);
+		}
 	}
 	
 	return result;
@@ -2831,7 +2876,7 @@ App.prototype.saveFile = function(forceDialog)
 			// is to show no saved status for device files
 			if (file.getMode() != App.MODE_DEVICE)
 			{
-				this.editor.setStatus(mxResources.get('allChangesSaved'));
+				this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 			}
 			else
 			{
@@ -3805,7 +3850,7 @@ App.prototype.save = function(name, done)
 				}
 				else
 				{
-					this.editor.setStatus(mxResources.get('allChangesSaved'));
+					this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 				}
 			}
 			
@@ -4052,17 +4097,6 @@ App.prototype.toggleChat = function()
 	}
 };
 
-/**
- * Translates this point by the given vector.
- * 
- * @param {number} dx X-coordinate of the translation.
- * @param {number} dy Y-coordinate of the translation.
- */
-App.prototype.status = function(html)
-{
-	this.editor.setStatus(html);
-};
-
 /**
  * Adds the listener for automatically saving the diagram for local changes.
  */
@@ -4085,7 +4119,7 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn)
 		}
 		catch (e)
 		{
-			this.editor.setStatus(e.message);
+			this.editor.setStatus(mxUtils.htmlEntities(e.message));
 		}
 	})).container, 300, (showRememberOption) ? 180 : 140, true, true, mxUtils.bind(this, function(cancel)
 	{

+ 1 - 0
war/js/diagramly/Devel.js

@@ -32,6 +32,7 @@ mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-ArchiMate.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-ArchiMate3.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-Arrows2.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-AWS.js');
+mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-AWS3.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-AWS3D.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-Azure.js');
 mxscript(drawDevUrl + 'js/diagramly/sidebar/Sidebar-Basic.js');

+ 9 - 7
war/js/diagramly/Dialogs.js

@@ -4236,6 +4236,7 @@ var LinkDialog = function(editorUi, initialValue, btnLabel, fn)
 		editorUi.hideDialog();
 		fn(linkInput.value, LinkDialog.selectedDocs);
 	});
+	mainBtn.style.verticalAlign = 'middle';
 	mainBtn.className = 'geBtn gePrimaryBtn';
 	
 	this.init = function()
@@ -4311,6 +4312,7 @@ var LinkDialog = function(editorUi, initialValue, btnLabel, fn)
 	{
 		editorUi.hideDialog();
 	});
+	cancelBtn.style.verticalAlign = 'middle';
 	cancelBtn.className = 'geBtn';
 	
 	if (editorUi.editor.cancelFirst)
@@ -4355,17 +4357,17 @@ var LinkDialog = function(editorUi, initialValue, btnLabel, fn)
 	
 	function addButton(src, tooltip, fn)
 	{
-		var gpBtn = mxUtils.button('', fn);
-		gpBtn.className = 'geBtn';
-		gpBtn.setAttribute('title', tooltip);
+		var btn = mxUtils.button('', fn);
+		btn.className = 'geBtn';
+		btn.setAttribute('title', tooltip);
 		var img = document.createElement('img');
 		img.style.height = '26px';
 		img.style.width = '26px';
 		img.setAttribute('src', src);
-		img.setAttribute('valign', 'bottom');
-		gpBtn.style.minWidth = '42px';
-		gpBtn.appendChild(img);
-		btns.appendChild(gpBtn);
+		btn.style.minWidth = '42px';
+		btn.style.verticalAlign = 'middle';
+		btn.appendChild(img);
+		btns.appendChild(btn);
 	};
 
 	if (typeof(google) != 'undefined' && typeof(google.picker) != 'undefined' && editorUi.drive != null)

+ 5 - 4
war/js/diagramly/DrawioFile.js

@@ -310,14 +310,14 @@ DrawioFile.prototype.open = function()
 			
 			if (this.isAutosave())
 			{
-				this.ui.editor.setStatus(mxResources.get('saving') + '...');
+				this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('saving')) + '...');
 				
 				this.autosave(this.autosaveDelay, this.maxAutosaveDelay, mxUtils.bind(this, function(resp)
 				{
 					// Does not update status if another autosave was scheduled
 					if (this.autosaveThread == null && this.ui.getCurrentFile() == this && !this.isModified())
 					{
-						this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+						this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 					}
 				}), mxUtils.bind(this, function(resp)
 				{
@@ -358,7 +358,8 @@ DrawioFile.prototype.addUnsavedStatus = function(err)
 	if (err instanceof Error && err.message != null)
 	{
 		this.ui.editor.setStatus('<div class="geStatusAlert" style="cursor:pointer;">' +
-				mxResources.get('unsavedChanges') + ' (' + err.message + ')</div>');
+				mxUtils.htmlEntities(mxResources.get('unsavedChanges')) +
+				' (' + mxUtils.htmlEntities(err.message) + ')</div>');
 	}
 	else
 	{
@@ -377,7 +378,7 @@ DrawioFile.prototype.addUnsavedStatus = function(err)
 //		}
 		
 		this.ui.editor.setStatus('<div class="geStatusMessage" style="cursor:pointer;">' +
-			mxResources.get('unsavedChangesClickHereToSave') + '</div>');
+			mxUtils.htmlEntities(mxResources.get('unsavedChangesClickHereToSave')) + '</div>');
 		
 		// Installs click handler for saving
 		if (this.ui.statusContainer != null)

+ 1 - 3
war/js/diagramly/DriveClient.js

@@ -855,11 +855,9 @@ DriveClient.prototype.saveFile = function(file, revision, success, error, noChec
 		// (required because generation of thumbnails is asynchronous)
 		var fn = mxUtils.bind(this, function()
 		{
-			var keepExistingThumb = this.ui.currentPage != null && this.ui.currentPage != this.ui.pages[0];
-
 			// NOTE: getThumbnail is asynchronous and returns false if no thumbnails can be created
 			if (unloading || file.constructor == DriveLibrary || !this.enableThumbnails || urlParams['thumb'] == '0' ||
-				keepExistingThumb || !this.ui.getThumbnail(this.thumbnailWidth, mxUtils.bind(this, function(canvas)
+				!this.ui.getThumbnail(this.thumbnailWidth, mxUtils.bind(this, function(canvas)
 			{
 				// Callback for getThumbnail
 				var thumb = null;

+ 16 - 16
war/js/diagramly/DriveRealtime.js

@@ -38,11 +38,11 @@ function DriveRealtime(file, doc)
 	{
 		var prevValue = this.ui.drive.enableThumbnails;
 		this.ui.drive.enableThumbnails = this.ui.editor.autosave;
-		this.ui.editor.setStatus(mxResources.get('saving') + '...');
+		this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('saving')) + '...');
 		
 		this.file.save(true, mxUtils.bind(this, function()
 		{
-			this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 		}));
 		
 		this.ui.drive.enableThumbnails = prevValue;
@@ -381,7 +381,7 @@ DriveRealtime.prototype.start = function()
 			}
 			else
 			{
-				this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+				this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 			}
 			
 			this.saving = false;
@@ -429,7 +429,7 @@ DriveRealtime.prototype.start = function()
 	// Updates backup and preview
 	if (forceSave)
 	{
-		this.ui.editor.setStatus(mxResources.get('saving') + '...');
+		this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('saving')) + '...');
 		this.file.save(false, initialized, initialized);
 	}
 	else
@@ -456,7 +456,7 @@ DriveRealtime.prototype.start = function()
  */
 DriveRealtime.prototype.triggerAutosave = function()
 {
-	this.ui.editor.setStatus(mxResources.get('updatingPreview'));
+	this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('updatingPreview')));
 	
 	this.file.autosave(this.realtimeAutosaveDelay, this.realtimeMaxAutosaveDelay, mxUtils.bind(this, function(resp)
 	{					
@@ -466,12 +466,12 @@ DriveRealtime.prototype.triggerAutosave = function()
 		// Does not update status if another autosave was scheduled
 		if (this.ui.getCurrentFile() == this.file && !this.saving)
 		{
-			this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 		}
 	}),
 	mxUtils.bind(this, function(resp)
 	{
-		this.ui.editor.setStatus(mxResources.get('errorUpdatingPreview'));
+		this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('errorUpdatingPreview')));
 		
 		// Handles error where mime type cannot be overridden because it has been changed by another app and no
 		// new revision was created. This happens eg. if draw.io pro overwrites the mime type and adds a new realtime
@@ -491,7 +491,7 @@ DriveRealtime.prototype.triggerAutosave = function()
  */
 DriveRealtime.prototype.triggerAutosave = function()
 {
-	this.ui.editor.setStatus(mxResources.get('updatingPreview'));
+	this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('updatingPreview')));
 	
 	this.file.autosave(this.realtimeAutosaveDelay, this.realtimeMaxAutosaveDelay, mxUtils.bind(this, function(resp)
 	{
@@ -501,12 +501,12 @@ DriveRealtime.prototype.triggerAutosave = function()
 		// Does not update status if another autosave was scheduled
 		if (this.ui.getCurrentFile() == this.file && !this.saving)
 		{
-			this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 		}
 	}),
 	mxUtils.bind(this, function(resp)
 	{
-		this.ui.editor.setStatus(mxResources.get('errorUpdatingPreview'));
+		this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('errorUpdatingPreview')));
 		
 		// Handles error where mime type cannot be overridden because it has been changed by another app and no
 		// new revision was created. This happens eg. if draw.io pro overwrites the mime type and adds a new realtime
@@ -536,7 +536,7 @@ DriveRealtime.prototype.installReadOnlyListener = function()
 			if (!this.file.isEditable())
 			{
 				this.ui.editor.graph.reset();
-				this.ui.editor.setStatus(mxResources.get('readOnly'));
+				this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('readOnly')));
 			}
 			else
 			{
@@ -804,8 +804,8 @@ DriveRealtime.prototype.updateStatus = function()
 				str = mxResources.get('lessThanAMinute');
 			}
 			
-			this.ui.editor.setStatus(mxResources.get('lastChange', [str]) +
-				(this.file.isEditable() ? '' : ' (' + mxResources.get('readOnly') + ')'));
+			this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('lastChange', [str])) +
+				(this.file.isEditable() ? '' : ' (' + mxUtils.htmlEntities(mxResources.get('readOnly')) + ')'));
 		}
 	}
 };
@@ -1081,7 +1081,7 @@ DriveRealtime.prototype.setFileModified = function()
 	
 	if (!this.saving)
 	{
-		this.ui.editor.setStatus(mxResources.get('saving') + '...');
+		this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('saving')) + '...');
 		this.saving = true;
 	}
 };
@@ -1139,7 +1139,7 @@ DriveRealtime.prototype.installGraphModelListener = function()
 					this.isAliveThread = window.setTimeout(mxUtils.bind(this, function()
 					{
 						this.ui.editor.setStatus('<div class="geStatusAlert geBlink" style="cursor:pointer;">' +
-								mxResources.get('noResponse') + '</div>');
+							mxUtils.htmlEntities(mxResources.get('noResponse')) + '</div>');
 						
 						this.isAliveThread = window.setTimeout(mxUtils.bind(this, function()
 						{
@@ -1185,7 +1185,7 @@ DriveRealtime.prototype.timeoutError = function()
 	}), null, mxResources.get('ignore'), mxUtils.bind(this, function()
 	{
 		this.ui.editor.setStatus('<div class="geStatusAlert geBlink" style="cursor:pointer;">' +
-				mxResources.get('disconnected') + '</div>');	
+			mxUtils.htmlEntities(mxResources.get('disconnected')) + '</div>');	
 		this.realtimeHeartbeat *= 2;
 	}));
 };

+ 13 - 12
war/js/diagramly/EditorUi.js

@@ -1260,7 +1260,7 @@
 				{
 					if (!file.isEditable())
 					{
-						this.editor.setStatus(mxResources.get('readOnly'));
+						this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('readOnly')));
 					}
 					else
 					{
@@ -2233,7 +2233,7 @@
 	
 		if (e != null || title != null)
 		{
-			var msg = mxResources.get('unknownError');
+			var msg = mxUtils.htmlEntities(mxResources.get('unknownError'));
 			var btn = mxResources.get('ok');
 			var retry = null;
 			title = (title != null) ? title : mxResources.get('error');
@@ -2253,36 +2253,36 @@
 				if (typeof(gapi) != 'undefined' && typeof(gapi.drive) != 'undefined' && typeof(gapi.drive.realtime) != 'undefined' &&
 					e.type == gapi.drive.realtime.ErrorType.FORBIDDEN)
 				{
-					msg = mxResources.get('forbidden');
+					msg = mxUtils.htmlEntities(mxResources.get('forbidden'));
 				}
 				else if (e.code == 404 || e.status == 404 || (typeof(gapi) != 'undefined' && typeof(gapi.drive) != 'undefined' &&
 						typeof(gapi.drive.realtime) != 'undefined' && e.type == gapi.drive.realtime.ErrorType.NOT_FOUND))
 				{
-					msg = mxResources.get('fileNotFoundOrDenied');
+					msg = mxUtils.htmlEntities(mxResources.get('fileNotFoundOrDenied'));
 					var id = window.location.hash;
 					
 					if (id != null && id.substring(0, 2) == '#G')
 					{
 						id = id.substring(2);
 						msg += ' <a href="https://drive.google.com/open?id=' + id + '" target="_blank">' +
-							mxResources.get('tryOpeningViaThisPage') + '</a>';
+							mxUtils.htmlEntities(mxResources.get('tryOpeningViaThisPage')) + '</a>';
 					}
 				}
 				else if (e.code == App.ERROR_TIMEOUT)
 				{
-					msg = mxResources.get('timeout');
+					msg = mxUtils.htmlEntities(mxResources.get('timeout'));
 				}
 				else if (e.code == App.ERROR_BUSY)
 				{
-					msg = mxResources.get('busy');
+					msg = mxUtils.htmlEntities(mxResources.get('busy'));
 				}
 				else if (e.message != null)
 				{
-					msg = e.message;
+					msg = mxUtils.htmlEntities(e.message);
 				}
 				else if (e.response != null && e.response.error != null)
 				{
-					msg = e.response.error;
+					msg = mxUtils.htmlEntities(e.response.error);
 				}
 			}
 	
@@ -6961,7 +6961,7 @@
 			}
 			else if (urlParams['modified'] != null)
 			{
-				this.editor.setStatus(mxResources.get(urlParams['modified']));
+				this.editor.setStatus(mxUtils.htmlEntities(mxResources.get(urlParams['modified'])));
 			}
 		});
 		
@@ -7140,11 +7140,11 @@
 				{
 					if (data.messageKey != null)
 					{
-						this.editor.setStatus(mxResources.get(data.messageKey));
+						this.editor.setStatus(mxUtils.htmlEntities(mxResources.get(data.messageKey)));
 					}
 					else if (data.message != null)
 					{
-						this.editor.setStatus(data.message);
+						this.editor.setStatus(mxUtils.htmlEntities(data.message));
 					}
 					
 					if (data.modified != null)
@@ -7189,6 +7189,7 @@
 								this.editor.graph.setEnabled(true);
 							});
 							
+							// LATER: Uses external export if current page (not first page) has mathEnabled
 							if (this.isExportToCanvas())
 							{
 								var graph = this.editor.graph;

+ 2 - 2
war/js/diagramly/ElectronApp.js

@@ -470,7 +470,7 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
 				file.save(true, mxUtils.bind(this, function(resp)
 				{
 					this.spinner.stop();
-					this.editor.setStatus(mxResources.get('allChangesSaved'));
+					this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 				}), mxUtils.bind(this, function(resp)
 				{
 					this.editor.setStatus('');
@@ -482,7 +482,7 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
 				file.saveAs(null, mxUtils.bind(this, function(resp)
 				{
 					this.spinner.stop();
-					this.editor.setStatus(mxResources.get('allChangesSaved'));
+					this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
 				}), mxUtils.bind(this, function(resp)
 				{
 					this.editor.setStatus('');

File diff suppressed because it is too large
+ 1346 - 0
war/js/diagramly/sidebar/Sidebar-AWS3.js


+ 11 - 3
war/js/diagramly/sidebar/Sidebar.js

@@ -73,6 +73,13 @@
 	Sidebar.prototype.aws2 = ['Analytics', 'Application Services', 'Compute', 'Database', 'Developer Tools', 'Enterprise Applications', 'Game Development', 'General', 'Internet of Things',  
 	                          'Management Tools', 'Mobile Services', 'Networking', 'On-Demand Workforce', 'SDKs', 'Security and Identity', 'Storage and Content Delivery', 'Groups'];
 
+	/**
+	 *
+	 */
+	Sidebar.prototype.aws3 = ['Analytics', 'Application Services', 'Artificial Intelligence', 'Business Productivity', 'Compute', 'Database', 'Desktop and App Streaming', 'Developer Tools', 
+	                          'Game Development', 'General', 'Groups', 'Internet of Things',  
+	                          'Management Tools', 'Messaging', 'Migration', 'Mobile Services', 'Networking and Content Delivery', 'On Demand Workforce', 'SDKs', 'Security Identity and Compliance', 'Storage'];
+	
 	/**
 	 * 
 	 */
@@ -115,6 +122,7 @@
            	                           {id: 'rack', prefix: 'rack', libs: Sidebar.prototype.rack},
            	                           {id: 'electrical', prefix: 'electrical', libs: Sidebar.prototype.electrical},
            	                           {id: 'aws2', prefix: 'aws2', libs: Sidebar.prototype.aws2},
+           	                           {id: 'aws3', prefix: 'aws3', libs: Sidebar.prototype.aws3},
            	                           {id: 'pid', prefix: 'pid', libs: Sidebar.prototype.pids},
            	                           {id: 'cisco', prefix: 'cisco', libs: Sidebar.prototype.cisco},
            	                           {id: 'office', prefix: 'office', libs: Sidebar.prototype.office},
@@ -292,9 +300,9 @@
             			          {title: mxResources.get('mockups'), id: 'mockups', image: IMAGE_PATH + '/sidebar-mockups.png'},
             			          {title: mxResources.get('uml'), id: 'uml', image: IMAGE_PATH + '/sidebar-uml.png'}]},
             			{title: mxResources.get('networking'),
-            			entries: [{title: mxResources.get('aws'), id: 'aws2', image: IMAGE_PATH + '/sidebar-aws.png'},
+            			entries: [{title: mxResources.get('aws'), id: 'aws3', image: IMAGE_PATH + '/sidebar-aws3.png'},
             			// TODO: Add isometric containers  		                          
-            			{title: mxResources.get('aws3d'), id: 'aws3d', image: IMAGE_PATH + '/sidebar-aws3d.png'},
+            			          {title: mxResources.get('aws3d'), id: 'aws3d', image: IMAGE_PATH + '/sidebar-aws3d.png'},
             			          {title: mxResources.get('azure'), id: 'azure', image: IMAGE_PATH + '/sidebar-azure.png'},
             			          {title: 'Cloud & Enterprise', id: 'mscae', image: IMAGE_PATH + '/sidebar-mscae.png'},
             			          {title: mxResources.get('cisco'), id: 'cisco', image: IMAGE_PATH + '/sidebar-cisco.png'},
@@ -607,7 +615,7 @@
 		this.addCitrixPalette();
 		this.addMSCAEPalette();
 		this.addBpmnPalette(dir, false);
-		this.addAWSPalette();
+		this.addAWS3Palette();
 		this.addAWS3DPalette();
 		this.addLeanMappingPalette();
 		this.addIos7Palette();

File diff suppressed because it is too large
+ 1 - 1
war/js/embed-static.min.js


+ 2 - 2
war/js/mxgraph/EditorUi.js

@@ -3223,7 +3223,7 @@ EditorUi.prototype.save = function(name)
 				}
 
 				localStorage.setItem(name, xml);
-				this.editor.setStatus(mxResources.get('saved') + ' ' + new Date());
+				this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('saved')) + ' ' + new Date());
 			}
 			else
 			{
@@ -3247,7 +3247,7 @@ EditorUi.prototype.save = function(name)
 		}
 		catch (e)
 		{
-			this.editor.setStatus('Error saving file');
+			this.editor.setStatus(mxUtils.htmlEntities(mxResources.get('errorSavingFile')));
 		}
 	}
 };

File diff suppressed because it is too large
+ 1 - 1
war/js/reader.min.js


File diff suppressed because it is too large
+ 87 - 86
war/js/viewer.min.js


+ 3 - 3
war/package.json

@@ -1,6 +1,6 @@
 {
   "name": "draw.io",
-  "version": "6.3.1",
+  "version": "6.2.4",
   "description": "draw.io desktop",
   "main": "electron.js",
   "scripts": {
@@ -24,9 +24,9 @@
   "homepage": "https://github.com/jgraph/draw.io",
   "dependencies": {
     "electron-log": "^1.3.0",
-    "electron-updater": "^1.8.3"
+    "electron-updater": "^1.8.2"
   },
   "devDependencies": {
-    "electron": "^1.6.3"
+    "electron": "^1.6.2"
   }
 }

+ 302 - 0
war/plugins/update.js

@@ -0,0 +1,302 @@
+/**
+ * Update plugin. Use updateUrl and updateInterval (optional, default is 60000ms)
+ * in the meta data of the diagram to configure the plugin. It will send the XML
+ * of the current page to the given URL as a POST request (with a parameter called
+ * xml) and allows for the following type of XML response (with CORS headers):
+ * 
+ * <updates>
+ * <update ...>
+ * </updates>
+ * 
+ * Where update must contain an id attribute to reference the cell in the diagram.
+ * 
+ * - An optional value attribute that contains XML markup is used as the value for
+ * the cell, with label and tooltip for the label and tooltip, respectively.
+ * Additionally, placeholders="1" can be used to enable placeholders in the label
+ * or tooltip of the cell.
+ * 
+ * - An optional replace-value attribute that contains 1 can be specified to
+ * replace the value of the cell. Default is to add the attributes of the XML
+ * value specified above to the existing value of the cell. (Attributes with
+ * an empty string value are removed.)
+ * 
+ * - An optional style attribute that contains the cell style is be used to replace
+ * the existing cell style.
+ * 
+ * - An optional icon attribute that contains JSON is used to add an icon to the
+ * given cell. The object value that the icon attribute is parsed to may contain
+ * a tooltip (string), align ("left"|"center"|"right", default is "right"), valign
+ * (top|middle|bottom, default is bottom) and append (true|false, default is false)
+ * for adding or replacing existing icons. The image attribute is an object value
+ * with src, width and height for defining the icon to be displayed (default is
+ * mxGraph.warningImage). An empty string for the attribute removes all icons.
+ * 
+ * See below for an example XML.
+ */
+Draw.loadPlugin(function(editorUi)
+{
+	if (editorUi.editor.chromeless)
+	{
+		var graph = editorUi.editor.graph;
+		var interval = 60000;
+		
+		function createOverlay(desc)
+		{
+			var overlay = new mxCellOverlay(desc.image || graph.warningImage,
+				desc.tooltip, desc.align, desc.valign, desc.offset);
+
+			// Installs a handler for clicks on the overlay
+			overlay.addListener(mxEvent.CLICK, function(sender, evt)
+			{
+				editorUi.alert(desc.tooltip);
+			});
+			
+			return overlay;
+		};
+		
+		function parseUpdates(xml)
+		{
+			if (xml != null && xml.length > 0)
+			{
+				var doc = mxUtils.parseXml(xml);
+				
+				if (doc != null && doc.documentElement != null)
+				{
+					var model = graph.getModel();
+					var nodes = doc.documentElement.getElementsByTagName('update');
+					
+					if (nodes != null && nodes.length > 0)
+					{
+						model.beginUpdate();
+
+						try
+						{
+							for (var i = 0; i < nodes.length; i++)
+							{
+								// Resolves the cell ID
+								var cell = model.getCell(nodes[i].getAttribute('id'));
+
+								if (cell != null)
+								{
+									// Changes the value
+									try
+									{
+										var value = nodes[i].getAttribute('value');
+										
+										if (value != null)
+										{
+											var node = mxUtils.parseXml(value).documentElement;
+
+											if (node != null)
+											{
+												if (nodes[i].getAttribute('replace-value') == '1')
+												{
+													graph.model.setValue(cell, node);
+												}
+												else
+												{
+													var attrs = node.attributes;
+													
+													for (var j = 0; j < attrs.length; j++)
+													{
+														graph.setAttributeForCell(cell, attrs[j].nodeName,
+															(attrs[j].nodeValue.length > 0) ? attrs[j].nodeValue : null);
+													}
+												}
+											}
+										}
+									}
+									catch (e)
+									{
+										console.log('Error in value for ' + cell.id + ': ' + e);
+									}
+									
+									// Changes the style
+									try
+									{
+										var style = nodes[i].getAttribute('style');
+										
+										if (style != null)
+										{
+											graph.model.setStyle(cell, style);
+										}
+									}
+									catch (e)
+									{
+										console.log('Error in style for ' + cell.id + ': ' + e);
+									}
+									
+									// Adds or removes an overlay icon
+									try
+									{
+										var icon = nodes[i].getAttribute('icon');
+										
+										if (icon != null)
+										{
+											var desc = (icon.length > 0) ? JSON.parse(icon) : null;
+											
+											if (desc == null || !desc.append)
+											{
+												graph.removeCellOverlays(cell);
+											}
+											
+											if (desc != null)
+											{
+												graph.addCellOverlay(cell, createOverlay(desc));
+											}
+										}
+									}
+									catch (e)
+									{
+										console.log('Error in icon for ' + cell.id + ': ' + e);
+									}
+								}
+							} // for
+						}
+						finally
+						{
+							model.endUpdate();
+						}
+					}
+				}
+			}
+		};
+		
+		var currentThread = null;
+		
+		function scheduleUpdates()
+		{
+			var root = editorUi.editor.graph.getModel().getRoot();
+			var result = false;
+			
+			if (root.value != null && typeof(root.value) == 'object')
+			{
+				interval = parseInt(root.value.getAttribute('updateInterval') || interval);
+				var url = root.value.getAttribute('updateUrl');
+				
+				if (url != null)
+				{
+					var currentXml = mxUtils.getXml(editorUi.editor.getGraphXml());
+					
+					function doUpdate()
+					{
+						if (url === 'demo')
+						{
+							parseUpdates(mxUtils.getXml(createDemoResponse().documentElement));	
+							schedule();
+						}
+						else
+						{
+							mxUtils.post(url, 'xml=' + encodeURIComponent(currentXml), function(req)
+							{
+								if (root === editorUi.editor.graph.getModel().getRoot())
+								{
+									if (req.getStatus() >= 200 && req.getStatus() <= 300)
+									{
+										parseUpdates(mxUtils.getXml(req.getDocumentElement()));
+										schedule();
+									}
+									else
+									{
+										editorUi.handleError({message: mxResources.get('error') + ' ' +
+											req.getStatus()});
+									}
+								}
+							}, function(err)
+							{
+								editorUi.handleError(err);
+							});
+						}
+					};
+					
+					function schedule()
+					{
+						currentThread = window.setTimeout(doUpdate, interval);
+					};
+					
+					doUpdate();
+					result = true;
+				}
+			}
+			
+			return result;
+		};
+		
+		function startUpdates()
+		{
+			var result = scheduleUpdates();
+			
+			if (result)
+			{
+				editorUi.editor.addListener('pageSelected', function()
+				{
+					window.clearTimeout(currentThread);
+					scheduleUpdates();
+				});
+			}
+			
+			return result;
+		};
+		
+		function createDemoResponse()
+		{
+			var doc = mxUtils.createXmlDocument();
+			var status = doc.createElement('updates');
+			
+			for (var id in graph.model.cells)
+			{
+				var cell = graph.model.cells[id];
+				
+				if (graph.model.isVertex(cell))
+				{
+					// For the purpose of the demo we flag stuff to update with update="1".
+					// This is not needed for the general case.
+					if (cell.value != null && typeof(cell.value) == 'object' &&
+						cell.value.getAttribute('update') == '1')
+					{
+						if (Math.random() > 0.5)
+						{
+							var update = doc.createElement('update');
+							update.setAttribute('id', cell.id);
+							update.setAttribute('value', '<object tooltip="%load%% Done" load="' +
+								Math.round(Math.random() * 100) + '" placeholders="1">');
+							update.setAttribute('style', cell.style + ';fillColor=#d5e8d4;gradientColor=white;');
+							update.setAttribute('icon', JSON.stringify({tooltip: 'Running', align: "right",
+								valign: "top", image: {src: IMAGE_PATH + '/spin.gif', width: 12, height: 12}}));
+							status.appendChild(update);
+							
+							// Adds another icon
+							if (Math.random() > 0.5)
+							{
+								var update = doc.createElement('update');
+								update.setAttribute('id', cell.id);
+								update.setAttribute('icon', JSON.stringify({tooltip: 'Locked', append: true,
+									image: {src: IMAGE_PATH + '/locked.png', width: 12, height:12}}));
+								status.appendChild(update);
+							}
+						}
+						else
+						{
+							var update = doc.createElement('update');
+							update.setAttribute('id', cell.id);
+							update.setAttribute('style', cell.style + ';fillColor=#d4e1f5;gradientColor=white;');
+							update.setAttribute('value', '<object tooltip="">');
+							update.setAttribute('icon', '');
+							status.appendChild(update);
+						}						
+					}
+				}
+			}
+
+			doc.appendChild(status);
+			
+			return doc;
+		};
+		
+		// Wait for file to be loaded if no animation data is present
+		if (!startUpdates())
+		{
+			editorUi.editor.addListener('fileLoaded', startUpdates);
+		}
+	}
+});

File diff suppressed because it is too large
+ 31675 - 0
war/stencils.xml


File diff suppressed because it is too large
+ 31675 - 0
war/stencils/aws3.xml