David Benson 7 rokov pred
rodič
commit
8dea587f68

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+01-MAR-2018: 8.3.5
+
+- Adds recent and search to Confluence Cloud splash dialog
+- Adds iconfinder to URLs with CORS
+- Adds support for cross-origin images
+- Fixes bug for vssx shapes with double quotes in labels
+- Add line-height CSS to simulate quirks box sizing [5289]
+
 27-FEB-2018: 8.3.4
 
 - Fixes license debug in Confluence Cloud

+ 1 - 1
README.md

@@ -19,7 +19,7 @@ The [mxGraph documentation](https://jgraph.github.io/mxgraph/) provides a lot of
 
 Running
 -------
-The simplest way to run draw.io initially is to fork this project, [publish the master branch to GitHub pages](https://help.github.com/categories/github-pages-basics/) and the [pages sites](https://jgraph.github.io/drawio/src/main/webapp/index.html?mode=device&gapi=0&od=0&gh=0&db=0&tr=0) will have the full editor functionality (sans the integrations).
+The simplest way to run draw.io initially is to fork this project, [publish the master branch to GitHub pages](https://help.github.com/categories/github-pages-basics/) and the [pages sites](https://jgraph.github.io/drawio/src/main/webapp/index.html) will have the full editor functionality (sans the integrations).
 
 The full packaged .war of the client and servlets is built when the project is tagged and available on the [releases page](https://github.com/jgraph/draw.io/releases).
 

+ 1 - 1
VERSION

@@ -1 +1 @@
-8.3.4
+8.3.5

+ 41 - 1
src/main/java/com/mxgraph/io/gliffy/model/GliffyText.java

@@ -35,9 +35,13 @@ public class GliffyText implements PostDeserializer.PostDeserializable
 	private boolean forceTopPaddingShift = false;
 	
 	private static Pattern pattern = Pattern.compile("<p(.*?)<\\/p>");
+	
+	private static Pattern spanPattern = Pattern.compile("<span style=\"(.*?)\">");
 
 	private static Pattern textAlign = Pattern.compile(".*(text-align: ?(left|center|right);).*", Pattern.DOTALL);
 
+	private static Pattern lineHeight = Pattern.compile(".*(line-height: .*px;).*", Pattern.DOTALL);
+
 	public GliffyText()
 	{
 	}
@@ -97,6 +101,14 @@ public class GliffyText implements PostDeserializer.PostDeserializable
 			if (halign != null)
 			{
 				sb.append("align=").append(halign).append(";");
+				
+
+				if (halign.equalsIgnoreCase("right"))
+				{
+					// Workaround for word wrapping where no wrapping occurs in Gliffy is to
+					// make room for additional chars if we know the alignment ignores x
+					x = 0;
+				}
 			}
 			else 
 				sb.append("align=center;");
@@ -124,7 +136,35 @@ public class GliffyText implements PostDeserializer.PostDeserializable
 		StringBuilder sb = new StringBuilder();
 		while (m.find())
 		{
-			sb.append("<div" + m.group(1) + "</div>");
+			// Adds line-height:0 to span with no line-height
+			// to match quirks mode sizing in standards mode
+			sb.append("<div");
+			String str = m.group(1);
+			Matcher m2 = spanPattern.matcher(str);
+			int last = 0;
+			
+			while (m2.find())
+			{
+				String span = str.substring(last, m2.end());
+				String style = m2.group(1);
+				
+				if (style != null)
+				{
+					Matcher m3 = lineHeight.matcher(style);
+					
+					if (!m3.find())
+					{
+						span = span.substring(0, m2.end(1) - last) + " line-height: 0;" + span.substring(m2.end(1) - last);
+					}
+				}
+
+				last = m2.end();
+				sb.append(span);
+			}
+			
+
+			sb.append(str.substring(last));
+			sb.append("</div>");
 		}
 
 		return sb.length() > 0 ? sb.toString() : html;

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

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 02/27/2018 04:31 PM
+# 03/01/2018 11:02 PM
 
 app.html
 index.html?offline=1

+ 1 - 1
src/main/webapp/connect/confluence/admin.html

@@ -3,7 +3,7 @@
 	<head>
 		<meta charset="UTF-8">
 		<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
-		<script src="ac-1-4-8.js" type="text/javascript"></script>
+		<script src="connectUtils-1-4-8.js" type="text/javascript"></script>
 		<script src="admin.js" type="text/javascript"></script>
 	</head>
 	

+ 1 - 10
src/main/webapp/connect/confluence/connect.json

@@ -19,15 +19,6 @@
     },
     "modules": 
     {
-		"adminPages": [
-			{
-                "key": "gliffyImport",
-                "url": "/connect/confluence/admin.html",
-                "name": {
-                    "value": "Gliffy - draw.io Conversion"
-                }
-            }
-		],
 		"generalPages": [
             {
                 "key": "lightbox",
@@ -38,7 +29,7 @@
             },
             {
                 "key": "customContentViewer",
-                "url": "/connect/confluence/viewer2.html?custom=1&contentId={content.id}",
+                "url": "/connect/confluence/viewer-1-4-8.html?custom=1&contentId={content.id}",
                 "name": {
                     "value": "Draw.io Viewer"
                 }

+ 63 - 82
src/main/webapp/connect/confluence/connectUtils-1-4-8.js

@@ -518,7 +518,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 		{
 			if (AC.draftEnabled)
 			{
-				editor.contentWindow.postMessage(JSON.stringify({action: 'template', callback: true}), '*');
+				editor.contentWindow.postMessage(JSON.stringify({action: 'template', callback: true, enableRecent: true, enableSearch: true}), '*');
 			}
 			else
 			{
@@ -1141,7 +1141,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							show: true, messageKey: 'saving'}), '*');
 						
 						AC.saveDiagram(pageId, diagramName, diagramXml,
-							successXml, saveError, false, 'text/plain', 'draw.io diagram', false, draftPage, true);
+							successXml, saveError, false, 'text/plain', 'draw.io diagram', false, draftPage);
 					}
 				}
 			}
@@ -1198,8 +1198,67 @@ AC.loadDiagram = function (pageId, diagramName, revision, success, error, owning
 	});
 };
 
+AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, revision, contentId, contentVer, success, error)
+{
+    var customObj = {
+        "type": "ac:com.mxgraph.confluence.plugins.diagramly:drawio-diagram",
+        "space": {
+           "key": spaceKey
+         },
+         "container": {
+               "type": pageType,
+               "id": pageId
+            },
+         "title": diagramName,
+         "body": {
+           "storage": {
+             "value": encodeURIComponent(JSON.stringify({
+                 "pageId": pageId,
+                 "diagramName": diagramName,
+                 "version": revision
+               })),
+             "representation": "storage"
+           }
+         },
+         "status": "current"
+    };
+    
+    if (contentId)
+    {
+        customObj.version = {
+            "number": ++contentVer
+        };
+    }
+    
+    AP.require(['request'], function(request) 
+    {
+       request({
+           type: contentId? 'PUT' : 'POST',
+           data: JSON.stringify(customObj),
+           url:  "/rest/api/content/" + (contentId? contentId : ""),
+           contentType: "application/json",
+           success: success,
+           error: function(resp) {
+               //User can delete a custom content externally and we will get error 403 and message will contain the given id
+               //Then save a new one
+               var err = JSON.parse(resp.responseText);
+               
+               if (contentId && err.statusCode == 403 && err.message.indexOf(contentId) > 0)
+               {
+                   AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, revision, null, null, success, error);
+               }
+               else
+               {
+                   error(resp);
+               }
+           }
+       });
+    });
+};
+
+
 //TODO We can upload both the diagram and its png in one call if needed?
-AC.saveDiagram = function(pageId, diagramName, xml, success, error, newSave, mime, comment, sendNotif, draftPage, addCustomContent) 
+AC.saveDiagram = function(pageId, diagramName, xml, success, error, newSave, mime, comment, sendNotif, draftPage) 
 {
 	loadSucess = function(resp) 
 	{
@@ -1255,85 +1314,7 @@ AC.saveDiagram = function(pageId, diagramName, xml, success, error, newSave, mim
 				data: reqData,
 				url:  "/rest/api/content/"+ pageId +"/child/attachment" + draft,
 				contentType: "multipart/form-data",
-				success: function (resp)
-                {
-                   /* var attObj = JSON.parse(resp);
-					if (addCustomContent && attObj.results && attObj.results[0])
-					{
-						var spaceKey = AC.getSpaceKey(attObj.results[0]._expandable.space);
-						//First, check if we already have a custom content related to this attachment
-						//Names are not unique, so should check first to decide: add or update
-						 request({
-		                        type: 'GET',
-		                        url:  "/rest/api/search?cql=" + encodeURIComponent('creator=currentUser() and type="ac:com.mxgraph.confluence.plugins.diagramly:drawio-diagram"' +
-		                        		' and title="'+diagramName+'" and space="' + spaceKey + '"') + '&limit=100', //I don't think there could be more than 100 diagrams with the same name!
-		                        contentType: "application/json",
-	                        success: function(resp) 
-	                        {
-	                            resp = JSON.parse(resp);
-	                            var list = resp.list;
-	                            
-	                            if (list && list.length > 0)
-	                            {
-	                            	//We need to fetch each one to find out the page id
-	                            	for (var i = 0; i < list.length; i++)
-                            		{
-	                            		
-                            		}
-	                            }
-	                            else //just add it
-                            	{
-                            	
-                            	}
-	                        },
-	                        error: error //TODO is this correct??
-	                    });
-	                    
-	                    var customObj = {
-	                         "type": "ac:com.mxgraph.confluence.plugins.diagramly:drawio-diagram",
-	                         "space": {
-	                            "key": spaceKey
-	                          },
-	                          "container": {
-                        	    "type": "page",
-                        	    "id": pageId
-                        	  },
-	                          "title": diagramName,
-	                          "body": {
-	                            "storage": {
-	                              "value": "",
-	                              "representation": "storage"
-	                            }
-	                          },
-	                          "metadata": {
-	                            "properties": {
-	                              "diagram-data": {
-	                                "key": "diagram-data",
-	                                "value": {
-	                                  "attId": attObj.id,
-	                                  "pageId": pageId,
-	                                  "diagramName": diagramName,
-	                                  "version": attObj.results[0].version? attObj.results[0].version.number : ""
-	                                } 
-	                              }
-	                            }
-	                          }
-	                    };
-	                    
-	                    request({
-	                        type: 'POST',
-	                        data: JSON.stringify(customObj),
-	                        url:  "/rest/api/content/",
-	                        contentType: "application/json",
-	                        success: function(resp) 
-	                        {
-	                            //TODO We can ignore the resp??
-	                        },
-	                        error: error //TODO is this correct??
-	                    });
-					}*/
-                    sessionCheck(resp);
-                },
+				success: sessionCheck,
 				error: error
 			 });
 		});

+ 25 - 2
src/main/webapp/connect/confluence/viewer-1-4-8.html

@@ -43,6 +43,7 @@ SHAPES_PATH = '/shapes';
 // Overrides browser language with Confluence user language
 var lang = getUrlParam('loc');
 var lightbox = getUrlParam('lightbox') == '1';
+var customContent = getUrlParam('custom') == '1';
 
 if (lightbox)
 {
@@ -339,7 +340,7 @@ if (lang != null)
 												function()
 												{
 													//nothing!
-												}, false, 'text/plain', 'Diagram imported by Draw.io', false, false, true);
+												}, false, 'text/plain', 'Diagram imported by Draw.io', false, false);
 												
 												//TODO save preview png
 												//This requires an editor to do the png export, may be a canvas can be used with supported browsers
@@ -382,7 +383,29 @@ if (lang != null)
 					}
 				};
 	
-				if (lightbox)
+                if (customContent)
+                {
+                    var contentId = getUrlParam('contentId');
+                    
+                    request({
+                        type: 'GET',
+                        url: '/rest/api/content/' + contentId + '/?expand=body.storage',
+                        contentType: 'application/json;charset=UTF-8',
+                        success: function (resp) 
+                        {
+                            resp = JSON.parse(resp);
+                            
+                            var info = JSON.parse(decodeURIComponent(resp.body.storage.value));
+                            
+                            showDiagram(info.pageId, info.pageId, info.diagramName, info.version, null, links);
+                        },
+                        error: function (resp) 
+                        {
+                            showError('Diagram not found!');
+                        }
+                    });
+                }
+                else if (lightbox)
 				{
 					// Gets the paramters from the customData object in lightbox mode
 					// LATER: Add XML to custom data (does not seem to work)

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 440 - 436
src/main/webapp/js/app.min.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 956 - 952
src/main/webapp/js/atlas-viewer.min.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 285 - 281
src/main/webapp/js/atlas.min.js


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

@@ -260,7 +260,7 @@ DriveClient.prototype.execute = function(fn)
 		// success executes after successful authorization.
 		this.ui.showAuthDialog(this, true, mxUtils.bind(this, function(remember, success)
 		{
-			this.authorize(false, function()
+			this.authorize(false, mxUtils.bind(this, function()
 			{
 				if (success != null)
 				{
@@ -268,7 +268,7 @@ DriveClient.prototype.execute = function(fn)
 				}
 				
 				fn();
-			}, mxUtils.bind(this, function(resp)
+			}), mxUtils.bind(this, function(resp)
 			{
 				var msg = mxResources.get('cannotLogin');
 				
@@ -287,7 +287,10 @@ DriveClient.prototype.execute = function(fn)
 				this.ui.drive.setUser(null);
 				gapi.auth.signOut();
 				
-				this.ui.showError(mxResources.get('error'), msg, mxResources.get('ok'));
+				this.ui.showError(mxResources.get('error'), msg, mxResources.get('help'), mxUtils.bind(this, function()
+				{
+					this.ui.openLink('https://desk.draw.io/support/solutions/articles/16000074659');
+				}), null, mxResources.get('ok'));
 			}), remember);
 		}));
 	});

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

@@ -65,6 +65,11 @@
 	 * Broken image symbol for offline SVG.
 	 */
 	EditorUi.prototype.svgBrokenImage = Graph.createSvgImage(10, 10, '<rect x="0" y="0" width="10" height="10" stroke="#000" fill="transparent"/><path d="m 0 0 L 10 10 L 0 10 L 10 0" stroke="#000" fill="transparent"/>');
+
+	/**
+	 * Specifies if img.crossOrigin is supported. This is true for all browsers except IE10 and earlier.
+	 */
+	EditorUi.prototype.crossOriginImages = !mxClient.IS_IE;
 	
 	/**
 	 * Defines the maximum size for images.
@@ -5025,8 +5030,7 @@
 		var converter = new mxUrlConverter();
 		converter.updateBaseUrl();
 
-		// Extends convert to avoid CORS using an image proxy server
-		// LATER: Use img.crossOrigin="anonymous" to avoid proxy
+		// Extends convert to avoid CORS using an image proxy server where needed
 		var convert = converter.convert;
 		var self = this;
 		
@@ -5040,7 +5044,8 @@
 				{
 					src = self.svgBrokenImage.src;
 				}
-				else if (remote && src.substring(0, converter.baseUrl.length) != converter.baseUrl)
+				else if (remote && src.substring(0, converter.baseUrl.length) != converter.baseUrl &&
+						(!self.crossOriginImages || !self.isCorsEnabledForUrl(src)))
 				{
 					src = PROXY_URL + '?url=' + encodeURIComponent(src);
 				}
@@ -5234,6 +5239,7 @@
 			url.substring(0, 34) === 'https://raw.githubusercontent.com/' ||
 			url.substring(0, 23) === 'https://cdn.rawgit.com/' ||
 			url.substring(0, 19) === 'https://rawgit.com/' ||
+			/^https?:\/\/[^\/]*\.iconfinder.com\//.test(url) ||
 			/^https?:\/\/[^\/]*\.github\.io\//.test(url);
 	};
 
@@ -5261,6 +5267,11 @@
 		    var img = new Image();
 		    var self = this;
 		    
+		    if (this.crossOriginImages)
+		    	{
+			    img.crossOrigin = 'anonymous';
+		    }	
+		    
 		    img.onload = function()
 		    {
 		        var canvas = document.createElement('canvas');

+ 7 - 4
src/main/webapp/js/diagramly/vsdx/importer.js

@@ -1035,12 +1035,15 @@ var com;
                                             /* append */ (function (sb) { return sb.str = sb.str.concat(geo_1.width); })(shapes_1);
                                             /* append */ (function (sb) { return sb.str = sb.str.concat(",\"h\":"); })(shapes_1);
                                             /* append */ (function (sb) { return sb.str = sb.str.concat(geo_1.height); })(shapes_1);
-                                            /* append */ (function (sb) { return sb.str = sb.str.concat(",\"title\":\""); })(shapes_1);
+                                            /* append */ (function (sb) { return sb.str = sb.str.concat(",\"title\":"); })(shapes_1);
                                             var shapeName_1 = master.getName();
-                                            if (shapeName_1 != null)
-                                                shapeName_1 = com.mxgraph.io.vsdx.mxVsdxUtils.htmlEntities(shapeName_1);
+                                            if (shapeName_1 == null)
+                                        	{
+                                            	shapeName_1 = "";
+                                        	}
+                                            shapeName_1 = JSON.stringify(shapeName_1);
                                             /* append */ (function (sb) { return sb.str = sb.str.concat(shapeName_1); })(shapes_1);
-                                            /* append */ (function (sb) { return sb.str = sb.str.concat("\"}"); })(shapes_1);
+                                            /* append */ (function (sb) { return sb.str = sb.str.concat("}"); })(shapes_1);
                                             comma_1 = ",";
                                         }
                                     }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 239 - 237
src/main/webapp/js/embed-static.min.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 4 - 4
src/main/webapp/js/extensions.min.js


+ 48 - 1
src/main/webapp/js/mxgraph/Actions.js

@@ -785,7 +785,54 @@ Actions.prototype.init = function()
 			else
 			{
 				graph.stopEditing(false);
-				graph.toggleCellStyleFlags(mxConstants.STYLE_FONTSTYLE, style);
+				
+				graph.getModel().beginUpdate();
+				try
+				{
+					graph.toggleCellStyleFlags(mxConstants.STYLE_FONTSTYLE, style);
+					
+					// Removes bold and italic tags and CSS styles inside labels
+					if ((style & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
+					{
+						graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+						{
+							elt.style.fontWeight = null;
+							
+							if (elt.nodeName == 'B')
+							{
+								graph.replaceElement(elt);
+							}
+						});
+					}
+					else if ((style & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
+					{
+						graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+						{
+							elt.style.fontStyle = null;
+							
+							if (elt.nodeName == 'I')
+							{
+								graph.replaceElement(elt);
+							}
+						});
+					}
+					else if ((style & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
+					{
+						graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+						{
+							elt.style.textDecoration = null;
+							
+							if (elt.nodeName == 'U')
+							{
+								graph.replaceElement(elt);
+							}
+						});
+					}
+				}
+				finally
+				{
+					graph.getModel().endUpdate();
+				}
 			}
 		}, null, null, shortcut);
 	});

+ 27 - 29
src/main/webapp/js/mxgraph/Format.js

@@ -618,37 +618,20 @@ BaseFormatPanel.prototype.installInputHandler = function(input, key, defaultValu
 				// Handles special case for fontSize where HTML labels are parsed and updated
 				if (key == mxConstants.STYLE_FONTSIZE)
 				{
-					var cells = graph.getSelectionCells();
-					
-					for (var i = 0; i < cells.length; i++)
+					graph.updateLabelElements(graph.getSelectionCells(), function(elt)
 					{
-						var cell = cells[i];
-							
-						// Changes font tags inside HTML labels
-						if (graph.isHtmlLabel(cell))
-						{
-							var div = document.createElement('div');
-							div.innerHTML = graph.convertValueToString(cell);
-							var elts = div.getElementsByTagName('font');
-							
-							for (var j = 0; j < elts.length; j++)
-							{
-								elts[j].removeAttribute('size');
-								elts[j].style.fontSize = value + 'px';
-							}
-							
-							graph.cellLabelChanged(cell, div.innerHTML)
-						}
-					}
+						elt.style.fontSize = value + 'px';
+						elt.removeAttribute('size');
+					});
 				}
+				
+				ui.fireEvent(new mxEventObject('styleChanged', 'keys', [key],
+						'values', [value], 'cells', graph.getSelectionCells()));
 			}
 			finally
 			{
 				graph.getModel().endUpdate();
 			}
-			
-			ui.fireEvent(new mxEventObject('styleChanged', 'keys', [key],
-					'values', [value], 'cells', graph.getSelectionCells()));
 		}
 		
 		input.value = value + unit;
@@ -1029,7 +1012,7 @@ BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setCol
 
 	var btn = null;
 
-	var apply = function(color, disableUpdate)
+	var apply = function(color, disableUpdate, forceUpdate)
 	{
 		if (!applying)
 		{
@@ -1064,12 +1047,12 @@ BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setCol
 				callbackFn(color);
 			}
 
-			if (!disableUpdate && (hideCheckbox || value != color))
+			if (!disableUpdate)
 			{
 				value = color;
 				
 				// Checks if the color value needs to be updated in the model
-				if (hideCheckbox || getColorFn() != value)
+				if (forceUpdate || hideCheckbox || getColorFn() != value)
 				{
 					setColorFn(value);
 				}
@@ -1081,7 +1064,10 @@ BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setCol
 
 	btn = mxUtils.button('', mxUtils.bind(this, function(evt)
 	{
-		this.editorUi.pickColor(value, apply);
+		this.editorUi.pickColor(value, function(color)
+		{
+			apply(color, null, true);
+		});
 		mxEvent.consume(evt);
 	}));
 	
@@ -2848,7 +2834,13 @@ TextFormatPanel.prototype.addFont = function(container)
 	{
 		install: function(apply) { bgColorApply = apply; },
 		destroy: function() { bgColorApply = null; }
-	}, null, true) : this.createCellColorOption(mxResources.get('backgroundColor'), mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, '#ffffff');
+	}, null, true) : this.createCellColorOption(mxResources.get('backgroundColor'), mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, '#ffffff', null, function(color)
+	{
+		graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+		{
+			elt.style.backgroundColor = null;
+		});
+	});
 	bgPanel.style.fontWeight = 'bold';
 
 	var borderPanel = this.createCellColorOption(mxResources.get('borderColor'), mxConstants.STYLE_LABEL_BORDERCOLOR, '#000000');
@@ -2886,6 +2878,12 @@ TextFormatPanel.prototype.addFont = function(container)
 		{
 			graph.setCellStyles(mxConstants.STYLE_NOLABEL, null, graph.getSelectionCells());
 		}
+
+		graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+		{
+			elt.removeAttribute('color');
+			elt.style.color = null;
+		});
 	});
 	panel.style.fontWeight = 'bold';
 	

+ 51 - 0
src/main/webapp/js/mxgraph/Graph.js

@@ -4704,6 +4704,57 @@ if (typeof mxVertexHandler != 'undefined')
 			}
 		};
 		
+		/**
+		 * Replaces the given element with a span.
+		 */
+		Graph.prototype.replaceElement = function(elt, tagName)
+		{
+			var span = elt.ownerDocument.createElement((tagName != null) ? tagName : 'span');
+			var attributes = Array.prototype.slice.call(elt.attributes);
+			
+			while (attr = attributes.pop())
+			{
+				span.setAttribute(attr.nodeName, attr.nodeValue);
+			}
+			
+			span.innerHTML = elt.innerHTML;
+			elt.parentNode.replaceChild(span, elt);
+		};
+		
+		/**
+		 * Handles label changes for XML user objects.
+		 */
+		Graph.prototype.updateLabelElements = function(cells, fn, tagName)
+		{
+			cells = (cells != null) ? cells : this.getSelectionCells();
+			var div = document.createElement('div');
+			
+			for (var i = 0; i < cells.length; i++)
+			{
+				// Changes font tags inside HTML labels
+				if (this.isHtmlLabel(cells[i]))
+				{
+					var label = this.convertValueToString(cells[i]);
+					
+					if (label != null && label.length > 0)
+					{
+						div.innerHTML = label;
+						var elts = div.getElementsByTagName((tagName != null) ? tagName : '*');
+						
+						for (var j = 0; j < elts.length; j++)
+						{
+							fn(elts[j]);
+						}
+						
+						if (div.innerHTML != label)
+						{
+							this.cellLabelChanged(cells[i], div.innerHTML);
+						}
+					}
+				}
+			}
+		};
+		
 		/**
 		 * Handles label changes for XML user objects.
 		 */

+ 20 - 3
src/main/webapp/js/mxgraph/Menus.js

@@ -56,6 +56,18 @@ Menus.prototype.init = function()
 			var tr = this.styleChange(menu, fontname, [mxConstants.STYLE_FONTFAMILY], [fontname], null, parent, function()
 			{
 				document.execCommand('fontname', false, fontname);
+			}, function()
+			{
+				graph.updateLabelElements(graph.getSelectionCells(), function(elt)
+				{
+					elt.removeAttribute('face');
+					elt.style.fontFamily = null;
+					
+					if (elt.nodeName == 'PRE')
+					{
+						graph.replaceElement(elt, 'div');
+					}
+				});
 			});
 			tr.firstChild.nextSibling.style.fontFamily = fontname;
 		});
@@ -758,7 +770,7 @@ Menus.prototype.edgeStyleChange = function(menu, label, keys, values, sprite, pa
 /**
  * Adds a style change item to the given menu.
  */
-Menus.prototype.styleChange = function(menu, label, keys, values, sprite, parent, fn)
+Menus.prototype.styleChange = function(menu, label, keys, values, sprite, parent, fn, post)
 {
 	var apply = this.createStyleChangeFunction(keys, values);
 	
@@ -772,7 +784,7 @@ Menus.prototype.styleChange = function(menu, label, keys, values, sprite, parent
 		}
 		else
 		{
-			apply();
+			apply(post);
 		}
 	}), parent, sprite);
 };
@@ -782,7 +794,7 @@ Menus.prototype.styleChange = function(menu, label, keys, values, sprite, parent
  */
 Menus.prototype.createStyleChangeFunction = function(keys, values)
 {
-	return mxUtils.bind(this, function()
+	return mxUtils.bind(this, function(post)
 	{
 		var graph = this.editorUi.editor.graph;
 		graph.stopEditing(false);
@@ -795,6 +807,11 @@ Menus.prototype.createStyleChangeFunction = function(keys, values)
 				graph.setCellStyles(keys[i], values[i]);
 			}
 			
+			if (post != null)
+			{
+				post();
+			}
+			
 			this.editorUi.fireEvent(new mxEventObject('styleChanged', 'keys', keys, 'values', values,
 				'cells', graph.getSelectionCells()));
 		}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 239 - 237
src/main/webapp/js/reader.min.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 956 - 952
src/main/webapp/js/viewer.min.js