Browse Source

10.3.1 release

Gaudenz Alder 6 years ago
parent
commit
a12988fbde

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+02-MAR-2019: 10.3.1
+
+- Fixes loading spinner for Trello
+- Uses magic numbers for templates
+
 01-MAR-2019: 10.3.0
 
 - Adds validation step for Google file saving

+ 1 - 1
VERSION

@@ -1 +1 @@
-10.3.0
+10.3.1

+ 10 - 16
src/main/java/com/mxgraph/online/ProxyServlet.java

@@ -5,6 +5,7 @@
 package com.mxgraph.online;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -13,7 +14,6 @@ import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.UnknownHostException;
-import java.util.Arrays;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -179,23 +179,17 @@ public class ProxyServlet extends HttpServlet
 			try (BufferedInputStream in = new BufferedInputStream(is,
 					BUFFER_SIZE))
 			{
-				StringBuilder result = new StringBuilder();
-				result.append(mxBase64.encodeToString(head, false));
-				byte[] chunk = new byte[BUFFER_SIZE];
-				int len = 0;
+				ByteArrayOutputStream os = new ByteArrayOutputStream();
+			    byte[] buffer = new byte[0xFFFF];
 
-				while ((len = in.read(chunk)) == BUFFER_SIZE)
-				{
-					result.append(mxBase64.encodeToString(chunk, false));
-				}
-
-				if (len > 0)
-				{
-					chunk = Arrays.copyOf(chunk, len);
-					result.append(mxBase64.encodeToString(chunk, false));
-				}
+				os.write(head, 0, head.length);
+				
+			    for (int len = is.read(buffer); len != -1; len = is.read(buffer))
+			    { 
+			        os.write(buffer, 0, len);
+			    }
 
-				out.write(result.toString().getBytes());
+				out.write(mxBase64.encodeToString(os.toByteArray(), false).getBytes());
 			}
 		}
 		else

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

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

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


+ 82 - 34
src/main/webapp/js/diagramly/App.js

@@ -1922,6 +1922,17 @@ App.prototype.getDiagramId = function()
 		id = id.substring(1);
 	}
 	
+	// Workaround for Trello client appending data after hash
+	if (id != null && id.length > 1 && id.charAt(0) == 'T')
+	{
+		var idx = id.indexOf('#');
+		
+		if (idx > 0)
+		{
+			id = id.substring(0, idx);
+		}
+	}
+	
 	return id;
 };
 
@@ -2225,6 +2236,9 @@ App.prototype.start = function()
 				{
 					var id = this.getDiagramId();
 					var file = this.getCurrentFile();
+
+					console.log('hashchange', id, file.getHash());
+
 					
 					if (file == null || file.getHash() != id)
 					{
@@ -3137,6 +3151,28 @@ App.prototype.saveFile = function(forceDialog, success)
 	}
 };
 
+/**
+ * Returns true if the given binary data is a Visio file.
+ */
+App.prototype.isVisioData = function(data)
+{
+	return data.length > 8 && (data.charCodeAt(0) == 0xD0 && data.charCodeAt(1) == 0xCF &&
+		data.charCodeAt(2) == 0x11 && data.charCodeAt(3) == 0xE0 && data.charCodeAt(4) == 0xA1 && data.charCodeAt(5) == 0xB1 &&
+		data.charCodeAt(6) == 0x1A && data.charCodeAt(7) == 0xE1) || (data.charCodeAt(0) == 0x50 && data.charCodeAt(1) == 0x4B &&
+		data.charCodeAt(2) == 0x03 && data.charCodeAt(3) == 0x04) || (data.charCodeAt(0) == 0x50 && data.charCodeAt(1) == 0x4B &&
+		data.charCodeAt(2) == 0x03 && data.charCodeAt(3) == 0x06);
+};
+
+/**
+ * Returns true if the given binary data is a PNG file.
+ */
+App.prototype.isPngData = function(data)
+{
+	return data.length > 8 && data.charCodeAt(0) == 137 && data.charCodeAt(1) == 80 &&
+		data.charCodeAt(2) == 78 && data.charCodeAt(3) == 71 && data.charCodeAt(4) == 13 &&
+		data.charCodeAt(5) == 10 && data.charCodeAt(6) == 26 && data.charCodeAt(7) == 10;
+};
+
 /**
  * Translates this point by the given vector.
  * 
@@ -3145,57 +3181,70 @@ App.prototype.saveFile = function(forceDialog, success)
  */
 App.prototype.loadTemplate = function(url, onload, onerror, templateFilename)
 {
+	var base64 = false;
 	var realUrl = url;
 	
 	if (!this.editor.isCorsEnabledForUrl(realUrl))
 	{
+		// Always uses base64 response to check magic numbers for file type
 		var nocache = 't=' + new Date().getTime();
-		realUrl = PROXY_URL + '?url=' + encodeURIComponent(url) + '&' + nocache;
+		realUrl = PROXY_URL + '?url=' + encodeURIComponent(url) + '&base64=1&' + nocache;
+		base64 = true;
 	}
 
 	var filterFn = (templateFilename != null) ? templateFilename : url;
 	
-	this.loadUrl(realUrl, mxUtils.bind(this, function(data)
+	this.loadUrl(realUrl, mxUtils.bind(this, function(responseData)
 	{
-		if (/(\.v(dx|sdx?))($|\?)/i.test(filterFn))
+		try
 		{
-			this.importVisio(this.base64ToBlob(data.substring(data.indexOf(',') + 1)), function(xml)
+			var data = (!base64) ? responseData : ((window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ?
+				atob(responseData) : Base64.decode(responseData));
+			
+			if (/(\.v(dx|sdx?))($|\?)/i.test(filterFn) || this.isVisioData(data))
 			{
-				onload(xml);
-			}, onerror, filterFn);
-		}
-		else if (!this.isOffline() && new XMLHttpRequest().upload && this.isRemoteFileFormat(data, filterFn))
-		{
-			// Asynchronous parsing via server
-			this.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
+				this.importVisio(this.base64ToBlob(data.substring(data.indexOf(',') + 1)), function(xml)
+				{
+					onload(xml);
+				}, onerror, filterFn);
+			}
+			else if (!this.isOffline() && new XMLHttpRequest().upload && this.isRemoteFileFormat(data, filterFn))
 			{
-				if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status <= 299 &&
-					xhr.responseText.substring(0, 13) == '<mxGraphModel')
+				// Asynchronous parsing via server
+				this.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
 				{
-					onload(xhr.responseText);
-				}
-			}), url);
-		}
-		else if (this.isLucidChartData(data))
-		{
-			this.convertLucidChart(data, mxUtils.bind(this, function(xml)
+					if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status <= 299 &&
+						xhr.responseText.substring(0, 13) == '<mxGraphModel')
+					{
+						onload(xhr.responseText);
+					}
+				}), url);
+			}
+			else if (this.isLucidChartData(data))
 			{
-				onload(xml);
-			}), mxUtils.bind(this, function(e)
+				this.convertLucidChart(data, mxUtils.bind(this, function(xml)
+				{
+					onload(xml);
+				}), mxUtils.bind(this, function(e)
+				{
+					onerror(e);
+				}));
+			}
+			else
 			{
-				onerror(e);
-			}));
+				if (/(\.png)($|\?)/i.test(filterFn) || this.isPngData(data))
+				{
+					data = this.extractGraphModelFromPng(responseData);
+				}
+				
+				onload(data);
+			}
 		}
-		else
+		catch (e)
 		{
-			if (/(\.png)($|\?)/i.test(filterFn))
-			{
-				data = this.extractGraphModelFromPng(data);
-			}
-			
-			onload(data);
+			onerror(e);
 		}
-	}), onerror, /(\.png)($|\?)/i.test(filterFn) || /(\.v(dx|sdx?))($|\?)/i.test(filterFn));
+	}), onerror, /(\.png)($|\?)/i.test(filterFn) || /(\.v(dx|sdx?))($|\?)/i.test(filterFn), null, null, base64);
 };
 
 /**
@@ -3718,7 +3767,7 @@ App.prototype.loadFile = function(id, sameWindow, file, success, force)
 							return id;
 						};
 						
-						if (!this.fileLoaded(tempFile))
+						if (!this.fileLoaded(tempFile, true))
 						{
 							doFallback();
 						}
@@ -4641,7 +4690,6 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
 		});
 
 		req.onerror = error;
-		
 		req.send();
 	}
 	else

+ 21 - 8
src/main/webapp/js/diagramly/EditorUi.js

@@ -2137,7 +2137,7 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.fileLoaded = function(file)
+	EditorUi.prototype.fileLoaded = function(file, noDialogs)
 	{
 		var oldFile = this.getCurrentFile();
 		this.fileLoadedError = null;
@@ -2171,7 +2171,7 @@
 			this.setBackgroundImage(null);
 					
 			// Avoids empty hash with no value
-			if (window.location.hash != null && window.location.hash.length > 0)
+			if (!noDialogs && window.location.hash != null && window.location.hash.length > 0)
 			{
 				window.location.hash = '';
 			}
@@ -2185,7 +2185,11 @@
 
 			this.editor.setStatus('');
 			this.updateUi();
-			this.showSplash();
+			
+			if (!noDialogs)
+			{
+				this.showSplash();
+			}
 		});
 	
 		if (file != null)
@@ -2319,7 +2323,7 @@
 				}
 				
 				// Asynchronous handling of errors
-				this.handleError(e, mxResources.get('errorLoadingFile'), mxUtils.bind(this, function()
+				var fn = mxUtils.bind(this, function()
 				{
 					// Removes URL parameter and reloads the page
 					if (urlParams['url'] != null && this.spinner.spin(document.body, mxResources.get('reconnecting')))
@@ -2334,7 +2338,16 @@
 					{
 						noFile();
 					}
-				}), true);
+				});
+				
+				if (!noDialogs)
+				{
+					this.handleError(e, mxResources.get('errorLoadingFile'), fn, true);
+				}
+				else
+				{
+					fn();
+				}
 			}
 		}
 		else
@@ -6306,12 +6319,12 @@
 	/**
 	 * Checks if the client is authorized and calls the next step.
 	 */
-	EditorUi.prototype.loadUrl = function(url, success, error, forceBinary, retry, dataUriPrefix)
+	EditorUi.prototype.loadUrl = function(url, success, error, forceBinary, retry, dataUriPrefix, noBinary)
 	{
 		try
 		{
-			var binary = forceBinary || /(\.png)($|\?)/i.test(url) ||
-				/(\.jpe?g)($|\?)/i.test(url) || /(\.gif)($|\?)/i.test(url);
+			var binary = !noBinary && (forceBinary || /(\.png)($|\?)/i.test(url) ||
+				/(\.jpe?g)($|\?)/i.test(url) || /(\.gif)($|\?)/i.test(url));
 			retry = (retry != null) ? retry : true;
 			
 			var fn = mxUtils.bind(this, function()

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


+ 8 - 4
src/main/webapp/plugins/cConf-1-4-8.js

@@ -159,20 +159,22 @@ Draw.loadPlugin(function(ui)
 		tbSelect.style.right = '20px';
 		tbSelect.style.width = '97px';
 		tbSelect.style.marginTop = '-2px';
-
+		
 		var opts = [{value: 'top', title: mxResources.get('top')},
 			{value: 'inline', title: mxResources.get('embed')},
 			{value: 'hidden', title: mxResources.get('hidden')}]
+		var validTb = false;
 
 		for (var i = 0; i < opts.length; i++)
 		{
+			validTb = validTb || macroData.tbstyle == opts[i].value;
 			var tbOption = document.createElement('option');
 			tbOption.setAttribute('value', opts[i].value);
 			mxUtils.write(tbOption, opts[i].title);
 			tbSelect.appendChild(tbOption);
 		}
-
-		tbSelect.value = macroData.tbstyle || 'top';
+		
+		tbSelect.value = (validTb) ? macroData.tbstyle : 'top';
 		stylePanel.appendChild(tbSelect);
 		div.appendChild(stylePanel);
 		
@@ -197,16 +199,18 @@ Draw.loadPlugin(function(ui)
 		var opts = [{value: 'auto', title: mxResources.get('automatic')},
 			{value: 'blank', title: mxResources.get('openInNewWindow')},
 			{value: 'self', title: mxResources.get('openInThisWindow')}]
+		var validLinks = false;
 
 		for (var i = 0; i < opts.length; i++)
 		{
+			validLinks = validLinks || macroData.links == opts[i].value;
 			var linkOption = document.createElement('option');
 			linkOption.setAttribute('value', opts[i].value);
 			mxUtils.write(linkOption, opts[i].title);
 			linksSelect.appendChild(linkOption);
 		}
 		
-		linksSelect.value = macroData.links || 'auto';
+		linksSelect.value = (validLinks) ? macroData.links : 'auto';
 		stylePanel.appendChild(linksSelect);
 		div.appendChild(stylePanel);
 		

+ 1 - 1
src/main/webapp/styles/atlas.css

@@ -202,7 +202,7 @@ div.mxWindow .geButton:active, .mxWindow .geLabel:active {
 	padding:0px 10px 0px 10px !important;
 	margin-left:0px !important;
 }
-.geToolbarContainer {
+.geToolbarContainer *:not(.geFormatContainer *) {
 	font-size: 13px;
 	color: rgb(153, 153, 153);
 	background-color: rgb(238, 238, 238);