Browse Source

12.7.8 release

Gaudenz Alder 5 years ago
parent
commit
9327b82489

+ 21 - 1
ChangeLog

@@ -1,4 +1,24 @@
-21-FEB-2020:12.7.4
+26-FEB-2020: 12.7.8
+
+- Adds logging for Confluence cloud errors
+- Adds global error dialog
+
+26-FEB-2020: 12.7.7
+
+- Adds error logging for Confluence and Jira cloud
+
+25-FEB-2020: 12.7.6
+
+- Fixes NPE in viewer
+
+25-FEB-2020: 12.7.5
+
+- Fixes removed contentID macro parameter in Confluence cloud
+- Adds recursive resize for size change in Arrange panel
+- Disables drop target for composite BPMN/UML shapes
+- Fixes missing tree move icon
+
+21-FEB-2020: 12.7.4
 
 - Changes Google picker to support team drives
 - Fixes crop for imported files

+ 1 - 1
VERSION

@@ -1 +1 @@
-12.7.4
+12.7.8

+ 14 - 0
etc/redirect-worker/package.json

@@ -0,0 +1,14 @@
+{
+  "private": true,
+  "name": "redirect-worker",
+  "version": "1.0.0",
+  "description": "Redirect worker for draw.io",
+  "main": "redirect.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "draw.io",
+  "license": "MIT",
+  "devDependencies": {},
+  "dependencies": {}
+}

+ 165 - 0
etc/redirect-worker/redirect.js

@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2011-2020, JGraph Ltd
+ */
+
+async function handleRequest(request) {
+  let requestURL = new URL(request.url)
+  let host = requestURL.host
+  let path = requestURL.pathname
+  
+  let hostRedirectMap = redirectMap.get(host)
+  
+  if (hostRedirectMap)
+  {
+	  //Match full path then reduce one level at a time
+	  let redirect, notUsedPath = '', done = false
+	  
+	  do
+	  {
+		  redirect = hostRedirectMap.get(path) || hostRedirectMap.get(path + '/');
+		  
+		  if (redirect) 
+		  {
+			  //Complete the URL
+			  if (redirect.startsWith('/'))
+			  {
+				  redirect = requestURL.protocol + '//' + host + redirect;
+			  }
+			  
+			  return Response.redirect(redirect + notUsedPath, 301)
+		  }
+		  else
+		  {
+			  let lastSlash = path.lastIndexOf('/');
+			  
+			  if (lastSlash >= 0)
+			  {
+				  notUsedPath = path.substr(lastSlash) + notUsedPath;
+				  path = path.substr(0, lastSlash);
+			  }
+			  else
+			  {
+				  done = true
+			  }
+		  }
+	  } while (!done)
+  }
+  
+  // If not in the map, return 404
+  return new Response('NOT_FOUND', { status: 404 });
+}
+
+addEventListener('fetch', async event => {
+  event.respondWith(handleRequest(event.request))
+})
+
+const redirectMap = new Map([
+	['about.draw.io', new Map([
+		['/drawio-desktop-10-7-5-release', 'https://github.com/jgraph/drawio-desktop/releases/tag/v10.7.5'],
+		['/insert-from-text-now-supports-plantuml', '/use-plantuml-in-draw-io'],
+		['/integrate-draw-io/', '/integrations-ecosystem/'],
+		['/new-edge-styles/', '/connector-styles-and-animations-in-draw-io/'],
+		['/publish-diagrams-to-github/', '/github-support/'],
+		['/prefer-draw-io-in-an-atlassian-style/', '/pick-your-favorite-draw-io-theme-kennedy-atlas-dark-or-minimal/'],
+		['/drawio-desktop-10-7-5-release', 'https://github.com/jgraph/drawio-desktop/releases/tag/v10.7.5'],
+		['/insert-from-text-now-supports-plantuml', '/use-plantuml-in-draw-io'],
+		['/integrate-draw-io/', '/integrations-ecosystem/'],
+		['/new-edge-styles/', '/connector-styles-and-animations-in-draw-io/'],
+		['/publish-diagrams-to-github/', '/github-support/'],
+		['/prefer-draw-io-in-an-atlassian-style/', '/pick-your-favorite-draw-io-theme-kennedy-atlas-dark-or-minimal/'],
+		['/integrations/confluence-integration-2/', 'https://www.diagrams.net/integrations.html'],
+		['/integrations/jira-integration/', 'https://www.diagrams.net/integrations.html'],
+		['/integrations/', 'https://www.diagrams.net/integrations.html'],
+		['/features/examples/', 'https://drawio-app.com/'],
+		['/features/training-material/', 'https://drawio-app.com/tutorials/'],
+		['/features/', 'https://www.diagrams.net/'],
+		['/integrations-ecosystem/', 'https://www.diagrams.net/integrations'],
+		['/multiple-pages-per-diagram/', 'https://www.diagrams.net/blog/multiple-page-diagrams'],
+		['/drawio-data-protection/', 'https://www.diagrams.net/blog/data-protection'],
+		['/use-draw-io-offline/', 'https://www.diagrams.net/blog/diagrams-offline'],
+		['/use-your-own-fonts-in-draw-io/', 'https://www.diagrams.net/blog/external-fonts'],
+		['/4-ways-to-connect-shapes/', 'https://www.diagrams.net/blog/connect-shapes'],
+		['/export-cloudockit-architecture-to-drawio/', 'https://www.diagrams.net/blog/cloudockit-to-drawio'],
+		['/google-drive-connector-for-confluence-cloud/', 'https://www.diagrams.net/'],
+		['/document-your-aws-architecture-with-cloudcraft-and-draw-io/', 'https://www.diagrams.net/blog/drawio-aws-cloudcraft'],
+		['/use-draw-io-diagrams-in-google-docs/', 'https://www.diagrams.net/blog/diagrams-google-docs'],
+		['/improved-import/', 'https://www.diagrams.net/blog/import-formats'],
+		['/incremental-find-plugin/', 'https://www.diagrams.net/doc/faq/find-shapes'],
+		['/sidebar-click/', 'https://www.diagrams.net/blog/quick-add-shapes'],
+		['/find-plugin-update/', 'https://www.diagrams.net/doc/faq/find-shapes'],
+		['/how-to-quickly-remove-sensitive-information-from-draw-io-diagrams/', 'https://www.diagrams.net/doc/faq/anonymize-plugin'],
+		['/draw-io-privacy-and-google-analytics/', 'https://www.diagrams.net/blog/google-analytics'],
+		['/share-diagrams-with-draw-io/', 'https://www.diagrams.net/blog/online-diagram-viewer'],
+		['/publish-link-and-embed-html/', 'https://www.diagrams.net/blog/publish-link'],
+		['/public-google-files/', 'https://www.diagrams.net/blog/share-diagrams-via-google'],
+		['/export-diagrams-as-urls/', 'https://www.diagrams.net/blog/export-url'],
+		['/using-draw-io-diagrams-in-wordpress/', 'https://www.diagrams.net/blog/export-svg'],
+		['/insert-from-text-now-supports-lists-and-graphs/', 'https://www.diagrams.net/blog/insert-from-text'],
+		['/altdrop/', 'https://www.diagrams.net/blog/shortcut-overlay-shapes'],
+		['/animation-and-automatic-layout-explore-complex-diagrams/', 'https://www.diagrams.net/doc/faq/explore-plugin'],
+		['/google-team-drives-support/', 'https://www.diagrams.net/blog/google-shared-drives'],
+		['/30k-reviews/', 'https://www.diagrams.net'],
+		['/external-fonts-in-draw-io/', 'https://www.diagrams.net/blog/external-fonts'],
+		['/analysing-vulnerabilities-with-threat-modelling-in-draw-io/', 'https://www.diagrams.net/blog/threat-modelling'],
+		['/fosdem2020-sponsor/', 'https://www.diagrams.net/blog/fosdem-sponsor'],
+		['/google-docs-add-on-now-supports-high-resolution-images/', 'https://www.diagrams.net/blog/high-resolution-images-google-docs'],
+		['/sql-plugin/', 'https://www.diagrams.net/blog/insert-sql'],
+		['/properties-plugin/', 'https://www.diagrams.net/doc/faq/properties-plugin'],
+		['/number-plugin/', 'https://www.diagrams.net/doc/faq/plugins'],
+		['/40k-reviews/', 'https://www.diagrams.net'],
+		['/new-veeam-stencil-set/', 'https://www.diagrams.net/blog/veeam-stencils'],
+		['/new-github-repository/', 'https://www.diagrams.net/blog/example-diagrams-github'],
+		['/updates-to-draw-io-desktop/', 'https://www.diagrams.net/blog/desktop-updates'],
+		['/simplified-tags-plugin/', 'https://www.diagrams.net/doc/faq/tags-plugin'],
+		['/github-support/', 'https://www.diagrams.net/blog/github-support'],
+		['/support-for-your-language-in-draw-io/', 'https://www.diagrams.net/blog/translate-drawio'],
+		['/altshiftcursor/', 'https://www.diagrams.net/blog/shortcut-clone-connect'],
+		['/altshiftselect-now-removes-selected-cells%ef%bb%bf/', 'https://www.diagrams.net/blog/shortcut-deselect-shapes'],
+		['/draw-io-diagrams-for-confluence/', 'https://www.diagrams.net/integrations'],
+		['/scratchpad-in-chrome-app/', 'https://www.diagrams.net/blog/drawio-chrome-app'],
+		['/find-and-tags/', 'https://www.diagrams.net/doc/faq/find-shapes'],
+		['/disable-recursive-resize/', 'https://www.diagrams.net/blog/disable-resize-children'],
+		['/placeholder-scope/', 'https://www.diagrams.net/blog/placeholder-scope'],
+		['/scissors-tool/', 'https://www.diagrams.net/blog/shortcut-move-area'],
+		['/shiftdelete-in-toolbar-now-deletes-cells-with-connections%ef%bb%bf/', 'https://www.diagrams.net/blog/shortcut-shift-delete'],
+		['/snap-to-point/', 'https://www.diagrams.net/blog/snap-to-point'],
+		['/features/examples/', 'https://drawio-app.com/'],
+		['/features/training-material/', 'https://drawio-app.com/tutorials/'],
+		['/terms-conditions/', 'https://seibert-media.com/general-terms/'],
+		['/', 'https://drawio-app.com/']
+	])],
+	['blog.draw.io', new Map([
+		['/', 'https://drawio-app.com/blog']
+	])],
+	['download.draw.io', new Map([
+		['/', 'https://github.com/jgraph/drawio-desktop/releases/latest']
+	])],
+	['get.draw.io', new Map([
+		['/', 'https://github.com/jgraph/drawio-desktop/releases/latest']
+	])],
+	['docsaddon.draw.io', new Map([
+		['/', 'https://gsuite.google.com/marketplace/app/drawio_viewer_for_docs/224440279306']
+	])],
+	['gsuite.draw.io', new Map([
+		['/', 'https://gsuite.google.com/marketplace/app/drawio_diagrams/671128082532']
+	])],
+	['office.draw.io', new Map([
+		['/', 'https://appsource.microsoft.com/product/office/wa200000113']
+	])],
+	['slidesaddon.draw.io', new Map([
+		['/', 'https://gsuite.google.com/marketplace/app/drawio_diagrams_for_slides/58828304893']
+	])],
+	['sheetsaddon.draw.io', new Map([
+		['/', 'https://gsuite.google.com/marketplace/app/drawio_diagrams_for_sheets/948903782998']
+	])],
+	['doc.draw.io', new Map([
+		['/i18n', 'https://docs.google.com/spreadsheets/d/1FoYdyEraEQuWofzbYCDPKN7EdKgS_2ZrsDrOA8scgwQ'],
+		['/', 'https://support.draw.io']
+	])],
+	['app.draw.io', new Map([
+		['/', 'https://www.draw.io/app']
+	])],
+	['new.draw.io', new Map([
+		['/', 'https://www.draw.io/?splash=0']
+	])]
+])

+ 6 - 0
etc/redirect-worker/wrangler.toml

@@ -0,0 +1,6 @@
+name = "redirect-worker"
+type = "javascript"
+account_id = ""
+workers_dev = true
+route = ""
+zone_id = ""

+ 63 - 29
src/main/java/com/mxgraph/online/AbsAuthServlet.java

@@ -30,8 +30,39 @@ abstract public class AbsAuthServlet extends HttpServlet
 	
 	static public class Config 
 	{
-		public String DEV_CLIENT_SECRET = null, CLIENT_SECRET = null, DEV_CLIENT_ID = null, CLIENT_ID = null,
-				DEV_REDIRECT_URI = null, REDIRECT_URI = null, AUTH_SERVICE_URL = null;
+		public String REDIRECT_PATH = null, AUTH_SERVICE_URL = null;
+		//TODO These variables are temporary until new method is propagated
+		public String OLD_REDIRECT_URL = null, OLD_CLIENT_ID = null;
+
+		protected HashMap<String, String> clientSecretMap = new HashMap<>();
+		
+		public Config(String clientIds, String clientSecrets)
+		{
+			try
+			{
+				String[] cIds = clientIds.split(SEPARATOR);
+				String[] cSecrets = clientSecrets.split(SEPARATOR);
+				
+				for (int i = 0; i < cIds.length; i++)
+				{
+					clientSecretMap.put(cIds[i], cSecrets[i]);
+				}
+			}
+			catch (Exception e) 
+			{
+				throw new RuntimeException("Invalid config. " + e.getMessage());
+			}
+		}
+		
+		public String getClientSecret(String cId)
+		{
+			return clientSecretMap.get(cId);
+		}
+		
+		public String getRedirectUrl(String domain)
+		{
+			return "https://" + domain + REDIRECT_PATH;
+		}
 	}
 	
 	protected Config getConfig()
@@ -61,7 +92,7 @@ abstract public class AbsAuthServlet extends HttpServlet
 		String refreshToken = request.getParameter("refresh_token");
 		String error = request.getParameter("error");
 		HashMap<String, String> stateVars = new HashMap<>();
-		int configIndex = 0;
+		String secret = null, client = null, redirectUri = null, domain = null, appIndex = null; //TODO appIndex variable is temporary until new method is propagated
 		
 		try
 		{
@@ -80,12 +111,9 @@ abstract public class AbsAuthServlet extends HttpServlet
 					}
 				}
 			
-				String appIndex = stateVars.get("appIndex");
-						
-				if (appIndex != null)
-				{
-					configIndex = Integer.parseInt(appIndex);
-				}
+				domain = stateVars.get("domain");
+				client = stateVars.get("cId");
+				appIndex = stateVars.get("appIndex"); //TODO appIndex variable is temporary until new method is propagated
 			}
 			catch(Exception e)
 			{
@@ -94,28 +122,34 @@ abstract public class AbsAuthServlet extends HttpServlet
 			}
 
 			Config CONFIG = getConfig();
-			String secret, client, redirectUri;
-			String[] secrets, clients, redirectUris;
-
-			if ("127.0.0.1".equals(request.getServerName()) || 
-					"devhost.jgraph.com".equals(request.getServerName()) ||
-					"localhost".equals(request.getServerName()))
-			{
-				secrets = CONFIG.DEV_CLIENT_SECRET.split(SEPARATOR);
-				clients = CONFIG.DEV_CLIENT_ID.split(SEPARATOR);
-				redirectUris = CONFIG.DEV_REDIRECT_URI.split(SEPARATOR);
-			}
-			else
+			redirectUri = CONFIG.getRedirectUrl(domain != null? domain : request.getServerName());
+			
+			//TODO This code block is temporary until new method is propagated
+			if (appIndex != null || client == null)
 			{
-				secrets = CONFIG.CLIENT_SECRET.split(SEPARATOR);
-				clients = CONFIG.CLIENT_ID.split(SEPARATOR);
-				redirectUris = CONFIG.REDIRECT_URI.split(SEPARATOR);
+				int configIndex = 0;
+				
+				try
+				{
+					configIndex = Integer.parseInt(appIndex);
+				}
+				catch(Exception e) {} // Ignore
+
+				
+				String[] clients = CONFIG.OLD_CLIENT_ID.split(SEPARATOR);
+				String[] redirectUris = CONFIG.OLD_REDIRECT_URL.split(SEPARATOR);
+
+				if (configIndex < 0 || configIndex >= clients.length)
+				{
+					configIndex = 0;
+				}
+				
+				client = clients[configIndex];
+				redirectUri = redirectUris[configIndex];
 			}
-	
-			secret = secrets.length > configIndex ? secrets[configIndex] : secrets[0];
-			client = clients.length > configIndex ? clients[configIndex] : clients[0];
-			redirectUri = redirectUris.length > configIndex ? redirectUris[configIndex] : redirectUris[0];
-	
+
+			secret = CONFIG.getClientSecret(client);
+			
 			if (error != null)
 			{
 				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

+ 18 - 14
src/main/java/com/mxgraph/online/GoogleAuthServlet.java

@@ -10,55 +10,59 @@ public class GoogleAuthServlet extends AbsAuthServlet
 {
 	public static String CLIENT_SECRET_FILE_PATH = "/WEB-INF/google_client_secret";
 	public static String CLIENT_ID_FILE_PATH = "/WEB-INF/google_client_id";
-	public static String CLIENT_REDIRECT_URI_FILE_PATH = "/WEB-INF/google_client_redirect_uri";
+	
 	private static Config CONFIG = null;
 	
 	protected Config getConfig()
 	{
 		if (CONFIG == null)
 		{
-			CONFIG = new Config();
+			String clientSerets, clientIds;
 			
 			try
 			{
-				CONFIG.CLIENT_SECRET = Utils
+				clientSerets = Utils
 						.readInputStream(getServletContext()
 								.getResourceAsStream(CLIENT_SECRET_FILE_PATH))
 						.replaceAll("\n", "");
-				CONFIG.DEV_CLIENT_SECRET = CONFIG.CLIENT_SECRET;
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Client secret path invalid");
+				throw new RuntimeException("Client secrets path invalid");
 			}
 
 			try
 			{
-				CONFIG.CLIENT_ID = Utils
+				clientIds = Utils
 						.readInputStream(getServletContext()
 								.getResourceAsStream(CLIENT_ID_FILE_PATH))
 						.replaceAll("\n", "");
-				CONFIG.DEV_CLIENT_ID = CONFIG.CLIENT_ID;
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Client ID path invalid");
+				throw new RuntimeException("Client IDs path invalid");
 			}
 			
+			CONFIG = new Config(clientIds, clientSerets);
+			CONFIG.REDIRECT_PATH = "/google";
+			CONFIG.AUTH_SERVICE_URL = "https://www.googleapis.com/oauth2/v4/token";
+			
+			//TODO This code is temporary until new method is propagated
 			try
 			{
-				CONFIG.REDIRECT_URI = Utils
+				CONFIG.OLD_REDIRECT_URL = Utils
 						.readInputStream(getServletContext()
-								.getResourceAsStream(CLIENT_REDIRECT_URI_FILE_PATH))
+								.getResourceAsStream("/WEB-INF/google_old_client_redirect_uri"))
+						.replaceAll("\n", "");
+				CONFIG.OLD_CLIENT_ID = Utils
+						.readInputStream(getServletContext()
+								.getResourceAsStream("/WEB-INF/google_old_client_id"))
 						.replaceAll("\n", "");
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Client ID path invalid");
+				throw new RuntimeException("OLD CONFIGs path is invalid");
 			}
-			
-			CONFIG.AUTH_SERVICE_URL = "https://www.googleapis.com/oauth2/v4/token";
-			CONFIG.DEV_REDIRECT_URI = "https://test.draw.io/google";
 		}
 		
 		return CONFIG;

+ 14 - 38
src/main/java/com/mxgraph/online/MSGraphAuthServlet.java

@@ -8,11 +8,8 @@ import java.io.IOException;
 @SuppressWarnings("serial")
 public class MSGraphAuthServlet extends AbsAuthServlet
 {
-	public static String DEV_CLIENT_SECRET_FILE_PATH = "/WEB-INF/msgraph_dev_client_secret";
 	public static String CLIENT_SECRET_FILE_PATH = "/WEB-INF/msgraph_client_secret";
-	public static String DEV_CLIENT_ID_FILE_PATH = "/WEB-INF/msgraph_dev_client_id";
 	public static String CLIENT_ID_FILE_PATH = "/WEB-INF/msgraph_client_id";
-	public static String CLIENT_REDIRECT_URI_FILE_PATH = "/WEB-INF/msgraph_client_redirect_uri";
 	
 	private static Config CONFIG = null;
 	
@@ -20,70 +17,49 @@ public class MSGraphAuthServlet extends AbsAuthServlet
 	{
 		if (CONFIG == null)
 		{
-			CONFIG = new Config();
+			String clientSerets, clientIds;
 			
 			try
 			{
-				CONFIG.DEV_CLIENT_SECRET = Utils
-						.readInputStream(getServletContext()
-								.getResourceAsStream(DEV_CLIENT_SECRET_FILE_PATH))
-						.replaceAll("\n", "");
-			}
-			catch (IOException e)
-			{
-				throw new RuntimeException("Dev client secret path invalid.");
-			}
-			
-			try
-			{
-				CONFIG.CLIENT_SECRET = Utils
+				clientSerets = Utils
 						.readInputStream(getServletContext()
 								.getResourceAsStream(CLIENT_SECRET_FILE_PATH))
 						.replaceAll("\n", "");
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Client secret path invalid.");
+				throw new RuntimeException("Client secrets path invalid.");
 			}
 			
 			try
 			{
-				CONFIG.DEV_CLIENT_ID = Utils
-						.readInputStream(getServletContext()
-								.getResourceAsStream(DEV_CLIENT_ID_FILE_PATH))
-						.replaceAll("\n", "");
-			}
-			catch (IOException e)
-			{
-				throw new RuntimeException("Dev client ID invalid.");
-			}
-
-			try
-			{
-				CONFIG.CLIENT_ID = Utils
+				clientIds = Utils
 						.readInputStream(getServletContext()
 								.getResourceAsStream(CLIENT_ID_FILE_PATH))
 						.replaceAll("\n", "");
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Client ID invalid.");
+				throw new RuntimeException("Client IDs path invalid.");
 			}
 			
+			CONFIG = new Config(clientIds, clientSerets);
+			CONFIG.REDIRECT_PATH = "/microsoft";
+			CONFIG.AUTH_SERVICE_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
+			
+			//TODO This code is temporary until new method is propagated
 			try
 			{
-				CONFIG.REDIRECT_URI = Utils
+				CONFIG.OLD_REDIRECT_URL = Utils
 						.readInputStream(getServletContext()
-								.getResourceAsStream(CLIENT_REDIRECT_URI_FILE_PATH))
+								.getResourceAsStream("/WEB-INF/msgraph_old_client_redirect_uri"))
 						.replaceAll("\n", "");
+				CONFIG.OLD_CLIENT_ID = clientIds;
 			}
 			catch (IOException e)
 			{
-				throw new RuntimeException("Redirect Uri is invalid");
+				throw new RuntimeException("OLD CONFIGs path is invalid");
 			}
-			
-			CONFIG.DEV_REDIRECT_URI = "https://test.draw.io/microsoft";
-			CONFIG.AUTH_SERVICE_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
 		}
 		
 		return CONFIG;

+ 1 - 0
src/main/webapp/WEB-INF/google_old_client_id

@@ -0,0 +1 @@
+850530949725.apps.googleusercontent.com/:::/671128082532-jhphbq6d0e1gnsus9mn7vf8a6fjn10mp.apps.googleusercontent.com/:::/850530949725.apps.googleusercontent.com/:::/850530949725.apps.googleusercontent.com/:::/671128082532-jhphbq6d0e1gnsus9mn7vf8a6fjn10mp.apps.googleusercontent.com

+ 1 - 0
src/main/webapp/WEB-INF/google_old_client_redirect_uri

@@ -0,0 +1 @@
+https://www.draw.io/google/:::/https://www.draw.io/google/:::/https://confluence.draw.io/google/:::/https://jira.draw.io/google/:::/https://test.draw.io/google

+ 1 - 0
src/main/webapp/WEB-INF/msgraph_old_client_redirect_uri

@@ -0,0 +1 @@
+https://www.draw.io/microsoft/:::/https://confluence.draw.io/microsoft/:::/https://jira.draw.io/microsoft/:::/https://test.draw.io/microsoft

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


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

@@ -507,7 +507,8 @@ App.main = function(callback, createUi)
 	// Logs uncaught errors
 	window.onerror = function(message, url, linenumber, colno, err)
 	{
-		EditorUi.logError(message, url, linenumber, colno, err);
+		EditorUi.logError('Global: ' + ((message != null) ? message : ''),
+			url, linenumber, colno, err);
 	};
 
 	// Removes info text in embed mode
@@ -2823,11 +2824,21 @@ App.prototype.showAlert = function(message)
  */
 App.prototype.start = function()
 {
+	// Handles all errors
+	var ui = this; 
+	
+	window.onerror = function(message, url, linenumber, colno, err)
+	{
+		EditorUi.logError('Uncaught: ' + ((message != null) ? message : ''),
+			url, linenumber, colno, err);
+		ui.handleError({message: message}, mxResources.get('unknownError'), null, null, null, null, true);
+	};
+	
 	if (this.bg != null && this.bg.parentNode != null)
 	{
 		this.bg.parentNode.removeChild(this.bg);
 	}
-
+	
 	this.restoreLibraries();
 	this.spinner.stop();
 	

+ 3 - 5
src/main/webapp/js/diagramly/DriveClient.js

@@ -28,13 +28,11 @@ DriveClient = function(editorUi)
 		this.clientId = window.DRAWIO_GOOGLE_VIEWER_CLIENT_ID || '850530949725.apps.googleusercontent.com';
 		this.scopes = ['https://www.googleapis.com/auth/drive.readonly',
 			'https://www.googleapis.com/auth/userinfo.profile'];
-		this.appIndex = 0;
 	}
 	else
 	{
 		this.appId = window.DRAWIO_GOOGLE_APP_ID || '671128082532';
 		this.clientId = window.DRAWIO_GOOGLE_CLIENT_ID || '671128082532-jhphbq6d0e1gnsus9mn7vf8a6fjn10mp.apps.googleusercontent.com';
-		this.appIndex = 1;
 	}
 	
 	this.mimeTypes = this.xmlMimeType + ',application/mxe,application/mxr,' +
@@ -616,8 +614,8 @@ DriveClient.prototype.authorize = function(immediate, success, error, remember,
 		{
 			if (immediate) //Note, we checked refresh token is not null above
 			{
-				//state is used to identify which app is used
-				var req = new mxXmlRequest(this.redirectUri + '?state=appIndex%3D' + this.appIndex + '&refresh_token=' + authInfo.refresh_token, null, 'GET');
+				//state is used to identify which app/domain is used
+				var req = new mxXmlRequest(this.redirectUri + '?state=' + encodeURIComponent('cId=' + this.clientId + '&domain=' + window.location.hostname) + '&refresh_token=' + authInfo.refresh_token, null, 'GET');
 				
 				req.send(mxUtils.bind(this, function(req)
 				{
@@ -650,7 +648,7 @@ DriveClient.prototype.authorize = function(immediate, success, error, remember,
 						'&response_type=code&include_granted_scopes=true' +
 						(remember? '&access_type=offline&prompt=consent%20select_account' : '') + //Ask for consent again to get a new refresh token
 						'&scope=' + encodeURIComponent(this.scopes.join(' ')) +
-						'&state=appIndex%3D' + this.appIndex; //To identify which app is used
+						'&state=' + encodeURIComponent('cId=' + this.clientId + '&domain=' + window.location.hostname); //To identify which app/domain is used
 				
 				if (popup == null)
 				{

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

@@ -822,7 +822,7 @@
 			}
 		}
 		
-		return cause;
+		return (cause != null) ? mxUtils.trim(cause) : cause;
 	};
 
 	/**

+ 22 - 13
src/main/webapp/js/diagramly/EditorUi.js

@@ -134,11 +134,11 @@
 	/**
 	 * Updates action states depending on the selection.
 	 */
-	EditorUi.logError = function(message, url, linenumber, colno, err)
+	EditorUi.logError = function(message, url, linenumber, colno, err, severity)
 	{
 		if (urlParams['dev'] == '1')
 		{
-			EditorUi.debug('logError', message, url, linenumber, colno, err);
+			EditorUi.debug('logError', message, url, linenumber, colno, err, severity);
 		}
 		else if (EditorUi.enableLogging)
 		{
@@ -155,9 +155,9 @@
 				else if (message != null && message.indexOf('DocumentClosedError') < 0)
 				{
 					EditorUi.lastErrorMessage = message;
-					var severity = (message.indexOf('NetworkError') >= 0 || message.indexOf('SecurityError') >= 0 ||
-						message.indexOf('NS_ERROR_FAILURE') >= 0 || message.indexOf('out of memory') >= 0) ?
-						'CONFIG' : 'SEVERE';
+					severity = ((severity != null) ? severity : (message.indexOf('NetworkError') >= 0 ||
+						message.indexOf('SecurityError') >= 0 || message.indexOf('NS_ERROR_FAILURE') >= 0 ||
+						message.indexOf('out of memory') >= 0) ? 'CONFIG' : 'SEVERE');
 					var logDomain = window.DRAWIO_LOG_URL != null ? window.DRAWIO_LOG_URL : '';
 					err = (err != null) ? err : new Error(message);
 
@@ -245,7 +245,10 @@
 				
 				for (var i = 0; i < arguments.length; i++)
 			    {
-					args.push(arguments[i]);
+					if (arguments[i] != null)
+					{
+						args.push(arguments[i]);
+					}
 			    }
 			    
 				console.log.apply(console, args);
@@ -1598,7 +1601,7 @@
 		
 		if (cause)
 		{
-			throw new Error(cause);
+			throw new Error(mxResources.get('notADiagramFile') + ' (' + cause + ')');
 		}
 		else
 		{
@@ -2570,7 +2573,7 @@
 				
 				if (!noDialogs)
 				{
-					this.handleError(e, mxResources.get('errorLoadingFile'), fn, true);
+					this.handleError(e, mxResources.get('errorLoadingFile'), fn, true, null, null, true);
 				}
 				else
 				{
@@ -3631,7 +3634,7 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.handleError = function(resp, title, fn, invokeFnOnClose, notFoundMessage, fileHash)
+	EditorUi.prototype.handleError = function(resp, title, fn, invokeFnOnClose, notFoundMessage, fileHash, disableLogging)
 	{
 		var resume = (this.spinner != null && this.spinner.pause != null) ? this.spinner.pause() : function() {};
 		var e = (resp != null && resp.error != null) ? resp.error : resp;
@@ -3643,7 +3646,7 @@
 			{
 				if (window.console != null)
 				{
-					console.error(resp);
+					console.error('EditorUi.handleError:', resp);
 				}
 			}
 			catch (ex)
@@ -3653,7 +3656,10 @@
 			
 			try
 			{
-				EditorUi.logError('EditorUi.handleError: ' + e.message, null, null, e);
+				if (!disableLogging && urlParams['dev'] != '1')
+				{
+					EditorUi.logError(resp.message, null, null, resp, 'INFO');
+				}
 			}
 			catch (e)
 			{
@@ -9136,13 +9142,16 @@
 			
 			img.onload = function()
 			{
+				img.width = (img.width > 0) ? img.width : 120;
+				img.height = (img.height > 0) ? img.height : 120;
+				
 				onload(img);
-			}
+			};
 			
 			if (onerror != null)
 			{
 				img.onerror = onerror;
-			}
+			};
 			
 			img.src = uri;
 		}

+ 4 - 2
src/main/webapp/js/diagramly/OneDriveClient.js

@@ -191,7 +191,8 @@ OneDriveClient.prototype.authenticate = function(success, error, failOnAuth)
 			
 			if (authInfo != null)
 			{
-				var req = new mxXmlRequest(this.redirectUri + '?refresh_token=' + authInfo.refresh_token, null, 'GET');
+				var req = new mxXmlRequest(this.redirectUri + '?refresh_token=' + authInfo.refresh_token +
+						'&state=' + encodeURIComponent('cId=' + this.clientId + '&domain=' + window.location.hostname), null, 'GET'); //To identify which app/domain is used
 				
 				req.send(mxUtils.bind(this, function(req)
 				{
@@ -233,7 +234,8 @@ OneDriveClient.prototype.authenticate = function(success, error, failOnAuth)
 					var url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' +
 						'?client_id=' + this.clientId + '&response_type=code' +
 						'&redirect_uri=' + encodeURIComponent(this.redirectUri) +
-						'&scope=' + encodeURIComponent(this.scopes);
+						'&scope=' + encodeURIComponent(this.scopes) +
+						'&state=' + encodeURIComponent('cId=' + this.clientId + '&domain=' + window.location.hostname); //To identify which app/domain is used
 	
 					var width = 525,
 						height = 525,

+ 4 - 1
src/main/webapp/js/diagramly/Trees.js

@@ -1130,8 +1130,11 @@
 		{
 			vertexHandlerInit.apply(this, arguments);
 			
+			var parent = this.graph.model.getParent(this.state.cell);
+			var pstate = this.graph.view.getState(parent);
+			
 			if ((isTreeMoving(this.state.cell) || isTreeVertex(this.state.cell)) &&
-				!this.state.style['childLayout'] == 'flowLayout' &&
+				(pstate == null || pstate.style['childLayout'] != 'flowLayout') &&
 				this.graph.getOutgoingEdges(this.state.cell).length > 0)
 			{
 				this.moveHandle = mxUtils.createImage(moveImage);

+ 10 - 2
src/main/webapp/js/mxgraph/EditorUi.js

@@ -359,11 +359,19 @@ EditorUi = function(editor, container, lightbox)
 			}
 		};
 		
+		// Updates toolbar and handles possible errors
 		var cellEditorStopEditing = graph.cellEditor.stopEditing;
 		graph.cellEditor.stopEditing = function(cell, trigger)
 		{
-			cellEditorStopEditing.apply(this, arguments);
-			updateToolbar();
+			try
+			{
+				cellEditorStopEditing.apply(this, arguments);
+				updateToolbar();
+			}
+			catch (e)
+			{
+				ui.handleError(e);
+			}
 		};
 		
 	    // Enables scrollbars and sets cursor style for the container

+ 8 - 0
src/main/webapp/js/mxgraph/Format.js

@@ -2224,7 +2224,15 @@ ArrangePanel.prototype.addGeometryHandler = function(input, fn)
 								geo = geo.clone();
 								fn(geo, value);
 								
+								var state = graph.view.getState(cells[i]);
+								
+								if (state != null && graph.isRecursiveVertexResize(state))
+								{
+									graph.resizeChildCells(cells[i], geo);
+								}
+								
 								graph.getModel().setGeometry(cells[i], geo);
+								graph.constrainChildCells(cells[i]);
 							}
 						}
 					}

+ 11 - 4
src/main/webapp/js/mxgraph/Graph.js

@@ -1469,6 +1469,15 @@ Graph.prototype.init = function(container)
 		return null;
 	};
 
+	/**
+	 * Returns if the child cells of the given vertex cell state should be resized.
+	 */
+	Graph.prototype.isRecursiveVertexResize = function(state)
+	{
+		return !this.isSwimlane(state.cell) && this.model.getChildCount(state.cell) > 0 &&
+			!this.isCellCollapsed(state.cell) && mxUtils.getValue(state.style, 'recursiveResize', '1') == '1' &&
+			mxUtils.getValue(state.style, 'childLayout', null) == null;
+	}
 
 	/**
 	 * Function: repaint
@@ -8196,10 +8205,8 @@ if (typeof mxVertexHandler != 'undefined')
 		 */
 		mxVertexHandler.prototype.isRecursiveResize = function(state, me)
 		{
-			return !this.graph.isSwimlane(state.cell) && this.graph.model.getChildCount(state.cell) > 0 &&
-				!mxEvent.isControlDown(me.getEvent()) && !this.graph.isCellCollapsed(state.cell) &&
-				mxUtils.getValue(state.style, 'recursiveResize', '1') == '1' &&
-				mxUtils.getValue(state.style, 'childLayout', null) == null;
+			return this.graph.isRecursiveVertexResize(state) &&
+				!mxEvent.isControlDown(me.getEvent());
 		};
 		
 		/**

+ 11 - 11
src/main/webapp/js/mxgraph/Sidebar.js

@@ -1293,7 +1293,7 @@ Sidebar.prototype.addUmlPalette = function(expand)
 			80, 26, 'Title', 'Title', null, null, dt + 'title label'),
 		this.addEntry(dt + 'component', function()
 		{
-		    var cell = new mxCell('&laquo;Annotation&raquo;<br/><b>Component</b>', new mxGeometry(0, 0, 180, 90), 'html=1;');
+		    var cell = new mxCell('&laquo;Annotation&raquo;<br/><b>Component</b>', new mxGeometry(0, 0, 180, 90), 'html=1;dropTarget=0;');
 		    cell.vertex = true;
 		    
 			var symbol = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=component;jettyWidth=8;jettyHeight=4;');
@@ -1308,7 +1308,7 @@ Sidebar.prototype.addUmlPalette = function(expand)
 		{
 		    var cell = new mxCell('<p style="margin:0px;margin-top:6px;text-align:center;"><b>Component</b></p>' +
 				'<hr/><p style="margin:0px;margin-left:8px;">+ Attribute1: Type<br/>+ Attribute2: Type</p>', new mxGeometry(0, 0, 180, 90),
-				'align=left;overflow=fill;html=1;');
+				'align=left;overflow=fill;html=1;dropTarget=0;');
 		    cell.vertex = true;
 		    
 			var symbol = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=component;jettyWidth=8;jettyHeight=4;');
@@ -1423,7 +1423,7 @@ Sidebar.prototype.addUmlPalette = function(expand)
 		this.addEntry('uml activity composite state', function()
 		{
 			var cell = new mxCell('Composite State', new mxGeometry(0, 0, 160, 60),
-					'swimlane;html=1;fontStyle=1;align=center;verticalAlign=middle;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=0;resizeLast=1;container=0;fontColor=#000000;collapsible=0;rounded=1;arcSize=30;strokeColor=#ff0000;fillColor=#ffffc0;swimlaneFillColor=#ffffc0;');
+					'swimlane;html=1;fontStyle=1;align=center;verticalAlign=middle;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=0;resizeLast=1;container=0;fontColor=#000000;collapsible=0;rounded=1;arcSize=30;strokeColor=#ff0000;fillColor=#ffffc0;swimlaneFillColor=#ffffc0;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('Subtitle', new mxGeometry(0, 0, 200, 26), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;whiteSpace=wrap;overflow=hidden;rotatable=0;fontColor=#000000;');
@@ -1674,7 +1674,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 	 	this.createVertexTemplateEntry('shape=ext;rounded=1;html=1;whiteSpace=wrap;strokeWidth=3;', 120, 80, 'Call Activity', 'Call Activity', null, null, 'bpmn call activity'),
 		this.addEntry('bpmn subprocess sub process sub-process', function()
 		{
-			var cell = new mxCell('Sub-Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;');
+			var cell = new mxCell('Sub-Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0.5, 1, 14, 14), 'html=1;shape=plus;outlineConnect=0;');
@@ -1687,7 +1687,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry(this.getTagsForStencil('mxgraph.bpmn', 'loop', 'subprocess sub process sub-process looped').join(' '), function()
 		{
-			var cell = new mxCell('Looped\nSub-Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1');
+			var cell = new mxCell('Looped\nSub-Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0.5, 1, 14, 14), 'html=1;shape=mxgraph.bpmn.loop;outlineConnect=0;');
@@ -1706,7 +1706,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry('bpmn receive task', function()
 		{
-			var cell = new mxCell('Receive', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;');
+			var cell = new mxCell('Receive', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0, 0, 20, 14), 'html=1;shape=message;outlineConnect=0;');
@@ -1719,7 +1719,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry(this.getTagsForStencil('mxgraph.bpmn', 'user_task').join(' '), function()
 		{
-			var cell = new mxCell('User', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;');
+			var cell = new mxCell('User', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0, 0, 14, 14), 'html=1;shape=mxgraph.bpmn.user_task;outlineConnect=0;');
@@ -1738,7 +1738,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry(this.getTagsForStencil('mxgraph.bpmn', 'timer_start', 'attached').join(' '), function()
 		{
-			var cell = new mxCell('Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;');
+			var cell = new mxCell('Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 
 			var cell1 = new mxCell('', new mxGeometry(1, 1, 30, 30), 'shape=mxgraph.bpmn.timer_start;perimeter=ellipsePerimeter;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;outlineConnect=0;');
@@ -1751,7 +1751,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry(this.getTagsForStencil('mxgraph.bpmn', 'timer_start', 'attached').join(' '), function()
 		{
-			var cell = new mxCell('Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;');
+			var cell = new mxCell('Process', new mxGeometry(0, 0, 120, 80), 'html=1;whiteSpace=wrap;rounded=1;dropTarget=0;');
 			cell.vertex = true;
 
 			var cell1 = new mxCell('', new mxGeometry(1, 0, 30, 30), 'shape=mxgraph.bpmn.timer_start;perimeter=ellipsePerimeter;html=1;labelPosition=right;labelBackgroundColor=#ffffff;align=left;outlineConnect=0;');
@@ -1768,7 +1768,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 	 	this.createVertexTemplateEntry('shape=hexagon;html=1;whiteSpace=wrap;perimeter=hexagonPerimeter;strokeWidth=4;rounded=0;', 60, 50, '', 'Call Conversation', null, null, 'bpmn call conversation'),
 		this.addEntry('bpmn subconversation sub conversation sub-conversation', function()
 		{
-			var cell = new mxCell('', new mxGeometry(0, 0, 60, 50), 'shape=hexagon;whiteSpace=wrap;html=1;perimeter=hexagonPerimeter;rounded=0;');
+			var cell = new mxCell('', new mxGeometry(0, 0, 60, 50), 'shape=hexagon;whiteSpace=wrap;html=1;perimeter=hexagonPerimeter;rounded=0;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0.5, 1, 14, 14), 'html=1;shape=plus;');
@@ -1781,7 +1781,7 @@ Sidebar.prototype.addBpmnPalette = function(dir, expand)
 		}),
 		this.addEntry('bpmn data object', function()
 		{
-			var cell = new mxCell('', new mxGeometry(0, 0, 40, 60), 'shape=note;whiteSpace=wrap;size=16;html=1;');
+			var cell = new mxCell('', new mxGeometry(0, 0, 40, 60), 'shape=note;whiteSpace=wrap;size=16;html=1;dropTarget=0;');
 			cell.vertex = true;
 			
 			var cell1 = new mxCell('', new mxGeometry(0, 0, 14, 14), 'html=1;shape=singleArrow;arrowWidth=0.4;arrowSize=0.4;outlineConnect=0;');

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


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

@@ -583,7 +583,7 @@ Draw.loadPlugin(function(ui)
 	{
 		if (confComments == null)
 		{
-			ui.remoteInvoke('getComments', [macroData.contentId], null, function(comments)
+			ui.remoteInvoke('getComments', [macroData.contentId || macroData.custContentId], null, function(comments)
 			{
 				confComments = [];
 				

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

@@ -6,7 +6,7 @@ if (workbox)
 	workbox.precaching.precacheAndRoute([
   {
     "url": "js/app.min.js",
-    "revision": "1b67010895bdee0fc8fd06172e36a631"
+    "revision": "16a81eaa17338dd133d83b45c76227b1"
   },
   {
     "url": "js/extensions.min.js",