Selaa lähdekoodia

10.0.23 release

Former-commit-id: 9c72843d093757a62a2c803b353afc3d546c1851
Gaudenz Alder 6 vuotta sitten
vanhempi
commit
5815c6c824

+ 7 - 0
ChangeLog

@@ -1,3 +1,10 @@
+08-JAN-2019: 10.0.23
+
+- Adds debug output for checksum errors
+- Adds custom properties in diffsync
+- Fixes possible ReferenceError
+- Fixes for Jira cloud plugin
+
 05-JAN-2019: 10.0.22
 
 - Adds initial change check in sync protocol

+ 1 - 1
VERSION

@@ -1 +1 @@
-10.0.22
+10.0.23

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

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

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 42 - 40
src/main/webapp/js/app.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 40 - 40
src/main/webapp/js/atlas-viewer.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 671 - 669
src/main/webapp/js/atlas.min.js


+ 61 - 16
src/main/webapp/js/diagramly/DiffSync.js

@@ -23,10 +23,15 @@ EditorUi.DIFF_UPDATE = 'u';
 EditorUi.prototype.codec = new mxCodec();
 
 /**
- * Removes all labels, user objects and styles from the given node in-place.
+ * Contains all view state properties that should not be ignored in diff sync.
+ */
+EditorUi.prototype.viewStateProperties = {background: true, backgroundImage: true, shadowVisible: true,
+	foldingEnabled: true, pageScale: true, mathEnabled: true, pageFormat: true};
+
+/**
+ * Contains all known cell properties that should be ignored in generic diff sync.
  */
-EditorUi.prototype.viewStateWhitelist = ['background', 'backgroundImage', 'foldingEnabled',
-	'pageScale', 'mathEnabled', 'shadowVisible', 'pageFormat'];
+EditorUi.prototype.cellPrototype = new mxCell();
 
 /**
  * Removes all labels, user objects and styles from the given node in-place.
@@ -565,6 +570,14 @@ EditorUi.prototype.patchCell = function(model, cell, diff, resolve)
 		{
 			model.setTerminal(cell, model.getCell(diff.target), false);
 		}
+		
+		for (var key in diff)
+		{
+			if (!(key in this.cellPrototype))
+			{
+				cell[key] = diff[key];
+			}
+		}
 	}
 };
 
@@ -610,7 +623,7 @@ EditorUi.prototype.diffPages = function(oldPages, newPages)
 	
 	for (var i = 0; i < newPages.length; i++)
 	{
-		lookup[newPages[i].getId()] = {'page': newPages[i], 'prev': prev/*, 'index': i*/};
+		lookup[newPages[i].getId()] = {page: newPages[i], prev: prev};
 		prev = newPages[i];
 	}
 
@@ -647,8 +660,6 @@ EditorUi.prototype.diffPages = function(oldPages, newPages)
 				prev.getId() != newPage.prev.getId()))
 			{
 				pageDiff.previous = (newPage.prev != null) ? newPage.prev.getId() : '';
-				// LATER: If previous has vanished this could be used to add the intent
-				//pageDiff['index'] = newPage.index;
 			}
 			
 			// FIXME: Check why names can be null in newer files
@@ -698,10 +709,10 @@ EditorUi.prototype.diffPages = function(oldPages, newPages)
 /**
  * Removes all labels, user objects and styles from the given node in-place.
  */
-EditorUi.prototype.createCellLookup = function(cell, prev, index, lookup)
+EditorUi.prototype.createCellLookup = function(cell, prev, lookup)
 {
 	lookup = (lookup != null) ? lookup : {};
-	lookup[cell.getId()] = {'cell': cell, 'prev': prev/*, 'index': index*/};
+	lookup[cell.getId()] = {cell: cell, prev: prev};
 	
 	var childCount = cell.getChildCount();
 	prev = null;
@@ -709,7 +720,7 @@ EditorUi.prototype.createCellLookup = function(cell, prev, index, lookup)
 	for (var i = 0; i < childCount; i++)
 	{
 		var child = cell.getChildAt(i);
-		this.createCellLookup(child, prev, i, lookup);
+		this.createCellLookup(child, prev, lookup);
 		prev = child;
 	}
 	
@@ -738,9 +749,7 @@ EditorUi.prototype.diffCellRecursive = function(cell, prev, lookup, diff, remove
 			(prev != null && newCell.prev != null &&
 			prev.getId() != newCell.prev.getId())))
 		{
-			temp['previous'] = (newCell.prev != null) ? newCell.prev.getId() : '';
-			// LATER: If previous has vanished this could be used to add the intent
-			//temp['index'] = newCell.index;
+			temp.previous = (newCell.prev != null) ? newCell.prev.getId() : '';
 		}
 		
 		if (Object.keys(temp).length > 0)
@@ -774,7 +783,7 @@ EditorUi.prototype.diffPage = function(oldPage, newPage)
 	this.updatePageRoot(oldPage);
 	this.updatePageRoot(newPage);
 
-	var lookup = this.createCellLookup(newPage.root, null, 0);
+	var lookup = this.createCellLookup(newPage.root);
 	var diff = this.diffCellRecursive(oldPage.root, null, lookup, diff, removed);
 
 	for (var id in lookup)
@@ -817,10 +826,8 @@ EditorUi.prototype.diffViewState = function(oldPage, newPage)
 
 	if (source != null && target != null)
 	{
-		for (var i = 0; i < this.viewStateWhitelist.length; i++)
+		for (var key in this.viewStateProperties)
 		{
-			var key = this.viewStateWhitelist[i];
-			
 			// LATER: Check if normalization is needed for
 			// object attribute order to compare JSON
 			var old = JSON.stringify(source[key]);
@@ -858,6 +865,14 @@ EditorUi.prototype.getCellForJson = function(json)
 	cell.edge = json.edge == 1;
 	cell.id = json.id;
 	
+	for (var key in json)
+	{
+		if (!(key in this.cellPrototype))
+		{
+			cell[key] = json[key];
+		}
+	}
+
 	return cell;
 };
 
@@ -936,6 +951,14 @@ EditorUi.prototype.getJsonForCell = function(cell, previous)
 		}
 	}
 	
+	for (var key in cell)
+	{
+		if (key != 'mxObjectId' && !(key in this.cellPrototype))
+		{
+			result[key] = cell[key];
+		}
+	}
+
 	return result;
 };
 
@@ -1029,6 +1052,28 @@ EditorUi.prototype.diffCell = function(oldCell, newCell)
 		diff.geometry = mxUtils.getXml(this.codec.encode(newCell.geometry));
 	}
 	
+	// Compares all keys from oldCell to newCell and uses null in the diff
+	// to force the attribute to be removed in the receinving client
+	for (var key in oldCell)
+	{
+		if (key != 'mxObjectId' && !(key in this.cellPrototype) &&
+			oldCell[key] != newCell[key])
+		{
+			diff[key] = (newCell[key] === undefined) ? null : newCell[key];
+		}
+	}
+	
+	// Compares the remaining keys in newCell with oldCell
+	for (var key in newCell)
+	{
+		if (!(key in oldCell) &&
+			key != 'mxObjectId' && !(key in this.cellPrototype) &&
+			oldCell[key] != newCell[key])
+		{
+			diff[key] = (newCell[key] === undefined) ? null : newCell[key];
+		}
+	}
+	
 	return diff;
 };
 

+ 31 - 52
src/main/webapp/js/diagramly/DrawioFile.js

@@ -129,7 +129,8 @@ DrawioFile.prototype.stats = {
 	msgSent: 0, /* number of messages sent */
 	msgReceived: 0, /* number of messages received */
 	cacheHits: 0, /* number of times the cache returned patches */
-	cacheMiss: 0, /* number of times we have given up to read the cache */
+	cacheMiss: 0, /* number of times we have missed a cache entry */
+	cacheFail: 0, /* number of times we have failed to read the cache */
 	conflicts: 0, /* number of write conflicts when saving a file */
 	timeouts: 0 /* number of time we have given up to retry after a write conflict */
 };
@@ -228,8 +229,10 @@ DrawioFile.prototype.mergeFile = function(file, success, error)
 		{
 			// Patching previous shadow to verify checksum
 			var patched = this.ui.patchPages(shadow, patches[0]);
-			var checksum = this.ui.getHashValueForPages(patched);
-			var current = this.ui.getHashValueForPages(this.shadowPages);
+			var patchedDetails = {};
+			var checksum = this.ui.getHashValueForPages(patched, patchedDetails);
+			var currentDetails = {};
+			var current = this.ui.getHashValueForPages(this.shadowPages, currentDetails);
 			
 			if (urlParams['test'] == '1')
 			{
@@ -245,7 +248,11 @@ DrawioFile.prototype.mergeFile = function(file, success, error)
 				
 				this.checksumError(error, patches,
 					'Checksum: ' + checksum +
+					((patchedDetails != null) ? ('\nDetails: ' +
+						JSON.stringify(patchedDetails)) : '') +
 					'\nCurrent: ' + current +
+					((currentDetails != null) ? ('\nCurrent Details: ' +
+						JSON.stringify(currentDetails)) : '') +
 					'\nPatched:\n' + data);
 				
 				// Abnormal termination
@@ -346,7 +353,7 @@ DrawioFile.prototype.checkShadow = function(shadow)
 			this.compressReportData(
 			this.ui.anonymizeString(
 			this.shadowData),
-			null, 1000);
+			null, 5000);
 		
 		this.sendErrorReport(
 			'Shadow is null or empty',
@@ -454,8 +461,9 @@ DrawioFile.prototype.sendErrorReport = function(title, details, error)
 		
 		EditorUi.sendReport(title + ' ' + new Date().toISOString() + ':' +
 			'\n\nBrowser=' + navigator.userAgent +
+			'\nPlugins=' + ((mxSettings.settings != null) ? mxSettings.getPlugins() : 'null') +
 			'\nFile=' + this.ui.hashValue(this.getId()) + ' (' + this.getMode() + ')' +
-			((this.sync != null) ? ('\nClient=' + this.sync.clientId) : '') +
+			'\nClient=' + ((this.sync != null) ? (this.sync.clientId) : 'null') +
 			'\nUser=' + uid +
 			'\nExt=' + ext +
 			'\nSize=' + this.getSize() +
@@ -542,28 +550,8 @@ DrawioFile.prototype.reloadFile = function(success, error)
  */
 DrawioFile.prototype.copyFile = function(success, error)
 {
-	if (this.constructor == DriveFile && !this.isRestricted())
-	{
-		this.makeCopy(mxUtils.bind(this, function()
-		{
-			if (this.ui.spinner.spin(document.body, mxResources.get('saving')))
-			{
-				try
-				{
-					this.save(true, success, error)
-				}
-				catch (e)
-				{
-					error(e);
-				}
-			}
-		}), error, true);
-	}
-	else
-	{
-		this.ui.editor.editAsNew(this.ui.getFileData(true),
-			this.ui.getCopyFilename(this));
-	}	
+	this.ui.editor.editAsNew(this.ui.getFileData(true),
+		this.ui.getCopyFilename(this));
 };
 
 /**
@@ -1128,7 +1116,7 @@ DrawioFile.prototype.addAllSavedStatus = function(status)
 	{
 		status = (status != null) ? status : mxUtils.htmlEntities(mxResources.get(this.allChangesSavedKey));
 		
-		if (this.constructor == DriveFile || this.constructor == DropboxFile)
+		if (this.isRevisionHistorySupported())
 		{
 			this.ui.editor.setStatus('<div title="'+ mxUtils.htmlEntities(mxResources.get('revisionHistory')) +
 				'" style="text-decoration:underline;cursor:pointer;">' + status + '</div>');
@@ -1307,23 +1295,7 @@ DrawioFile.prototype.showCopyDialog = function(success, error, overwrite)
 		mxResources.get('cancel'), mxUtils.bind(this, function()
 	{
 		this.ui.hideDialog();
-	}), 360, (this.constructor == DriveFile) ? 180 : 150);
-	
-	// Adds important notice to dialog
-	if (this.ui.dialog != null && this.ui.dialog.container != null &&
-		this.constructor == DriveFile)
-	{
-		var alert = this.ui.createRealtimeNotice();
-		alert.style.left = '0';
-		alert.style.right = '0';
-		alert.style.borderRadius = '0';
-		alert.style.borderLeftStyle = 'none';
-		alert.style.borderRightStyle = 'none';
-		alert.style.marginBottom = '26px';
-		alert.style.padding = '8px 0 8px 0';
-
-		this.ui.dialog.container.appendChild(alert);
-	}
+	}), 360, 150);
 };
 
 /**
@@ -1372,7 +1344,7 @@ DrawioFile.prototype.redirectToNewApp = function(error)
 				}
 			});
 			
-			if (this.isModified())
+			if (error == null && this.isModified())
 			{
 				this.ui.confirm(mxResources.get('allChangesLost'), mxUtils.bind(this, function()
 				{
@@ -1387,15 +1359,22 @@ DrawioFile.prototype.redirectToNewApp = function(error)
 		
 		if (error != null)
 		{
-			this.ui.confirm(mxResources.get('redirectToNewApp'), redirect, mxUtils.bind(this, function()
+			if (this.isModified())
 			{
-				this.redirectDialogShowing = false;
-				
-				if (error != null)
+				this.ui.confirm(mxResources.get('redirectToNewApp'), mxUtils.bind(this, function()
 				{
+					this.redirectDialogShowing = false;
 					error();
-				}
-			}));
+				}), redirect, mxResources.get('cancel'), mxResources.get('discardChanges'));
+			}
+			else
+			{
+				this.ui.confirm(mxResources.get('redirectToNewApp'), redirect, mxUtils.bind(this, function()
+				{
+					this.redirectDialogShowing = false;
+					error();
+				}));
+			}
 		}
 		else
 		{

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

@@ -791,11 +791,12 @@ DrawioFileSync.prototype.catchup = function(etag, secret, success, error, abort)
 								!failed && req.getStatus() != 401)
 							{
 								cacheReadyRetryCount++;
+								this.file.stats.cacheMiss++;
 								window.setTimeout(doCatchup, (cacheReadyRetryCount + 1) * this.cacheReadyDelay);
 							}
 							else
 							{
-								this.file.stats.cacheMiss++;
+								this.file.stats.cacheFail++;
 								this.reload(success, error, abort);
 							}
 						}
@@ -885,8 +886,13 @@ DrawioFileSync.prototype.merge = function(patches, checksum, etag, success, erro
 			// Compares the checksum
 			if (checksum != null && checksum != current)
 			{
+				var from = this.ui.hashValue(this.file.getCurrentEtag());
+				var to = this.ui.hashValue(etag);
+				
 				this.file.checksumError(error, patches,
 					'Checksum: ' + checksum +
+					'\nFrom: ' + from +
+					'\nTo: ' + to +
 					((details != null && details.length > 0) ? ('\nDetails: ' +
 						details.join(', ')) : '') +
 					'\nCurrent: ' + current +
@@ -1017,11 +1023,16 @@ DrawioFileSync.prototype.fileSaved = function(pages, lastDesc, success, error)
 			var diff = this.ui.diffPages(shadow, pages);
 			
 			// Data is stored in cache and message is sent to all listeners
+			var etag = this.file.getDescriptorEtag(lastDesc);
+			var current = this.file.getCurrentEtag();
+			
+			details.from = this.ui.hashValue(etag);
+			details.to = this.ui.hashValue(current);
+			
 			var data = this.objectToString(this.createMessage({patch: diff, checksum: checksum, details: details}));
 			var msg = this.objectToString(this.createMessage({m: this.lastModified.getTime()}));
 			var secret = this.file.getDescriptorSecret(this.file.getDescriptor());
-			var etag = this.file.getDescriptorEtag(lastDesc);
-			var current = this.file.getCurrentEtag();
+
 			this.file.stats.bytesSent += data.length;
 			this.file.stats.msgSent++;
 	

+ 28 - 0
src/main/webapp/js/diagramly/DriveFile.js

@@ -260,6 +260,34 @@ DriveFile.prototype.saveFile = function(title, revision, success, error, unloadi
 	}
 };
 
+/**
+ * Shows a conflict dialog to the user.
+ */
+DriveFile.prototype.copyFile = function(success, error)
+{
+	if (!this.isRestricted())
+	{
+		this.makeCopy(mxUtils.bind(this, function()
+		{
+			if (this.ui.spinner.spin(document.body, mxResources.get('saving')))
+			{
+				try
+				{
+					this.save(true, success, error)
+				}
+				catch (e)
+				{
+					error(e);
+				}
+			}
+		}), error, true);
+	}
+	else
+	{
+		DrawioFile.prototype.copyFile.apply(this, arguments);
+	}	
+};
+
 /**
  * Shows a conflict dialog to the user.
  */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
src/main/webapp/js/embed-static.min.js


+ 3 - 7
src/main/webapp/js/mxgraph/Graph.js

@@ -2687,7 +2687,7 @@ Graph.prototype.isCellConnectable = function(cell)
 	var state = this.view.getState(cell);
 	var style = (state != null) ? state.style : this.getCellStyle(cell);
 	
-	return (style['connectable'] != null) ? style['connectable']  != '0' :
+	return (style['connectable'] != null) ? style['connectable'] != '0' :
 		mxGraph.prototype.isCellConnectable.apply(this, arguments);
 };
 
@@ -3750,13 +3750,9 @@ HoverIcons.prototype.getState = function(state)
 	{
 		var cell = state.cell;
 		
-		if (!this.graph.getModel().contains(cell))
+		// Uses connectable parent vertex if child is not connectable
+		if (this.graph.getModel().isVertex(cell) && !this.graph.isCellConnectable(cell))
 		{
-			return null;
-		}
-		else if (this.graph.getModel().isVertex(cell) && !this.graph.isCellConnectable(cell))
-		{
-			// Uses connectable parent vertex if child is not connectable
 			var parent = this.graph.getModel().getParent(cell);
 			
 			if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 14 - 0
src/main/webapp/js/onedrive/OneDrive.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 10 - 0
src/main/webapp/js/onedrive/OneDriveOrig.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
src/main/webapp/js/reader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 40 - 40
src/main/webapp/js/viewer.min.js