浏览代码

8.0.7 release

Former-commit-id: 59d9f0cdaab8dd83fcd7dfb22f7d92284e082f52
Gaudenz Alder 7 年之前
父节点
当前提交
eff65ddc07

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+06-FEB-2018: 8.0.7
+
+- Adds recent/search in Confluence connect
+- Fixes various bugs
+
 02-FEB-2018: 8.0.6
 
 - Fixes Ctrl+connect of orthogonal edges

+ 1 - 1
VERSION

@@ -1 +1 @@
-8.0.6
+8.0.7

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

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 02/02/2018 10:10 PM
+# 02/06/2018 06:05 PM
 
 app.html
 index.html?offline=1

+ 251 - 37
src/main/webapp/connect/confluence/ac.js

@@ -468,7 +468,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 			}
 			else
 			{
-				editor.contentWindow.postMessage(JSON.stringify({action: 'template'}), '*');
+				editor.contentWindow.postMessage(JSON.stringify({action: 'template', enableRecent: true, enableSearch: true}), '*');
 			}
 		};
 		
@@ -628,55 +628,269 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							AC.removeAttachment(pageId, draftName);
 						}
 					}	
+				}
+				else if (drawMsg.event == 'searchDocs')
+				{
+					//since we don't use a unique file extension for draw.io diagrams, we need to find pages having draw.io macro also
+					//So, two search requests are needed
+					AP.require('request', function(request) {
+						request({
+							//TODO this query can be enhanced to get part of the name matching but the problem is with the png!
+							url: '/rest/api/content/search?cql=' + encodeURIComponent('type=attachment and (title ~ "' + drawMsg.searchStr + '" or title ~ "' + drawMsg.searchStr + '.png")') + '&limit=100', //limit is 100 and the pages limit is 50 since each diagram has two attachments (and we assume one diagram per page) 
+							success: function(resp) 
+							{
+								resp = JSON.parse(resp);
+								var retList = [];
+								var list = resp.results; 
+								if (list)
+								{
+									var attMap = {};
+									//convert the list to map so we can search by name effeciently
+									for (var i = 0; i < list.length; i++)
+									{
+										//key is pageId + | + att name
+										var pageId = list[i]["_links"]["webui"].match(/pages\/(\d+)/);
+										
+										if (pageId != null)
+										{
+											attMap[pageId[1] + '|' + list[i].title] = {att: list[i], pageId: pageId[1]};
+										}
+									}
+
+									//TODO confirm that the attachments are in a page having draw.io macro
+									for (var key in attMap) 
+									{
+										var att = attMap[key];
+										
+										if (attMap[key+'.png']) //each draw.io attachment should have an associated png preview
+										{
+											//We cannot get the latest version info, it can searched when a diagram is selected
+											retList.push({
+												title: att.att.title,
+												url: "/download/attachments/" + att.pageId + "/"
+													+ encodeURIComponent(att.att.title),
+												info: {
+													id: att.att.id, 
+													pageId: att.pageId 
+												},
+												imgUrl: baseUrl + "/download/attachments/" + att.pageId + "/"
+													+ encodeURIComponent(att.att.title)
+													+ ".png?api=v2"
+											});
+										}
+									}
+									editor.contentWindow.postMessage(JSON.stringify({action: 'searchDocsList',
+										list: retList}), '*');
+								}
+							},
+							error : function(resp) 
+							{
+								editor.contentWindow.postMessage(JSON.stringify({action: 'searchDocsList',
+									list: [], errorMsg: "Network Error!"}), '*');
+							}
+						});
+					});
+
+				}
+				else if (drawMsg.event == 'recentDocs')
+				{
+					//since we don't use a unique file extension for draw.io diagrams, we need to find pages having draw.io macro also
+					//So, two search requests are needed
+					AP.require('request', function(request) {
+						request({
+							url: '/rest/api/content/search?cql=type=attachment%20and%20lastmodified%3E%20startOfDay(%22-7d%22)&limit=100', //cql= type=attachment and lastmodified > startOfDay("-7d") //modified in the last 7 days
+																																		   //limit is 100 and the pages limit is 50 since each diagram has two attachments (and we assume one diagram per page) 
+							success: function(resp) 
+							{
+								resp = JSON.parse(resp);
+								var retList = [];
+								var list = resp.results; 
+								if (list)
+								{
+									var attMap = {};
+									//convert the list to map so we can search by name effeciently
+									for (var i = 0; i < list.length; i++)
+									{
+										//key is pageId + | + att name
+										var pageId = list[i]["_links"]["webui"].match(/pages\/(\d+)/);
+										
+										if (pageId != null)
+										{
+											attMap[pageId[1] + '|' + list[i].title] = {att: list[i], pageId: pageId[1]};
+										}
+									}
+
+									//confirm that the attachments are in a page having draw.io macro
+									request({
+										url: '/rest/api/content/search?cql=macro=drawio%20and%20lastmodified%3E%20startOfDay(%22-7d%22)&limit=50', //cql= macro=drawio and lastmodified > startOfDay("-7d") //modified in the last 7 days
+										success: function(resp) 
+										{
+											resp = JSON.parse(resp);
+											var pages = {};
+											var list = resp.results; 
+											if (list)
+											{
+												for (var i = 0; i < list.length; i++)
+												{
+													pages[list[i].id] = list[i];
+												}
+											}
+											
+											
+											for (var key in attMap) 
+											{
+												var att = attMap[key];
+												
+												if (attMap[key+'.png'] && pages[att.pageId] != null) //each draw.io attachment should have an associated png preview
+												{
+													//We cannot get the latest version info, it can searched when a diagram is selected
+													retList.push({
+														title: att.att.title,
+														url: "/download/attachments/" + att.pageId + "/"
+															+ encodeURIComponent(att.att.title),
+														info: {
+															id: att.att.id, 
+															pageId: att.pageId
+														},
+														imgUrl: baseUrl + "/download/attachments/" + att.pageId + "/"
+														+ encodeURIComponent(att.att.title)
+														+ ".png?api=v2"
+													});
+												}
+											}
+											editor.contentWindow.postMessage(JSON.stringify({action: 'recentDocsList',
+												list: retList}), '*');
+										},
+										error : function(resp) 
+										{
+											editor.contentWindow.postMessage(JSON.stringify({action: 'recentDocsList',
+												list: [], errorMsg: "Network Error!"}), '*');
+										}
+									});
+								}
+							},
+							error : function(resp) 
+							{
+								editor.contentWindow.postMessage(JSON.stringify({action: 'recentDocsList',
+									list: [], errorMsg: "Network Error!"}), '*');
+							}
+						});
+					});
+
+					
 				}
 				else if (drawMsg.event == 'template')
 				{
 					editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
 						show: true, messageKey: 'inserting'}), '*');
 					
-					checkName(drawMsg.name, function(name)
+					if (drawMsg.docUrl)
 					{
-						editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
-							show: false}), '*');
-						diagramName = name;
-
-						if (AC.draftEnabled)
+						checkName(drawMsg.name, function(name)
 						{
-							draftName = '~drawio~' + user + '~' + diagramName + AC.draftExtension;
-							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
-								show: true, messageKey: 'inserting'}), '*');
+							diagramName = name;
 							
-							saveDraft(drawMsg.xml, function()
+							AP.require('request', function(request) {
+								
+								var loadTemplate = function(version)
+								{
+									request({
+										url: drawMsg.docUrl + (version != null? "?version=" + version : ""),
+										success: function(xml) 
+										{
+											editor.contentWindow.postMessage(JSON.stringify({action: 'load',
+												autosave: 1, xml: xml, title: diagramName}), '*');
+											editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+												show: false}), '*');
+										},
+										error : function(resp) 
+										{
+											editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+												show: false}), '*');
+											editor.contentWindow.postMessage(JSON.stringify({action: 'dialog',
+												titleKey: 'error', message: "Diagram cannot be loaded", messageKey: null,
+												buttonKey: 'ok'}), '*');
+										}
+									});
+								}
+								
+								request({
+									url: '/rest/api/content/' + drawMsg.info.id,
+									success: function(resp) 
+									{
+										resp = JSON.parse(resp);
+										
+										try
+										{
+											loadTemplate(resp.version.number);
+										}
+										catch(e)
+										{
+											loadTemplate();
+										}
+									},
+									error : function(resp) 
+									{
+										loadTemplate();
+									}
+								});
+							});
+						},
+						function(name, err, errKey)
+						{
+							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+								show: false}), '*');
+							editor.contentWindow.postMessage(JSON.stringify({action: 'dialog',
+								titleKey: 'error', message: err, messageKey: errKey,
+								buttonKey: 'ok'}), '*');
+						});
+					}
+					else
+					{
+						checkName(drawMsg.name, function(name)
+						{
+							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+								show: false}), '*');
+							diagramName = name;
+	
+							if (AC.draftEnabled)
+							{
+								draftName = '~drawio~' + user + '~' + diagramName + AC.draftExtension;
+								editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+									show: true, messageKey: 'inserting'}), '*');
+								
+								saveDraft(drawMsg.xml, function()
+								{
+									editor.contentWindow.postMessage(JSON.stringify({action: 'spinner', show: false}), '*');
+									editor.contentWindow.postMessage(JSON.stringify({action: 'load',
+										autosave: 1, xml: drawMsg.xml, title: diagramName}), '*');
+								},
+								function()
+								{
+									editor.parentNode.removeChild(editor);
+									var message = messages.error('Draft Write Error', 'Draft could not be created');
+				    		
+				    				messages.onClose(message, function()
+				    				{
+				    					confluence.closeMacroEditor();
+				    				});
+								});
+							}
+							else
 							{
-								editor.contentWindow.postMessage(JSON.stringify({action: 'spinner', show: false}), '*');
 								editor.contentWindow.postMessage(JSON.stringify({action: 'load',
 									autosave: 1, xml: drawMsg.xml, title: diagramName}), '*');
-							},
-							function()
-							{
-								editor.parentNode.removeChild(editor);
-								var message = messages.error('Draft Write Error', 'Draft could not be created');
-			    		
-			    				messages.onClose(message, function()
-			    				{
-			    					confluence.closeMacroEditor();
-			    				});
-							});
-						}
-						else
+							}
+						},
+						function(name, err, errKey)
 						{
-							editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-								autosave: 1, xml: drawMsg.xml, title: diagramName}), '*');
-						}
-					},
-					function(name, err, errKey)
-					{
-						editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
-							show: false}), '*');
-						editor.contentWindow.postMessage(JSON.stringify({action: 'dialog',
-							titleKey: 'error', message: err, messageKey: errKey,
-							buttonKey: 'ok'}), '*');
-					});
+							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+								show: false}), '*');
+							editor.contentWindow.postMessage(JSON.stringify({action: 'dialog',
+								titleKey: 'error', message: err, messageKey: errKey,
+								buttonKey: 'ok'}), '*');
+						});
+					}
 				}
 				else if (drawMsg.event == 'autosave')
 				{

+ 12 - 9
src/main/webapp/index.html

@@ -208,7 +208,7 @@
 		}
 		#geFooterItem1:hover {
 			background-color: #b0b0b0;
-		}		
+		}
 		.geFooterContainer>div>img {
 			opacity:0.5;
 			background:#e5e5e5;
@@ -243,9 +243,9 @@
 		/**
 		 * Synchronously adds scripts to the page.
 		 */
-		function mxscript(src, onLoad, id, dataAppKey)
+		function mxscript(src, onLoad, id, dataAppKey, noWrite)
 		{
-			if (onLoad != null)
+			if (onLoad != null || noWrite)
 			{
 				var s = document.createElement('script');
 				s.setAttribute('type', 'text/javascript');
@@ -262,14 +262,17 @@
 					s.setAttribute('data-app-key', dataAppKey);
 				}
 				
-				s.onload = s.onreadystatechange = function()
+				if (onLoad != null)
 				{
-					if (!r && (!this.readyState || this.readyState == 'complete'))
+					s.onload = s.onreadystatechange = function()
 					{
-			      		r = true;
-			      		onLoad();
-					}
-			  	};
+						if (!r && (!this.readyState || this.readyState == 'complete'))
+						{
+				      		r = true;
+				      		onLoad();
+						}
+				  	};
+				}
 			  	
 			  	var t = document.getElementsByTagName('script')[0];
 			  	t.parentNode.insertBefore(s, t);

文件差异内容过多而无法显示
+ 616 - 611
src/main/webapp/js/app.min.js


文件差异内容过多而无法显示
+ 596 - 595
src/main/webapp/js/atlas-viewer.min.js


文件差异内容过多而无法显示
+ 682 - 677
src/main/webapp/js/atlas.min.js


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

@@ -291,7 +291,7 @@ App.getStoredMode = function()
 							window.location.hash == '') || (window.location.hash != null &&
 							window.location.hash.substring(0, 2) == '#G'))
 						{
-							mxscript('https://apis.google.com/js/api.js');
+							mxscript('https://apis.google.com/js/api.js', null, null, null, mxClient.IS_SVG);
 						}
 						// Keeps lazy loading for fallback to authenticated Google file if not public in loadFile
 						else if (urlParams['chrome'] == '0' && (window.location.hash == null ||
@@ -494,7 +494,7 @@ App.main = function(callback, createUi)
 			}
 			else if (urlParams['chrome'] != '0' && !EditorUi.isElectronApp)
 			{
-				mxscript(App.FOOTER_PLUGIN_URL);
+				mxscript(App.FOOTER_PLUGIN_URL, null, null, null, mxClient.IS_SVG);
 			}
 			
 			if (plugins != null && plugins.length > 0 && urlParams['plugins'] != '0')
@@ -537,7 +537,7 @@ App.main = function(callback, createUi)
 			(urlParams['embed'] == '1' && urlParams['gapi'] == '1')) && isSvgBrowser &&
 			isLocalStorage && (document.documentMode == null || document.documentMode >= 10))))
 		{
-			mxscript('https://apis.google.com/js/api.js?onload=DrawGapiClientCallback');
+			mxscript('https://apis.google.com/js/api.js?onload=DrawGapiClientCallback', null, null, null, mxClient.IS_SVG);
 		}
 		// Disables client
 		else if (typeof window.gapi === 'undefined')

+ 247 - 59
src/main/webapp/js/diagramly/Dialogs.js

@@ -2629,7 +2629,7 @@ var ParseDialog = function(editorUi, title)
 /**
  * Constructs a new dialog for creating files from templates.
  */
-var NewDialog = function(editorUi, compact, showName, callback, createOnly, cancelCallback, leftHighlight, rightHighlight, rightHighlightBorder, itemPadding, templateFile)
+var NewDialog = function(editorUi, compact, showName, callback, createOnly, cancelCallback, leftHighlight, rightHighlight, rightHighlightBorder, itemPadding, templateFile, recentDocsCallback, searchDocsCallback, openExtDocCallback)
 {
 	showName = (showName != null) ? showName : true;
 	createOnly = (createOnly != null) ? createOnly : false;
@@ -2638,13 +2638,18 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 	rightHighlightBorder = (rightHighlightBorder != null) ? rightHighlightBorder : '1px solid #ccd9ea';
 	templateFile = (templateFile != null) ? templateFile : TEMPLATE_PATH + '/index.xml';
 	
+	
 	var outer = document.createElement('div');
 	outer.style.height = '100%';
 	
 	var header = document.createElement('div');
 	header.style.whiteSpace = 'nowrap';
 	header.style.height = '46px';
-	outer.appendChild(header);
+	
+	if (showName)
+	{
+		outer.appendChild(header);
+	}
 	
 	var logo = document.createElement('img');
 	logo.setAttribute('border', '0');
@@ -2745,13 +2750,197 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 		header.appendChild(nameInput);
 	}
 
+	var hasTabs = false;
+	
+	var i0 = 0;
+	
+	// Dynamic loading
+	function addTemplates()
+	{
+		var first = true;
+		
+		//TODO support paging of external templates
+		while (i0 < templates.length && (first || mxUtils.mod(i0, 30) != 0))
+		{
+			var tmp = templates[i0++];
+			addButton(tmp.url, tmp.libs, tmp.title, tmp.tooltip? tmp.tooltip : tmp.title, tmp.select, tmp.imgUrl, tmp.info);
+			first = false;
+		}
+	};
+
+	var createButton = mxUtils.button(mxResources.get('create'), function()
+	{
+		create();
+	});
+	
+	createButton.className = 'geBtn gePrimaryBtn';
+
+	if (recentDocsCallback || searchDocsCallback)
+	{
+		
+		var tabsEl = [];
+		var oldTemplates = null;
+		
+		var setActiveTab = function(index)
+		{
+			createButton.setAttribute('disabled', 'disabled');
+			
+			for (var i = 0; i < tabsEl.length; i++)
+			{
+				if (i == index)
+					tabsEl[i].className = 'geBtn gePrimaryBtn';
+				else
+					tabsEl[i].className = 'geBtn';
+			}
+		}
+		
+		hasTabs = true;
+		var tabs = document.createElement('div');
+		tabs.style.whiteSpace = 'nowrap';
+		tabs.style.height = '30px';
+		outer.appendChild(tabs);
+		
+		var templatesTab = mxUtils.button(mxResources.get('Templates', null, 'Templates'), function()
+		{
+			list.style.display = '';
+			div.style.left = '160px';
+			setActiveTab(0);
+
+			div.scrollTop = 0;
+			div.innerHTML = '';
+			i0 = 0;
+			
+			if (oldTemplates != templates)
+			{
+				templates = oldTemplates;
+				addTemplates();	
+				oldTemplates = null;
+			}
+		});
+		
+		tabsEl.push(templatesTab);
+		tabs.appendChild(templatesTab);
+		
+		var getExtTemplates = function(isSearch)
+		{
+			list.style.display = 'none';
+			div.style.left = '30px';
+			
+			setActiveTab(isSearch? -1 : 1); //deselect all of them if isSearch 
+			
+			if (oldTemplates == null) 
+			{
+				oldTemplates = templates;
+			}
+			
+			div.scrollTop = 0;
+			div.innerHTML = '';
+			
+			var spinner = new Spinner({
+				lines: 12, // The number of lines to draw
+				length: 10, // The length of each line
+				width: 5, // The line thickness
+				radius: 10, // The radius of the inner circle
+				rotate: 0, // The rotation offset
+				color: '#000', // #rgb or #rrggbb
+				speed: 1.5, // Rounds per second
+				trail: 60, // Afterglow percentage
+				shadow: false, // Whether to render a shadow
+				hwaccel: false, // Whether to use hardware acceleration
+				top: '40%',
+				zIndex: 2e9 // The z-index (defaults to 2000000000)
+			});
+			spinner.spin(div);
+			
+			i0 = 0;
+
+			var callback = function(list, errorMsg) 
+			{
+				spinner.stop();
+				
+				templates = list;
+				
+				if (errorMsg)
+				{
+					div.innerHTML = errorMsg;
+				}
+				else if (list.length == 0)
+				{
+					div.innerHTML = mxResources.get('noDiagrams', null, 'No Diagrams Found');
+				}
+				else
+				{
+					div.innerHTML = '';
+					addTemplates();
+				}
+			}
+			
+			if (isSearch)
+				searchDocsCallback(searchInput.value, callback);
+			else
+				recentDocsCallback(callback);
+		}
+		
+		if (recentDocsCallback)
+		{
+			var recentTab = mxUtils.button(mxResources.get('Recent', null, 'Recent'), function()
+			{
+				getExtTemplates();
+			});
+
+			tabs.appendChild(recentTab);
+			tabsEl.push(recentTab);
+		}
+		
+		if (searchDocsCallback)
+		{
+			var searchTab = document.createElement('span');
+			searchTab.style.marginLeft = '10px';
+			searchTab.innerHTML = mxResources.get('search') + ":";
+			tabs.appendChild(searchTab);
+
+			var searchInput = document.createElement('input');
+			searchInput.style.marginRight = '10px';
+			searchInput.style.marginLeft = '10px';
+			searchInput.style.width = '220px';
+
+			mxEvent.addListener(searchInput, 'keypress', function(e)
+			{
+				if (e.keyCode == 13)
+				{
+					getExtTemplates(true);
+				}
+			});
+
+			tabs.appendChild(searchInput);
+
+			var searchBtn = mxUtils.button(mxResources.get('search'), function()
+			{
+				getExtTemplates(true);
+			});
+					
+			searchBtn.className = 'geBtn';
+
+			tabs.appendChild(searchBtn);
+		}
+		
+		setActiveTab(0);
+	}
+	
 	var templateLibs = null;
 	var templateXml = null;
 	var selectedElt = null;
+	var templateExtUrl = null;
+	var templateInfoObj = null;
 	
 	function create()
 	{
-		if (callback)
+		if (templateExtUrl)
+		{
+			editorUi.hideDialog();
+			openExtDocCallback(templateExtUrl, templateInfoObj, nameInput.value);
+		}
+		else if (callback)
 		{
 			if (!showName)
 			{
@@ -2782,36 +2971,26 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 		}
 	};
 	
-	var createButton = mxUtils.button(mxResources.get('create'), function()
-	{
-		create();
-	});
-	
-	createButton.className = 'geBtn gePrimaryBtn';
-
 	var div = document.createElement('div');
 	div.style.border = '1px solid #d3d3d3';
 	div.style.position = 'absolute';
 	div.style.left = '160px';
 	div.style.right = '34px';
-	div.style.top = (showName) ? '72px' : '40px';
+	var divTop = (showName) ? 72 : 40;
+	divTop += hasTabs? 30 : 0;
+	div.style.top = divTop + 'px';
 	div.style.bottom = '68px';
 	div.style.margin = '6px 0 0 -1px';
 	div.style.padding = '6px';
 	div.style.overflow = 'auto';
 	
 	var list = document.createElement('div');
-	list.style.cssText = 'position:absolute;left:30px;width:128px;top:72px;bottom:68px;margin-top:6px;overflow:auto;border:1px solid #d3d3d3;';
-	
-	if (!showName)
-	{
-		list.style.top = '40px';
-	}
+	list.style.cssText = 'position:absolute;left:30px;width:128px;top:' + divTop + 'px;bottom:68px;margin-top:6px;overflow:auto;border:1px solid #d3d3d3;';
 	
 	var w = 140;
 	var h = 140;
 
-	function selectElement(elt, xml, libs)
+	function selectElement(elt, xml, libs, extUrl, infoObj)
 	{
 		if (selectedElt != null)
 		{
@@ -2819,15 +2998,19 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 			selectedElt.style.border = '1px solid transparent';
 		}
 		
+		createButton.removeAttribute('disabled');
+		
 		templateXml = xml;
 		templateLibs = libs;
 		selectedElt = elt;
+		templateExtUrl = extUrl;
+		templateInfoObj = infoObj;
 		
 		selectedElt.style.backgroundColor = rightHighlight;
 		selectedElt.style.border = rightHighlightBorder;
 	};
 
-	function addButton(url, libs, title, tooltip, select)
+	function addButton(url, libs, title, tooltip, select, imgUrl, infoObj)
 	{
 		var elt = document.createElement('div');
 		elt.className = 'geTemplate';
@@ -2839,7 +3022,25 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 			elt.setAttribute('title', tooltip);
 		}
 		
-		if (url != null && url.length > 0)
+		if (imgUrl != null)
+		{
+			elt.style.backgroundImage = 'url(' + imgUrl + ')';
+			elt.style.backgroundSize = 'contain';
+			elt.style.backgroundPosition = 'center center';
+			elt.style.backgroundRepeat = 'no-repeat';
+			
+			mxEvent.addListener(elt, 'click', function(evt)
+			{
+				selectElement(elt, null, null, url, infoObj);
+			});
+			
+			mxEvent.addListener(elt, 'dblclick', function(evt)
+			{
+				create();
+			});
+
+		}
+		else if (url != null && url.length > 0)
 		{
 			var png = url.substring(0, url.length - 4) + '.png';
 			
@@ -2859,7 +3060,6 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 				{
 					if (req.getStatus() >= 200 && req.getStatus() <= 299)
 					{
-						createButton.removeAttribute('disabled');
 						selectElement(elt, req.getText(), libs);
 						
 						if (createIt)
@@ -2905,25 +3105,11 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 	
 	// Adds local basic templates
 	categories['basic'] = [{title: 'blankDiagram', select: true}];
+	
 	var templates = categories['basic'];
 	
 	function initUi()
 	{
-		var i0 = 0;
-		
-		// Dynamic loading
-		function addTemplates()
-		{
-			var first = true;
-			
-			while (i0 < templates.length && (first || mxUtils.mod(i0, 30) != 0))
-			{
-				var tmp = templates[i0++];
-				addButton(tmp.url, tmp.libs, tmp.title, tmp.tooltip, tmp.select);
-				first = false;
-			}
-		};
-
 		mxEvent.addListener(div, 'scroll', function(evt)
 		{
 			if (div.scrollTop + div.clientHeight >= div.scrollHeight)
@@ -2980,8 +3166,10 @@ var NewDialog = function(editorUi, compact, showName, callback, createOnly, canc
 						div.scrollTop = 0;
 						div.innerHTML = '';
 						i0 = 0;
+						
 						templates = categories[cat2];
-						addTemplates();
+						oldTemplates = null;
+						addTemplates();	
 					}
 				});
 			})(cat, entry);
@@ -3131,7 +3319,7 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
 {
 	overrideExtension = (overrideExtension != null) ? overrideExtension : true;
 	allowBrowser = (allowBrowser != null) ? allowBrowser : true;
-	rowLimit = (rowLimit != null) ? rowLimit : 3;
+	rowLimit = (rowLimit != null) ? rowLimit : 4;
 	var div = document.createElement('div');
 	var showButtons = true;
 	
@@ -3347,15 +3535,20 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
 			
 			addLogo(IMAGE_PATH + '/google-drive-logo.svg', mxResources.get('googleDrive'), App.MODE_GOOGLE, 'drive');
 		}
-	
-		if (editorUi.gitHub != null)
+		
+		if (typeof window.OneDriveClient === 'function')
 		{
-			var gitHubOption = document.createElement('option');
-			gitHubOption.setAttribute('value', App.MODE_GITHUB);
-			mxUtils.write(gitHubOption, mxResources.get('github'));
-			serviceSelect.appendChild(gitHubOption);
+			var oneDriveOption = document.createElement('option');
+			oneDriveOption.setAttribute('value', App.MODE_ONEDRIVE);
+			mxUtils.write(oneDriveOption, mxResources.get('oneDrive'));
+			serviceSelect.appendChild(oneDriveOption);
 			
-			addLogo(IMAGE_PATH + '/github-logo.svg', mxResources.get('github'), App.MODE_GITHUB, 'gitHub');
+			if (editorUi.mode == App.MODE_ONEDRIVE)
+			{
+				oneDriveOption.setAttribute('selected', 'selected');
+			}
+			
+			addLogo(IMAGE_PATH + '/onedrive-logo.svg', mxResources.get('oneDrive'), App.MODE_ONEDRIVE, 'oneDrive');
 		}
 
 		if (typeof window.DropboxClient === 'function')
@@ -3372,22 +3565,17 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
 			
 			addLogo(IMAGE_PATH + '/dropbox-logo.svg', mxResources.get('dropbox'), App.MODE_DROPBOX, 'dropbox');
 		}
-	
-		if (typeof window.OneDriveClient === 'function')
+
+		if (editorUi.gitHub != null)
 		{
-			var oneDriveOption = document.createElement('option');
-			oneDriveOption.setAttribute('value', App.MODE_ONEDRIVE);
-			mxUtils.write(oneDriveOption, mxResources.get('oneDrive'));
-			serviceSelect.appendChild(oneDriveOption);
-			
-			if (editorUi.mode == App.MODE_ONEDRIVE)
-			{
-				oneDriveOption.setAttribute('selected', 'selected');
-			}
+			var gitHubOption = document.createElement('option');
+			gitHubOption.setAttribute('value', App.MODE_GITHUB);
+			mxUtils.write(gitHubOption, mxResources.get('github'));
+			serviceSelect.appendChild(gitHubOption);
 			
-			addLogo(IMAGE_PATH + '/onedrive-logo.svg', mxResources.get('oneDrive'), App.MODE_ONEDRIVE, 'oneDrive');
+			addLogo(IMAGE_PATH + '/github-logo.svg', mxResources.get('github'), App.MODE_GITHUB, 'gitHub');
 		}
-		
+
 		if (editorUi.trello != null)
 		{
 			var trelloOption = document.createElement('option');
@@ -3482,7 +3670,7 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
 
 	var btns = document.createElement('div');
 	btns.style.marginTop = (showButtons) ? '26px' : '38px';
-	btns.style.textAlign = (showButtons) ? 'center' : 'right';
+	btns.style.textAlign = 'right';
 	
 	if (!showButtons)
 	{

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

@@ -103,7 +103,7 @@ DrawioFile.prototype.save = function(revision, success, error, unloading)
  */
 DrawioFile.prototype.updateFileData = function()
 {
-	this.setData(this.ui.getFileData());
+	this.setData(this.ui.getFileData(null, null, null, null, null, null, null, null, this));
 };
 
 /**

+ 31 - 3
src/main/webapp/js/diagramly/EditorUi.js

@@ -769,14 +769,14 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.getFileData = function(forceXml, forceSvg, forceHtml, embeddedCallback, ignoreSelection, currentPage, node, compact)
+	EditorUi.prototype.getFileData = function(forceXml, forceSvg, forceHtml, embeddedCallback, ignoreSelection, currentPage, node, compact, file)
 	{
 		ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;
 		currentPage = (currentPage != null) ? currentPage : false;
 		
 		node = (node != null) ? node : this.getXmlFileData(ignoreSelection, currentPage);
+		file = (file != null) ? file : this.getCurrentFile();
 		var graph = this.editor.graph;
-		var file = this.getCurrentFile();
 		
 		// Exports SVG 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
@@ -8482,6 +8482,9 @@
 				{
 					this.spinner.stop();
 					
+					var enableRecentDocs = data.enableRecent == 1;
+					var enableSearchDocs = data.enableSearch == 1;
+					
 					var dlg = new NewDialog(this, false, data.callback != null, mxUtils.bind(this, function(xml, name)
 					{
 						xml = xml || this.emptyDiagramXml;
@@ -8502,7 +8505,24 @@
 								this.editor.setStatus('');
 							}
 						}
-					}));
+					}), null, null, null, null, null, null, null, 
+					enableRecentDocs? mxUtils.bind(this, function(recentReadyCallback) 
+					{
+						this.recentReadyCallback = recentReadyCallback;
+						
+						parent.postMessage(JSON.stringify({event: 'recentDocs'}), '*');
+					}) : null, 
+					enableSearchDocs?  mxUtils.bind(this, function(searchStr, searchReadyCallback) 
+					{
+						this.searchReadyCallback = searchReadyCallback;
+						
+						parent.postMessage(JSON.stringify({event: 'searchDocs', searchStr: searchStr}), '*');
+					}) : null, 
+					function(url, info, name) 
+					{
+						parent.postMessage(JSON.stringify({event: 'template', docUrl: url, info: info,
+							name: name}), '*');
+					});
 
 					this.showDialog(dlg.container, 620, 440, true, false, mxUtils.bind(this, function(cancel)
 					{
@@ -8515,6 +8535,14 @@
 					
 					return;
 				}
+				else if (data.action == 'searchDocsList')
+				{
+					this.searchReadyCallback(data.list, data.errorMsg);
+				}
+				else if (data.action == 'recentDocsList')
+				{
+					this.recentReadyCallback(data.list, data.errorMsg);
+				}
 				else if (data.action == 'status')
 				{
 					if (data.messageKey != null)

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

@@ -1918,7 +1918,7 @@
 				else
 				{
 					// Creates a copy with no predefined storage
-					editorUi.editor.editAsNew(editorUi.getEditBlankXml(), title);
+					editorUi.editor.editAsNew(this.editorUi.getFileData(true), title);
 				}
 			}
 		}));

+ 11 - 2
src/main/webapp/js/diagramly/StorageFile.js

@@ -187,7 +187,7 @@ StorageFile.prototype.rename = function(title, success, error)
 	{
 		this.ui.getLocalData(title, mxUtils.bind(this, function(data)
 		{
-			this.ui.confirm(mxResources.get('replaceIt', [title]), mxUtils.bind(this, function()
+			var fn = mxUtils.bind(this, function()
 			{
 				this.title = title;
 				
@@ -201,7 +201,16 @@ StorageFile.prototype.rename = function(title, success, error)
 				{
 					this.ui.removeLocalData(oldTitle, success);
 				}), error);
-			}), error);
+			});
+			
+			if (data != null)
+			{
+				this.ui.confirm(mxResources.get('replaceIt', [title]), fn, error);
+			}
+			else
+			{
+				fn();
+			}
 		}));
 	}
 	else

文件差异内容过多而无法显示
+ 11 - 11
src/main/webapp/js/embed-static.min.js


+ 1 - 1
src/main/webapp/js/mxgraph/Graph.js

@@ -4772,7 +4772,7 @@ if (typeof mxVertexHandler != 'undefined')
 				{
 					var state = this.view.getState(parents[i]);
 					
-					if (state != null && this.isCellDeletable(state.cell))
+					if (state != null && (this.model.isEdge(state.cell) || this.model.isVertex(state.cell)) && this.isCellDeletable(state.cell))
 					{
 						var stroke = mxUtils.getValue(state.style, mxConstants.STYLE_STROKECOLOR, mxConstants.NONE);
 						var fill = mxUtils.getValue(state.style, mxConstants.STYLE_FILLCOLOR, mxConstants.NONE);

文件差异内容过多而无法显示
+ 11 - 11
src/main/webapp/js/reader.min.js


文件差异内容过多而无法显示
+ 596 - 595
src/main/webapp/js/viewer.min.js


+ 2 - 2
src/main/webapp/open.html

@@ -61,8 +61,8 @@
 				var value = localStorage.getItem(key);
 				
 				if (key.length > 0 && key.charAt(0) != '.' && value.length > 0 &&
-					(value.substring(0, 8) === '<mxfile ' ||
-					value.substring(0, 11) === '<mxlibrary>'))
+					(value.substring(0, 8) === '<mxfile ' || value.substring(0, 11) === '<mxlibrary>' ||
+					value.substring(0, 5) === '<?xml') || value.substring(0, 12) === '<!--[if IE]>')
 				{
 					keys.push(key);
 				}

+ 17 - 11
src/main/webapp/styles/dark.css

@@ -1,9 +1,9 @@
 html body .geDiagramContainer, html body div.geMenubarContainer, html body .geFooterContainer>div>img, html body div.mxPopupMenu,  html body td.mxPopupMenuIcon, html body .geFormatContainer {
-	background-color: #2a2a2a;
+	background-color:#2a2a2a;
 }
-html body .geFooterContainer, html body .geFooterContainer a, html body #geFooterItem1, html body textarea, html body .mxWindowTitle, html body .geDialogTitle, html body .geDialogFooter {
+html body .geFooterContainer, html body #geFooterItem1, html body textarea, html body .mxWindowTitle, html body .geDialogTitle, html body .geDialogFooter {
 	background:#2a2a2a;
-	color: #cccccc;
+	color:#cccccc;
 }
 html body div.mxRubberband {
 	border:1px dashed #ffffff !important; background:#505759 !important;
@@ -12,19 +12,19 @@ html body .geToolbarContainer, html body .geSidebar, html body .geSidebarContain
 	background:#2a2a2a;
 	border-color:#505759;
 	box-shadow:none;
-	color: #cccccc;
+	color:#cccccc;
 }
 html body .geSprite, html body .geSocialFooter img, html body .mxPopupMenuItem>img {
 	filter:invert(100%);
 }
 html body .geFormatContainer {
-	border-left: 1px solid #505759;
+	border-left:1px solid #505759;
 }
 html body .geDiagramContainer {
-	border-bottom: 1px solid #505759;
+	border-bottom:1px solid #505759;
 }
 html body .geSidebarContainer a, html body .geMenubarContainer a, html body .geToolbar a {
-	color: #cccccc;
+	color:#cccccc;
 }
 html body .geMenubarMenu {
 	border-color:#505759 !important;
@@ -32,6 +32,12 @@ html body .geMenubarMenu {
 html body .geToolbarMenu, html body .geFooterContainer, html body .geFooterContainer td {
 	border-color:#505759;
 }
+html body .geFooterContainer a {
+	background-color:none;
+}
+html body .geFooterContainer td:hover, html body #geFooterItem1:hover {
+	background-color:#000000;
+}
 html body div.mxPopupMenu {
 	border-color:#505759 !important;
 	box-shadow:none;
@@ -51,17 +57,17 @@ html body .geBtn {
 html body .gePrimaryBtn {
 	background:#505759 !important;
 	border-color:#cccccc !important;
-	color: #cccccc !important;
+	color:#cccccc !important;
 }
 html body .geBtn:hover {
 	background:#000000 !important;
 }
 html body tr.mxPopupMenuItem {
-	color: #cccccc;
+	color:#cccccc;
 }
 html body tr.mxPopupMenuItemHover {
 	background:#000000;
-	color: #cccccc;
+	color:#cccccc;
 }
 html body .geSidebarContainer .geTitle:hover, html body .geMenubarContainer .geItem:hover, html body .geBaseButton:hover {
 	background:#000000;
@@ -77,5 +83,5 @@ html body .geDialog, html body div.mxWindow {
 	background:#2a2a2a;
 	border-color:#c0c0c0;
 	box-shadow:none;
-	color: #cccccc;
+	color:#cccccc;
 }

文件差异内容过多而无法显示
+ 1 - 1
src/main/webapp/templates/business/accd.xml