瀏覽代碼

15.0.4 release

David Benson [draw.io] 4 年之前
父節點
當前提交
2e7e78d452

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+31-AUG-2021: 15.0.4
+
+- Fixes offset for background pages
+- Fixes dash color for sketch theme in dark mode
+- Adds .drawio.xyz extension to embedded files
+- Adds includeDiagram config option
+- Adds app icon click handler, removes debug output
+- Adds support for background pages in PDF export
+
 27-AUG-2021: 15.0.3
 
 - Fixes missing background images in thumbnails

+ 1 - 1
VERSION

@@ -1 +1 @@
-15.0.3
+15.0.4

文件差異過大導致無法顯示
+ 985 - 981
src/main/webapp/js/app.min.js


+ 2 - 1
src/main/webapp/js/diagramly/Dialogs.js

@@ -4921,6 +4921,7 @@ var LinkDialog = function(editorUi, initialValue, btnLabel, fn, showPages, showN
 	linkInput.style.backgroundRepeat = 'no-repeat';
 	linkInput.style.backgroundPosition = '100% 50%';
 	linkInput.style.paddingRight = '14px';
+	linkInput.style.marginBottom = '4px';
 
 	var cross = document.createElement('div');
 	cross.setAttribute('title', mxResources.get('reset'));
@@ -5151,7 +5152,7 @@ var LinkDialog = function(editorUi, initialValue, btnLabel, fn, showPages, showN
 	};
 	
 	var btns = document.createElement('div');
-	btns.style.marginTop = '20px';
+	btns.style.marginTop = '18px';
 	btns.style.textAlign = 'center';
 	
 	var helpBtn = mxUtils.button(mxResources.get('help'), function()

+ 15 - 2
src/main/webapp/js/diagramly/Editor.js

@@ -223,6 +223,12 @@
 	 */
 	Editor.enableCustomProperties = true;
 	
+	/**
+	 * Sets the default value for including a copy of the diagram.
+	 * Default is true.
+	 */
+	 Editor.defaultIncludeDiagram = true;
+
 	/**
 	 * Specifies if custom properties should be enabled.
 	 */
@@ -1800,6 +1806,11 @@
 				Editor.compressXml = config.compressXml;
 			}
 			
+			if (config.includeDiagram != null)
+			{
+				Editor.defaultIncludeDiagram = config.includeDiagram;
+			}
+			
 			if (config.simpleLabels != null)
 			{
 				Editor.simpleLabels = config.simpleLabels;
@@ -2194,7 +2205,7 @@
 	 * Adds persistent style to file
 	 */
 	var editorGetGraphXml = Editor.prototype.getGraphXml;	
-	Editor.prototype.getGraphXml = function(ignoreSelection)
+	Editor.prototype.getGraphXml = function(ignoreSelection, resolveReferences)
 	{
 		ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;
 		var node = editorGetGraphXml.apply(this, arguments);
@@ -2205,7 +2216,9 @@
 			node.setAttribute('style', this.graph.currentStyle);
 		}
 
-		var bgImg = this.graph.getBackgroundImageObject(this.graph.backgroundImage);
+		var bgImg = this.graph.getBackgroundImageObject(
+			this.graph.backgroundImage,
+			resolveReferences);
 		
 		// Adds the background image
 		if (bgImg != null)

+ 69 - 27
src/main/webapp/js/diagramly/EditorUi.js

@@ -1197,14 +1197,14 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.getXmlFileData = function(ignoreSelection, currentPage, uncompressed)
+	EditorUi.prototype.getXmlFileData = function(ignoreSelection, currentPage, uncompressed, resolveReferences)
 	{
 		ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;
 		currentPage = (currentPage != null) ? currentPage : false;
 		uncompressed = (uncompressed != null) ? uncompressed : !Editor.compressXml;
 		
 		// Generats graph model XML node for single page export
-		var node = this.editor.getGraphXml(ignoreSelection);
+		var node = this.editor.getGraphXml(ignoreSelection, resolveReferences);
 		
 		if (ignoreSelection && this.fileNode != null && this.currentPage != null)
 		{
@@ -1259,22 +1259,53 @@
 				// Restores order of pages
 				for (var i = 0; i < this.pages.length; i++)
 				{
-					if (this.currentPage != this.pages[i])
+					var page = this.pages[i];
+					var currNode = page.node;
+
+					if (page != this.currentPage)
 					{
-						if (this.pages[i].needsUpdate)
+						if (page.needsUpdate)
 						{
 							var enc = new mxCodec(mxUtils.createXmlDocument());
-							var temp = enc.encode(new mxGraphModel(this.pages[i].root));
-							this.editor.graph.saveViewState(this.pages[i].viewState, temp);
-							EditorUi.removeChildNodes(this.pages[i].node);
-							mxUtils.setTextContent(this.pages[i].node, Graph.compressNode(temp));
+							var temp = enc.encode(new mxGraphModel(page.root));
+							this.editor.graph.saveViewState(page.viewState,
+								temp, null, resolveReferences);
+							EditorUi.removeChildNodes(page.node);
+							mxUtils.setTextContent(page.node, Graph.compressNode(temp));
 
 							// Marks the page as up-to-date
-							delete this.pages[i].needsUpdate;
+							delete page.needsUpdate;
+						}
+						else if (resolveReferences)
+						{
+							// Checks for unresolved background page references
+							if (page.viewState == null)
+							{
+								var modelNode = this.editor.extractGraphModel(page.node);
+								page.viewState = this.editor.graph.createViewState(modelNode)
+							}
+
+							if (page.viewState.backgroundImage != null &&
+								Graph.isPageLink(page.viewState.backgroundImage.originalSrc) &&
+								page.viewState.backgroundImage.src == null)
+							{
+								page.viewState.backgroundImage = this.createImageForPageLink(page.viewState.backgroundImage.originalSrc);
+							}
+
+							if (page.viewState.backgroundImage != null &&
+								page.viewState.backgroundImage.originalSrc != null)
+							{
+								var enc = new mxCodec(mxUtils.createXmlDocument());
+								var temp = enc.encode(new mxGraphModel(page.root));
+								this.editor.graph.saveViewState(page.viewState,
+									temp, null, resolveReferences);
+								currNode = currNode.cloneNode(false);
+								mxUtils.setTextContent(node, Graph.compressNode(temp));
+							}
 						}
 					}
 					
-					appendPage(this.pages[i].node);
+					appendPage(currNode);
 				}
 			}
 		}
@@ -1544,8 +1575,8 @@
 	 * @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, file, uncompressed)
+	EditorUi.prototype.getFileData = function(forceXml, forceSvg, forceHtml, embeddedCallback,
+		ignoreSelection, currentPage, node, compact, file, uncompressed, resolveReferences)
 	{
 		ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;
 		currentPage = (currentPage != null) ? currentPage : false;
@@ -1585,8 +1616,9 @@
 				graph.model.setRoot(page.root);
 			}
 		}
-		
-		node = (node != null) ? node : this.getXmlFileData(ignoreSelection, currentPage, uncompressed);
+
+		node = (node != null) ? node : this.getXmlFileData(ignoreSelection,
+			currentPage, uncompressed, resolveReferences);
 		file = (file != null) ? file : this.getCurrentFile();
 
 		var result = this.createFileData(node, graph, file, window.location.href,
@@ -1857,8 +1889,12 @@
 		var basename = (file != null && file.getTitle() != null) ? file.getTitle() : this.defaultFilename;
 		
 		if (/(\.xml)$/i.test(basename) || /(\.html)$/i.test(basename) ||
-			/(\.svg)$/i.test(basename) || /(\.png)$/i.test(basename) ||
-			/(\.drawio)$/i.test(basename))
+			/(\.svg)$/i.test(basename) || /(\.png)$/i.test(basename))
+		{
+			basename = basename.substring(0, basename.lastIndexOf('.'));
+		}
+		
+		if (/(\.drawio)$/i.test(basename))
 		{
 			basename = basename.substring(0, basename.lastIndexOf('.'));
 		}
@@ -1886,7 +1922,8 @@
 		{
 			ignoreSelection = (ignoreSelection != null) ? ignoreSelection : this.editor.graph.isSelectionEmpty();
 			var basename = this.getBaseFilename(!currentPage);
-			var filename = basename + '.' + format;
+			var filename = basename + ((format == 'xml' || (format == 'pdf' &&
+				includeXml)) ? '.drawio' : '') + '.' + format;
 			
 			if (format == 'xml')
 			{
@@ -2006,8 +2043,8 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.createDownloadRequest = function(filename, format, ignoreSelection, base64, transparent,
-		currentPage, scale, border, grid, includeXml)
+	EditorUi.prototype.createDownloadRequest = function(filename, format, ignoreSelection,
+		base64, transparent, currentPage, scale, border, grid, includeXml)
 	{
 		var graph = this.editor.graph;
 		var bounds = graph.getGraphBounds();
@@ -2015,7 +2052,9 @@
 		// Exports only current page for images that does not contain file data, but for
 		// the other formats with XML included or pdf with all pages, we need to send the complete data and use
 		// the from/to URL parameters to specify the page to be exported.
-		var data = this.getFileData(true, null, null, null, ignoreSelection, currentPage == false? false : format != 'xmlpng');
+		var data = this.getFileData(true, null, null, null, ignoreSelection,
+			currentPage == false ? false : format != 'xmlpng', null, null,
+			null, null, format == 'pdf');
 		var range = '';
 		var allPages = '';
 		
@@ -4272,8 +4311,10 @@
 	EditorUi.prototype.saveCanvas = function(canvas, xml, format, ignorePageName, dpi)
 	{
 		var ext = ((format == 'jpeg') ? 'jpg' : format);
-		var filename = this.getBaseFilename(ignorePageName) + '.' + ext;
+		var filename = this.getBaseFilename(ignorePageName) +
+			((xml != null) ? '.drawio' : '') + '.' + ext;
    	    var data = this.createImageDataUri(canvas, xml, format, dpi);
+
    	    this.saveData(filename, ext, data.substring(data.lastIndexOf(',') + 1), 'image/' + format, true);
 	};
 	
@@ -4909,7 +4950,7 @@
 					this.editor.graph.addSvgShadow(svgRoot);
 				}
 				
-				var filename = this.getBaseFilename() + '.svg';
+				var filename = this.getBaseFilename() + ((editable) ? '.drawio' : '') + '.svg';
 	
 				var doSave = mxUtils.bind(this, function(svgRoot)
 				{
@@ -5725,7 +5766,8 @@
 		
 		var selection = this.addCheckbox(div, mxResources.get('selectionOnly'), false,
 			this.editor.graph.isSelectionEmpty());
-		var include = (hideInclude) ? null : this.addCheckbox(div, mxResources.get('includeCopyOfMyDiagram'), true);
+		var include = (hideInclude) ? null : this.addCheckbox(div, mxResources.get('includeCopyOfMyDiagram'),
+			Editor.defaultIncludeDiagram);
 		
 		var graph = this.editor.graph;
 		var transparent = (hideInclude) ? null : this.addCheckbox(div, mxResources.get('transparentBackground'),
@@ -5753,7 +5795,7 @@
 	EditorUi.prototype.showExportDialog = function(title, embedOption, btnLabel, helpLink, callback,
 		cropOption, defaultInclude, format, exportOption)
 	{
-		defaultInclude = (defaultInclude != null) ? defaultInclude : true;
+		defaultInclude = (defaultInclude != null) ? defaultInclude : Editor.defaultIncludeDiagram;
 		
 		var div = document.createElement('div');
 		div.style.whiteSpace = 'nowrap';
@@ -9004,13 +9046,13 @@
 		// Restores background page references in output data
 		var graphGetBackgroundImageObject = graph.getBackgroundImageObject;
 		
-		graph.getBackgroundImageObject = function(obj)
+		graph.getBackgroundImageObject = function(obj, resolveReferences)
 		{
 			var result = graphGetBackgroundImageObject.apply(this, arguments);
 
-			if (result != null && result.originalSrc != null)
+			if (result != null && result.originalSrc != null && !resolveReferences)
 			{
-				result = {src: result.originalSrc, width: result.width, height: result.height};
+				result = {src: result.originalSrc};
 			}
 
 			return result;

+ 6 - 5
src/main/webapp/js/diagramly/Menus.js

@@ -363,7 +363,8 @@
 								var result = '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->\n' +
 									'<!DOCTYPE html>\n<html>\n<head>\n<title>' + mxUtils.htmlEntities(basename) + '</title>\n' +
 									'<meta charset="utf-8"/>\n</head>\n<body>' + html + '\n' + scriptTag + '\n</body>\n</html>';
-								editorUi.saveData(basename + '.html', 'html', result, 'text/html');
+								editorUi.saveData(basename + ((basename.substring(basename.lenth - 7) ==
+									'.drawio') ? '' : '.drawio') + '.html', 'html', result, 'text/html');
 							}));
 					});
 				});
@@ -443,8 +444,8 @@
 					
 				if (EditorUi.isElectronApp || isDrawioWeb)
 				{
-					include = editorUi.addCheckbox(div,
-							mxResources.get('includeCopyOfMyDiagram'), true);
+					include = editorUi.addCheckbox(div, mxResources.get('includeCopyOfMyDiagram'),
+						Editor.defaultIncludeDiagram);
 					dlgH += 30;
 				}
 				
@@ -696,7 +697,7 @@
 								addShadow, editable, border, !cropImage, false, null, grid, null,
 								keepTheme, exportType);
 						}
-					}), true, true, 'png', true);
+					}), true, Editor.defaultIncludeDiagram, 'png', true);
 			}
 			else if (!editorUi.isOffline() && (!mxClient.IS_IOS || !navigator.standalone))
 			{
@@ -2608,7 +2609,7 @@
 						
 						return false;
 					}, null, null, null, null, editorUi.editor.fileExtensions);
-					this.editorUi.showDialog(dlg.container, 340, 90, true, true);
+					this.editorUi.showDialog(dlg.container, 340, 96, true, true);
 					dlg.init();
 				}
 			}

+ 41 - 7
src/main/webapp/js/diagramly/Minimal.js

@@ -910,7 +910,7 @@ EditorUi.initMinimalTheme = function()
 		ui.actions.get('forkme').visible = urlParams['sketch'] != '1';
 		ui.actions.get('downloadDesktop').visible = urlParams['sketch'] != '1';
 
-        var toggleDarkModeAction = ui.actions.put('toggleDarkMode', new Action(mxResources.get('dark'), function()
+        var toggleDarkModeAction = ui.actions.put('toggleDarkMode', new Action(mxResources.get('dark'), function(e)
         {
             ui.setDarkMode(!Editor.darkMode);
         }));
@@ -1887,7 +1887,19 @@ EditorUi.initMinimalTheme = function()
 			elt.style.padding = '6px';
 			elt.style.margin = '0px';
 			toolbar.appendChild(elt);
-			
+
+			mxEvent.disableContextMenu(elt);
+
+			mxEvent.addGestureListeners(elt, mxUtils.bind(this, function(evt)
+			{
+				if (mxEvent.isShiftDown(evt) || mxEvent.isAltDown(evt) ||
+					mxEvent.isMetaDown(evt) || mxEvent.isControlDown(evt) ||
+					mxEvent.isPopupTrigger(evt))
+				{
+					this.appIconClicked(evt);
+				}
+			}), null, null);
+
 			ui.statusContainer.style.position = '';
 			ui.statusContainer.style.display = 'none';
 			ui.statusContainer.style.margin = '0px';
@@ -1977,7 +1989,7 @@ EditorUi.initMinimalTheme = function()
 						var elt = addElt(ui.sidebar.createEdgeTemplateFromCells([cell],
 							cell.geometry.width, 40, mxResources.get('arrow'),
 							false, null, true), mxResources.get('arrow'));
-						elt.style.borderBottom = '1px solid lightgray';
+						elt.style.borderBottom = '1px solid ' + (Editor.isDarkMode() ? '#505050' : 'lightgray');
 						elt.style.paddingBottom = '14px';
 						elt.style.marginBottom = '14px';
 				 	})();
@@ -2306,10 +2318,11 @@ EditorUi.initMinimalTheme = function()
         	before = menubar.firstChild;
 	        iw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
 	        var small = iw < 1000 || urlParams['sketch'] == '1';
+			var appElt = null;
 	 
 	        if (!small)
 	        {
-	        	addMenu('diagram');
+	        	appElt = addMenu('diagram');
 	        }
 
 			if (urlParams['sketch'] == '1')
@@ -2318,9 +2331,15 @@ EditorUi.initMinimalTheme = function()
 			}
 			else
 			{
-		        createGroup([((small) ? addMenu('diagram', null, IMAGE_PATH + '/drawlogo.svg') : null),
-		        	addMenuItem(mxResources.get('shapes'), ui.actions.get('toggleShapes').funct, null, mxResources.get('shapes'), ui.actions.get('image'),
-	        		(small) ? shapesImage : null),
+				var temp = (small) ? addMenu('diagram', null, IMAGE_PATH + '/drawlogo.svg') : null;
+
+				if (temp != null)
+				{
+					appElt = temp;
+				}
+
+		        createGroup([appElt, addMenuItem(mxResources.get('shapes'), ui.actions.get('toggleShapes').funct, null,
+					mxResources.get('shapes'), ui.actions.get('image'), (small) ? shapesImage : null),
 	       			addMenuItem(mxResources.get('format'), ui.actions.get('toggleFormat').funct, null,
 	       			mxResources.get('format') + ' (' + ui.actions.get('formatPanel').shortcut + ')', ui.actions.get('image'),
 	   				(small) ? formatImage : null)],
@@ -2366,6 +2385,21 @@ EditorUi.initMinimalTheme = function()
 			        }
 		        }
 			}
+			
+			if (appElt != null)
+			{
+				mxEvent.disableContextMenu(appElt);
+
+				mxEvent.addGestureListeners(appElt, mxUtils.bind(this, function(evt)
+				{
+					if (mxEvent.isShiftDown(evt) || mxEvent.isAltDown(evt) ||
+						mxEvent.isMetaDown(evt) || mxEvent.isControlDown(evt) ||
+						mxEvent.isPopupTrigger(evt))
+					{
+						ui.appIconClicked(evt);
+					}
+				}), null, null);
+			}
 	        
 	        var langMenu = ui.menus.get('language');
 

+ 2 - 2
src/main/webapp/js/diagramly/Pages.js

@@ -598,7 +598,7 @@ Graph.prototype.createViewState = function(node)
 /**
  * Writes the graph properties from the realtime model to the given mxGraphModel node.
  */
-Graph.prototype.saveViewState = function(vs, node, ignoreTransient)
+Graph.prototype.saveViewState = function(vs, node, ignoreTransient, resolveReferences)
 {
 	if (!ignoreTransient)
 	{
@@ -632,7 +632,7 @@ Graph.prototype.saveViewState = function(vs, node, ignoreTransient)
 		node.setAttribute('background', vs.background);
 	}
 
-	var bgImg = this.getBackgroundImageObject(vs.backgroundImage);
+	var bgImg = this.getBackgroundImageObject(vs.backgroundImage, resolveReferences);
 
 	if (bgImg != null)
 	{

+ 16 - 2
src/main/webapp/js/export.js

@@ -429,7 +429,8 @@ function render(data)
 		if (bgImg != null)
 		{
 			bgImg = JSON.parse(bgImg);
-			graph.setBackgroundImage(new mxImage(bgImg.src, bgImg.width, bgImg.height));
+			graph.setBackgroundImage(new mxImage(bgImg.src, bgImg.width,
+				bgImg.height, bgImg.x, bgImg.y));
 		}
 		
 		// Parses XML into graph
@@ -745,6 +746,7 @@ function render(data)
 				preview.autoOrigin = autoOrigin; 
 				preview.appendGraph(graph, scale, x0, y0);
 			}
+
 			// Adds shadow
 			// NOTE: Shadow rasterizes output
 			/*if (mxClient.IS_SVG && xmlDoc.documentElement.getAttribute('shadow') == '1')
@@ -768,6 +770,18 @@ function render(data)
 		}
 		else
 		{
+			var bgImg = graph.backgroundImage;
+
+			if (bgImg != null)
+			{
+				var t = graph.view.translate;
+				var s = graph.view.scale;
+
+				bounds.add(new mxRectangle(
+					(t.x + bgImg.x) * s, (t.y + bgImg.y) * s,
+					bgImg.width * s, bgImg.height * s));
+			}
+
 			// Adds shadow
 			// NOTE: PDF shadow rasterizes output so it's disabled
 			if (data.format != 'pdf' && mxClient.IS_SVG && xmlDoc.documentElement.getAttribute('shadow') == '1')
@@ -781,7 +795,7 @@ function render(data)
 			document.body.style.width = Math.ceil(bounds.x + bounds.width) + 'px';
 			document.body.style.height = Math.ceil(bounds.y + bounds.height) + 'px';
 		}
-	}
+	};
 	
 	if (diagrams != null && diagrams.length > 0)
 	{

+ 62 - 26
src/main/webapp/js/grapheditor/Editor.js

@@ -2032,14 +2032,17 @@ var FilenameDialog = function(editorUi, filename, buttonText, fn, label, validat
 	
 	var table = document.createElement('table');
 	var tbody = document.createElement('tbody');
-	table.style.marginTop = '8px';
+	table.style.position = 'absolute';
+	table.style.top = '30px';
+	table.style.left = '20px';
 	
 	row = document.createElement('tr');
 	
 	td = document.createElement('td');
 	td.style.whiteSpace = 'nowrap';
+	td.style.maxWidth = '100px';
+	td.style.textOverflow = 'ellipsis';
 	td.style.fontSize = '10pt';
-	td.style.width = (hints) ? '80px' : '120px';
 	mxUtils.write(td, (label || mxResources.get('filename')) + ':');
 	
 	row.appendChild(td);
@@ -2148,18 +2151,36 @@ var FilenameDialog = function(editorUi, filename, buttonText, fn, label, validat
 		tbody.appendChild(row);
 		
 		if (hints != null)
-		{
+		{	
+			td.appendChild(FilenameDialog.createTypeHint(editorUi, nameInput, hints));
+
 			if (editorUi.editor.diagramFileTypes != null)
 			{
-				var typeSelect = FilenameDialog.createFileTypes(editorUi, nameInput, editorUi.editor.diagramFileTypes);
-				typeSelect.style.marginLeft = '6px';
-				typeSelect.style.width = '74px';
-				
+				row = document.createElement('tr');
+		
+				td = document.createElement('td');
+				td.style.whiteSpace = 'nowrap';
+				td.style.maxWidth = '100px';
+				td.style.textOverflow = 'ellipsis';
+				td.style.fontSize = '10pt';
+				mxUtils.write(td, mxResources.get('type') + ':');
+				row.appendChild(td);
+
+				td = document.createElement('td');
+				td.style.whiteSpace = 'nowrap';
+				row.appendChild(td);
+
+				var typeSelect = FilenameDialog.createFileTypes(editorUi,
+					nameInput, editorUi.editor.diagramFileTypes);
+				typeSelect.style.marginLeft = '4px';
+				typeSelect.style.width = '198px';
+
 				td.appendChild(typeSelect);
-				nameInput.style.width = (w != null) ? (w - 40) + 'px' : '140px';
-			}
+				nameInput.style.width = (w != null) ? (w - 40) + 'px' : '190px';
 
-			td.appendChild(FilenameDialog.createTypeHint(editorUi, nameInput, hints));
+				row.appendChild(td);
+				tbody.appendChild(row);
+			}
 		}
 	}
 	
@@ -2176,7 +2197,7 @@ var FilenameDialog = function(editorUi, filename, buttonText, fn, label, validat
 	row = document.createElement('tr');
 	td = document.createElement('td');
 	td.colSpan = 2;
-	td.style.paddingTop = '20px';
+	td.style.paddingTop = (hints != null) ? '12px' : '20px';
 	td.style.whiteSpace = 'nowrap';
 	td.setAttribute('align', 'right');
 	
@@ -2240,7 +2261,13 @@ FilenameDialog.filenameHelpLink = null;
 FilenameDialog.createTypeHint = function(ui, nameInput, hints)
 {
 	var hint = document.createElement('img');
-	hint.style.cssText = 'vertical-align:top;height:16px;width:16px;margin-left:4px;background-repeat:no-repeat;background-position:center bottom;cursor:pointer;';
+	hint.style.backgroundPosition = 'center bottom';
+	hint.style.backgroundRepeat = 'no-repeat';
+	hint.style.margin = '2px 0 0 4px';
+	hint.style.verticalAlign = 'top';
+	hint.style.cursor = 'pointer';
+	hint.style.height = '16px';
+	hint.style.width = '16px';
 	mxUtils.setOpacity(hint, 70);
 	
 	var nameChanged = function()
@@ -2253,7 +2280,6 @@ FilenameDialog.createTypeHint = function(ui, nameInput, hints)
 			if (hints[i].ext.length > 0 && nameInput.value.toLowerCase().substring(
 				nameInput.value.length - hints[i].ext.length - 1) == '.' + hints[i].ext)
 			{
-				hint.setAttribute('src',  mxClient.imageBasePath + '/warning.png');
 				hint.setAttribute('title', mxResources.get(hints[i].title));
 				break;
 			}
@@ -2292,7 +2318,7 @@ FilenameDialog.createTypeHint = function(ui, nameInput, hints)
 FilenameDialog.createFileTypes = function(editorUi, nameInput, types)
 {
 	var typeSelect = document.createElement('select');
-	
+
 	for (var i = 0; i < types.length; i++)
 	{
 		var typeOption = document.createElement('option');
@@ -2305,11 +2331,16 @@ FilenameDialog.createFileTypes = function(editorUi, nameInput, types)
 	mxEvent.addListener(typeSelect, 'change', function(evt)
 	{
 		var ext = types[typeSelect.value].extension;
-		var idx = nameInput.value.lastIndexOf('.');
+		var idx2 = nameInput.value.lastIndexOf('.drawio.');
+		var idx = (idx2 > 0) ? idx2 : nameInput.value.lastIndexOf('.');
+
+		if (ext != 'drawio')
+		{
+			ext = 'drawio.' + ext;
+		}
 		
 		if (idx > 0)
 		{
-			var ext = types[typeSelect.value].extension;
 			nameInput.value = nameInput.value.substring(0, idx + 1) + ext;
 		}
 		else
@@ -2331,21 +2362,26 @@ FilenameDialog.createFileTypes = function(editorUi, nameInput, types)
 	
 	var nameInputChanged = function(evt)
 	{
-		var idx = nameInput.value.lastIndexOf('.');
+		var name = nameInput.value.toLowerCase();
 		var active = 0;
 		
 		// Finds current extension
-		if (idx > 0)
+		for (var i = 0; i < types.length; i++)
 		{
-			var ext = nameInput.value.toLowerCase().substring(idx + 1);
-			
-			for (var i = 0; i < types.length; i++)
+			var ext = types[i].extension;
+			var subExt = null;
+
+			if (ext != 'drawio')
 			{
-				if (ext == types[i].extension)
-				{
-					active = i;
-					break;
-				}
+				subExt = ext;
+				ext = '.drawio.' + ext;
+			}
+
+			if (name.substring(name.length - ext.length - 1) == '.' + ext ||
+				(subExt != null && name.substring(name.length - subExt.length - 1) == '.' + subExt))
+			{
+				active = i;
+				break;
 			}
 		}
 		

+ 1 - 1
src/main/webapp/js/grapheditor/Format.js

@@ -1080,7 +1080,7 @@ BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setCol
 	mxUtils.write(span, label);
 	div.appendChild(span);
 	
-	var title = 'Shift+Click for Color Picker';
+	var title = 'Shift+Click for Color Dropper';
 	var value = getColorFn();
 	var applying = false;
 	var btn = null;

文件差異過大導致無法顯示
+ 1085 - 1081
src/main/webapp/js/viewer-static.min.js


文件差異過大導致無法顯示
+ 1085 - 1081
src/main/webapp/js/viewer.min.js


文件差異過大導致無法顯示
+ 2 - 2
src/main/webapp/mxgraph/mxClient.js


文件差異過大導致無法顯示
+ 1 - 1
src/main/webapp/service-worker.js


文件差異過大導致無法顯示
+ 1 - 1
src/main/webapp/service-worker.js.map